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 patch for m32r gas relocations



Earlier this year we fixed a problem in bfd/elf32-m32r.c. It turned out
that we only fixed the problem in one reloc (well, three, R_M32R_LO16 and
its two HIs).  Last week I circulated a patch which gave the same fix to
R_M32R_32. There was some agreement that more relocs needed the fix, so
this is an extension of that patch to do all partial_inplace m32r relocs.

Specifically, all partial_inplace==TRUE references to
bfd_elf_generic_reloc() become references to a new routine,
m32r_elf_generic_reloc().  The new patch uses e.g.
reloc_entry->howto->src_mask, whereas last week's patch could assume a
constant mask value.

I tested this on my small test cases, which only create _HI16_, _LO16_ and
_32_ relocs. I also did before-and-after runs of make check-gcc, which hit
the multilibs

                    m32r-sim/-mmodel=small/-G 0/-m32r
                    m32r-sim/-mmodel=small/-G 0/-m32rx
                    m32r-sim/-mmodel=small/-msdata=use -G 8/-m32r
                    m32r-sim/-mmodel=small/-msdata=use -G 8/-m32rx
                    m32r-sim/-mmodel=medium/-G 0/-m32r
                    m32r-sim/-mmodel=medium/-G 0/-m32rx
                    m32r-sim/-mmodel=medium/-msdata=use -G 8/-m32r
                    m32r-sim/-mmodel=medium/-msdata=use -G 8/-m32rx
                    m32r-sim/-mmodel=large/-G 0/-m32r
                    m32r-sim/-mmodel=large/-G 0/-m32rx
                    m32r-sim/-mmodel=large/-msdata=use -G 8/-m32r
                    m32r-sim/-mmodel=large/-msdata=use -G 8/-m32rx

Before and after gcc.sum's were identical, except that "after" had 4 more
PASSes, by curing 4 instances of

	FAIL: gcc.c-torture/execute/920625-1.c execution,  -O1

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 recently rewritten m32r_elf_lo16_reloc(), and
	extends its fixes to the R_M32R_{16,24,32} relocs.





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/27 21:08:49
*************** 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
*** 591,596 ****
--- 593,668 ----
  
    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;
+ }
+ 
+ /* 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;
+   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;
+     }
+ 
+   /* 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;
+ 
+   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 & (0xffffffff - reloc_entry->howto->src_mask))
+ 	| (relocation & reloc_entry->howto->dst_mask);
    bfd_put_32 (input_bfd, insn, data + reloc_entry->address);
  
    if (output_bfd != (bfd *) NULL)



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