BFD_RELOC_MIPS_16

Maciej W. Rozycki macro@orcam.me.uk
Fri Aug 5 15:13:07 GMT 2022


On Thu, 4 Aug 2022, Alan Modra wrote:

> > > time.  Like BFD_RELOC_8, BFD_RELOC_16 now has no corresponding object
> > > file relocation, and thus .half, .hword, .short and .dc.w must be
> > > resolved at assembly time.
> > 
> >  That should be R_MIPS_REL16 AFAICT, reloc #33 according to MIPS NewABI 
> > documentation[1]:
> > 
> >     Name      Value  Field   Symbol  Calculation
> > R_MIPS_REL16   33    V-hw16   any        S+A
> 
> Huh.  So R_MIPS_REL16 isn't a pc-relative reloc as the name might
> indicate.  I'll apply the following.

 It's not clear to me what the REL infix might imply here given how other 
relevant relocations have been defined:

    Name      Value   Field    Symbol  Calculation
R_MIPS_16       1    V-half16   any    S+sign_extend(A)
R_MIPS_REL32    3    T-word32   any    S+A-EA
R_MIPS_PC16    10    V-pc16     any    sign_extend(A)+S-P

but the calculation given is I believe unambiguous and refers neither EA 
(effective address; meaningful for dynamic loading only and referring to 
factoring the base address into the calculation) nor P (PC).

 Of course I cannot claim the document is flawless; even the definition of 
R_MIPS_16 carried over from the old ABI isn't right anymore given that 
NewABI has RELA relocations.  Maybe IRIX actually implemented R_MIPS_REL16 
in a different manner.  I have no means to verify that however, so the 
document is the best resource we have.

 Last but not least please note that NewABI makes heavy use of composed 
relocations, so R_MIPS_REL16 may have just been a way to specify a 16-bit 
relocatable field, useful for compact jump tables for example, especially 
given the relocation's straightforward calculation, and R_MIPS_16 had 
already been taken so a different name had to be come up with.  Then you 
can compose R_MIPS_PC16 with R_MIPS_REL16 to make a PC-relative 16-bit 
relocatable field, similarly to how say a 64-bit base-address-relative 
relocatable field is made by composing R_MIPS_REL32 (alias R_MIPS_REL) 
with R_MIPS_64.

 The latter operation is documented in the specification referred as are 
a couple of other ones[1]:

"The initial elf.h file defined several relocations for dealing with GOTs 
larger than 64KB which we do not include, favoring other approaches as 
described above:

" R_MIPS_REL64
                 This can be produced by composing R_MIPS_REL with
                 R_MIPS_64.

" R_MIPS_LIT_HI16, R_MIPS_LIT_LO16
                 These can be produced by composing R_MIPS_LITERAL
                 with R_MIPS_HI16 or R_MIPS_LO16.

" R_MIPS_GPOFF_HI16, R_MIPS_GPOFF_LO16
                 As described above, these can be produced by composing
                 R_MIPS_GPREL with R_MIPS_HI16 or R_MIPS_LO16."

but the list is by no means exhaustive given that relocation composition 
is a generic ELF feature (even is scarcely implemented).  So I'm now quite 
convinced the calculation is right and only the name of the relocation 
misleading.

> 	* elf64-mips.c (mips_reloc_map): Map BFD_RELOC_16 to R_MIPS_REL16.
> 	* elfn32-mips.c (mips_reloc_map): Likewise.

 LGTM, thanks!

References:

[1] "64-bit ELF Object File Specification", Draft Version 2.5, MIPS
    Technologies / Silicon Graphics Computer Systems, Document Number
    007-4658-001, Section 2.9.4 "Discarded Relocations", pp. 52-53

  Maciej


More information about the Binutils mailing list