[lld] r310871 - [COFF] Add support for aligncomm directives

Martin Storsjo via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 14 12:07:27 PDT 2017


Author: mstorsjo
Date: Mon Aug 14 12:07:27 2017
New Revision: 310871

URL: http://llvm.org/viewvc/llvm-project?rev=310871&view=rev
Log:
[COFF] Add support for aligncomm directives

These are emitted for comm symbols in object files, when targeting
a GNU environment.

Alternatively, just ignore them since we already align CommonChunk
to the natural size of the content (up to 32 bytes). That would only
trade away the possibility to overalign small symbols, which doesn't
sound like something that might not need to be handled?

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

Added:
    lld/trunk/test/COFF/common-alignment.test
Modified:
    lld/trunk/COFF/Chunks.cpp
    lld/trunk/COFF/Chunks.h
    lld/trunk/COFF/Config.h
    lld/trunk/COFF/Driver.cpp
    lld/trunk/COFF/Driver.h
    lld/trunk/COFF/DriverUtils.cpp
    lld/trunk/COFF/Options.td
    lld/trunk/COFF/Symbols.h

Modified: lld/trunk/COFF/Chunks.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.cpp?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.cpp (original)
+++ lld/trunk/COFF/Chunks.cpp Mon Aug 14 12:07:27 2017
@@ -377,6 +377,10 @@ CommonChunk::CommonChunk(const COFFSymbo
   Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
 }
 
