[lld] r338271 - [AArch64] Support execute-only LOAD segments.

David Bolvansky via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 30 10:02:47 PDT 2018


Author: xbolva00
Date: Mon Jul 30 10:02:46 2018
New Revision: 338271

URL: http://llvm.org/viewvc/llvm-project?rev=338271&view=rev
Log:
[AArch64] Support execute-only LOAD segments.

Summary:
This adds an LLD flag to mark executable LOAD segments execute-only for AArch64 targets. 

In AArch64 the expectation is that code is execute-only compatible, so this just adds a linker option to enforce this.

Patch by: ivanlozano (Ivan Lozano)

Reviewers: srhines, echristo, peter.smith, eugenis, javed.absar, espindola, ruiu

Reviewed By: ruiu

Subscribers: dokyungs, emaste, arichardson, kristof.beyls, llvm-commits

Differential Revision: https://reviews.llvm.org/D49456

Added:
    lld/trunk/test/ELF/execute-only-mixed-data.s
    lld/trunk/test/ELF/execute-only.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=338271&r1=338270&r2=338271&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Mon Jul 30 10:02:46 2018
@@ -133,6 +133,7 @@ struct Configuration {
   bool EhFrameHdr;
   bool EmitRelocs;
   bool EnableNewDtags;
+  bool ExecuteOnly;
   bool ExportDynamic;
   bool FixCortexA53Errata843419;
   bool GcSections;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=338271&r1=338270&r2=338271&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Mon Jul 30 10:02:46 2018
@@ -302,6 +302,14 @@ static void checkOptions(opt::InputArgLi
     if (Config->Pie)
       error("-r and -pie may not be used together");
   }
+
+  if (Config->ExecuteOnly) {
+    if (Config->EMachine != EM_AARCH64)
+      error("-execute-only is only supported on AArch64 targets");
+
+    if (Config->SingleRoRx && !Script->HasSectionsCommand)
+      error("-execute-only and -no-rosegment cannot be used together");
+  }
 }
 
 static const char *getReproduceOption(opt::InputArgList &Args) {
@@ -747,6 +755,8 @@ void LinkerDriver::readConfigs(opt::Inpu
   Config->EnableNewDtags =
       Args.hasFlag(OPT_enable_new_dtags, OPT_disable_new_dtags, true);
   Config->Entry = Args.getLastArgValue(OPT_entry);
+  Config->ExecuteOnly =
+      Args.hasFlag(OPT_execute_only, OPT_no_execute_only, false);
   Config->ExportDynamic =
       Args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, false);
   Config->FilterList = args::getStrings(Args, OPT_filter);

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=338271&r1=338270&r2=338271&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Mon Jul 30 10:02:46 2018
@@ -131,6 +131,10 @@ def error_unresolved_symbols: F<"error-u
 
 defm exclude_libs: Eq<"exclude-libs", "Exclude static libraries from automatic export">;
 
+defm execute_only: B<"execute-only",
+    "Do not mark executable sections readable",
+    "Mark executable sections readable (default)">;
+
 defm export_dynamic: B<"export-dynamic",
     "Put symbols in the dynamic symbol table",
     "Do not put symbols in the dynamic symbol table (default)">;

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=338271&r1=338270&r2=338271&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Mon Jul 30 10:02:46 2018
@@ -1608,6 +1608,15 @@ template <class ELFT> void Writer<ELFT>:
     if (auto *Sec = dyn_cast<OutputSection>(Base))
       OutputSections.push_back(Sec);
 
+  // Ensure data sections are not mixed with executable sections when
+  // -execute-only is used.
+  if (Config->ExecuteOnly)
+    for (OutputSection *OS : OutputSections)
+      if (OS->Flags & SHF_EXECINSTR)
+        for (InputSection *IS : getInputSections(OS))
+          if (!(IS->Flags & SHF_EXECINSTR))
+            error("-execute-only does not support intermingling data and code");
+
   // Prefer command line supplied address over other constraints.
   for (OutputSection *Sec : OutputSections) {
     auto I = Config->SectionStartMap.find(Sec->Name);
@@ -1767,6 +1776,8 @@ static bool needsPtLoad(OutputSection *S
 static uint64_t computeFlags(uint64_t Flags) {
   if (Config->Omagic)
     return PF_R | PF_W | PF_X;
+  if (Config->ExecuteOnly && (Flags & PF_X))
+    return Flags & ~PF_R;
   if (Config->SingleRoRx && !(Flags & PF_W))
     return Flags | PF_X;
   return Flags;

Added: lld/trunk/test/ELF/execute-only-mixed-data.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/execute-only-mixed-data.s?rev=338271&view=auto
==============================================================================
--- lld/trunk/test/ELF/execute-only-mixed-data.s (added)
+++ lld/trunk/test/ELF/execute-only-mixed-data.s Mon Jul 30 10:02:46 2018
@@ -0,0 +1,26 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
+
+// RUN: echo "SECTIONS \
+// RUN: { \
+// RUN:  .text : { *(.text) *(.rodata.foo) } \
+// RUN:  .rodata : { *(.rodata.bar) } \
+// RUN: }" > %t.lds
+// RUN: not ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1 | FileCheck %s
+
+// RUN: echo "SECTIONS \
+// RUN: { \
+// RUN:  .text : { *(.text) } \
+// RUN:  .rodata : { *(.rodata.bar) *(.rodata.foo) } \
+// RUN: }" > %t.lds
+// RUN: ld.lld -T%t.lds %t.o -o %t -execute-only 2>&1
+
+// CHECK: -execute-only does not support intermingling data and code
+
+    br lr
+
+.section .rodata.foo
+.word 0x1
+.section .rodata.bar
+.word 0x2

Added: lld/trunk/test/ELF/execute-only.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/execute-only.s?rev=338271&view=auto
==============================================================================
--- lld/trunk/test/ELF/execute-only.s (added)
+++ lld/trunk/test/ELF/execute-only.s Mon Jul 30 10:02:46 2018
@@ -0,0 +1,10 @@
+// REQUIRES: aarch64
+
+// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-none %s -o %t.o
+// RUN: ld.lld -Ttext=0xcafe0000 %t.o -o %t.so -shared -execute-only
+// RUN: llvm-readelf -l %t.so | FileCheck %s
+
+// CHECK:      LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004   E 0x{{.*}}
+// CHECK-NOT:  LOAD {{.*}} 0x00000000cafe0000 0x000004 0x000004 R E 0x{{.*}}
+
+        br lr




More information about the llvm-commits mailing list