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]

Re: [patch] m32r gas relocation processing


: How about this instead?
: I've been slow in fully testing this [or it would have been installed
: already].  Maybe you can help?

  I didn't realize that you were looking at the same problem.  I had
  considered reworking the relocation routines in elf32-m32r.c but
  scrapped that approach in favor of mimicking the mips port.  It
  seems like we do some unecessary processing with this patch.  For
  example, do we need to build the hilist if we're generating relocs?
  My patch didn't really address that issue either.

  In general, I feel that the processing for REL relocations (when 
  we're actually emitting the relocs to a file), is too intertwined
  with the final relocation processing. This patch certainly fixes
  the test case and I'm fine with using it.

  This is dlindsay's issue though (I was just helping) so I'm going
  to let him do the tool chain testing.  Thanks.

  Catherine
  
2000-03-09  Doug Evans  <dje@casey.transmeta.com>

	* elf32-m32r.c (m32r_elf_lo16_reloc): Rewrite.

Index: elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.6
diff -c -p -r1.6 elf32-m32r.c
*** elf32-m32r.c	2000/03/01 19:40:53	1.6
--- elf32-m32r.c	2000/03/09 23:08:03
*************** m32r_elf_relocate_hi16 (input_bfd, type,
*** 498,506 ****
     R_M32R_HI16_[SU]LO relocation described above.  */
  
  bfd_reloc_status_type
! m32r_elf_lo16_reloc (abfd, reloc_entry, symbol, data,
  		     input_section, output_bfd, error_message)
!      bfd *abfd;
       arelent *reloc_entry;
       asymbol *symbol;
       PTR data;
--- 498,506 ----
     R_M32R_HI16_[SU]LO relocation described above.  */
  
  bfd_reloc_status_type
! m32r_elf_lo16_reloc (input_bfd, reloc_entry, symbol, data,
  		     input_section, output_bfd, error_message)
!      bfd *input_bfd;
       arelent *reloc_entry;
       asymbol *symbol;
       PTR data;
*************** m32r_elf_lo16_reloc (abfd, reloc_entry, 
*** 508,513 ****
--- 508,528 ----
       bfd *output_bfd;
       char **error_message;
  {
+   bfd_reloc_status_type ret;
+   bfd_vma relocation;
+   unsigned long insn;
+ 
+   /* This part is from bfd_elf_generic_reloc.
+      If we're relocating, and this an external symbol, we don't want
+      to change anything.  */
+   if (output_bfd != (bfd *) NULL
+       && (symbol->flags & BSF_SECTION_SYM) == 0
+       && reloc_entry->addend == 0)
+     {
+       reloc_entry->address += input_section->output_offset;
+       return bfd_reloc_ok;
+     }
+ 
    if (m32r_hi16_list != NULL)
      {
        struct m32r_hi16 *l;
*************** m32r_elf_lo16_reloc (abfd, reloc_entry, 
*** 523,530 ****
  	  /* 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)
  		   & 0xffff) ^ 0x8000) - 0x8000;
  	  val = ((insn & 0xffff) << 16) + vallo;
  	  val += l->addend;
--- 538,545 ----
  	  /* 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 (input_bfd, l->addr);
! 	  vallo = ((bfd_get_32 (input_bfd, (bfd_byte *) data + reloc_entry->address)
  		   & 0xffff) ^ 0x8000) - 0x8000;
  	  val = ((insn & 0xffff) << 16) + vallo;
  	  val += l->addend;
*************** m32r_elf_lo16_reloc (abfd, reloc_entry, 
*** 534,540 ****
  	    val += 0x10000;
  
  	  insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
! 	  bfd_put_32 (abfd, insn, l->addr);
  
  	  next = l->next;
  	  free (l);
--- 549,555 ----
  	    val += 0x10000;
  
  	  insn = (insn &~ 0xffff) | ((val >> 16) & 0xffff);
! 	  bfd_put_32 (input_bfd, insn, l->addr);
  
  	  next = l->next;
  	  free (l);
*************** m32r_elf_lo16_reloc (abfd, reloc_entry, 
*** 543,552 ****
  
        m32r_hi16_list = NULL;
      }
  
!   /* Now do the LO16 reloc in the usual way.  */
!   return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
! 				input_section, output_bfd, error_message);
  }
  
  /* Handle the R_M32R_SDA16 reloc.
--- 558,602 ----
  
        m32r_hi16_list = NULL;
      }
+ 
+   /* Now do the LO16 reloc in the usual way.
+      ??? It would be nice to call bfd_elf_generic_reloc here,
+      but we have partial_inplace == TRUE.  bfd_elf_generic_reloc will
+      pass the handling back to bfd_install_relocation which will install
+      a section relative addend which is wrong.  */
+ 
+   /* Sanity check the address (offset in section).  */
+   if (reloc_entry->address > input_section->_cooked_size)
+     return bfd_reloc_outofrange;
+ 
+   ret = bfd_reloc_ok;
+   if (bfd_is_und_section (symbol->section)
+       && output_bfd == (bfd *) NULL)
+     ret = bfd_reloc_undefined;
+ 
+   if (bfd_is_com_section (symbol->section)
+       || output_bfd != (bfd *) NULL)
+     relocation = 0;
+   else
+     relocation = symbol->value;
+ 
+   /* Only do this for a final link.  */
+   if (output_bfd == (bfd *) NULL)
+     {
+       relocation += symbol->section->output_section->vma;
+       relocation += symbol->section->output_offset;
+     }
+ 
+   relocation += reloc_entry->addend;
+ 
+   insn = bfd_get_32 (input_bfd, data + reloc_entry->address);
+   insn = (insn & 0xffff0000) | (relocation & 0xffff);
+   bfd_put_32 (input_bfd, insn, data + reloc_entry->address);
+ 
+   if (output_bfd != (bfd *) NULL)
+     reloc_entry->address += input_section->output_offset;
  
!   return ret;
  }
  
  /* Handle the R_M32R_SDA16 reloc.

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