Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -684,6 +684,7 @@ class MergeSyntheticSection : public SyntheticSection { public: void addSection(MergeInputSection *MS); + void writeTo(uint8_t *Buf) override; protected: MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags, @@ -699,7 +700,6 @@ uint32_t Alignment); size_t getSize() const override; - void writeTo(uint8_t *Buf) override; void finalizeContents() override; private: @@ -713,7 +713,6 @@ : MergeSyntheticSection(Name, Type, Flags, Alignment) {} size_t getSize() const override { return Size; } - void writeTo(uint8_t *Buf) override; void finalizeContents() override; private: Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2407,6 +2407,10 @@ Sections.push_back(MS); } +void MergeSyntheticSection::writeTo(uint8_t *Buf) { + memcpy(Buf, Data.data(), Data.size()); +} + MergeTailSection::MergeTailSection(StringRef Name, uint32_t Type, uint64_t Flags, uint32_t Alignment) : MergeSyntheticSection(Name, Type, Flags, Alignment), @@ -2414,8 +2418,6 @@ size_t MergeTailSection::getSize() const { return Builder.getSize(); } -void MergeTailSection::writeTo(uint8_t *Buf) { Builder.write(Buf); } - void MergeTailSection::finalizeContents() { // Add all string pieces to the string table builder to create section // contents. @@ -2434,11 +2436,13 @@ for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I) if (Sec->Pieces[I].Live) Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I)); -} -void MergeNoTailSection::writeTo(uint8_t *Buf) { - for (size_t I = 0; I < NumShards; ++I) - Shards[I].write(Buf + ShardOffsets[I]); + // Populate data. + size_t Size = Builder.getSize(); + uint8_t *Buf = new (BAlloc) uint8_t[Size]; + Data = ArrayRef(Buf, Size); + memset(Buf, 0, Size); + Builder.write(Buf); } // This function is very hot (i.e. it can take several seconds to finish) @@ -2491,6 +2495,13 @@ Sec->Pieces[I].OutputOff += ShardOffsets[getShardId(Sec->Pieces[I].Hash)]; }); + + // Populate data. + uint8_t *Buf = new (BAlloc) uint8_t[Size]; + Data = ArrayRef(Buf, Size); + memset(Buf, 0, Size); + for (size_t I = 0; I < NumShards; ++I) + Shards[I].write(Buf + ShardOffsets[I]); } static MergeSyntheticSection *createMergeSynthetic(StringRef Name, Index: test/ELF/icf-not-equal-merged-sections.s =================================================================== --- /dev/null +++ test/ELF/icf-not-equal-merged-sections.s @@ -0,0 +1,36 @@ +# REQUIRES: x86 + +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o +# RUN: ld.lld %t.o -o %t --icf=all --ignore-data-address-equality --print-icf-sections | FileCheck -allow-empty %s +# RUN: llvm-readobj -s -section-data %t | FileCheck --check-prefix=NODEDUP %s + +# CHECK-NOT: selected section :(.rodata) + +# NODEDUP: Name: .rodata +# NODEDUP-NEXT: Type: SHT_PROGBITS +# NODEDUP-NEXT: Flags [ +# NODEDUP-NEXT: SHF_ALLOC +# NODEDUP-NEXT: SHF_MERGE +# NODEDUP-NEXT: ] +# NODEDUP-NEXT: Address: +# NODEDUP-NEXT: Offset: +# NODEDUP-NEXT: Size: 16 +# NODEDUP-NEXT: Link: +# NODEDUP-NEXT: Info: +# NODEDUP-NEXT: AddressAlignment: 8 +# NODEDUP-NEXT: EntrySize: 0 +# NODEDUP-NEXT: SectionData ( +# NODEDUP-NEXT: 0000: 77665544 33221100 67452301 10325476 +# NODEDUP-NEXT: ) + +.section .rodata.cst4,"aM",@progbits,4 +rodata4: + .long 0x00112233 + .long 0x44556677 + .long 0x00112233 + .long 0x44556677 + +.section .rodata.cst8,"aM",@progbits,8 +rodata8: + .long 0x01234567 + .long 0x76543210