[lld] r273134 - [COFF] Add /section command line flag.
Rui Ueyama via llvm-commits
llvm-commits at lists.llvm.org
Sun Jun 19 20:39:39 PDT 2016
Author: ruiu
Date: Sun Jun 19 22:39:39 2016
New Revision: 273134
URL: http://llvm.org/viewvc/llvm-project?rev=273134&view=rev
Log:
[COFF] Add /section command line flag.
Added:
lld/trunk/test/COFF/section.test
Modified:
lld/trunk/COFF/Config.h
lld/trunk/COFF/Driver.cpp
lld/trunk/COFF/Driver.h
lld/trunk/COFF/DriverUtils.cpp
lld/trunk/COFF/Writer.cpp
Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=273134&r1=273133&r2=273134&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Sun Jun 19 22:39:39 2016
@@ -106,6 +106,9 @@ struct Configuration {
// Used for /merge:from=to (e.g. /merge:.rdata=.text)
std::map<StringRef, StringRef> Merge;
+ // Used for /section=.name,{DEKPRSW} to set section attributes.
+ std::map<StringRef, uint32_t> Section;
+
// Options for manifest files.
ManifestKind Manifest = SideBySide;
int ManifestID = 1;
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=273134&r1=273133&r2=273134&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Sun Jun 19 22:39:39 2016
@@ -119,6 +119,9 @@ void LinkerDriver::parseDirectives(Strin
case OPT_nodefaultlib:
Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
break;
+ case OPT_section:
+ parseSection(Arg->getValue());
+ break;
case OPT_editandcontinue:
case OPT_fastfail:
case OPT_guardsym:
@@ -408,6 +411,10 @@ void LinkerDriver::link(llvm::ArrayRef<c
for (auto *Arg : Args.filtered(OPT_merge))
parseMerge(Arg->getValue());
+ // Handle /section
+ for (auto *Arg : Args.filtered(OPT_section))
+ parseSection(Arg->getValue());
+
// Handle /manifest
if (auto *Arg = Args.getLastArg(OPT_manifest_colon))
parseManifest(Arg->getValue());
Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=273134&r1=273133&r2=273134&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Sun Jun 19 22:39:39 2016
@@ -133,6 +133,7 @@ void parseSubsystem(StringRef Arg, Windo
void parseAlternateName(StringRef);
void parseMerge(StringRef);
+void parseSection(StringRef);
// Parses a string in the form of "EMBED[,=<integer>]|NO".
void parseManifest(StringRef Arg);
Modified: lld/trunk/COFF/DriverUtils.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/DriverUtils.cpp?rev=273134&r1=273133&r2=273134&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Sun Jun 19 22:39:39 2016
@@ -175,6 +175,47 @@ void parseMerge(StringRef S) {
}
}
+static uint32_t parseSectionAttributes(StringRef S) {
+ uint32_t Ret = 0;
+ for (char C : S.lower()) {
+ switch (C) {
+ case 'd':
+ Ret |= IMAGE_SCN_MEM_DISCARDABLE;
+ break;
+ case 'e':
+ Ret |= IMAGE_SCN_MEM_EXECUTE;
+ break;
+ case 'k':
+ Ret |= IMAGE_SCN_MEM_NOT_CACHED;
+ break;
+ case 'p':
+ Ret |= IMAGE_SCN_MEM_NOT_PAGED;
+ break;
+ case 'r':
+ Ret |= IMAGE_SCN_MEM_READ;
+ break;
+ case 's':
+ Ret |= IMAGE_SCN_MEM_SHARED;
+ break;
+ case 'w':
+ Ret |= IMAGE_SCN_MEM_WRITE;
+ break;
+ default:
+ error(Twine("/section: invalid argument: ") + S);
+ }
+ }
+ return Ret;
+}
+
+// Parses /section option argument.
+void parseSection(StringRef S) {
+ StringRef Name, Attrs;
+ std::tie(Name, Attrs) = S.split(',');
+ if (Name.empty() || Attrs.empty())
+ error(Twine("/section: invalid argument: ") + S);
+ Config->Section[Name] = parseSectionAttributes(Attrs);
+}
+
// Parses a string in the form of "EMBED[,=<integer>]|NO".
// Results are directly written to Config.
void parseManifest(StringRef Arg) {
Modified: lld/trunk/COFF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Writer.cpp?rev=273134&r1=273133&r2=273134&view=diff
==============================================================================
--- lld/trunk/COFF/Writer.cpp (original)
+++ lld/trunk/COFF/Writer.cpp Sun Jun 19 22:39:39 2016
@@ -59,6 +59,7 @@ private:
void openFile(StringRef OutputPath);
template <typename PEHeaderTy> void writeHeader();
void fixSafeSEHSymbols();
+ void setSectionPermissions();
void writeSections();
void sortExceptionTable();
void applyRelocations();
@@ -114,6 +115,7 @@ public:
StringRef getName() { return Name; }
std::vector<Chunk *> &getChunks() { return Chunks; }
void addPermissions(uint32_t C);
+ void setPermissions(uint32_t C);
uint32_t getPermissions() { return Header.Characteristics & PermMask; }
uint32_t getCharacteristics() { return Header.Characteristics; }
uint64_t getRVA() { return Header.VirtualAddress; }
@@ -176,6 +178,10 @@ void OutputSection::addPermissions(uint3
Header.Characteristics |= C & PermMask;
}
+void OutputSection::setPermissions(uint32_t C) {
+ Header.Characteristics = C & PermMask;
+}
+
// Write the section header to a given buffer.
void OutputSection::writeHeaderTo(uint8_t *Buf) {
auto *Hdr = reinterpret_cast<coff_section *>(Buf);
@@ -222,6 +228,7 @@ void Writer::run() {
createSection(".reloc");
assignAddresses();
removeEmptySections();
+ setSectionPermissions();
createSymbolAndStringTable();
openFile(Config->OutputFile);
if (Config->is64()) {
@@ -657,6 +664,17 @@ void Writer::fixSafeSEHSymbols() {
Config->SEHCount->setVA(SEHTable->getSize() / 4);
}
+// Handles /section options to allow users to overwrite
+// section attributes.
+void Writer::setSectionPermissions() {
+ for (auto &P : Config->Section) {
+ StringRef Name = P.first;
+ uint32_t Perm = P.second;
+ if (auto *Sec = findSection(Name))
+ Sec->setPermissions(Perm);
+ }
+}
+
// Write section contents to a mmap'ed file.
void Writer::writeSections() {
uint8_t *Buf = Buffer->getBufferStart();
Added: lld/trunk/test/COFF/section.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/section.test?rev=273134&view=auto
==============================================================================
--- lld/trunk/test/COFF/section.test (added)
+++ lld/trunk/test/COFF/section.test Sun Jun 19 22:39:39 2016
@@ -0,0 +1,62 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN: /section:.foo,r %t.obj
+# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=R %s
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN: /section:.foo,w %t.obj
+# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=W %s
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN: /section:.foo,e %t.obj
+# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=E %s
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
+# RUN: /section:.foo,s %t.obj
+# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s
+
+# R: Characteristics [
+# R-NEXT: IMAGE_SCN_MEM_READ
+# R-NEXT: ]
+
+# W: Characteristics [
+# W-NEXT: IMAGE_SCN_MEM_WRITE
+# W-NEXT: ]
+
+# E: Characteristics [
+# E-NEXT: IMAGE_SCN_MEM_EXECUTE
+# E-NEXT: ]
+
+# S: Characteristics [
+# S-NEXT: IMAGE_SCN_MEM_SHARED
+# S-NEXT: ]
+
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .foo
+ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+ Alignment: 4
+ SectionData: 000000000000
+symbols:
+ - Name: .foo
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 6
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ - Name: main
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+...
More information about the llvm-commits
mailing list