diff --git a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp index 10949c85f554..9a350b23b008 100644 --- a/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp +++ b/lld/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp @@ -161,6 +161,20 @@ private: // Filter non-defined atoms, and group defined atoms by its section. SectionToSymbolsT definedSymbols; for (const coff_symbol *sym : symbols) { + // A symbol with section number 0 and non-zero value represents an + // uninitialized data. I don't understand why there are two ways to define + // an uninitialized data symbol (.bss and this way), but that's how COFF + // works. + if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED && + sym->Value > 0) { + StringRef name = _symbolName[sym]; + uint32_t size = sym->Value; + auto *atom = new (_alloc) COFFBSSAtom(*this, name, sym, size, 0); + result.push_back(atom); + continue; + } + + // Skip if it's not for defined atom. if (sym->SectionNumber == llvm::COFF::IMAGE_SYM_ABSOLUTE || sym->SectionNumber == llvm::COFF::IMAGE_SYM_UNDEFINED) continue; diff --git a/lld/test/pecoff/Inputs/bss-undef.obj.yaml b/lld/test/pecoff/Inputs/bss-undef.obj.yaml new file mode 100644 index 000000000000..d10c8f7eefeb --- /dev/null +++ b/lld/test/pecoff/Inputs/bss-undef.obj.yaml @@ -0,0 +1,43 @@ +--- +header: + Machine: IMAGE_FILE_MACHINE_I386 + Characteristics: [ ] +sections: + - Name: .text + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 4 + SectionData: "" + - Name: .data + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ] + Alignment: 4 + SectionData: 03000000 +symbols: + - Name: .text + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + NumberOfAuxSymbols: 1 + AuxiliaryData: 000000000000000000000000000000000000 + - Name: .data + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + NumberOfAuxSymbols: 1 + AuxiliaryData: 040000000000000000000000000000000000 + - Name: _bssdata1 + Value: 4 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL + - Name: _bssdata2 + Value: 4 + SectionNumber: 0 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... diff --git a/lld/test/pecoff/bss-undef.test b/lld/test/pecoff/bss-undef.test new file mode 100644 index 000000000000..e77940f2154f --- /dev/null +++ b/lld/test/pecoff/bss-undef.test @@ -0,0 +1,22 @@ +# RUN: yaml2obj %p/Inputs/bss-undef.obj.yaml > %t.obj +# +# RUN: lld -flavor link /out:%t /subsystem:console /force -- %t.obj \ +# RUN: && llvm-readobj -sections %t | FileCheck %s + +CHECK: Section { +CHECK: Number: 2 +CHECK-NEXT: Name: .bss +CHECK-NEXT: VirtualSize: 0x0 +CHECK-NEXT: VirtualAddress: 0x2000 +CHECK-NEXT: RawDataSize: 512 +CHECK-NEXT: PointerToRawData: 0x0 +CHECK-NEXT: PointerToRelocations: 0x0 +CHECK-NEXT: PointerToLineNumbers: 0x0 +CHECK-NEXT: RelocationCount: 0 +CHECK-NEXT: LineNumberCount: 0 +CHECK-NEXT: Characteristics [ +CHECK-NEXT: IMAGE_SCN_CNT_UNINITIALIZED_DATA +CHECK-NEXT: IMAGE_SCN_MEM_READ +CHECK-NEXT: IMAGE_SCN_MEM_WRITE +CHECK-NEXT: ] +CHECK-NEXT: }