]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Merge branch 'master' into roland/cfi
authorRoland McGrath <roland@redhat.com>
Wed, 23 Jun 2010 10:19:44 +0000 (03:19 -0700)
committerRoland McGrath <roland@redhat.com>
Wed, 23 Jun 2010 10:19:44 +0000 (03:19 -0700)
Conflicts:
libdw/cfi.c

1  2 
libdw/ChangeLog
libdw/cfi.c
libdw/libdw.h

diff --cc libdw/ChangeLog
index c22540aa8785f3a4ccf285d8dfbaedf009454433,7aca379505b5842e2cdca351d7d59e4eeb6c09bc..b671da8ff52c7189da349abb3091c0ade745809f
@@@ -1,27 -1,9 +1,33 @@@
+ 2010-06-23  Roland McGrath  <roland@redhat.com>
+       * cfi.c (dwarf_cfi_validate_fde): Function removed.
+       * libdw.h: Remove it.
+       * libdw.map: Likewise.
 +2010-06-23  Roland McGrath  <roland@redhat.com>
 +
 +      * cfi.c (dwarf_cfi_frames): New function.
 +      * libdw.h: Declare it.
 +
 +      * fde.c (__libdw_fde_by_offset): Take new argument NEXTOFF.
 +      If non-null, return -1 marker without error at end of section,
 +      skip CIEs, and store next offset.  Maintain fde_tailp and next.
 +      * cfi.h: Update decl.
 +
 +      * cfi.h (struct dwarf_fde): New member next.
 +      (struct Dwarf_CFI_s): New members first_fde, fde_tailp.
 +      * dwarf_getcfi.c (dwarf_getcfi): Initialize them.
 +      * dwarf_getcfi_elf.c (allocate_cfi): Likewise.
 +      * fde.c (intern_fde): Initialize next.
 +
 +      * cfi.c (clear_prev): New function, broken out of ...
 +      (execute_cfi): ... here.  Call it.  Take new flag argument; when
 +      false, stop at the first PC change and don't clear_prev.
 +      (cie_cache_initial_state, __libdw_frame_at_address): Update callers.
 +
 +      * cfi.h (struct Dwarf_Frame_s): New member fde_pc.
 +      * cfi.c (execute_cfi): Set it to pending PROGRAM pointer at return.
 +
  2010-06-22  Roland McGrath  <roland@redhat.com>
  
        * dwarf_getlocation.c (check_constant_offset): data[48] are constant.
diff --cc libdw/cfi.c
index 2ea7cfdd9829a5526a9ecd361201c512810157ac,aeb48e697931763c5ebb9a14dccb1978f90885b6..7dacfc8b38026ca35688d2e19e3a634bb3ef794e
@@@ -512,148 -504,3 +512,109 @@@ __libdw_frame_at_address (Dwarf_CFI *ca
      }
    return result;
  }
- int
- dwarf_cfi_validate_fde (cache, offset, start, end, signalp, encoding)
-      Dwarf_CFI *cache;
-      Dwarf_Off offset;
-      Dwarf_Addr *start;
-      Dwarf_Addr *end;
-      bool *signalp;
-      uint8_t *encoding;
- {
-   if (cache == NULL)
-     return -1;
-   struct dwarf_fde *fde = __libdw_fde_by_offset (cache, offset, NULL);
-   if (unlikely (fde == NULL))
-     return -1;
-   Dwarf_Frame *fs;
-   int result = __libdw_frame_at_address (cache, fde, fde->end, &fs);
-   if (unlikely (result != DWARF_E_NOERROR))
-     {
-       __libdw_seterrno (result);
-       return -1;
-     }
-   result = fs->nregs + 1;
-   free (fs);
-   if (start != NULL)
-     *start = fde->start;
-   if (end != NULL)
-     *end = fde->end;
-   if (signalp != NULL)
-     *signalp = fde->cie->signal_frame;
-   if (encoding != NULL)
-     *encoding = fde->cie->fde_encoding;
-   return result;
- }
 +
 +ptrdiff_t
 +dwarf_cfi_frames (Dwarf_CFI *cache, ptrdiff_t offset,
 +                void **state, Dwarf_Frame **framep)
 +{
 +  if (cache == NULL)
 +    return -1;
 +
 +  if (offset < 0)
 +    {
 +      /* Special case call for cleanup.  */
 +
 +      if (*state != NULL)
 +      {
 +        clear_prev (*state);
 +        free (*state);
 +        *state = NULL;
 +      }
 +      return 0;
 +    }
 +
 +  Dwarf_Frame *fs = *state;
 +
 +  struct dwarf_fde *fde;
 +  if (offset == 0)
 +    {
 +      /* Start at the beginning.  */
 +      assert (fs == NULL);
 +      fde = cache->first_fde ?: (void *) -1l;
 +    }
 +  else
 +    {
 +      /* Resume from the last iteration.  */
 +      assert (fs != NULL);
 +      fde = fs->fde;
 +      if (fs->fde_pc == fde->instructions_end)
 +      {
 +        /* We've hit the end of this FDE.  Move to the next one.  */
 +        clear_prev (fs);
 +        free (fs);
 +        *state = fs = NULL;
 +        fde = fde->next;
 +      }
 +    }
 +
 +  if (fs == NULL)
 +    {
 +      /* We're starting fresh on a new FDE.  */
 +
 +      if (fde == (void *) -1l)
 +      {
 +        /* No cached next FDE.  We have to intern the next one.  */
 +
 +        fde = __libdw_fde_by_offset (cache, offset, &offset);
 +        if (fde == (void *) -1l)
 +          /* End of the line.  */
 +          return 0;
 +      }
 +
 +      /* Start from this FDE's CIE's initial state.  */
 +      int result = cie_cache_initial_state (cache, fde->cie);
 +      if (likely (result == DWARF_E_NOERROR))
 +      {
 +        fs = duplicate_frame_state (fde->cie->initial_state, NULL);
 +        if (unlikely (fs == NULL))
 +          result = DWARF_E_NOMEM;
 +      }
 +      if (unlikely (result != DWARF_E_NOERROR))
 +      {
 +        __libdw_seterrno (result);
 +        return -1;
 +      }
 +
 +      fs->fde_pc = fde->instructions;
 +      *state = fs;
 +    }
 +
 +  /* Now play forward from the last position in the FDE.  */
 +
 +  assert (fs->fde == fde);
 +  assert (fs->fde_pc < fde->instructions_end);
 +  int result = execute_cfi (cache, fde->cie, &fs, false,
 +                          fs->fde_pc, fde->instructions_end, false,
 +                          fs->end, 0);
 +  if (likely (result == DWARF_E_NOERROR))
 +    {
 +      *framep = duplicate_frame_state (fs, NULL);
 +      if (unlikely (*framep == NULL))
 +      {
 +        clear_prev (fs);
 +        free (fs);
 +        fs = NULL;
 +        result = DWARF_E_NOMEM;
 +      }
 +    }
 +
 +  *state = fs;
 +
 +  if (unlikely (result != DWARF_E_NOERROR))
 +    {
 +      __libdw_seterrno (result);
 +      offset = -1;
 +    }
 +
 +  return offset;
 +}
diff --cc libdw/libdw.h
Simple merge