summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2019-01-26 00:14:52 +0000
committerNico Weber <nicolasweber@gmx.de>2019-01-26 00:14:52 +0000
commit6bb3a1aa757f5c352fa298b246dcd4c4182ef9e1 (patch)
tree9747f7e89cd5edc3637bf0c3cf9b1c9708a1b95a
parente9cac31dac90aaf0829b7215778fce41edc946f5 (diff)
downloadbcm5719-llvm-6bb3a1aa757f5c352fa298b246dcd4c4182ef9e1.tar.gz
bcm5719-llvm-6bb3a1aa757f5c352fa298b246dcd4c4182ef9e1.zip
lld-link: Store comdat selection in SectionChunk, reject more invalid associated comdats
I need the comdat selection for PR40094. To keep the patch for that smaller, I'm adding it here, and as a first application I'm using it to reject associative comdats referring to earlier associative comdats. Depends on D56929; together with that all associative comdats referring to other associative comdats are now rejected. Differential Revision: https://reviews.llvm.org/D56931 llvm-svn: 352254
-rw-r--r--lld/COFF/Chunks.h3
-rw-r--r--lld/COFF/InputFiles.cpp21
-rw-r--r--lld/test/COFF/associative-comdat-order.test20
3 files changed, 32 insertions, 12 deletions
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 0185da17b2b..60dbf1ff7a4 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -223,6 +223,9 @@ public:
// The COMDAT leader symbol if this is a COMDAT chunk.
DefinedRegular *Sym = nullptr;
+ // The COMDAT selection if this is a COMDAT chunk.
+ llvm::COFF::COMDATType Selection;
+
ArrayRef<coff_relocation> Relocs;
// Used by the garbage collector.
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index f291a9dbf83..4b87e02a6dd 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -226,10 +226,7 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
uint32_t ParentIndex) {
SectionChunk *Parent = SparseChunks[ParentIndex];
- 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.
+ auto Diag = [&]() {
StringRef Name, ParentName;
COFFObj->getSymbolName(Sym, Name);
@@ -238,6 +235,13 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
COFFObj->getSectionName(ParentSec, ParentName);
error(toString(this) + ": associative comdat " + Name +
" has invalid reference to section " + ParentName);
+ };
+
+ 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.
+ Diag();
return;
}
@@ -245,7 +249,14 @@ void ObjFile::readAssociativeDefinition(COFFSymbolRef Sym,
// the section; otherwise mark it as discarded.
int32_t SectionNumber = Sym.getSectionNumber();
if (Parent) {
- SparseChunks[SectionNumber] = readSection(SectionNumber, Def, "");
+ if (Parent->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ Diag();
+ return;
+ }
+
+ SectionChunk *C = readSection(SectionNumber, Def, "");
+ C->Selection = IMAGE_COMDAT_SELECT_ASSOCIATIVE;
+ SparseChunks[SectionNumber] = C;
if (SparseChunks[SectionNumber])
Parent->addAssociative(SparseChunks[SectionNumber]);
} else {
diff --git a/lld/test/COFF/associative-comdat-order.test b/lld/test/COFF/associative-comdat-order.test
index 31105d51268..09b1b460215 100644
--- a/lld/test/COFF/associative-comdat-order.test
+++ b/lld/test/COFF/associative-comdat-order.test
@@ -1,10 +1,16 @@
-# 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:
+# RUN: sed -e s/ASSOC1/2/ -e s/ASSOC2/3/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck --check-prefix=FORWARD %s
+# FORWARD: lld-link: error: {{.*}}: associative comdat .text$ac1 has invalid reference to section .text$ac2
+# FORWARD-NOT: lld-link: error:
+
+# Tests that an associative comdat being associated with another
+# associated comdat earlier in the file produces an error.
+# RUN: sed -e s/ASSOC1/3/ -e s/ASSOC2/1/ %s | yaml2obj > %t.obj
+# RUN: not lld-link /include:symbol /dll /noentry /nodefaultlib %t.obj /out:%t.exe 2>&1 | FileCheck --check-prefix=BACKWARD %s
+# BACKWARD: lld-link: error: {{.*}}: associative comdat .text$ac2 has invalid reference to section .text$ac1
+# BACKWARD-NOT: lld-link: error:
--- !COFF
header:
@@ -35,7 +41,7 @@ symbols:
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 3099354981
- Number: 2
+ Number: ASSOC1
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: '.text$ac2'
Value: 0
@@ -48,7 +54,7 @@ symbols:
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 3099354981
- Number: 3
+ Number: ASSOC2
Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
- Name: '.text$nm'
Value: 0
OpenPOWER on IntegriCloud