diff options
-rw-r--r-- | lld/COFF/Chunks.h | 3 | ||||
-rw-r--r-- | lld/COFF/ICF.cpp | 3 | ||||
-rw-r--r-- | lld/test/COFF/icf-local.test | 66 |
3 files changed, 69 insertions, 3 deletions
diff --git a/lld/COFF/Chunks.h b/lld/COFF/Chunks.h index 7f6d06198c8..60b8e76f823 100644 --- a/lld/COFF/Chunks.h +++ b/lld/COFF/Chunks.h @@ -204,8 +204,7 @@ private: void replace(SectionChunk *Other); std::atomic<uint64_t> GroupID = { 0 }; - // Chunks are basically unnamed chunks of bytes. - // Symbols are associated for debugging and logging purposs only. + // Sym points to a section symbol if this is a COMDAT chunk. DefinedRegular *Sym = nullptr; }; diff --git a/lld/COFF/ICF.cpp b/lld/COFF/ICF.cpp index 3dab8a79ed6..f99b41624a8 100644 --- a/lld/COFF/ICF.cpp +++ b/lld/COFF/ICF.cpp @@ -185,8 +185,9 @@ void ICF::run(const std::vector<Chunk *> &Vec) { // Collect only mergeable sections and group by hash value. parallel_for_each(Vec.begin(), Vec.end(), [&](Chunk *C) { if (auto *SC = dyn_cast<SectionChunk>(C)) { + bool Global = SC->Sym && SC->Sym->isExternal(); bool Writable = SC->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE; - if (SC->isCOMDAT() && SC->isLive() && !Writable) + if (SC->isCOMDAT() && SC->isLive() && Global && !Writable) SC->GroupID = getHash(SC) | (uint64_t(1) << 63); } }); diff --git a/lld/test/COFF/icf-local.test b/lld/test/COFF/icf-local.test new file mode 100644 index 00000000000..a0b4c91559a --- /dev/null +++ b/lld/test/COFF/icf-local.test @@ -0,0 +1,66 @@ +# COMDAT sections with non-external linkage should not be merged by ICF. + +# RUN: yaml2obj < %s > %t1.obj +# RUN: sed s/foo/main/ %s | yaml2obj > %t2.obj +# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /verbose \ +# RUN: %t1.obj %t2.obj > %t.log 2>&1 +# RUN: FileCheck %s < %t.log + +# CHECK-NOT: Removed bar + +--- +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 488D0500000000C3 + Relocations: + - VirtualAddress: 3 + SymbolName: bar + Type: IMAGE_REL_AMD64_REL32 + - Name: .rdata + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ] + Alignment: 8 + SectionData: 2A000000000000002B00000000000000 +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: 1 + NumberOfLinenumbers: 0 + CheckSum: 1092178131 + Number: 1 + - Name: .rdata + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 16 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 1200668497 + Number: 5 + Selection: IMAGE_COMDAT_SELECT_ANY + - Name: foo + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: bar + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC +... |