FW: SH-COFF PCREL relocation bug ( with proposed fix)

Dhananjay R. Deshpande dhananjayd@KPITCummins.com
Thu Jun 5 12:09:00 GMT 2003


Hi,

If the symbol in pc relative move insn is external and is undefined, the linker doesn't complain about undefined symbol. If external symbol is defined in other
file, the displacement is not calculated (is zero).

For e.g if the following code is assembled and linked with sh-coff tools - 

        .global start
        .extern foo        
	  .section .text
start:  mov.l   foo, r1
        mov.w   r0, @r1

the linker silently creates a.out without complaining about foo.

The bfd/coff-sh.c hunk in the patch below fixes this.

With this, if the symbol is outside the section but in the same file, the displacement is wrong. 

        .section .bss
        .global foo
        .align  1

foo:    .long   0

        .global start
        .section .text
start:  mov.l   foo, r1
        mov.w   r0, @r1

The hunk of gas/config/obj-coff.c in patch below does generate correct displacement after linking. But I am not sure if this is correct fix. I will like the assembler to not calculate the displacement in the case of symbol outside section and is it possible to handle the adjustment done in obj-coff.c in linker. I will appreciate if anybody more familiar with Binutils can suggest anything.

Regards,
Dhananjay

================================================================================
--- /home/kpit/fsfsrc/binutils-2.13.2.1/bfd/coff-sh.c	Sun Jul 14 06:43:51 2002
+++ binutils-2.13.2.1/bfd/coff-sh.c	Fri May 30 12:19:10 2003
@@ -2883,7 +2883,9 @@ sh_relocate_section (output_bfd, info, i
 	  && rel->r_type != R_SH_IMM32CE
 	  && rel->r_type != R_SH_IMAGEBASE
 #endif
-	  && rel->r_type != R_SH_PCDISP)
+	  && rel->r_type != R_SH_PCDISP
+	  && rel->r_type != R_SH_PCRELIMM8BY2
+	  && rel->r_type != R_SH_PCRELIMM8BY4)
 	continue;
 
       symndx = rel->r_symndx;
@@ -2913,7 +2915,9 @@ sh_relocate_section (output_bfd, info, i
       else
 	addend = 0;
 
-      if (rel->r_type == R_SH_PCDISP)
+      if (rel->r_type == R_SH_PCDISP
+	|| rel->r_type == R_SH_PCRELIMM8BY2
+	|| rel->r_type == R_SH_PCRELIMM8BY4)
 	addend -= 4;
 
       if (rel->r_type >= SH_COFF_HOWTO_COUNT)
================================================================================
--- /home/kpit/fsfsrc/binutils-2.13.2.1/gas/config/obj-coff.c	Sun Jul 14 06:44:22 2002
+++ binutils-2.13.2.1/gas/config/obj-coff.c	Fri May 30 14:34:21 2003
@@ -4439,7 +4439,7 @@ fixup_segment (segP, this_segment_type)
 
       if (pcrel)
 	{
-#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32)
+#if !defined(TC_M88K) && !(defined(TE_PE) && defined(TC_I386)) && !defined(TC_A29K) && !defined(TC_OR32) && !defined(TC_SH)
 	  /* This adjustment is not correct on the m88k, for which the
 	     linker does all the computation.  */
 	  add_number -= md_pcrel_from (fixP);

================================================================================



More information about the Binutils mailing list