diff options
-rw-r--r-- | bfd/ChangeLog | 9 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 50 | ||||
-rw-r--r-- | ld/ChangeLog | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/ambiguousv1b.d | 5 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/funref.s | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/funref2.s | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-powerpc/funv1.s | 14 |
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 |