[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