This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

[8/21] bfd_install_relocation strikes again


The !OBJ_ELF part of tc-ppc.c:md_apply_fix says:

  /* FIXME FIXME FIXME: The value we are passed in *valP includes
     the symbol values.  If we are doing this relocation the code in
     write.c is going to call bfd_install_relocation, which is also
     going to use the symbol value.  That means that if the reloc is
     fully resolved we want to use *valP since bfd_install_relocation is
     not being used.
     However, if the reloc is not fully resolved we do not want to use
     *valP, and must use fx_offset instead.  However, if the reloc
     is PC relative, we do want to use *valP since it includes the
     result of md_pcrel_from.  This is confusing.  */
  if (fixP->fx_addsy == (symbolS *) NULL)
    fixP->fx_done = 1;

  else if (fixP->fx_pcrel)
    ;

  else
    value = fixP->fx_offset;

But the "double symbol" problem described here applies to PC-relative
relocs just as much as it does to other relocs.  E.g. if we have:

bar:    bl foo
	...
foo:

the relocation field is set to:

        (foo - .text) * 2 - (bar - .text)

rather than the intended:

        (foo - .text) - (bar - .text)

So we should still recompute VALUE for PC_relative relocs, but re-apply
md_pcrel_from_section to the result.

OK to install?

Richard


gas/
	* config/tc-ppc.c (md_apply_fix): On COFF targets, always reread
	"value" from fx_offset.  Manually resubtract md_pcrel_from_section
	where necessary.

gas/testsuite/
	* gas/ppc/xcoff-branch-1.s, gas/ppc/xcoff-branch-1-32.d,
	gas/ppc/xcoff-branch-1-64.d: New tests.
	* gas/ppc/aix.exp: Run them.

