From mboxrd@z Thu Jan 1 00:00:00 1970 From: Geoff Keating To: ian@zembu.com Cc: mark@codesourcery.com, gavin@cygnus.com, binutils@sourceware.cygnus.com, brendan@cygnus.com Subject: Re: Reloc changes to bfd/elf32-mips.c Date: Thu, 07 Oct 1999 04:47:00 -0000 Message-id: <199910071147.VAA02187@gluttony.geoffk.wattle.id.au> References: <199909271118.VAA01663@gluttony.geoffk.wattle.id.au> <19990928005956V.mitchell@codesourcery.com> <199909290330.NAA00657@gluttony.geoffk.wattle.id.au> <19990929035539.20417.qmail@daffy.airs.com> <199909290450.OAA00966@gluttony.geoffk.wattle.id.au> <19990929050239.26015.qmail@daffy.airs.com> <199910070151.LAA01021@gluttony.geoffk.wattle.id.au> <19991007023447.2184.qmail@daffy.airs.com> <199910070333.NAA01364@gluttony.geoffk.wattle.id.au> <19991007035232.2360.qmail@daffy.airs.com> X-SW-Source: 1999-10/msg00022.html OK, then, how about this? Note also the mips_elf_highest correction. -- Geoffrey Keating ===File ~/patches/cygnus/tx49-bin-literal-2.patch=========== md5sum: a6297c4d85f373cc de4c3a99fcc4f1be 197060 Index: binutils/bfd/ChangeLog 0a Thu Oct 7 21:31:03 1999 Geoffrey Keating * 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. . Changed files: binutils/bfd/ChangeLog binutils/bfd/elf32-mips.c md5sum: 965e5323396f23af 0cc7822e898c842b 265823 --- /sloth/disk0/co/binutils-mainline/binutils/bfd/elf32-mips.c Tue Sep 28 14:05:32 1999 +++ binutils/bfd/elf32-mips.c Thu Oct 7 21:37:28 1999 @@ -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_b 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_b /* 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_b 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_b 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_b 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_b 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_b bfd_put_32 (input_bfd, high_bits, contents + rel->r_offset + 4); continue; -#endif /* !BFD64 */ } /* Actually perform the relocation. */ ============================================================