[lld] r217358 - [ELF] Implement --rosegment

Shankar Easwaran shankarke at gmail.com
Sun Sep 7 21:05:53 PDT 2014


Author: shankare
Date: Sun Sep  7 23:05:52 2014
New Revision: 217358

URL: http://llvm.org/viewvc/llvm-project?rev=217358&view=rev
Log:
[ELF] Implement --rosegment

By default linker would not create a separate segment to hold read only data.

This option overrides that behavior by creating the a separate read only segment
for read only data.

Added:
    lld/trunk/test/elf/Inputs/rodata.c
    lld/trunk/test/elf/Inputs/rodata.o
    lld/trunk/test/elf/rosegment.test
Modified:
    lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
    lld/trunk/lib/Driver/GnuLdDriver.cpp
    lld/trunk/lib/Driver/GnuLdOptions.td
    lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
    lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp

Modified: lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h?rev=217358&r1=217357&r2=217358&view=diff
==============================================================================
--- lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h (original)
+++ lld/trunk/include/lld/ReaderWriter/ELFLinkingContext.h Sun Sep  7 23:05:52 2014
@@ -251,6 +251,13 @@ public:
     return true;
   }
 
+  // By default, the linker would merge sections that are read only with
+  // segments that have read and execute permissions. When the user specifies a
+  // flag --rosegment, a separate segment needs to be created.
+  bool mergeRODataToTextSegment() const { return _mergeRODataToTextSegment; }
+
+  void setCreateSeparateROSegment() { _mergeRODataToTextSegment = false; }
+
 private:
   ELFLinkingContext() LLVM_DELETED_FUNCTION;
 
@@ -273,6 +280,7 @@ protected:
   bool _useShlibUndefines;
   bool _dynamicLinkerArg;
   bool _noAllowDynamicLibraries;
+  bool _mergeRODataToTextSegment;
   OutputMagic _outputMagic;
   StringRefVector _inputSearchPaths;
   std::unique_ptr<Writer> _writer;

Modified: lld/trunk/lib/Driver/GnuLdDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdDriver.cpp?rev=217358&r1=217357&r2=217358&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdDriver.cpp (original)
+++ lld/trunk/lib/Driver/GnuLdDriver.cpp Sun Sep  7 23:05:52 2014
@@ -537,6 +537,10 @@ bool GnuLdDriver::parse(int argc, const
       ctx->setSharedObjectName(inputArg->getValue());
       break;
 
+    case OPT_rosegment:
+      ctx->setCreateSeparateROSegment();
+      break;
+
     default:
       break;
     } // end switch on option ID

Modified: lld/trunk/lib/Driver/GnuLdOptions.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/Driver/GnuLdOptions.td?rev=217358&r1=217357&r2=217358&view=diff
==============================================================================
--- lld/trunk/lib/Driver/GnuLdOptions.td (original)
+++ lld/trunk/lib/Driver/GnuLdOptions.td Sun Sep  7 23:05:52 2014
@@ -201,6 +201,9 @@ def defsym : Joined<["--"], "defsym=">,
 //===----------------------------------------------------------------------===//
 def grp_customopts : OptionGroup<"opts">,
      HelpText<"CUSTOM OPTIONS">;
+def rosegment: Flag<["--"], "rosegment">,
+     HelpText<"Put read-only non-executable sections in their own segment">,
+     Group<grp_customopts>;
 def z : Separate<["-"], "z">,
      HelpText<"Linker Option extensions">,
      Group<grp_customopts>;

Modified: lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h?rev=217358&r1=217357&r2=217358&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h (original)
+++ lld/trunk/lib/ReaderWriter/ELF/DefaultLayout.h Sun Sep  7 23:05:52 2014
@@ -634,7 +634,8 @@ template <class ELFT> void DefaultLayout
         StringRef segmentName = section->segmentKindToStr();
 
         int64_t lookupSectionFlag = msi->flags();
