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]

R_ARC_B22_PCREL relocs busted?


Folks,

In the ARC target, it looks like pc-relative branches fixed during linking
are busted.  Note that I did pick up the recent fixes to enable
partial_inplace and disable pcrel_offset in bfd/elf32-arc.c.

To reproduce, take the two source files below and assemble separately, then
link.

1.s:
===
.extern _myfunc
.global main
.text
main:
  nop
  nop
  bl _myfunc
  b main

2.s:
===
.text
.global _myfunc
_myfunc:
  j.f [blink]

Here is the resulting disassembly:

a.out:     file format elf32-littlearc

Disassembly of section .text:

00000074 <main>:
  74:   ff ff ff 7f     7fffffff     nop
  78:   ff ff ff 7f     7fffffff     nop
  7c:   80 01 00 28     28000180     bl         8c <_myfunc+0x8>

  80:   00 fe ff 27     27fffe00     b          74 <main>


00000084 <_myfunc>:
  84:   00 81 0f 38     380f8100     j.f        [blink]

I have come up with a patch for this but I'm certain that I'm just
addressing the symptom, not the root of the problem.  Perhaps a coordinated
change between the assembler and linker would be better.  Also, I'm not
certain if I've caught all the appropriate conditions under which the addend
fudge needs to be applied.  If those in the know (Nick?) could have a look
and determine the correct solution, it would be appreciated.

Thanks,

Andre Paquette

Index: elf32-arc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arc.c,v
retrieving revision 1.8
diff -C3 -r1.8 elf32-arc.c
*** elf32-arc.c	2001/09/18 09:57:23	1.8
--- elf32-arc.c	2001/09/20 14:34:29
***************
*** 32,37 ****
--- 32,39 ----
    PARAMS ((bfd *));
  static void arc_elf_final_write_processing
    PARAMS ((bfd *, boolean));
+ static bfd_reloc_status_type arc_elf_pcrel_reloc
+   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).
*/
***************
*** 93,99 ****
  	 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  */
--- 95,101 ----
  	 true,			/* pc_relative  */
  	 7,			/* bitpos  */
  	 complain_overflow_signed, /* complain_on_overflow  */
! 	 arc_elf_pcrel_reloc,	/* special_function  */
  	 "R_ARC_B22_PCREL",	/* name  */
  	 true,			/* partial_inplace  */
  	 0x07ffff80,		/* src_mask  */
***************
*** 101,106 ****
--- 103,144 ----
  	 false),		/* pcrel_offset  */
  
  };
+ 
+ /* Taken from elf.c, bfd_elf_generic_reloc with the exception that
+  * the addend gets fudged when passed to the linker. */
+ 
+ bfd_reloc_status_type
+ arc_elf_pcrel_reloc (abfd,
+ 		       reloc_entry,
+ 		       symbol,
+ 		       data,
+ 		       input_section,
+ 		       output_bfd,
+ 		       error_message)
+      bfd *abfd ATTRIBUTE_UNUSED;
+      arelent *reloc_entry;
+      asymbol *symbol;
+      PTR data ATTRIBUTE_UNUSED;
+      asection *input_section;
+      bfd *output_bfd;
+      char **error_message ATTRIBUTE_UNUSED;
+ {
+   if (output_bfd != (bfd *) NULL
+       && (symbol->flags & BSF_SECTION_SYM) == 0
+       && (! reloc_entry->howto->partial_inplace
+ 	  || reloc_entry->addend == 0))
+     {
+       reloc_entry->address += input_section->output_offset;
+       return bfd_reloc_ok;
+     }
+ 
+   /* If linking, back up the final symbol address by the address
+      of the reloc.  */
+   if (output_bfd == (bfd *) NULL)
+     reloc_entry->addend -= reloc_entry->address;
+ 
+   return bfd_reloc_continue;
+ }
  
  /* Map BFD reloc types to ARC ELF reloc types.  */
    


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