forked from Imagelibrary/binutils-gdb
_bfd_mips_elf_lo16_reloc vallo comment
This explains exactly why the high reloc adjustment is as it is, replacing the rather nebulous existing comment. I've also changed the expression from (lo+0x8000)&0xffff to (lo&0xffff)^0x8000 which better matches part of the standard 16-bit sign extension (resulting in exactly the same value), and hoisted the calculation out of the loop. * elfxx-mips.c (_bfd_mips_elf_lo16_reloc): Expand vallo comment. Hoist calculation out of loop.
This commit is contained in:
@@ -2624,7 +2624,21 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
|
|||||||
|
|
||||||
_bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false,
|
_bfd_mips_elf_reloc_unshuffle (abfd, reloc_entry->howto->type, false,
|
||||||
location);
|
location);
|
||||||
vallo = bfd_get_32 (abfd, location);
|
/* The high 16 bits of the addend are stored in the high insn, the
|
||||||
|
low 16 bits in the low insn, but there is a catch: You can't
|
||||||
|
just concatenate the high and low parts. The high part of the
|
||||||
|
addend is adjusted for the fact that the low part is sign
|
||||||
|
extended. For example, an addend of 0x38000 would have 0x0004 in
|
||||||
|
the high part and 0x8000 (=0xff..f8000) in the low part.
|
||||||
|
To extract the actual addend, calculate (a)
|
||||||
|
((hi & 0xffff) << 16) + ((lo & 0xffff) ^ 0x8000) - 0x8000.
|
||||||
|
We will be applying (symbol + addend) & 0xffff to the low insn,
|
||||||
|
and we want to apply (b) (symbol + addend + 0x8000) >> 16 to the
|
||||||
|
high insn (the +0x8000 adjusting for when the applied low part is
|
||||||
|
negative). Substituting (a) into (b) and recognising that
|
||||||
|
(hi & 0xffff) is already in the high insn gives a high part
|
||||||
|
addend adjustment of (lo & 0xffff) ^ 0x8000. */
|
||||||
|
vallo = (bfd_get_32 (abfd, location) & 0xffff) ^ 0x8000;
|
||||||
_bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, false,
|
_bfd_mips_elf_reloc_shuffle (abfd, reloc_entry->howto->type, false,
|
||||||
location);
|
location);
|
||||||
|
|
||||||
@@ -2648,9 +2662,7 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
|
|||||||
else if (hi->rel.howto->type == R_MICROMIPS_GOT16)
|
else if (hi->rel.howto->type == R_MICROMIPS_GOT16)
|
||||||
hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MICROMIPS_HI16, false);
|
hi->rel.howto = MIPS_ELF_RTYPE_TO_HOWTO (abfd, R_MICROMIPS_HI16, false);
|
||||||
|
|
||||||
/* VALLO is a signed 16-bit number. Bias it by 0x8000 so that any
|
hi->rel.addend += vallo;
|
||||||
carry or borrow will induce a change of +1 or -1 in the high part. */
|
|
||||||
hi->rel.addend += (vallo + 0x8000) & 0xffff;
|
|
||||||
|
|
||||||
ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
|
ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
|
||||||
hi->input_section, output_bfd,
|
hi->input_section, output_bfd,
|
||||||
|
|||||||
Reference in New Issue
Block a user