diff options
author | Geoffrey Keating <geoffk@geoffk.org> | 2000-03-11 02:23:10 +0000 |
---|---|---|
committer | Geoffrey Keating <geoffk@geoffk.org> | 2000-03-11 02:23:10 +0000 |
commit | 7893e6a2a71b67caf5836923bd15afe4fd7d9cb3 (patch) | |
tree | 5898fcee002821b7da5c93df106d9fb616a98889 /bfd/elf32-mips.c | |
parent | bb2d6cd7b19cd82313963d2d878a94e6e85a38b6 (diff) | |
download | gdb-7893e6a2a71b67caf5836923bd15afe4fd7d9cb3.zip gdb-7893e6a2a71b67caf5836923bd15afe4fd7d9cb3.tar.gz gdb-7893e6a2a71b67caf5836923bd15afe4fd7d9cb3.tar.bz2 |
* elf32-mips.c (_bfd_mips_elf_relocate_section): Do proper
sign-extension and big-endian compensation for
R_MIPS_64 even in ld -r.
Diffstat (limited to 'bfd/elf32-mips.c')
-rw-r--r-- | bfd/elf32-mips.c | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c index 671dcb1..d91bab9 100644 --- a/bfd/elf32-mips.c +++ b/bfd/elf32-mips.c @@ -6668,6 +6668,10 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, Elf_Internal_Sym *sym; unsigned long r_symndx; + if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd) + && bfd_big_endian (input_bfd)) + rel->r_offset -= 4; + /* Since we're just relocating, all we need to do is copy the relocations back out to the object file, unless they're against a section symbol, in which case we need @@ -6724,6 +6728,43 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, writing will be source of the addend in the final link. */ addend &= howto->src_mask; + + if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd)) + /* See the comment above about using R_MIPS_64 in the 32-bit + ABI. Here, we need to update the addend. It would be + possible to get away with just using the R_MIPS_32 reloc + but for endianness. */ + { + bfd_vma sign_bits; + bfd_vma low_bits; + bfd_vma high_bits; + + if (addend & 0x80000000u) + sign_bits = 0xffffffffu; + else + sign_bits = 0; + + /* If we don't know that we have a 64-bit type, + do two separate stores. */ + if (bfd_big_endian (input_bfd)) + { + /* Store the sign-bits (which are most significant) + first. */ + low_bits = sign_bits; + high_bits = addend; + } + else + { + low_bits = addend; + high_bits = sign_bits; + } + bfd_put_32 (input_bfd, low_bits, + contents + rel->r_offset); + bfd_put_32 (input_bfd, high_bits, + contents + rel->r_offset + 4); + continue; + } + if (!mips_elf_perform_relocation (info, howto, rel, addend, input_bfd, input_section, contents, false)) @@ -6818,13 +6859,13 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section, bfd_vma low_bits; bfd_vma high_bits; - if (value & 0x80000000) - sign_bits = 0xffffffff; + if (value & 0x80000000u) + sign_bits = 0xffffffffu; else sign_bits = 0; - /* If only a 32-bit VMA is available do two separate - stores. */ + /* If we don't know that we have a 64-bit type, + do two separate stores. */ if (bfd_big_endian (input_bfd)) { /* Undo what we did above. */ |