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: Another relocation oddness


> In this file:
> kernel-debuginfo-2.6.29-0.258.rc8.git2.fc11.i586:usr:lib:debug:lib:modules:2.6.29-0.258.rc8.git2.fc11.i586:vmlinux

This is not an ET_REL file.  It's a final link that uses --emit-relocs.
The DWARF data (and all the rest) is fully relocated already.  

The kernel build uses --emit-relocs for the benefit of some post-processing
that turns the relocs (for allocated sections) into one big table used at
runtime to do simple in-place adjustments.  (Though the kernel binary is
ET_EXEC, basically it acts as if it were an ET_DYN with DT_TEXTREL and all
its relocs being just R_386_RELATIVE.)

To start with, it is probably fine not to even look for relocs in files
that are not ET_REL.  Whatever relocs they have are "extra information" and
not really needed to make sense of the DWARF data.  (But I'll continue with
the details of interpreting this data, in case we want to do the extra
checking just because.)

> I'm seeing relocations that seem wrong: the addend and the value of the 
> symbol the relocation is done against are the same.

These are SHT_REL, not SHT_RELA.  It doesn't have an addend, it only has an
in-place value.  When relocation still has to be done (as in an ET_REL),
the value in place acts as the addend (i.e. symbol value applied with +=).
When relocation has already been done, obviously this cannot be so.  The
final value is in place, and any original nonzero "addend" is lost.  

This is why prelink converts SHT_REL to SHT_RELA, btw.  In prelink cases,
the symbol is usually an undefined external.  Hence it has no way to figure
out the "original" symbol value added to the original "addend" in place.

Here we always have the original symbol value.  We can "derelocate" the
in-place value by subtracting the symbol value to recover the lost addend.

In normal non-ET_REL files, the relocs left in allocated sections are those
in the dynamic relocs.  That is, SHT_REL{,A} sections that are SHF_ALLOC
themselves.  Those are "normal" relocs, i.e. that have not been applied yet
so in-place values are just the addends (in SHT_REL).  

I suppose if someone used --emit-relocs in a normal dynamic link of an
executable or DSO, there might be both a dynamic reloc (in an
SHT_REL,SHF_ALLOC section) and a preserved reloc (in an SHT_REL,~SHF_ALLOC
reloc section) pointing to the same location in an allocated section.  But
nobody does that.  Moreover, in dwarflint we are only checking the relocs
that apply to non-allocated sections.  For all those, it is unambiguous
that the relocs have already been applied to the non-allocated section data.

Eventually we might want to be checking .eh_frame, the only allocated
section containing a DWARFish format.  In the outlying cases of pure
theory, .eh_frame could have dynamic relocs and have this ambiguity if it
also has --emit-relocs relocs.  But, 
1. the compiler is always smart enough to emit .eh_frame for PIC without TEXTREL
2. nobody really uses --emit-relocs with this
3. we will not be touching .eh_frame with the DWARF writer, it's an
   allocated section--so dwarflint checks on it are not crucial for our
   correctness checking (just for verifying against gcc/as/ld bugs)
4. we might decide to touch/rewrite .eh_frame in the DWARF writer,
   but would do so only in ET_REL files where this is all moot

One day #2 will probably stop being true in the kernel, because it will
start to have .eh_frame itself.  But it is statically linked with
--emit-relocs and never produces dynamic relocs, so again there is no
ambiguity.

So, the "more than complete enough" checking plan (i.e. where you bother
with reloc checks in non-ET_REL at all) would be as follows.  For a reloc
in an SHT_REL (not SHT_RELA) section in a non-ET_REL file, subtract the
symbol value (and barf if it's SHN_UNDEF)--note that since it's an ET_REL,
the st_value is the final value directly, not section-relative.  If there
is an SHT_REL,SHF_ALLOC section that applies to the section you are
checking, complain and punt (however you would if all its relocs were
unknown types or whatnot).  (If the SHT_REL,SHF_ALLOC section has a target
section that is not SHF_ALLOC, elflint should complain about that.)


Thanks,
Roland

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