Index: lld/ELF/Config.h =================================================================== --- lld/ELF/Config.h +++ lld/ELF/Config.h @@ -163,9 +163,9 @@ bool WarnSymbolOrdering; bool WriteAddends; bool ZCombreloc; + bool ZCopyreloc; bool ZExecstack; bool ZHazardplt; - bool ZNocopyreloc; bool ZNodelete; bool ZNodlopen; bool ZNow; Index: lld/ELF/Driver.cpp =================================================================== --- lld/ELF/Driver.cpp +++ lld/ELF/Driver.cpp @@ -313,6 +313,17 @@ return false; } +static bool getZFlag(opt::InputArgList &Args, StringRef K1, StringRef K2, + bool Default) { + for (auto *Arg : Args.filtered_reverse(OPT_z)) { + if (K1 == Arg->getValue()) + return true; + if (K2 == Arg->getValue()) + return false; + } + return Default; +} + void LinkerDriver::main(ArrayRef ArgsArr) { ELFOptTable Parser; opt::InputArgList Args = Parser.parse(ArgsArr.slice(1)); @@ -748,19 +759,19 @@ Config->WarnCommon = Args.hasFlag(OPT_warn_common, OPT_no_warn_common, false); Config->WarnSymbolOrdering = Args.hasFlag(OPT_warn_symbol_ordering, OPT_no_warn_symbol_ordering, true); - Config->ZCombreloc = !hasZOption(Args, "nocombreloc"); - Config->ZExecstack = hasZOption(Args, "execstack"); + Config->ZCombreloc = getZFlag(Args, "combreloc", "nocombreloc", true); + Config->ZCopyreloc = getZFlag(Args, "copyreloc", "nocopyreloc", true); + Config->ZExecstack = getZFlag(Args, "execstack", "noexecstack", false); Config->ZHazardplt = hasZOption(Args, "hazardplt"); - Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc"); Config->ZNodelete = hasZOption(Args, "nodelete"); Config->ZNodlopen = hasZOption(Args, "nodlopen"); - Config->ZNow = hasZOption(Args, "now"); + Config->ZNow = getZFlag(Args, "now", "lazy", false); Config->ZOrigin = hasZOption(Args, "origin"); - Config->ZRelro = !hasZOption(Args, "norelro"); + Config->ZRelro = getZFlag(Args, "relro", "norelro", true); Config->ZRetpolineplt = hasZOption(Args, "retpolineplt"); Config->ZRodynamic = hasZOption(Args, "rodynamic"); Config->ZStackSize = args::getZOptionValue(Args, OPT_z, "stack-size", 0); - Config->ZText = !hasZOption(Args, "notext"); + Config->ZText = getZFlag(Args, "text", "notext", true); Config->ZWxneeded = hasZOption(Args, "wxneeded"); // Parse LTO plugin-related options for compatibility with gold. Index: lld/ELF/Relocations.cpp =================================================================== --- lld/ELF/Relocations.cpp +++ lld/ELF/Relocations.cpp @@ -843,7 +843,7 @@ // Produce a copy relocation. auto &SS = cast(Sym); if (!SS.CopyRelSec) { - if (Config->ZNocopyreloc) + if (!Config->ZCopyreloc) error("unresolvable relocation " + toString(Type) + " against symbol '" + toString(SS) + "'; recompile with -fPIC or remove '-z nocopyreloc'" + Index: lld/test/ELF/combrelocs.s =================================================================== --- lld/test/ELF/combrelocs.s +++ lld/test/ELF/combrelocs.s @@ -4,6 +4,9 @@ # RUN: ld.lld -shared %t.o -o %t.out # RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s +# RUN: ld.lld -shared %t.o -o %t.out -z combreloc +# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s + # CHECK: Relocations [ # CHECK-NEXT: Section ({{.*}}) .rela.dyn { # CHECK-NEXT: Relocation { Index: lld/test/ELF/dt_flags.s =================================================================== --- lld/test/ELF/dt_flags.s +++ lld/test/ELF/dt_flags.s @@ -2,9 +2,14 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t # RUN: ld.lld -shared %t -o %t.so + # RUN: ld.lld -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1 -# RUN: ld.lld %t %t.so -o %t2 # RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s + +# RUN: ld.lld %t %t.so -o %t2 +# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s + +# RUN: ld.lld -z lazy %t %t.so -o %t2 # RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s # FLAGS: DynamicSection [ Index: lld/test/ELF/gnustack.s =================================================================== --- lld/test/ELF/gnustack.s +++ lld/test/ELF/gnustack.s @@ -1,10 +1,15 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 + # RUN: ld.lld %t1 -z execstack -o %t # RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RWX %s + # RUN: ld.lld %t1 -o %t # RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s +# RUN: ld.lld %t1 -o %t -z noexecstack +# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s + # RW: Type: PT_GNU_STACK # RW-NEXT: Offset: 0x0 # RW-NEXT: VirtualAddress: 0x0 Index: lld/test/ELF/relro.s =================================================================== --- lld/test/ELF/relro.s +++ lld/test/ELF/relro.s @@ -1,13 +1,17 @@ +// REQUIRES: x86 + // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o // RUN: ld.lld -shared %t2.o -o %t2.so -// RUN: ld.lld %t.o %t2.so -z now -z relro -o %t + +// RUN: ld.lld %t.o %t2.so -z now -z norelro -z relro -o %t // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s -// RUN: ld.lld %t.o %t2.so -z relro -o %t + +// RUN: ld.lld %t.o %t2.so -z norelro -z relro -o %t // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s + // RUN: ld.lld %t.o %t2.so -z norelro -o %t // RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s -// REQUIRES: x86 // CHECK: Program Headers: // CHECK-NEXT: Type Index: lld/test/ELF/ztext.s =================================================================== --- lld/test/ELF/ztext.s +++ lld/test/ELF/ztext.s @@ -2,6 +2,7 @@ # 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/ztext.s -o %t2.o # RUN: ld.lld %t2.o -o %t2.so -shared + # RUN: ld.lld -z notext %t.o %t2.so -o %t -shared # RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s # RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie @@ -9,6 +10,10 @@ # RUN: ld.lld -z notext %t.o %t2.so -o %t3 # RUN: llvm-readobj -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s +# RUN: not ld.lld %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s +# RUN: not ld.lld -z text %t.o %t2.so -o %t -shared 2>&1 | FileCheck --check-prefix=ERR %s +# ERR: error: can't create dynamic relocation + # If the preference is to have text relocations, don't create plt of copy relocations. # CHECK: Relocations [