This is the mail archive of the binutils@sourceware.cygnus.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH to elf32-mips.c for HI16 in REL sections



Here's a patch for another bug (checked in).

When calculating the value of a R_MIPS_HI16 relocation, we must scan
ahead to find the addend for the R_MIPS_LO16 relocation in the object
file (if we're not using RELA relocations).  We were finding the
relocation, but forgot that we're using REL relocations, and therefore
didn't get the right addend.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-08-03  Mark Mitchell  <mark@codesourcery.com>

	* elf32-mips.c (mips_elf_next_lo16_addend): Rename to ...
	(mips_elf_next_lo16_relocation): Don't compute the addend here.
	Just return the relocation found.
	(mips_elf_relocate_section): Pull the LO16 addend out of the
	section itself when using REL relocations.
	
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.42
diff -c -p -r1.42 elf32-mips.c
*** elf32-mips.c	1999/08/03 16:58:26	1.42
--- elf32-mips.c	1999/08/04 03:51:39
*************** static boolean mips_elf_record_global_go
*** 165,172 ****
  	   struct mips_got_info *));
  static bfd_vma mips_elf_got_page
    PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *));
! static boolean mips_elf_next_lo16_addend
!   PARAMS ((const Elf_Internal_Rela *, const Elf_Internal_Rela *, bfd_vma *));
  static bfd_reloc_status_type mips_elf_calculate_relocation
    PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *,
  	   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
--- 165,172 ----
  	   struct mips_got_info *));
  static bfd_vma mips_elf_got_page
    PARAMS ((bfd *, struct bfd_link_info *, bfd_vma, bfd_vma *));
! static const Elf_Internal_Rela *mips_elf_next_lo16_relocation
!   PARAMS ((const Elf_Internal_Rela *, const Elf_Internal_Rela *));
  static bfd_reloc_status_type mips_elf_calculate_relocation
    PARAMS ((bfd *, bfd *, asection *, struct bfd_link_info *,
  	   const Elf_Internal_Rela *, bfd_vma, reloc_howto_type *,
*************** mips_elf_got16_entry (abfd, info, value)
*** 5563,5577 ****
    return index;
  }
  
! /* Sets *ADDENDP to the addend for the first R_MIPS_LO16 relocation
!    found, beginning with RELOCATION.  RELEND is one-past-the-end of
!    the relocation table.  */
  
! static boolean
! mips_elf_next_lo16_addend (relocation, relend, addendp)
       const Elf_Internal_Rela *relocation;
       const Elf_Internal_Rela *relend;
-      bfd_vma *addendp;
  {
    /* According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must be
       immediately following.  However, for the IRIX6 ABI, the next
--- 5563,5575 ----
    return index;
  }
  
! /* Returns the first R_MIPS_LO16 relocation found, beginning with
!    RELOCATION.  RELEND is one-past-the-end of the relocation table.  */
  
! static const Elf_Internal_Rela *
! mips_elf_next_lo16_relocation (relocation, relend)
       const Elf_Internal_Rela *relocation;
       const Elf_Internal_Rela *relend;
  {
    /* According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must be
       immediately following.  However, for the IRIX6 ABI, the next
*************** mips_elf_next_lo16_addend (relocation, r
*** 5582,5598 ****
    while (relocation < relend)
      {
        if (ELF32_R_TYPE (relocation->r_info) == R_MIPS_LO16)
! 	{
! 	  *addendp = relocation->r_addend;
! 	  return true;
! 	}
  
        ++relocation;
      }
  
    /* We didn't find it.  */
    bfd_set_error (bfd_error_bad_value);
!   return false;
  }
  
  /* Create a rel.dyn relocation for the dynamic linker to resolve.  The
--- 5580,5593 ----
    while (relocation < relend)
      {
        if (ELF32_R_TYPE (relocation->r_info) == R_MIPS_LO16)
! 	return relocation;
  
        ++relocation;
      }
  
    /* We didn't find it.  */
    bfd_set_error (bfd_error_bad_value);
!   return NULL;
  }
  
  /* Create a rel.dyn relocation for the dynamic linker to resolve.  The
*************** _bfd_mips_elf_relocate_section (output_b
*** 6529,6541 ****
  		      && mips_elf_local_relocation_p (input_bfd, rel,
  						      local_sections)))
  		{
  		  /* Scan ahead to find a matching R_MIPS_LO16
  		     relocation.  */
! 		  bfd_vma l;
! 		  
! 		  if (!mips_elf_next_lo16_addend (rel, relend, &l))
  		    return false;
  
  		  /* Save the high-order bit for later.  When we
  		     encounter the R_MIPS_LO16 relocation we will need
  		     them again.  */
--- 6524,6547 ----
  		      && mips_elf_local_relocation_p (input_bfd, rel,
  						      local_sections)))
  		{
+ 		  bfd_vma l;
+ 		  const Elf_Internal_Rela *lo16_relocation;
+ 		  reloc_howto_type *lo16_howto;
+ 
  		  /* Scan ahead to find a matching R_MIPS_LO16
  		     relocation.  */
! 		  lo16_relocation 
! 		    = mips_elf_next_lo16_relocation (rel, relend); 
! 		  if (lo16_relocation == NULL)
  		    return false;
  
+ 		  /* Obtain the addend kept there.  */
+ 		  lo16_howto = mips_rtype_to_howto (R_MIPS_LO16);
+ 		  l = mips_elf_obtain_contents (lo16_howto,
+ 						lo16_relocation,
+ 						input_bfd, contents);
+ 		  l &= lo16_howto->src_mask;
+ 
  		  /* Save the high-order bit for later.  When we
  		     encounter the R_MIPS_LO16 relocation we will need
  		     them again.  */
*************** _bfd_mips_elf_relocate_section (output_b
*** 6607,6613 ****
  	     then we only want to write out the high-order 16 bits.
  	     The subsequent R_MIPS_LO16 will handle the low-order bits.  */
  	  if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16)
! 	    addend >>= 16;
  	  /* If the relocation is for an R_MIPS_26 relocation, then
  	     the two low-order bits are not stored in the object file;
  	     they are implicitly zero.  */
--- 6613,6619 ----
  	     then we only want to write out the high-order 16 bits.
  	     The subsequent R_MIPS_LO16 will handle the low-order bits.  */
  	  if (r_type == R_MIPS_HI16 || r_type == R_MIPS_GOT16)
! 	    addend = mips_elf_high (addend);
  	  /* If the relocation is for an R_MIPS_26 relocation, then
  	     the two low-order bits are not stored in the object file;
  	     they are implicitly zero.  */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]