summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf64-ppc.c50
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-powerpc/ambiguousv1b.d5
-rw-r--r--ld/testsuite/ld-powerpc/funref.s1
-rw-r--r--ld/testsuite/ld-powerpc/funref2.s1
-rw-r--r--ld/testsuite/ld-powerpc/funv1.s14
7 files changed, 59 insertions, 28 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 0b24aaee621..88a69142553 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,12 @@
+2020-01-15 Alan Modra <amodra@gmail.com>
+
+ PR 25384
+ * elf64-ppc.c (ELIMINATE_COPY_RELOCS): Update comment.
+ (ppc64_elf_adjust_dynamic_symbol): Don't allow .dynbss copies
+ of function symbols unless dot symbols are present. Do warn
+ whenever one is created, regardles of whether a PLT entry is
+ also emitted for the function symbol.
+
2019-08-28 Tamar Christina <tamar.christina@arm.com>
Backported from mainline.
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c
index 5be3fe00f18..9ced4f8c4ac 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -2574,20 +2574,20 @@ must_be_dyn_reloc (struct bfd_link_info *info,
}
/* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
- copying dynamic variables from a shared lib into an app's dynbss
+ copying dynamic variables from a shared lib into an app's .dynbss
section, and instead use a dynamic relocation to point into the
- shared lib. With code that gcc generates, it's vital that this be
- enabled; In the PowerPC64 ABI, the address of a function is actually
- the address of a function descriptor, which resides in the .opd
- section. gcc uses the descriptor directly rather than going via the
- GOT as some other ABI's do, which means that initialized function
- pointers must reference the descriptor. Thus, a function pointer
- initialized to the address of a function in a shared library will
- either require a copy reloc, or a dynamic reloc. Using a copy reloc
- redefines the function descriptor symbol to point to the copy. This
- presents a problem as a plt entry for that function is also
- initialized from the function descriptor symbol and the copy reloc
- may not be initialized first. */
+ shared lib. With code that gcc generates it is vital that this be
+ enabled; In the PowerPC64 ELFv1 ABI the address of a function is
+ actually the address of a function descriptor which resides in the
+ .opd section. gcc uses the descriptor directly rather than going
+ via the GOT as some other ABIs do, which means that initialized
+ function pointers reference the descriptor. Thus, a function
+ pointer initialized to the address of a function in a shared
+ library will either require a .dynbss copy and a copy reloc, or a
+ dynamic reloc. Using a .dynbss copy redefines the function
+ descriptor symbol to point to the copy. This presents a problem as
+ a PLT entry for that function is also initialized from the function
+ descriptor symbol and the copy may not be initialized first. */
#define ELIMINATE_COPY_RELOCS 1
/* Section name for stubs is the associated section name plus this
@@ -6134,13 +6134,23 @@ ppc64_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
|| h->protected_def)
return TRUE;
- if (h->plt.plist != NULL)
- {
- /* We should never get here, but unfortunately there are versions
- of gcc out there that improperly (for this ABI) put initialized
- function pointers, vtable refs and suchlike in read-only
- sections. Allow them to proceed, but warn that this might
- break at runtime. */
+ if (h->type == STT_FUNC
+ || h->type == STT_GNU_IFUNC)
+ {
+ /* .dynbss copies of function symbols only work if we have
+ ELFv1 dot-symbols. ELFv1 compilers since 2004 default to not
+ use dot-symbols and set the function symbol size to the text
+ size of the function rather than the size of the descriptor.
+ That's wrong for copying a descriptor. */
+ if (((struct ppc_link_hash_entry *) h)->oh == NULL
+ || !(h->size == 24 || h->size == 16))
+ return TRUE;
+
+ /* We should never get here, but unfortunately there are old
+ versions of gcc (circa gcc-3.2) that improperly for the
+ ELFv1 ABI put initialized function pointers, vtable refs and
+ suchlike in read-only sections. Allow them to proceed, but
+ warn that this might break at runtime. */
info->callbacks->einfo
(_("%P: copy reloc against `%pT' requires lazy plt linking; "
"avoid setting LD_BIND_NOW=1 or upgrade gcc\n"),
diff --git a/ld/ChangeLog b/ld/ChangeLog
index ef1f5446c0c..cd613514737 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2020-01-15 Alan Modra <amodra@gmail.com>
+
+ * testsuite/ld-powerpc/ambiguousv1b.d: Adjust expected output.
+ * testsuite/ld-powerpc/funref.s: Align func_tab.
+ * testsuite/ld-powerpc/funref2.s: Likewise.
+ * testsuite/ld-powerpc/funv1.s: Add dot symbols.
+
2019-09-05 Eric Botcazou <ebotcazou@adacore.com>
PR ld/24574
diff --git a/ld/testsuite/ld-powerpc/ambiguousv1b.d b/ld/testsuite/ld-powerpc/ambiguousv1b.d
index 9be1371e5ec..205f7ea46f3 100644
--- a/ld/testsuite/ld-powerpc/ambiguousv1b.d
+++ b/ld/testsuite/ld-powerpc/ambiguousv1b.d
@@ -3,6 +3,7 @@
#as: -a64
#ld: -melf64ppc --emit-stub-syms
#ld_after_inputfiles: tmpdir/funv1.so
+#warning: .*requires lazy plt linking.*
#readelf: -rs --wide
# Check that we do the right thing with funref2.s that doesn't have
# anything to mark it as ELFv1 or ELFv2. Since my_func address is
@@ -15,9 +16,9 @@ Relocation section .* contains 1 entry:
Symbol table '\.dynsym' contains 2 entries:
#...
-.*: 0*[1-9a-f][0-9a-f]* 4 FUNC GLOBAL DEFAULT 1[23] my_func
+.*: 0*[1-9a-f][0-9a-f]* +24 FUNC +GLOBAL DEFAULT +1[23] my_func
#...
Symbol table '\.symtab' contains .* entries:
#...
-.*: 0*[1-9a-f][0-9a-f]* 4 FUNC GLOBAL DEFAULT 1[23] my_func
+.*: 0*[1-9a-f][0-9a-f]* +24 FUNC +GLOBAL DEFAULT +1[23] my_func
#pass
diff --git a/ld/testsuite/ld-powerpc/funref.s b/ld/testsuite/ld-powerpc/funref.s
index 3f7de479ce5..27c1bcf6b1b 100644
--- a/ld/testsuite/ld-powerpc/funref.s
+++ b/ld/testsuite/ld-powerpc/funref.s
@@ -1,4 +1,5 @@
.data
.globl func_tab
+ .p2align 3
func_tab:
.dc.a my_func
diff --git a/ld/testsuite/ld-powerpc/funref2.s b/ld/testsuite/ld-powerpc/funref2.s
index a2bf9491264..14c58f0123d 100644
--- a/ld/testsuite/ld-powerpc/funref2.s
+++ b/ld/testsuite/ld-powerpc/funref2.s
@@ -1,4 +1,5 @@
.section .rodata,"a",@progbits
.globl func_tab
+ .p2align 3
func_tab:
.dc.a my_func
diff --git a/ld/testsuite/ld-powerpc/funv1.s b/ld/testsuite/ld-powerpc/funv1.s
index e79009d1d21..988ad0d8c14 100644
--- a/ld/testsuite/ld-powerpc/funv1.s
+++ b/ld/testsuite/ld-powerpc/funv1.s
@@ -1,10 +1,12 @@
- .globl my_func
- .type my_func,@function
- .section .opd,"aw",@progbits
+# old style ELFv1, with dot-symbols
+ .globl my_func, .my_func
+ .type .my_func, @function
+ .section .opd, "aw", @progbits
my_func:
- .quad .Lmy_func, .TOC.@tocbase
+ .quad .my_func, .TOC.@tocbase, 0
+ .size my_func, . - my_func
.text
-.Lmy_func:
+.my_func:
blr
- .size my_func,.-.Lmy_func
+ .size .my_func, . - .my_func