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