Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lld/COFF/Chunks.cpp15
-rw-r--r--lld/COFF/Chunks.h2
-rw-r--r--lld/COFF/Symbols.h1
-rw-r--r--lld/test/COFF/Inputs/icf4.yaml47
-rw-r--r--lld/test/COFF/Inputs/icf5.yaml30
-rw-r--r--lld/test/COFF/icf.test9
6 files changed, 98 insertions, 6 deletions
diff --git a/lld/COFF/Chunks.cpp b/lld/COFF/Chunks.cpp
index aa2c0be3ef51..7a068eebf102 100644
--- a/lld/COFF/Chunks.cpp
+++ b/lld/COFF/Chunks.cpp
@@ -173,6 +173,13 @@ bool SectionChunk::equals(const SectionChunk *X) const {
if (getContents() != X->getContents())
return false;
+ // Compare associative sections
+ if (AssocChildren.size() != X->AssocChildren.size())
+ return false;
+ for (size_t I = 0, E = AssocChildren.size(); I != E; ++I)
+ if (AssocChildren[I]->Ptr != X->AssocChildren[I]->Ptr)
+ return false;
+
// Compare relocations
auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
if (R1.Type != R2.Type)
@@ -181,11 +188,13 @@ bool SectionChunk::equals(const SectionChunk *X) const {
return false;
SymbolBody *B1 = File->getSymbolBody(R1.SymbolTableIndex);
SymbolBody *B2 = X->File->getSymbolBody(R2.SymbolTableIndex);
+ if (B1 == B2)
+ return true;
auto *D1 = dyn_cast<DefinedRegular>(B1);
auto *D2 = dyn_cast<DefinedRegular>(B2);
- if (D1 && D2 && D1->getChunk() == D2->getChunk())
- return true;
- return B1 == B2;
+ return (D1 && D2 &&
+ D1->getValue() == D2->getValue() &&
+ D1->getChunk() == D2->getChunk());
};
return std::equal(Relocs.begin(), Relocs.end(), X->Relocs.begin(), Eq);
}
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h
index 37a6003cf8ec..3b6bf5f7700b 100644
--- a/lld/COFF/Chunks.h
+++ b/lld/COFF/Chunks.h
@@ -151,7 +151,7 @@ private:
const coff_section *Header;
StringRef SectionName;
- std::vector<Chunk *> AssocChildren;
+ std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
size_t NumRelocs;
diff --git a/lld/COFF/Symbols.h b/lld/COFF/Symbols.h
index e0cb7b16acb0..f87b8f12d378 100644
--- a/lld/COFF/Symbols.h
+++ b/lld/COFF/Symbols.h
@@ -137,6 +137,7 @@ public:
bool isLive() const { return (*Data)->isLive(); }
void markLive() { (*Data)->markLive(); }
Chunk *getChunk() { return *Data; }
+ uint64_t getValue() { return Sym.getValue(); }
private:
StringRef Name;
diff --git a/lld/test/COFF/Inputs/icf4.yaml b/lld/test/COFF/Inputs/icf4.yaml
new file mode 100644
index 000000000000..a013d5516ba2
--- /dev/null
+++ b/lld/test/COFF/Inputs/icf4.yaml
@@ -0,0 +1,47 @@
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 0000000000000000
+ - Name: .assoc
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 0000000000000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ # icf4 is *not* identical with mainCRTStartup because it has an associative section
+ - Name: icf4
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
+ - Name: .assoc
+ Value: 0
+ SectionNumber: 2
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 1
+ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
diff --git a/lld/test/COFF/Inputs/icf5.yaml b/lld/test/COFF/Inputs/icf5.yaml
new file mode 100644
index 000000000000..d5b5cbfd5b81
--- /dev/null
+++ b/lld/test/COFF/Inputs/icf5.yaml
@@ -0,0 +1,30 @@
+---
+header:
+ Machine: IMAGE_FILE_MACHINE_AMD64
+ Characteristics: []
+sections:
+ - Name: .text
+ Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+ Alignment: 16
+ SectionData: 0000000000000000
+symbols:
+ - Name: .text
+ Value: 0
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_NULL
+ StorageClass: IMAGE_SYM_CLASS_STATIC
+ SectionDefinition:
+ Length: 8
+ NumberOfRelocations: 0
+ NumberOfLinenumbers: 0
+ CheckSum: 0
+ Number: 0
+ Selection: IMAGE_COMDAT_SELECT_ANY
+ # icf5 is *not* identical with its symbol value is different
+ - Name: icf5
+ Value: 5
+ SectionNumber: 1
+ SimpleType: IMAGE_SYM_TYPE_NULL
+ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
+ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
diff --git a/lld/test/COFF/icf.test b/lld/test/COFF/icf.test
index d5ea949df6ff..cc4e856a9e1e 100644
--- a/lld/test/COFF/icf.test
+++ b/lld/test/COFF/icf.test
@@ -1,11 +1,16 @@
# RUN: yaml2obj < %p/Inputs/icf1.yaml > %t1.obj
# RUN: yaml2obj < %p/Inputs/icf2.yaml > %t2.obj
# RUN: yaml2obj < %p/Inputs/icf3.yaml > %t3.obj
+# RUN: yaml2obj < %p/Inputs/icf4.yaml > %t4.obj
+# RUN: yaml2obj < %p/Inputs/icf5.yaml > %t5.obj
#
-# RUN: lld -flavor link2 /out:%t.exe %t1.obj %t2.obj %t3.obj \
-# RUN: /opt:lldicf /include:icf2 /include:icf3 /verbose >& %t.log
+# RUN: lld -flavor link2 /out:%t.exe %t1.obj %t2.obj %t3.obj %t4.obj %t5.obj \
+# RUN: /opt:lldicf /include:icf2 /include:icf3 /include:icf4 /include:icf5 \
+# RUN: /verbose >& %t.log
# RUN: FileCheck %s < %t.log
CHECK-NOT: Replaced mainCRTStartup
CHECK: Replaced icf2
CHECK-NOT: Replaced icf3
+CHECK-NOT: Replaced icf4
+CHECK-NOT: Replaced icf5