_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:
Alan Modra 2023-04-29 11:00:30 +09:30
parent 59305ae624
commit e84ca83738

View File

@ -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,
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,
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)
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
carry or borrow will induce a change of +1 or -1 in the high part. */
hi->rel.addend += (vallo + 0x8000) & 0xffff;
hi->rel.addend += vallo;
ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
hi->input_section, output_bfd,