From 0a7412f00ba4a2ccca069c55a1e21cdafb3bade1 Mon Sep 17 00:00:00 2001 From: George Rimar Date: Thu, 9 Mar 2017 08:48:34 +0000 Subject: [PATCH] [ELF] - Implemented -znotext gold linker manual describes them as: -z text Do not permit relocations in read-only segments -z notext Permit relocations in read-only segments (default) In LLD default is to not permit them. Patch implements -z notext. Differential revision: https://reviews.llvm.org/D30530 llvm-svn: 297366 --- lld/ELF/Config.h | 1 + lld/ELF/Driver.cpp | 1 + lld/ELF/Relocations.cpp | 11 ++++++----- lld/ELF/SyntheticSections.cpp | 2 ++ lld/test/ELF/ztext-text-notext.s | 15 +++++++++++++++ 5 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 lld/test/ELF/ztext-text-notext.s diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 67c6c3510fea7..ef184d508d257 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -142,6 +142,7 @@ struct Configuration { bool ZNow; bool ZOrigin; bool ZRelro; + bool ZText; bool ExitEarly; bool ZWxneeded; DiscardPolicy Discard; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index e48177a13d2e5..e7913a087578b 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -599,6 +599,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->ZOrigin = hasZOption(Args, "origin"); Config->ZRelro = !hasZOption(Args, "norelro"); Config->ZStackSize = getZOptionValue(Args, "stack-size", 0); + Config->ZText = !hasZOption(Args, "notext"); Config->ZWxneeded = hasZOption(Args, "wxneeded"); if (Config->LTOO > 3) diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index c1631c6768a85..7d39b08eeff31 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -520,11 +520,12 @@ static RelExpr adjustExpr(const elf::ObjectFile &File, SymbolBody &Body, // 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) { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index a642345b6f5b9..5011796f083aa 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -1111,6 +1111,8 @@ template void DynamicSection::finalizeContents() { 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) diff --git a/lld/test/ELF/ztext-text-notext.s b/lld/test/ELF/ztext-text-notext.s new file mode 100644 index 0000000000000..cdd5b67d6adb1 --- /dev/null +++ b/lld/test/ELF/ztext-text-notext.s @@ -0,0 +1,15 @@ +# 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 + +foo: +.quad foo