diff --git a/llvm/lib/ObjectYAML/COFFYAML.cpp b/llvm/lib/ObjectYAML/COFFYAML.cpp index f206e31b5507..b5154467f11a 100644 --- a/llvm/lib/ObjectYAML/COFFYAML.cpp +++ b/llvm/lib/ObjectYAML/COFFYAML.cpp @@ -578,6 +578,12 @@ void MappingTraits::mapping(IO &IO, COFFYAML::Section &Sec) { else if (Sec.Name == ".debug$H") IO.mapOptional("GlobalHashes", Sec.DebugH); + // Uninitialized sections, such as .bss, typically have no data, but the size + // is carried in SizeOfRawData, even though PointerToRawData is zero. + if (Sec.SectionData.binary_size() == 0 && + NC->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + IO.mapOptional("SizeOfRawData", Sec.Header.SizeOfRawData); + IO.mapOptional("Relocations", Sec.Relocations); } diff --git a/llvm/test/tools/obj2yaml/coff-bss.s b/llvm/test/tools/obj2yaml/coff-bss.s new file mode 100644 index 000000000000..fed5d058714b --- /dev/null +++ b/llvm/test/tools/obj2yaml/coff-bss.s @@ -0,0 +1,14 @@ +# RUN: llvm-mc -filetype=obj -triple=x86_64-windows-msvc %s -o %t.obj +# RUN: llvm-objdump -h %t.obj | FileCheck %s +# RUN: obj2yaml %t.obj | yaml2obj -o %t.2.obj +# RUN: llvm-objdump -h %t.2.obj | FileCheck %s + +# CHECK: Idx Name Size VMA Type +# CHECK: .bss 00000004 0000000000000000 BSS + +# Before PR41836, Size would be 0 after yaml conversion. + +.bss +.global gv_bss +gv_bss: +.long 0 diff --git a/llvm/tools/yaml2obj/yaml2coff.cpp b/llvm/tools/yaml2obj/yaml2coff.cpp index e9f1f558201a..3afbd5848af7 100644 --- a/llvm/tools/yaml2obj/yaml2coff.cpp +++ b/llvm/tools/yaml2obj/yaml2coff.cpp @@ -259,7 +259,8 @@ static bool layoutCOFF(COFFParser &CP) { S.Header.NumberOfRelocations * COFF::RelocationSize; } } else { - S.Header.SizeOfRawData = 0; + // Leave SizeOfRawData unaltered. For .bss sections in object files, it + // carries the section size. S.Header.PointerToRawData = 0; } } @@ -496,7 +497,7 @@ static bool writeCOFF(COFFParser &CP, raw_ostream &OS) { // Output section data. for (const COFFYAML::Section &S : CP.Obj.Sections) { - if (!S.Header.SizeOfRawData) + if (S.Header.SizeOfRawData == 0 || S.Header.PointerToRawData == 0) continue; assert(S.Header.PointerToRawData >= OS.tell()); OS.write_zeros(S.Header.PointerToRawData - OS.tell());