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]

dwarflint todo item


cf https://bugzilla.redhat.com/show_bug.cgi?id=546017#c4
and http://lists.dwarfstd.org/private.cgi/dwarf-discuss-dwarfstd.org/2009-December/000812.html

These two things merit lint warnings in the high-level stratum.

1. DW_AT_const_value with a constant form that is actually meant to be an
   address constant.  This is a problem for consumers, because they expect
   that only DW_FORM_addr operands need to be adjusted for PIC addresses,
   while constant forms are exact integer constants.  Only if the value of
   DW_AT_const_value is DW_FORM_addr do we know that we might need to apply
   an address adjustment at runtime.

   You can detect this in a few ways:

   In an ET_REL file, DW_FORM_data[48] with an operand that has a reloc
   record.  This is an entirely reliable test when you can do it.  For
   non-ET_REL files, you have to do some less perfect heuristics:

   We think it only comes up with the data[48] forms, so you don't need to
   try these heuristics with any other forms AFAICT.

   If the value lies within some ELF symbol's st_value+st_size range (or
   matches st_value exactly, in case of st_size=0), it was probably an
   address.

   If the DIE with DW_AT_const_value has a DW_AT_type (but use
   dwarf_attr_integrate or equivalent for indirections), then if
   that refers to a pointer type then it was probably an address.
   (You may need to follow levels of typedef and qualifier DIEs to
   find the DW_TAG_pointer_type or DW_TAG_reference_type and be sure.)

   If either or both of those is true, then it probably was an address that
   should have used DW_FORM_addr.  OTOH, if it was a pointer type and the
   value was 0, then that is probably a constant 0 whether or not any
   symbol has st_value=0.

2. In a DWARF expression, DW_OP_addr used with DW_OP_GNU_push_tls_address
   or DW_OP_form_tls_address.  This is a related problem, with the same
   issue for consumers, but the inverse false indication in what old
   compilers generate.

   The value on the stack before DW_OP_GNU_push_tls_address or
   DW_OP_form_tls_address is an offset into the TLS block, not an address.
   It doesn't get adjusted for any runtime bias like real addresses do.
   So using DW_OP_addr is wrong and should get a warning.

   For extra credit, you can test the constant value (either in wrong
   DW_OP_addr or right DW_OP_const*/lit*) for sanity.  This is really a
   separate item and not at all necessary, but extra sanity checks are
   always nice wishlist items.  In an ET_REL file, the value should always
   be one with a reloc record that uses a TLS *OFF reloc type (correct set
   of types is machine-dependent and would need a new ebl hook).  In other
   files, the value should always be inside the p_memsz of the PT_TLS phdr.

Both of these trip up consumers and so should get a suspicious/wrong
warning.  However, they both need to be in the quirks table for all extant
GCC versions.  We hope to have 4.6 (and 4.[45]-RH) changed to do these two
differently so that DW_{FORM,OP}_addr exactly matches the set of address
constants that require runtime adjustment.  But so far all GCC versions
emit the "wrong" patterns described above.


In all cases of DW_{FORM,OP}_addr, an extra check is for matching (having a
reloc pointing to, in ET_REL) an ELF symbol that is actually SHN_ABS.  That
is not really the compiler's fault, since it didn't know what strangeness
with linker scripts or hand assembly was going to produce that.  But it
will probably cause consumers to apply an adjustment when they shouldn't,
so a warning about it might be nice.


Thanks,
Roland

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