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]

Fix opd->adjust index in elf64-ppc.c


If a section contains a call to a local function via a descriptor
at .opd+N, toc_adjusting_stub_needed would drop the addend when
applying opd->adjust.  This caused the gcc bootstrap failure
reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66729:
we optimised away the first .opd entry and, because we were dropping
the addned, ended up assuming the function calling .opd+N didn't need
the TOC.

The testcase in the patch is executable if you uncomment the call
to printf.  Before the patch it segfaults, after the patch it prints
the string twice.

Tested with a gcc bootstrap & regression test on powerpc64-linux-gnu.
OK to install?

Thanks,
Richard


bfd/
	* elf64-ppc.c (toc_adjusting_stub_needed): Use the symbol value
	plus addend rather than the original st_value when looking up
	entries in opd->adjust.

ld/testsuite/
	* ld-powerpc/tocopt6-inc.s, ld-powerpc/tocopt6a.s,
	ld-powerpc/tocopt6b.s, ld-powerpc/tocopt6c.s,
	ld-powerpc/tocopt6.d: New test.
	* ld-powerpc/powerpc.exp (ppc64elftests): Add it.

diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 7be21c7..468e8bf 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -11640,7 +11640,7 @@ toc_adjusting_stub_needed (struct bfd_link_info *info, asection *isec)
 		{
 		  long adjust;
 
-		  adjust = opd->adjust[OPD_NDX (sym->st_value)];
+		  adjust = opd->adjust[OPD_NDX (sym_value)];
 		  if (adjust == -1)
 		    /* Assume deleted functions won't ever be called.  */
 		    continue;
diff --git a/ld/testsuite/ld-powerpc/powerpc.exp b/ld/testsuite/ld-powerpc/powerpc.exp
index 976e89b..0b53c0b 100644
--- a/ld/testsuite/ld-powerpc/powerpc.exp
+++ b/ld/testsuite/ld-powerpc/powerpc.exp
@@ -215,6 +215,8 @@ set ppc64elftests {
         {tocopt4a.s tocopt4b.s} {{objdump -s tocopt4.d}} "tocopt4"}
     {"TOC opt5" "-melf64ppc" "" "-a64"  {tocopt5.s}
 	{{objdump -s tocopt5.d}} "tocopt5"}
+    {"TOC opt6" "-melf64ppc" "" "-a64"  {tocopt6a.s tocopt6b.s tocopt6c.s}
+	{{objdump -d tocopt6.d}} "tocopt6"}
     {"ambig shared v1" "-shared -melf64ppc" "" "-a64" {funv1.s} {} "funv1.so"}
     {"ambig shared v2" "-shared -melf64ppc" "" "-a64" {funv2.s} {} "funv2.so"}
 }
diff --git a/ld/testsuite/ld-powerpc/tocopt6-inc.s b/ld/testsuite/ld-powerpc/tocopt6-inc.s
new file mode 100644
index 0000000..03b894b
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocopt6-inc.s
@@ -0,0 +1,86 @@
+	.macro	start, sym
+	.type	\sym, @function
+	.pushsection .opd, "aw"
+\sym:	.quad	.L.\sym, .TOC.@tocbase, 0
+	.popsection
+.L.\sym:
+	mflr	0
+	std	31, -8(1)
+	std	0, 16(1)
+	stdu	1, -128(1)
+	mr	31, 1
+	.endm
+
+
+	.macro	end, sym
+	addi	1,31,128
+	ld	0, 16(1)
+	mtlr	0
+	ld	31, -8(1)
+	blr
+	.size	\sym, . - .L.\sym
+	.endm
+
+
+	.macro	forward, from, to
+	start	\from
+	bl	\to
+	nop
+	end	\from
+	.endm
+
+
+	.macro	usegot, sym
+	.pushsection .data
+\sym\@:	.quad	\@
+	.popsection
+	.pushsection .toc, "aw"
+.LT\@:	.tc	\sym\@[TC], \sym\@
+	.popsection
+	ld	3,.LT\@@toc(2)
+	.endm
+
+
+	.macro	in123
+	.pushsection .toc, "aw"
+.LThello:
+	.tc	hello[TC],hello
+	.popsection
+
+	.pushsection .rodata
+hello:	.asciz	"Hello, world!\n"
+	.popsection
+
+	.pushsection .text.in123, "axG", @progbits, in123, comdat
+	.weak	in123
+	start	in123
+	ld	3, .LThello@toc(2)
+	#bl	printf
+	nop
+	end	in123
+	.popsection
+	.endm
+
+
+	.macro	in23
+	.pushsection .text
+	forward local, in123
+	.popsection
+
+	.pushsection .text.in23, "axG", @progbits, in23, comdat
+	.weak	in23
+	forward	in23, local
+	.popsection
+	.endm
+
+
+	.macro	gobblegot, sym
+	.pushsection .text
+	.globl	\sym
+	start	\sym
+	.rept	5000
+	usegot	a
+	.endr
+	end	\sym
+	.popsection
+	.endm
diff --git a/ld/testsuite/ld-powerpc/tocopt6.d b/ld/testsuite/ld-powerpc/tocopt6.d
new file mode 100644
index 0000000..a34fec1
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocopt6.d
@@ -0,0 +1,12 @@
+#...
+.*	bl .*<.*long_branch_r2off\.f1>
+.*	ld *r2,40\(r1\)
+.*	bl .*<.*long_branch_r2off\.f2>
+.*	ld *r2,40\(r1\)
+.*	bl .*<\.f3>
+.*	nop
+.*	bl .*<.*long_branch_r2off\.g2>
+.*	ld *r2,40\(r1\)
+.*	bl .*<.*long_branch_r2off\.in23>
+.*	ld *r2,40\(r1\)
+#pass
diff --git a/ld/testsuite/ld-powerpc/tocopt6a.s b/ld/testsuite/ld-powerpc/tocopt6a.s
new file mode 100644
index 0000000..48032ef
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocopt6a.s
@@ -0,0 +1,3 @@
+	.include "tocopt6-inc.s"
+	in123
+	gobblegot f1
diff --git a/ld/testsuite/ld-powerpc/tocopt6b.s b/ld/testsuite/ld-powerpc/tocopt6b.s
new file mode 100644
index 0000000..61798d1
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocopt6b.s
@@ -0,0 +1,8 @@
+	.include "tocopt6-inc.s"
+	in123
+	in23
+	gobblegot f2
+
+	.section .text
+	.globl g2
+	forward g2, in23
diff --git a/ld/testsuite/ld-powerpc/tocopt6c.s b/ld/testsuite/ld-powerpc/tocopt6c.s
new file mode 100644
index 0000000..08ae58d
--- /dev/null
+++ b/ld/testsuite/ld-powerpc/tocopt6c.s
@@ -0,0 +1,20 @@
+	.include "tocopt6-inc.s"
+	in123
+	in23
+	gobblegot f3
+
+	.section .text
+	.globl main
+	start main
+	bl f1
+	nop
+	bl f2
+	nop
+	bl f3
+	nop
+	bl g2
+	nop
+	bl in23
+	nop
+	li 3, 0
+	end main


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