This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: R_ARC_B22_PCREL relocs busted?
- To: Andre Paquette <APaquette at Catena dot com>
- Subject: Re: R_ARC_B22_PCREL relocs busted?
- From: Nick Clifton <nickc at cambridge dot redhat dot com>
- Date: 02 Oct 2001 15:24:53 +0100
- Cc: Nick at north-pole dot nickc dot cambridge dot redhat dot com,Clifton at north-pole dot nickc dot cambridge dot redhat dot com,Andre at north-pole dot nickc dot cambridge dot redhat dot com,Paquette at north-pole dot nickc dot cambridge dot redhat dot com,"'binutils at sourceware dot cygnus dot com '" <binutils at sourceware dot cygnus dot com>
- References: <522FDAAFD532D511A0AB0002A51390EB3C89FB@cat01s2.catena.com>
Hi Andre,
[Sorry about the delay in replying].
> Note that if you just re-link the original objects after patching
> binutils, the problem appears to go away. If you both re-assemble
> and re-link, it comes out looking like what I've got above.
Yes you are right. In the end I have gone back to the patch that you
supplied and applied a variant of it. (See below). The only real
change I made was to add an explanatory comment and to have the new
function call bfd_elf_generic_reloc() rather than incorporating the
code from that function into this function. That way if the code in
elf.c changes you will not need to update this function.
I think that basically there is a bug in bfd_install_relocation /
bfd_perform_relocation with regard to the handling of the pcrel_offset
field. Changing them however is not a good idea, as they are generic
functions and they are used by lots of ports. So instead using a
special handler function is this simplest workaround.
Cheers
Nick
2001-10-02 Nick Clifton <nickc@cambridge.redhat.com>
* elf32-arc.c: Include libiberty.h
(R_ARC_B22_PCREL): Use arc_elf_b22_pcrel
(bfd_elf32_bfd_reloc_type_lookup): Use ARRAY_SIZE.
(arc_elf_pcrel_reloc): New function. Remove section offset
added by bfd_install_relocation before passing reloc on to
generic elf reloc handler.
Index: bfd/elf32-arc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arc.c,v
retrieving revision 1.8
diff -p -r1.8 elf32-arc.c
*** elf32-arc.c 2001/09/18 09:57:23 1.8
--- elf32-arc.c 2001/10/02 14:24:13
***************
*** 23,28 ****
--- 23,29 ----
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/arc.h"
+ #include "libiberty.h"
static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
*************** static boolean arc_elf_object_p
*** 32,37 ****
--- 33,40 ----
PARAMS ((bfd *));
static void arc_elf_final_write_processing
PARAMS ((bfd *, boolean));
+ static bfd_reloc_status_type arc_elf_b22_pcrel
+ PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
/* Try to minimize the amount of space occupied by relocation tables
on the ROM (not that the ROM won't be swamped by other ELF overhead). */
*************** static reloc_howto_type elf_arc_howto_ta
*** 93,105 ****
true, /* pc_relative */
7, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
! bfd_elf_generic_reloc, /* special_function */
"R_ARC_B22_PCREL", /* name */
true, /* partial_inplace */
0x07ffff80, /* src_mask */
0x07ffff80, /* dst_mask */
false), /* pcrel_offset */
-
};
/* Map BFD reloc types to ARC ELF reloc types. */
--- 96,107 ----
true, /* pc_relative */
7, /* bitpos */
complain_overflow_signed, /* complain_on_overflow */
! arc_elf_b22_pcrel, /* special_function */
"R_ARC_B22_PCREL", /* name */
true, /* partial_inplace */
0x07ffff80, /* src_mask */
0x07ffff80, /* dst_mask */
false), /* pcrel_offset */
};
/* Map BFD reloc types to ARC ELF reloc types. */
*************** bfd_elf32_bfd_reloc_type_lookup (abfd, c
*** 126,136 ****
{
unsigned int i;
! for (i = 0; i < sizeof (arc_reloc_map) / sizeof (struct arc_reloc_map); i++)
! {
! if (arc_reloc_map[i].bfd_reloc_val == code)
! return &elf_arc_howto_table[arc_reloc_map[i].elf_reloc_val];
! }
return NULL;
}
--- 128,137 ----
{
unsigned int i;
! for (i = ARRAY_SIZE (arc_reloc_map); i--;)
! if (arc_reloc_map[i].bfd_reloc_val == code)
! return elf_arc_howto_table + arc_reloc_map[i].elf_reloc_val;
!
return NULL;
}
*************** arc_elf_final_write_processing (abfd, li
*** 211,216 ****
--- 212,241 ----
elf_elfheader (abfd)->e_flags |= val;
}
+ bfd_reloc_status_type
+ arc_elf_b22_pcrel (abfd, reloc_entry, symbol, data, input_section,
+ output_bfd, error_message)
+ bfd * abfd;
+ arelent * reloc_entry;
+ asymbol * symbol;
+ PTR data;
+ asection * input_section;
+ bfd * output_bfd;
+ char ** error_message;
+ {
+ /* If linking, back up the final symbol address by the address of the
+ reloc. This cannot be accomplished by setting the pcrel_offset
+ field to true, as bfd_install_relocation will detect this and refuse
+ to install the offset in the first place, but bfd_perform_relocation
+ will still insist on removing it. */
+ if (output_bfd == (bfd *) NULL)
+ reloc_entry->addend -= reloc_entry->address;
+
+ /* Fall through to the default elf reloc handler. */
+ return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
+ input_section, output_bfd, error_message);
+ }
+
#define TARGET_LITTLE_SYM bfd_elf32_littlearc_vec
#define TARGET_LITTLE_NAME "elf32-littlearc"
#define TARGET_BIG_SYM bfd_elf32_bigarc_vec