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]

revised revised patch for m32r gas relocations



A few days ago I circulated a patch for all the partial_inplace
m32r relocs. There were two suggestions:

(1) the lo16 reloc routine could be cleaned up, so that it called the new
m32r_elf_generic_reloc(), instead of doing things for itself.

(2) m32r_elf_generic_reloc didn't handle 16 bit relocs (howto->size==1) in
the same manner as bfd_install_relocation, ie there was a bug that
c-torture didn't catch.

This patch addresses both those concerns. The patch is relative
to a file which has (only) the lo16 fix installed.

It has passed the same testing as the last one.

A ChangeLog entry:

Mon Mar 27 15:28:00 2000  Donald Lindsay  <dlindsay@cygnus.com>

	* elf32-m32r.c (m32r_elf_generic_reloc): new function.  All
	HOWTO references to bfd_elf_generic_reloc, that have
	partial_inplace == true, now use the new function.  The function
	is based on the recent rewrite of m32r_elf_lo16_reloc(), and
	extends its fixes to the R_M32R_{16,24,32} relocs.
	The new logic in m32r_elf_lo16_reloc() has been removed, and
	it instead calls the new routine to obtain that functionality.


Index: elf32-m32r.c
===================================================================
RCS file: /cvs/cvsfiles/devo/bfd/elf32-m32r.c,v
retrieving revision 1.30
diff -p -r1.30 elf32-m32r.c
*** elf32-m32r.c	2000/03/14 18:21:18	1.30
--- elf32-m32r.c	2000/03/30 20:39:50
*************** static void m32r_elf_relocate_hi16
*** 35,40 ****
--- 35,42 ----
  	   bfd_byte *, bfd_vma));
  bfd_reloc_status_type m32r_elf_lo16_reloc
    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+ bfd_reloc_status_type m32r_elf_generic_reloc
+   PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
  static bfd_reloc_status_type m32r_elf_sda16_reloc
    PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
  static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
*************** static reloc_howto_type m32r_elf_howto_t
*** 105,111 ****
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_bitfield, /* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
  	 "R_M32R_16",		/* name */
  	 true,			/* partial_inplace */
  	 0xffff,		/* src_mask */
--- 107,113 ----
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_bitfield, /* complain_on_overflow */
! 	 m32r_elf_generic_reloc,/* special_function */
  	 "R_M32R_16",		/* name */
  	 true,			/* partial_inplace */
  	 0xffff,		/* src_mask */
*************** static reloc_howto_type m32r_elf_howto_t
*** 120,126 ****
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_bitfield, /* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
  	 "R_M32R_32",		/* name */
  	 true,			/* partial_inplace */
  	 0xffffffff,		/* src_mask */
--- 122,128 ----
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_bitfield, /* complain_on_overflow */
! 	 m32r_elf_generic_reloc,/* special_function */
  	 "R_M32R_32",		/* name */
  	 true,			/* partial_inplace */
  	 0xffffffff,		/* src_mask */
*************** static reloc_howto_type m32r_elf_howto_t
*** 135,141 ****
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_unsigned, /* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
  	 "R_M32R_24",		/* name */
  	 true,			/* partial_inplace */
  	 0xffffff,		/* src_mask */
--- 137,143 ----
  	 false,			/* pc_relative */
  	 0,			/* bitpos */
  	 complain_overflow_unsigned, /* complain_on_overflow */
! 	 m32r_elf_generic_reloc,/* special_function */
  	 "R_M32R_24",		/* name */
  	 true,			/* partial_inplace */
  	 0xffffff,		/* src_mask */
*************** m32r_elf_lo16_reloc (input_bfd, reloc_en
*** 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;
--- 510,515 ----
*************** m32r_elf_lo16_reloc (input_bfd, reloc_en
*** 564,570 ****
--- 551,595 ----
       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.  */
+   return m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
+ 				input_section, output_bfd, error_message);
+ }
+ 
+ /* Do generic partial_inplace relocation.  
+    This is a local replacement for bfd_elf_generic_reloc. */
  
+ bfd_reloc_status_type
+ m32r_elf_generic_reloc (input_bfd, reloc_entry, symbol, data,
+ 		     input_section, output_bfd, error_message)
+      bfd *input_bfd;
+      arelent *reloc_entry;
+      asymbol *symbol;
+      PTR data;
+      asection *input_section;
+      bfd *output_bfd;
+      char **error_message;
+ {
+   bfd_reloc_status_type ret;
+   bfd_vma relocation;
+   bfd_byte *inplace_address;
+ 
+   /* 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;
+     }
+ 
+   /* Now do the the 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;
*************** m32r_elf_lo16_reloc (input_bfd, reloc_en
*** 588,597 ****
      }
  
    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;
--- 613,644 ----
      }
  
    relocation += reloc_entry->addend;
+   inplace_address = data + reloc_entry->address;
  
! #define DOIT(x) 					\
!   x = ( (x & ~reloc_entry->howto->dst_mask) | 		\
!   (((x & reloc_entry->howto->src_mask) +  relocation) &	\
!   reloc_entry->howto->dst_mask))
! 
!   switch (reloc_entry->howto->size)
!     {
!     case 1:
!       {
! 	short x = bfd_get_16 (input_bfd, inplace_address);
! 	DOIT (x);
!       	bfd_put_16 (input_bfd, x, inplace_address);
!       }
!       break;
!     case 2:
!       {
! 	unsigned long x = bfd_get_32 (input_bfd, inplace_address);
! 	DOIT (x);
!       	bfd_put_32 (input_bfd, x, inplace_address);
!       }
!       break;
!     default:
!       BFD_ASSERT (0);
!     }
  
    if (output_bfd != (bfd *) NULL)
      reloc_entry->address += input_section->output_offset;



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