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