+void CommonChunk::setAlign(uint32_t NewAlign) {
+  Align = std::max(Align, NewAlign);
+}
+
 uint32_t CommonChunk::getPermissions() const {
   return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
          IMAGE_SCN_MEM_WRITE;

Modified: lld/trunk/COFF/Chunks.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Chunks.h?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Chunks.h (original)
+++ lld/trunk/COFF/Chunks.h Mon Aug 14 12:07:27 2017
@@ -243,6 +243,7 @@ public:
   bool hasData() const override { return false; }
   uint32_t getPermissions() const override;
   StringRef getSectionName() const override { return ".bss"; }
+  void setAlign(uint32_t NewAlign);
 
 private:
   const COFFSymbolRef Sym;

Modified: lld/trunk/COFF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Config.h?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Config.h (original)
+++ lld/trunk/COFF/Config.h Mon Aug 14 12:07:27 2017
@@ -139,6 +139,9 @@ struct Configuration {
   StringRef ManifestUIAccess = "'false'";
   StringRef ManifestFile;
 
+  // Used for /aligncomm.
+  std::map<std::string, int> AlignComm;
+
   // Used for /failifmismatch.
   std::map<StringRef, StringRef> MustMatch;
 

Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Mon Aug 14 12:07:27 2017
@@ -202,6 +202,9 @@ void LinkerDriver::parseDirectives(Strin
 
   for (auto *Arg : Args) {
     switch (Arg->getOption().getUnaliasedOption().getID()) {
+    case OPT_aligncomm:
+      parseAligncomm(Arg->getValue());
+      break;
     case OPT_alternatename:
       parseAlternateName(Arg->getValue());
       break;
@@ -899,6 +902,10 @@ void LinkerDriver::link(ArrayRef<const c
   for (auto *Arg : Args.filtered(OPT_section))
     parseSection(Arg->getValue());
 
+  // Handle /aligncomm
+  for (auto *Arg : Args.filtered(OPT_aligncomm))
+    parseAligncomm(Arg->getValue());
+
   // Handle /manifestdependency. This enables /manifest unless /manifest:no is
   // also passed.
   if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) {
@@ -1158,6 +1165,23 @@ void LinkerDriver::link(ArrayRef<const c
     assignExportOrdinals();
   }
 
+  // Set extra alignment for .comm symbols
+  for (auto Pair : Config->AlignComm) {
+    StringRef Name = Pair.first;
+    int Align = Pair.second;
+    Symbol *Sym = Symtab.find(Name);
+    if (!Sym) {
+      warn("/aligncomm symbol " + Name + " not found");
+      continue;
+    }
+    auto *DC = dyn_cast<DefinedCommon>(Sym->body());
+    if (!DC) {
+      warn("/aligncomm symbol " + Name + " of wrong kind");
+      continue;
+    }
+    DC->getChunk()->setAlign(Align);
+  }
+
   // Windows specific -- Create a side-by-side manifest file.
   if (Config->Manifest == Configuration::SideBySide)
     createSideBySideManifest();

Modified: lld/trunk/COFF/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.h?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.h (original)
+++ lld/trunk/COFF/Driver.h Mon Aug 14 12:07:27 2017
@@ -145,6 +145,7 @@ void parseSubsystem(StringRef Arg, Windo
 void parseAlternateName(StringRef);
 void parseMerge(StringRef);
 void parseSection(StringRef);
+void parseAligncomm(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=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/DriverUtils.cpp (original)
+++ lld/trunk/COFF/DriverUtils.cpp Mon Aug 14 12:07:27 2017
@@ -221,6 +221,22 @@ void parseSection(StringRef S) {
   Config->Section[Name] = parseSectionAttributes(Attrs);
 }
 
+// Parses /aligncomm option argument.
+void parseAligncomm(StringRef S) {
+  StringRef Name, Align;
+  std::tie(Name, Align) = S.split(',');
+  if (Name.empty() || Align.empty()) {
+    error("/aligncomm: invalid argument: " + S);
+    return;
+  }
+  int V;
+  if (Align.getAsInteger(0, V)) {
+    error("/aligncomm: invalid argument: " + S);
+    return;
+  }
+  Config->AlignComm[Name] = std::max(Config->AlignComm[Name], 1 << V);
+}
+
 // Parses a string in the form of "EMBED[,=<integer>]|NO".
 // Results are directly written to Config.
 void parseManifest(StringRef Arg) {

Modified: lld/trunk/COFF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Options.td?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Options.td (original)
+++ lld/trunk/COFF/Options.td Mon Aug 14 12:07:27 2017
@@ -16,6 +16,7 @@ multiclass B<string name, string help> {
 }
 
 def align   : P<"align", "Section alignment">;
+def aligncomm : P<"aligncomm", "Set common symbol alignment">;
 def alternatename : P<"alternatename", "Define weak alias">;
 def base    : P<"base", "Base address of the program">;
 def defaultlib : P<"defaultlib", "Add the library to the list of input files">;

Modified: lld/trunk/COFF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Symbols.h?rev=310871&r1=310870&r2=310871&view=diff
==============================================================================
--- lld/trunk/COFF/Symbols.h (original)
+++ lld/trunk/COFF/Symbols.h Mon Aug 14 12:07:27 2017
@@ -182,7 +182,7 @@ public:
   }
 
   uint64_t getRVA() { return Data->getRVA(); }
-  Chunk *getChunk() { return Data; }
+  CommonChunk *getChunk() { return Data; }
 
 private:
   friend SymbolTable;

Added: lld/trunk/test/COFF/common-alignment.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/common-alignment.test?rev=310871&view=auto
==============================================================================
--- lld/trunk/test/COFF/common-alignment.test (added)
+++ lld/trunk/test/COFF/common-alignment.test Mon Aug 14 12:07:27 2017
@@ -0,0 +1,78 @@
+# REQUIRES: x86
+# RUN: yaml2obj %s > %t.obj
+# RUN: lld-link /out:%t.exe /entry:main %t.obj %t.obj
+# RUN: llvm-objdump -d %t.exe | FileCheck %s
+
+# Operands of B8 (MOV EAX) are common symbols
+# CHECK: 3000: b8 00 10 00 40
+# CHECK: 3005: b8 10 10 00 40
+
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: []
+sections:
+  - Name:            .text
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     b800000000b800000000
+    Relocations:
+      - VirtualAddress:  1
+        SymbolName:      bssdata4
+        Type:            IMAGE_REL_AMD64_ADDR32
+      - VirtualAddress:  6
+        SymbolName:      bssdata4_align16
+        Type:            IMAGE_REL_AMD64_ADDR32
+  - Name:            .data
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       4
+    SectionData:     03000000
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     202d616c69676e636f6d6d3a62737364617461345f616c69676e31362c340a  # -aligncomm:bssdata4_align16,4
+
+symbols:
+  - Name:            .text
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          0
+      NumberOfRelocations: 5
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            .data
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          4
+      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
+  - Name:            bssdata4
+    Value:           4
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            bssdata4_align16
+    Value:           4
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...




More information about the llvm-commits mailing list