* elf32-mips.c: Fix addend for _gp_disp special symbol.

This commit is contained in:
Thiemo Seufer 2003-06-27 07:31:27 +00:00
parent d6e08ad8ab
commit 917090909e
2 changed files with 34 additions and 29 deletions

View File

@ -1,3 +1,7 @@
2003-06-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* elf32-mips.c: Fix addend for _gp_disp special symbol.
2003-06-27 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* elfxx-mips.c (_bfd_mips_elf_fake_sections): Remove non-default

View File

@ -887,41 +887,42 @@ mips_elf_lo16_reloc (abfd, reloc_entry, symbol, data, input_section,
unsigned long vallo;
struct mips_hi16 *next;
/* Do the HI16 relocation. Note that we actually don't need
to know anything about the LO16 itself, except where to
find the low 16 bits of the addend needed by the LO16. */
insn = bfd_get_32 (abfd, l->addr);
vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
/* The low order 16 bits are always treated as a signed
value. */
vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
val = ((insn & 0xffff) << 16) + vallo;
val += l->addend;
/* If PC-relative, we need to subtract out the address of the LO
half of the HI/LO. (The actual relocation is relative
to that instruction.) */
if (reloc_entry->howto->pc_relative)
val -= reloc_entry->address;
/* At this point, "val" has the value of the combined HI/LO
pair. If the low order 16 bits (which will be used for
the LO16 insn) are negative, then we will need an
adjustment for the high order 16 bits. */
val += 0x8000;
val = (val >> 16) & 0xffff;
insn &= ~ (bfd_vma) 0xffff;
insn |= val;
bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
{
gp_disp_relent = *reloc_entry;
reloc_entry = &gp_disp_relent;
reloc_entry->addend = l->addend;
}
else
{
/* Do the HI16 relocation. Note that we actually don't need
to know anything about the LO16 itself, except where to
find the low 16 bits of the addend needed by the LO16. */
insn = bfd_get_32 (abfd, l->addr);
vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
/* The low order 16 bits are always treated as a signed
value. */
vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
val = ((insn & 0xffff) << 16) + vallo;
val += l->addend;
/* If PC-relative, we need to subtract out the address of the LO
half of the HI/LO. (The actual relocation is relative
to that instruction.) */
if (reloc_entry->howto->pc_relative)
val -= reloc_entry->address;
/* At this point, "val" has the value of the combined HI/LO
pair. If the low order 16 bits (which will be used for
the LO16 insn) are negative, then we will need an
adjustment for the high order 16 bits. */
val += 0x8000;
val = (val >> 16) & 0xffff;
insn &= ~ (bfd_vma) 0xffff;
insn |= val;
bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
}
next = l->next;
free (l);