This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
revised patch for m32r gas relocations
- To: binutils at sourceware dot cygnus dot com
- Subject: revised patch for m32r gas relocations
- From: Donald Lindsay <dlindsay at cygnus dot com>
- Date: Mon, 27 Mar 2000 15:39:57 -0800 (PST)
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)