[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