diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 620807fe5b6c..b208cddc99d7 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -136,6 +136,7 @@ struct Configuration { bool WarnMissingEntry; bool ZCombreloc; bool ZExecstack; + bool ZNocopyreloc; bool ZNodelete; bool ZNow; bool ZOrigin; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index a82b8a8fcdea..b8d648bd70db 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -574,6 +574,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); Config->ZExecstack = hasZOption(Args, "execstack"); + Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc"); Config->ZNodelete = hasZOption(Args, "nodelete"); Config->ZNow = hasZOption(Args, "now"); Config->ZOrigin = hasZOption(Args, "origin"); diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index defbec4a8c52..0842331f87da 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -543,8 +543,14 @@ static RelExpr adjustExpr(const elf::ObjectFile &File, SymbolBody &Body, if (Body.isObject()) { // Produce a copy relocation. auto *B = cast>(&Body); - if (!B->NeedsCopy) + if (!B->NeedsCopy) { + if (Config->ZNocopyreloc) + error(S.getLocation(RelOff) + ": unresolvable relocation " + toString(Type) + + " against symbol '" + toString(*B) + + "'; recompile with -fPIC or remove '-z nocopyreloc'"); + addCopyRelSymbol(B); + } return Expr; } if (Body.isFunc()) { diff --git a/lld/test/ELF/relocation-nocopy.s b/lld/test/ELF/relocation-nocopy.s new file mode 100644 index 000000000000..533277dc8ec3 --- /dev/null +++ b/lld/test/ELF/relocation-nocopy.s @@ -0,0 +1,19 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o +// RUN: ld.lld -shared %t2.o -o %t.so +// RUN: not ld.lld -z nocopyreloc %t.o %t.so -o %t3 2>&1 | FileCheck %s + +// CHECK: unresolvable relocation R_X86_64_32S against symbol 'x' +// CHECK: unresolvable relocation R_X86_64_32S against symbol 'y' +// CHECK: unresolvable relocation R_X86_64_32S against symbol 'z' + +.text +.global _start +_start: +movl $5, x +movl $7, y +movl $9, z +movl $x, %edx +movl $y, %edx +movl $z, %edx