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)
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);
}
const coff_section *Header;
StringRef SectionName;
- std::vector<Chunk *> AssocChildren;
+ std::vector<SectionChunk *> AssocChildren;
llvm::iterator_range<const coff_relocation *> Relocs;
size_t NumRelocs;
bool isLive() const { return (*Data)->isLive(); }
void markLive() { (*Data)->markLive(); }
Chunk *getChunk() { return *Data; }
+ uint64_t getValue() { return Sym.getValue(); }
private:
StringRef Name;
--- /dev/null
+---
+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
--- /dev/null
+---
+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
# 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