aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog11
-rw-r--r--bfd/elf32-mips.c58
2 files changed, 32 insertions, 37 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d4c4d15..ea94b3e 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,14 @@
+Fri Oct 8 13:03:45 1999 Geoffrey Keating <geoffk@cygnus.com>
+
+ * elf32-mips.c (mips_elf_calculate_relocation): R_MIPS_LITERAL
+ relocs also need the GP value.
+ (_bfd_mips_elf_relocate_section): Handle unpaired LO16 relocs
+ properly. Handle sign-extension for R_MIPS_64 correctly. Correct
+ the GP value for R_MIPS_LITERAL relocs too. Handle
+ R_MIPS_64 relocs properly on big-endian MIPS.
+ (mips_elf_sign_extend): Behave properly with 'long long'.
+ (mips_elf_highest): Correct typo.
+
Mon Oct 4 17:49:45 1999 Nick Clifton <nickc@cygnus.com>
* cpu-m32r.c (arch_info_struct): New static global.
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index c114563..0e7dd08 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -5069,7 +5069,7 @@ mips_elf_sign_extend (value, bits)
bfd_vma value;
int bits;
{
- if (value & (1 << (bits - 1)))
+ if (value & ((bfd_vma)1 << (bits - 1)))
/* VALUE is negative. */
value |= ((bfd_vma) - 1) << bits;
@@ -5128,7 +5128,7 @@ mips_elf_highest (value)
bfd_vma value ATTRIBUTE_UNUSED;
{
#ifdef BFD64
- return ((value + (bfd_vma) 0x800080008000) > 48) & 0xffff;
+ return ((value + (bfd_vma) 0x800080008000) >> 48) & 0xffff;
#else
abort ();
return (bfd_vma) -1;
@@ -5946,6 +5946,7 @@ mips_elf_calculate_relocation (abfd,
case R_MIPS_LO16:
case R_MIPS_GPREL16:
case R_MIPS_GPREL32:
+ case R_MIPS_LITERAL:
gp0 = _bfd_get_gp_value (input_bfd);
gp = _bfd_get_gp_value (abfd);
break;
@@ -6412,9 +6413,7 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
Elf_Internal_Rela *rel;
const Elf_Internal_Rela *relend;
bfd_vma addend;
- bfd_vma last_hi16_addend;
boolean use_saved_addend_p = false;
- boolean last_hi16_addend_valid_p = false;
struct elf_backend_data *bed;
bed = get_elf_backend_data (output_bfd);
@@ -6432,13 +6431,20 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
/* Find the relocation howto for this relocation. */
if (r_type == R_MIPS_64 && !ABI_64_P (output_bfd))
- /* Some 32-bit code uses R_MIPS_64. In particular, people use
- 64-bit code, but make sure all their addresses are in the
- lowermost or uppermost 32-bit section of the 64-bit address
- space. Thus, when they use an R_MIPS_64 they mean what is
- usually meant by R_MIPS_32, with the exception that the
- stored value is sign-extended to 64 bits. */
- howto = elf_mips_howto_table + R_MIPS_32;
+ {
+ /* Some 32-bit code uses R_MIPS_64. In particular, people use
+ 64-bit code, but make sure all their addresses are in the
+ lowermost or uppermost 32-bit section of the 64-bit address
+ space. Thus, when they use an R_MIPS_64 they mean what is
+ usually meant by R_MIPS_32, with the exception that the
+ stored value is sign-extended to 64 bits. */
+ howto = elf_mips_howto_table + R_MIPS_32;
+
+ /* On big-endian systems, we need to lie about the position
+ of the reloc. */
+ if (bfd_big_endian (input_bfd))
+ rel->r_offset += 4;
+ }
else
howto = mips_rtype_to_howto (r_type);
@@ -6502,26 +6508,11 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
l &= lo16_howto->src_mask;
l = mips_elf_sign_extend (l, 16);
- /* Save the high-order bit for later. When we
- encounter the R_MIPS_LO16 relocation we will need
- them again. */
addend <<= 16;
- last_hi16_addend = addend;
- last_hi16_addend_valid_p = true;
/* Compute the combined addend. */
addend += l;
}
- else if (r_type == R_MIPS_LO16)
- {
- /* Used the saved HI16 addend. */
- if (!last_hi16_addend_valid_p)
- {
- bfd_set_error (bfd_error_bad_value);
- return false;
- }
- addend |= last_hi16_addend;
- }
else if (r_type == R_MIPS16_GPREL)
{
/* The addend is scrambled in the object file. See
@@ -6554,7 +6545,8 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
if (r_type == R_MIPS16_GPREL
|| r_type == R_MIPS_GPREL16
- || r_type == R_MIPS_GPREL32)
+ || r_type == R_MIPS_GPREL32
+ || r_type == R_MIPS_LITERAL)
addend -= (_bfd_get_gp_value (output_bfd)
- _bfd_get_gp_value (input_bfd));
else if (r_type == R_MIPS_26 || r_type == R_MIPS16_26)
@@ -6683,15 +6675,6 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
go to extreme lengths to support this usage on systems with
only a 32-bit VMA. */
{
-#ifdef BFD64
- /* Just sign-extend the value, and then fall through to the
- normal case, using the R_MIPS_64 howto. That will store
- the 64-bit value into a 64-bit area. */
- value = mips_elf_sign_extend (value, 64);
- howto = elf_mips_howto_table + R_MIPS_64;
-#else /* !BFD64 */
- /* In the 32-bit VMA case, we must handle sign-extension and
- endianness manually. */
bfd_vma sign_bits;
bfd_vma low_bits;
bfd_vma high_bits;
@@ -6705,6 +6688,8 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
stores. */
if (bfd_big_endian (input_bfd))
{
+ /* Undo what we did above. */
+ rel->r_offset -= 4;
/* Store the sign-bits (which are most significant)
first. */
low_bits = sign_bits;
@@ -6720,7 +6705,6 @@ _bfd_mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_put_32 (input_bfd, high_bits,
contents + rel->r_offset + 4);
continue;
-#endif /* !BFD64 */
}
/* Actually perform the relocation. */