This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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: [patch] MIPS: Incorrect calculation for R_MIPS_LO16 relocs


"Maciej W. Rozycki" <macro@linux-mips.org> writes:
>  There is a problem in BFD with calculation done for R_MIPS_LO16
> relocations upon a final link when the associated symbol is placed in a
> mergeable section containing strings.  In this case only the low 16 bits
> of the addend retrieved from the relocation itself are used -- the
> corresponding high 16 bits (from either a R_MIPS_HI16 or a R_MIPS_GOT16
> relocations) are not retrieved.  The value is passed to 
> _bfd_merged_section_offset() which looks up a wrong string if the high 16 
> bits should be non-zero.  As a result, if symbol offsets change due to 
> merging, the relocation is not adjusted properly to point to the new 
> location.
>
>  The fix it to retrieve the corresponding high 16 bits and pass a complete
> addend to _bfd_merged_section_offset().  Here is a patch that does that.  
> The included test case illustrates the bug conditions -- with current
> binutils %lo(g) doesn't point to "g" after the final link anymore.  This
> bug has been originally observed with the Linux kernel when built with
> current gcc.

I'm uneasy about this approach.  In the ABI, R_MIPS_LO16 is defined
entirely in terms of its own offset.  Nothing says that the LO16 offset
is formed by adding in the high-part offset.  OK, so obviously there was
no need to, given that only the low 16 bits of the result matter.  But that
doesn't make this any less of an extra-ABI change.

IMO this should be fixed some other way.  Not quite sure yet, but I'll
have a prod.

Richard


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