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


Roland McGrath wrote:
>> 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.

Is this useful for anything?

> 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,

(non-ET_REL I assume)

> 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.)

At this time, dwarflint gives an error if ET_REL file misses a 
relocation, but does relocation even in non-ET_REL files, if they are 
present.  According to what you say, it should instead ignore relocation 
sections in non-ET_REL files.

Now what about DW_OP_call_ref, and others that Dwarf3 document claims to 
be "relocatable in a relocatable object file, and relocated in an 
executable or shared object"?  These are basically the reason why I 
never had any doubts that I should handle relocations in non-ET_REL files.

Alan Modra's advice (from Jan's email, ignoring relocs that use normal 
symbol table) seems reasonable to me.

PM

Attachment: signature.asc
Description: PGP signature


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