diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1589,8 +1589,15 @@ } uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const { - if (needsDynSymIndex()) - return symTab->getSymbolIndex(sym); + if (needsDynSymIndex()) { + size_t index = symTab->getSymbolIndex(sym); + if (index == 0 && (type == target->gotRel || type == target->pltRel)) + error(Twine(type == target->gotRel ? "GOT" : "PLT") + + " relocation references symbol not present in dynamic " + "symbol table: " + + toString(*sym)); + return index; + } return 0; } diff --git a/lld/test/ELF/invalid-plt-relocation.test b/lld/test/ELF/invalid-plt-relocation.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/invalid-plt-relocation.test @@ -0,0 +1,32 @@ +# REQUIRES: x86 + +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc -triple x86_64-linux-gnu --filetype=obj -o %t/unwind.o %t/unwind.s +# RUN: ld.lld -shared -o %t/libunwind.so %t/unwind.o +# RUN: llvm-as -o %t/resume.bc %t/resume.ll +# RUN: not ld.lld -shared -o %t/libresume.so %t/resume.bc %t/libunwind.so \ +# RUN: --gc-sections --wrap _Unwind_Resume 2>&1 | FileCheck %s + +# CHECK: error: PLT relocation references symbol not present in dynamic symbol table: __wrap__Unwind_Resume + +#--- unwind.s +.globl _Unwind_Resume +.globl __wrap__Unwind_Resume +_Unwind_Resume: +__wrap__Unwind_Resume: + retq + +#--- resume.ll +target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" +define dso_local void @_Z1fv() optnone noinline personality i8* bitcast (void ()* @throw to i8*) { + invoke void @throw() + to label %unreachable unwind label %lpad +lpad: + %1 = landingpad { i8*, i32 } + cleanup + resume { i8*, i32 } %1 +unreachable: + unreachable +} +declare void @throw()