Index: gas/config/tc-ppc.c
===================================================================
--- gas/config/tc-ppc.c	2009-03-10 13:38:53.000000000 +0000
+++ gas/config/tc-ppc.c	2009-03-10 13:46:12.000000000 +0000
@@ -5617,18 +5617,19 @@ md_apply_fix (fixS *fixP, valueT *valP, 
      going to use the symbol value.  That means that if the reloc is
      fully resolved we want to use *valP since bfd_install_relocation is
      not being used.
-     However, if the reloc is not fully resolved we do not want to use
-     *valP, and must use fx_offset instead.  However, if the reloc
-     is PC relative, we do want to use *valP since it includes the
-     result of md_pcrel_from.  This is confusing.  */
+     However, if the reloc is not fully resolved we do not want to
+     use *valP, and must use fx_offset instead.  If the relocation
+     is PC-relative, we then need to re-apply md_pcrel_from_section
+     to this new relocation value.  */
   if (fixP->fx_addsy == (symbolS *) NULL)
     fixP->fx_done = 1;
 
-  else if (fixP->fx_pcrel)
-    ;
-
   else
-    value = fixP->fx_offset;
+    {
+      value = fixP->fx_offset;
+      if (fixP->fx_pcrel)
+	value -= md_pcrel_from_section (fixP, seg);
+    }
 #endif
 
   if (fixP->fx_subsy != (symbolS *) NULL)
Index: gas/testsuite/gas/ppc/xcoff-branch-1.s
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ gas/testsuite/gas/ppc/xcoff-branch-1.s	2009-03-10 13:46:12.000000000 +0000
@@ -0,0 +1,40 @@
+	.globl	.foo
+	.globl	foo1
+	.globl	foo2
+	.globl	.bar
+	.globl	.frob
+
+	.csect	.foo[PR]
+.foo:
+	bl	foo2 + 0x4
+	bl	foo1 + 0xc
+	bl	foo1
+	bl	foo2
+	bl	.bar
+foo1:
+	bl	.foo
+	bl	.frob
+	bl	.foo + 0x10
+	bl	.bar + 0x8
+foo2:
+	bl	.frob + 0x10
+	blr
+
+	.csect	.bar[PR]
+.bar:	bl	foo1
+	bl	foo2
+	bl	foo1 + 0x8
+	bl	foo2 + 0x4
+	bl	.foo
+	bl	.bar
+	bl	.frob
+	bl	.foo + 0x1c
+	bl	.bar + 0xc
+	bl	.frob + 0x4
+
+	.csect	.frob[PR]
+.frob:	bl	.foo
+	bl	.bar
+	bl	.frob
+	bl	foo1
+	bl	foo2
Index: gas/testsuite/gas/ppc/xcoff-branch-1-32.d
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ gas/testsuite/gas/ppc/xcoff-branch-1-32.d	2009-03-10 13:46:12.000000000 +0000
@@ -0,0 +1,61 @@
+#as: -a32
+#source: xcoff-branch-1.s
+#objdump: -dr
+#name: XCOFF branch test 1 (32-bit)
+
+.*
+
+
+Disassembly of section \.text:
+
+0+00 <\.foo>:
+   0:	48 00 00 29 	bl      28 <foo2\+0x4>
+   4:	48 00 00 1d 	bl      20 <foo1\+0xc>
+   8:	48 00 00 0d 	bl      14 <foo1>
+   c:	48 00 00 19 	bl      24 <foo2>
+  10:	48 00 00 1d 	bl      2c <\.bar>
+			10: R_(RBR_26|BR)	.*
+
+0+14 <foo1>:
+  14:	4b ff ff ed 	bl      0 <\.foo>
+  18:	48 00 00 3d 	bl      54 <\.frob>
+			18: R_(RBR_26|BR)	.*
+  1c:	4b ff ff f5 	bl      10 <\.foo\+0x10>
+  20:	48 00 00 15 	bl      34 <\.bar\+0x8>
+			20: R_(RBR_26|BR)	.*
+
+0+24 <foo2>:
+  24:	48 00 00 41 	bl      64 <\.frob\+0x10>
+			24: R_(RBR_26|BR)	.*
+  28:	4e 80 00 20 	br
+
+0+2c <\.bar>:
+  2c:	4b ff ff e9 	bl      14 <foo1>
+			2c: R_(RBR_26|BR)	.*
+  30:	4b ff ff f5 	bl      24 <foo2>
+			30: R_(RBR_26|BR)	.*
+  34:	4b ff ff e9 	bl      1c <foo1\+0x8>
+			34: R_(RBR_26|BR)	.*
+  38:	4b ff ff f1 	bl      28 <foo2\+0x4>
+			38: R_(RBR_26|BR)	.*
+  3c:	4b ff ff c5 	bl      0 <\.foo>
+			3c: R_(RBR_26|BR)	.*
+  40:	4b ff ff ed 	bl      2c <\.bar>
+  44:	48 00 00 11 	bl      54 <\.frob>
+			44: R_(RBR_26|BR)	.*
+  48:	4b ff ff d5 	bl      1c <foo1\+0x8>
+			48: R_(RBR_26|BR)	.*
+  4c:	4b ff ff ed 	bl      38 <\.bar\+0xc>
+  50:	48 00 00 09 	bl      58 <\.frob\+0x4>
+			50: R_(RBR_26|BR)	.*
+
+0+54 <\.frob>:
+  54:	4b ff ff ad 	bl      0 <\.foo>
+			54: R_(RBR_26|BR)	.*
+  58:	4b ff ff d5 	bl      2c <\.bar>
+			58: R_(RBR_26|BR)	.*
+  5c:	4b ff ff f9 	bl      54 <\.frob>
+  60:	4b ff ff b5 	bl      14 <foo1>
+			60: R_(RBR_26|BR)	.*
+  64:	4b ff ff c1 	bl      24 <foo2>
+			64: R_(RBR_26|BR)	.*
Index: gas/testsuite/gas/ppc/xcoff-branch-1-64.d
===================================================================
--- /dev/null	2009-02-06 09:11:03.343159000 +0000
+++ gas/testsuite/gas/ppc/xcoff-branch-1-64.d	2009-03-10 13:46:12.000000000 +0000
@@ -0,0 +1,61 @@
+#as: -a64
+#source: xcoff-branch-1.s
+#objdump: -dr
+#name: XCOFF branch test 1 (64-bit)
+
+.*
+
+
+Disassembly of section \.text:
+
+0+00 <\.foo>:
+   0:	48 00 00 29 	bl      28 <foo2\+0x4>
+   4:	48 00 00 1d 	bl      20 <foo1\+0xc>
+   8:	48 00 00 0d 	bl      14 <foo1>
+   c:	48 00 00 19 	bl      24 <foo2>
+  10:	48 00 00 1d 	bl      2c <\.bar>
+			10: R_(RBR_26|BR)	.*
+
+0+14 <foo1>:
+  14:	4b ff ff ed 	bl      0 <\.foo>
+  18:	48 00 00 3d 	bl      54 <\.frob>
+			18: R_(RBR_26|BR)	.*
+  1c:	4b ff ff f5 	bl      10 <\.foo\+0x10>
+  20:	48 00 00 15 	bl      34 <\.bar\+0x8>
+			20: R_(RBR_26|BR)	.*
+
+0+24 <foo2>:
+  24:	48 00 00 41 	bl      64 <\.frob\+0x10>
+			24: R_(RBR_26|BR)	.*
+  28:	4e 80 00 20 	blr
+
+0+2c <\.bar>:
+  2c:	4b ff ff e9 	bl      14 <foo1>
+			2c: R_(RBR_26|BR)	.*
+  30:	4b ff ff f5 	bl      24 <foo2>
+			30: R_(RBR_26|BR)	.*
+  34:	4b ff ff e9 	bl      1c <foo1\+0x8>
+			34: R_(RBR_26|BR)	.*
+  38:	4b ff ff f1 	bl      28 <foo2\+0x4>
+			38: R_(RBR_26|BR)	.*
+  3c:	4b ff ff c5 	bl      0 <\.foo>
+			3c: R_(RBR_26|BR)	.*
+  40:	4b ff ff ed 	bl      2c <\.bar>
+  44:	48 00 00 11 	bl      54 <\.frob>
+			44: R_(RBR_26|BR)	.*
+  48:	4b ff ff d5 	bl      1c <foo1\+0x8>
+			48: R_(RBR_26|BR)	.*
+  4c:	4b ff ff ed 	bl      38 <\.bar\+0xc>
+  50:	48 00 00 09 	bl      58 <\.frob\+0x4>
+			50: R_(RBR_26|BR)	.*
+
+0+54 <\.frob>:
+  54:	4b ff ff ad 	bl      0 <\.foo>
+			54: R_(RBR_26|BR)	.*
+  58:	4b ff ff d5 	bl      2c <\.bar>
+			58: R_(RBR_26|BR)	.*
+  5c:	4b ff ff f9 	bl      54 <\.frob>
+  60:	4b ff ff b5 	bl      14 <foo1>
+			60: R_(RBR_26|BR)	.*
+  64:	4b ff ff c1 	bl      24 <foo2>
+			64: R_(RBR_26|BR)	.*
Index: gas/testsuite/gas/ppc/aix.exp
===================================================================
--- gas/testsuite/gas/ppc/aix.exp	2009-03-10 13:38:53.000000000 +0000
+++ gas/testsuite/gas/ppc/aix.exp	2009-03-10 13:46:12.000000000 +0000
@@ -63,4 +63,6 @@ if [istarget powerpc-ibm-aix*] then {
 
     run_dump_test "textalign-xcoff-001"
     run_dump_test "textalign-xcoff-002"
+    run_dump_test "xcoff-branch-1-32"
+    run_dump_test "xcoff-branch-1-64"
 }


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