-        if (!(lookupSectionFlag & llvm::ELF::SHF_WRITE))
+        if ((!(lookupSectionFlag & llvm::ELF::SHF_WRITE)) &&
+            (_context.mergeRODataToTextSegment()))
           lookupSectionFlag &= ~llvm::ELF::SHF_EXECINSTR;
 
         // Merge string sections into Data segment itself

Modified: lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp?rev=217358&r1=217357&r2=217358&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp (original)
+++ lld/trunk/lib/ReaderWriter/ELF/ELFLinkingContext.cpp Sun Sep  7 23:05:52 2014
@@ -59,8 +59,8 @@ ELFLinkingContext::ELFLinkingContext(
       _isStaticExecutable(false), _noInhibitExec(false),
       _mergeCommonStrings(false), _runLayoutPass(true),
       _useShlibUndefines(true), _dynamicLinkerArg(false),
-      _noAllowDynamicLibraries(false), _outputMagic(OutputMagic::DEFAULT),
-      _sysrootPath("") {}
+      _noAllowDynamicLibraries(false), _mergeRODataToTextSegment(true),
+      _outputMagic(OutputMagic::DEFAULT), _sysrootPath("") {}
 
 bool ELFLinkingContext::is64Bits() const { return getTriple().isArch64Bit(); }
 

Added: lld/trunk/test/elf/Inputs/rodata.c
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/rodata.c?rev=217358&view=auto
==============================================================================
--- lld/trunk/test/elf/Inputs/rodata.c (added)
+++ lld/trunk/test/elf/Inputs/rodata.c Sun Sep  7 23:05:52 2014
@@ -0,0 +1,4 @@
+const unsigned char *str = "llvm";
+int foo() {
+  return str[0];
+}

Added: lld/trunk/test/elf/Inputs/rodata.o
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/Inputs/rodata.o?rev=217358&view=auto
==============================================================================
Binary files lld/trunk/test/elf/Inputs/rodata.o (added) and lld/trunk/test/elf/Inputs/rodata.o Sun Sep  7 23:05:52 2014 differ

Added: lld/trunk/test/elf/rosegment.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/elf/rosegment.test?rev=217358&view=auto
==============================================================================
--- lld/trunk/test/elf/rosegment.test (added)
+++ lld/trunk/test/elf/rosegment.test Sun Sep  7 23:05:52 2014
@@ -0,0 +1,26 @@
+# Tests that the option --rosegment produces an output file with a separate
+# segment created for read only data.
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/rodata.o -o %t1.elf \
+RUN: --noinhibit-exec
+RUN: lld -flavor gnu -target x86_64 %p/Inputs/rodata.o --rosegment -o %t2.elf \
+RUN: --noinhibit-exec
+RUN: llvm-readobj -program-headers %t1.elf | FileCheck %s -check-prefix=NORO-SEGMENT
+RUN: llvm-readobj -program-headers %t2.elf | FileCheck %s -check-prefix=RO-SEGMENT
+
+#NORO-SEGMENT:    Type: PT_PHDR
+#NORO-SEGMENT:    Type: PT_INTERP
+#NORO-SEGMENT:    Type: PT_LOAD
+#NORO-SEGMENT:    Type: PT_LOAD
+#NORO-SEGMENT:    Type: PT_GNU_EH_FRAME
+#NORO-SEGMENT:    Type: PT_DYNAMIC
+
+#RO-SEGMENT:    Type: PT_PHDR
+#RO-SEGMENT:    Type: PT_INTERP
+#RO-SEGMENT:    Type: PT_LOAD
+#RO-SEGMENT:    Type: PT_LOAD
+#RO-SEGMENT:   Flags [
+#RO-SEGMENT:      PF_R (0x4)
+#RO-SEGMENT:    ]
+#RO-SEGMENT:    Type: PT_LOAD
+#RO-SEGMENT:    Type: PT_GNU_EH_FRAME
+#RO-SEGMENT:    Type: PT_DYNAMIC





More information about the llvm-commits mailing list