Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -143,6 +143,7 @@ bool ZNow; bool ZOrigin; bool ZRelro; + bool ZText; bool ExitEarly; bool ZWxneeded; DiscardPolicy Discard; Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -267,6 +267,18 @@ return false; } +static bool getZOption(opt::InputArgList &Args, StringRef KeyYes, + StringRef KeyNo) { + for (auto *Arg : llvm::reverse(Args)) { + if (Arg->getOption().getID() != OPT_z) + continue; + StringRef S = Arg->getValue(); + if (S == KeyYes || S == KeyNo) + return S == KeyYes; + } + return true; +} + static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key, uint64_t Default) { for (auto *Arg : Args.filtered(OPT_z)) { @@ -599,6 +611,7 @@ Config->ZOrigin = hasZOption(Args, "origin"); Config->ZRelro = !hasZOption(Args, "norelro"); Config->ZStackSize = getZOptionValue(Args, "stack-size", 0); + Config->ZText = getZOption(Args, "text", "notext"); Config->ZWxneeded = hasZOption(Args, "wxneeded"); if (Config->LTOO > 3) Index: ELF/Relocations.cpp =================================================================== --- ELF/Relocations.cpp +++ ELF/Relocations.cpp @@ -520,11 +520,12 @@ // only memory. We can hack around it if we are producing an executable and // the refered symbol can be preemepted to refer to the executable. if (Config->Shared || (Config->pic() && !isRelExpr(Expr))) { - error(S.getLocation(RelOff) + ": can't create dynamic relocation " + - toString(Type) + " against " + - (Body.getName().empty() ? "local symbol in readonly segment" - : "symbol '" + toString(Body) + "'") + - " defined in " + toString(Body.File)); + if (Config->ZText) + error(S.getLocation(RelOff) + ": can't create dynamic relocation " + + toString(Type) + " against " + + (Body.getName().empty() ? "local symbol in readonly segment" + : "symbol '" + toString(Body) + "'") + + " defined in " + toString(Body.File)); return Expr; } if (Body.getVisibility() != STV_DEFAULT) { Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1106,6 +1106,8 @@ add({DT_SYMENT, sizeof(Elf_Sym)}); add({DT_STRTAB, In::DynStrTab}); add({DT_STRSZ, In::DynStrTab->getSize()}); + if (!Config->ZText) + add({DT_TEXTREL, (uint64_t)0}); if (In::GnuHashTab) add({DT_GNU_HASH, In::GnuHashTab}); if (In::HashTab) Index: test/ELF/ztext-text-notext.s =================================================================== --- test/ELF/ztext-text-notext.s +++ test/ELF/ztext-text-notext.s @@ -0,0 +1,18 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: ld.lld -z notext %t.o -o %t -shared +# RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section {{.*}} .rela.dyn { +# CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000 +# CHECK-NEXT: } +# CHECK-NEXT: ] +# CHECK: DynamicSection [ +# CHECK: 0x0000000000000016 TEXTREL 0x0 + +# RUN: not ld.lld -z notext -z text %t.o -o %t -shared 2>&1 | FileCheck %s --check-prefix=ERR +# ERR: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment + +foo: +.quad foo