This is the mail archive of the binutils@sources.redhat.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]

Re: R_ARC_B22_PCREL relocs busted?


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




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