diff --git a/lld/ELF/Arch/PPC64.cpp b/lld/ELF/Arch/PPC64.cpp --- a/lld/ELF/Arch/PPC64.cpp +++ b/lld/ELF/Arch/PPC64.cpp @@ -1380,9 +1380,10 @@ if (type == R_PPC64_REL24_NOTOC && (s.stOther >> 5) > 1) return true; - // If a symbol is a weak undefined and we are compiling an executable - // it doesn't need a range-extending thunk since it can't be called. - if (s.isUndefWeak() && !config->shared) + // An undefined weak symbol not in a PLT does not need a thunk. If it is + // hidden, its binding has been converted to local, so we just check + // isUndefined() here. A undefined non-weak symbol has been errored. + if (s.isUndefined()) return false; // If the offset exceeds the range of the branch type then it will need diff --git a/lld/test/ELF/ppc64-undefined-weak.s b/lld/test/ELF/ppc64-undefined-weak.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-undefined-weak.s @@ -0,0 +1,40 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE +# RUN: ld.lld -pie %t.o -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PIC +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-objdump -d --no-show-raw-insn %t.so | FileCheck %s --check-prefix=PIC + +# RUN: llvm-mc -filetype=obj -triple=powerpc64 %s -o %t.o +# RUN: ld.lld %t.o -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s --check-prefix=PDE + +## Branches to an undefined weak symbol need a thunk iff a dynamic relocation is +## produced. undefweak2 is hidden and does not need a dynamic relocation, so we +## suppress the thunk. undefweak1 needs a thunk iff -pie or -shared. + +# PDE-LABEL: <_start>: +# PDE-NEXT: bl {{.*}} <_start> +# PDE-NEXT: nop +# PDE-NEXT: bl {{.*}} <_start+0x8> +# PDE-NEXT: nop + +# PIC-LABEL: <_start>: +# PIC-NEXT: bl {{.*}} <__plt_undefweak1> +# PIC-NEXT: ld 2, 24(1) +# PIC-NEXT: bl {{.*}} <_start+0x8> +# PIC-NEXT: nop + +.text +.global _start +_start: + bl undefweak1 + nop + bl undefweak2 + nop + +.weak undefweak1, undefweak2 +.hidden undefweak2 diff --git a/lld/test/ELF/ppc64-undefined.s b/lld/test/ELF/ppc64-undefined.s new file mode 100644 --- /dev/null +++ b/lld/test/ELF/ppc64-undefined.s @@ -0,0 +1,12 @@ +# REQUIRES: ppc + +# RUN: llvm-mc -filetype=obj -triple=powerpc64le %s -o %t.o +# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERR + +# ERR: error: undefined symbol: undef + +.text +.global _start +_start: + bl undef + nop diff --git a/lld/test/ELF/ppc64-weak-undef-call-shared.s b/lld/test/ELF/ppc64-weak-undef-call-shared.s deleted file mode 100644 --- a/lld/test/ELF/ppc64-weak-undef-call-shared.s +++ /dev/null @@ -1,21 +0,0 @@ -# REQUIRES: ppc - -# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t.o -# RUN: ld.lld -shared %t.o -o %t.so -# RUN: llvm-readobj --symbols -r --dyn-syms %t.so | FileCheck %s - -# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o -# RUN: ld.lld -shared %t.o -o %t.so -# RUN: llvm-readobj --symbols -r --dyn-syms %t.so | FileCheck %s - -.section ".toc","aw" -.quad weakfunc -// CHECK-NOT: R_PPC64_RELATIVE - -.text -.Lfoo: - bl weakfunc - nop -// CHECK-NOT: R_PPC64_REL24 - -.weak weakfunc diff --git a/lld/test/ELF/ppc64-weak-undef-call.s b/lld/test/ELF/ppc64-weak-undef-call.s deleted file mode 100644 --- a/lld/test/ELF/ppc64-weak-undef-call.s +++ /dev/null @@ -1,29 +0,0 @@ -# REQUIRES: ppc - -# RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %t -# RUN: ld.lld %t -o %t2 -# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s - -# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t -# RUN: ld.lld %t -o %t2 -# RUN: llvm-objdump -d --no-show-raw-insn %t2 | FileCheck %s - -# CHECK: Disassembly of section .text: -# CHECK-EMPTY: - -.text -.global _start -_start: - bl weakfunc - nop - blr - -.weak weakfunc - -# It does not really matter how we fixup the bl, if at all, because it needs to -# be unreachable. But, we should link successfully. We should not, however, -# generate a .plt entry (this would be wasted space). For now, we do nothing -# (leaving the zero relative offset present in the input). -# CHECK: 10010158: bl 0x10010158 -# CHECK: 1001015c: nop -# CHECK: 10010160: blr