This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix opd->adjust index in elf64-ppc.c
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Sun, 05 Jul 2015 08:22:35 +0100
- Subject: Fix opd->adjust index in elf64-ppc.c
- Authentication-results: sourceware.org; auth=none
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