[lld] r351917 - lld-link: Use just one code path to process associative comdats, reject some invalid associated comdats

Nico Weber via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 22 18:07:10 PST 2019


Author: nico
Date: Tue Jan 22 18:07:10 2019
New Revision: 351917

URL: http://llvm.org/viewvc/llvm-project?rev=351917&view=rev
Log:
lld-link: Use just one code path to process associative comdats, reject some invalid associated comdats

Currently, if an associative comdat appears after the comdat it's associated
with it's processed immediately, else it's deferred until the end of the object
file. I found this confusing to think about while working on PR40094, so this
makes it so that associated comdats are always processed at the end of the
object file.  This seems to be perf-neutral and simpler.

Now there's a natural place to reject the associated comdats referring to later
associated comdats (associated comdats referring to associated comdats is
invalid per COFF spec) that, so reject those. (A later patch will reject
associated comdats referring to earlier comdats.)

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

Added:
    lld/trunk/test/COFF/associative-comdat-empty.s
    lld/trunk/test/COFF/associative-comdat-order.s
Modified:
    lld/trunk/COFF/InputFiles.cpp

Modified: lld/trunk/COFF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/InputFiles.cpp?rev=351917&r1=351916&r2=351917&view=diff
==============================================================================
--- lld/trunk/COFF/InputFiles.cpp (original)
+++ lld/trunk/COFF/InputFiles.cpp Tue Jan 22 18:07:10 2019
@@ -223,14 +223,23 @@ void ObjFile::readAssociativeDefinition(
 
 void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
                                         const coff_aux_section_definition *Def,
-                                        uint32_t ParentSection) {
-  SectionChunk *Parent = SparseChunks[ParentSection];
+                                        uint32_t ParentIndex) {
+  SectionChunk *Parent = SparseChunks[ParentIndex];
 
-  // If the parent is pending, it probably means that its section definition
-  // appears after us in the symbol table. Leave the associated section as
-  // pending; we will handle it during the second pass in initializeSymbols().
-  if (Parent == PendingComdat)
+  if (Parent == PendingComdat) {
+    // This can happen if an associative comdat refers to another associative
+    // comdat that appears after it (invalid per COFF spec) or to a section
+    // without any symbols.
+    StringRef Name, ParentName;
+    COFFObj->getSymbolName(Sym, Name);
+
+    const coff_section *ParentSec;
+    COFFObj->getSection(ParentIndex, ParentSec);
+    COFFObj->getSectionName(ParentSec, ParentName);
+    error(toString(this) + ": associative comdat " + Name +
+          " has invalid reference to section " + ParentName);
     return;
+  }
 
   // Check whether the parent is prevailing. If it is, so are we, and we read
   // the section; otherwise mark it as discarded.
@@ -326,8 +335,7 @@ void ObjFile::initializeSymbols() {
       // was pending at the point when the symbol was read. This can happen in
       // two cases:
       // 1) section definition symbol for a comdat leader;
-      // 2) symbol belongs to a comdat section associated with a section whose
-      //    section definition symbol appears later in the symbol table.
+      // 2) symbol belongs to a comdat section associated with another section.
       // In both of these cases, we can expect the section to be resolved by
       // the time we finish visiting the remaining symbols in the symbol
       // table. So we postpone the handling of this symbol until that time.
@@ -437,21 +445,15 @@ Optional<Symbol *> ObjFile::createDefine
     return Leader;
   }
 
-  // Read associative section definitions and prepare to handle the comdat
-  // leader symbol by setting the section's ComdatDefs pointer if we encounter a
-  // non-associative comdat.
+  // Prepare to handle the comdat leader symbol by setting the section's
+  // ComdatDefs pointer if we encounter a non-associative comdat.
   if (SparseChunks[SectionNumber] == PendingComdat) {
     if (const coff_aux_section_definition *Def = Sym.getSectionDefinition()) {
-      if (Def->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
-        readAssociativeDefinition(Sym, Def);
-      else
+      if (Def->Selection != IMAGE_COMDAT_SELECT_ASSOCIATIVE)
         ComdatDefs[SectionNumber] = Def;
     }
-  }
-
-  // readAssociativeDefinition() writes to SparseChunks, so need to check again.
-  if (SparseChunks[SectionNumber] == PendingComdat)
     return None;
+  }
 
   return createRegular(Sym);
 }

Added: lld/trunk/test/COFF/associative-comdat-empty.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/associative-comdat-empty.s?rev=351917&view=auto
==============================================================================
--- lld/trunk/test/COFF/associative-comdat-empty.s (added)
+++ lld/trunk/test/COFF/associative-comdat-empty.s Tue Jan 22 18:07:10 2019
@@ -0,0 +1,56 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck %s
+
+# Tests an associative comdat being associated with an empty section errors.
+# CHECK: lld-link: error: {{.*}}: associative comdat .text$ac1 has invalid reference to section .text$nm
+# CHECK-NOT: lld-link: error:
+
+--- !COFF
+header:          
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:        
+  - Name:            '.text$ac1'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+  - Name:            '.text$nm'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+symbols:         
+  - Name:            '.text$ac1'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          2
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$nm'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          0
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          4
+      Selection:       IMAGE_COMDAT_SELECT_ANY
+  - Name:            assocsym
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...
+
+

Added: lld/trunk/test/COFF/associative-comdat-order.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/associative-comdat-order.s?rev=351917&view=auto
==============================================================================
--- lld/trunk/test/COFF/associative-comdat-order.s (added)
+++ lld/trunk/test/COFF/associative-comdat-order.s Tue Jan 22 18:07:10 2019
@@ -0,0 +1,85 @@
+# RUN: yaml2obj < %s > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck %s
+
+# Tests that an associative comdat being associated with another
+# associated comdat later in the file produces an error.
+# CHECK: lld-link: error: {{.*}}: associative comdat .text$ac1 has invalid reference to section .text$ac2
+# CHECK-NOT: lld-link: error:
+
+--- !COFF
+header:          
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:        
+  - Name:            '.text$ac1'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+  - Name:            '.text$ac2'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+  - Name:            '.text$nm'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
+    Alignment:       1
+    SectionData:     '01000000'
+symbols:         
+  - Name:            '.text$ac1'
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          2
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$ac2'
+    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:        3099354981
+      Number:          3
+      Selection:       IMAGE_COMDAT_SELECT_ASSOCIATIVE
+  - Name:            '.text$nm'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition: 
+      Length:          4
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3099354981
+      Number:          4
+      Selection:       IMAGE_COMDAT_SELECT_ANY
+  - Name:            symbol
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            assocsym2
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            assocsym
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...
+




More information about the llvm-commits mailing list