This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Some elfutils/libdw/cfi comments


On Tue, 2010-06-15 at 20:34 -0700, Roland McGrath wrote:
> > But there is dwarf_offdie, which you can feed a "raw" Dwarf_Off. So you
> > can iterate with dwarf_nextcu and get the actual Dwarf_Die through
> > dwarf_offdie. It would be convenient (at least for my little hacking
> > project) to have something similar for CFI. Something like:
> > 
> > /* Compute what's known about a call frame for a FDE at a given offset.
> >    Returns 0 for success or -1 for errors.
> >    On success, *FRAME is a malloc'd pointer.  */
> > extern int dwarf_cfi_offframe (Dwarf_CFI *cache, Dwarf_Off offset,
> >                                Dwarf_Frame **frame)
> >   __nonnull_attribute__ (3);
> > 
> > If that makes sense, I could try to hack up something.
> 
> I'm not sure it does make sense.  I guess I don't really understand what
> information you want to get out of this.  An FDE is an artifact of the
> format, a set of PCs that is encoded together.  The Dwarf_Frame represents
> the state at one particular PC value.  So I can only guess what you mean
> this call would do.  Is it the same as dwarf_cfi_addrframe called on the
> address that is the first PC value covered by the FDE at OFFSET?

Yes, that was my intention.

> What information do you want to get out of that Dwarf_Frame?

OK, lets back up and better explain what I am trying to do.

For SystemTap we have a translation pass in which we use elfutils to
extract information from targets and a runtime pass in which we don't
use elfutils. For the cfi information at translation time we now just
extract the whole debug_frame and eh_frame information and at runtime we
have our own unwinder parse that. What I am really trying to do is make
the runtime pass more efficient by extracting at translation time just
what is needed from the FDEs (and CIEs).

The first part of this was creating a binary search table for
debug_frame tables (just like there is an eh_frame_hdr), that can then
be used at runtime to do a quick lookup. This works with just
dwarf_next_cfi (). But only because in the .debug_frame the FDE encoding
is always DW_EH_PE_absptr. So there is no need to read the CIEs. And the
size is either 4 or 8, depending on the elf class from e_ident. Which
means we can just use the "raw" Dwarf_CFI_Entry values.

But the same wouldn't work for recreating an eh_frame_hdr (in case it
was missing, which could be the case theoretically, although I have
never actually seen it in practice). It could be done of course, since
we "just" have to keep track of the CIEs, add a little parser for
augmentation string, and decode the addresses of the FDEs referring to
this CIE. But libdw/cfi.c already does all that, so it would be
convenient to reuse this.

The other use case would be to make sure all FDEs and CIEs are valid,
don't contain "out of bounds" pointers and all addresses are encoded in
the same way. So we could make the eh/debug_frame data as safe, to skip
all extra checking and reparsing of the augmentation data all the time.

> If you are interested in the PC bounds covered by the FDE, this is not a
> convenient way to get the upper bound, only the lower bound (i.e. if you
> had the internal struct dwarf_fde, only fde->start and not fde->end).  The
> addresses you get from dwarf_frame_info are the bounds of what PC that
> Dwarf_Frame applies to.  This is a subrange of the FDE's PC range, not the
> whole thing.  You can then iterate through the whole FDE's CFI program by
> calling dwarf_cfi_addrframe again on the end address, until you get an
> error because you hit a hole--but you may well just be moving into the next
> FDE if it's immediately adjacent.  You can only actually know the end of
> the FDE's range by decoding the bytes at Dwarf_FDE.start from your
> dwarf_next_cfi call, which requires looking up the CIE_pointer (possibly
> pointing later in the file after the FDE!) to grok its augmentation string
> so you know for sure how to decode the FDE's PC range.

OK. Reading back I think what I would really like is two or three
functions:
- Given the CIE_pointer from a Dwarf_FDE that returns the Dwarf_CIE.
- Given the augmentation data from a Dwarf_CIE that returns the ptr
  encoding used.
- Given an encoding and an address from the Dwarf_FDE (start/end) the
  decoded addresses.
Or a combination of the above.

Does that make sense as an extension?

Cheers,

Mark


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]