diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h index 806dd13715e..509417beb28 100644 --- a/include/llvm/ObjectYAML/DWARFYAML.h +++ b/include/llvm/ObjectYAML/DWARFYAML.h @@ -99,6 +99,9 @@ struct PubSection { uint32_t UnitSize; bool IsGNUStyle = false; std::vector Entries; + + PubSection() = default; + PubSection(bool IsGNUStyle) : IsGNUStyle(IsGNUStyle) {} }; struct FormValue { @@ -161,11 +164,11 @@ struct Data { std::vector DebugStrings; std::vector ARanges; std::vector DebugRanges; - PubSection PubNames; - PubSection PubTypes; + Optional PubNames; + Optional PubTypes; - PubSection GNUPubNames; - PubSection GNUPubTypes; + Optional GNUPubNames; + Optional GNUPubTypes; std::vector CompileUnits; diff --git a/lib/ObjectYAML/DWARFYAML.cpp b/lib/ObjectYAML/DWARFYAML.cpp index 4805f727e0c..30a77c74dc6 100644 --- a/lib/ObjectYAML/DWARFYAML.cpp +++ b/lib/ObjectYAML/DWARFYAML.cpp @@ -17,10 +17,8 @@ namespace llvm { bool DWARFYAML::Data::isEmpty() const { return DebugStrings.empty() && AbbrevDecls.empty() && ARanges.empty() && - DebugRanges.empty() && PubNames.Entries.empty() && - PubTypes.Entries.empty() && GNUPubNames.Entries.empty() && - GNUPubTypes.Entries.empty() && CompileUnits.empty() && - DebugLines.empty(); + DebugRanges.empty() && !PubNames && !PubTypes && !GNUPubNames && + !GNUPubTypes && CompileUnits.empty() && DebugLines.empty(); } SetVector DWARFYAML::Data::getUsedSectionNames() const { @@ -41,14 +39,10 @@ void MappingTraits::mapping(IO &IO, DWARFYAML::Data &DWARF) { IO.mapOptional("debug_aranges", DWARF.ARanges); if (!DWARF.DebugRanges.empty() || !IO.outputting()) IO.mapOptional("debug_ranges", DWARF.DebugRanges); - if (!DWARF.PubNames.Entries.empty() || !IO.outputting()) - IO.mapOptional("debug_pubnames", DWARF.PubNames); - if (!DWARF.PubTypes.Entries.empty() || !IO.outputting()) - IO.mapOptional("debug_pubtypes", DWARF.PubTypes); - if (!DWARF.GNUPubNames.Entries.empty() || !IO.outputting()) - IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames); - if (!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting()) - IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes); + IO.mapOptional("debug_pubnames", DWARF.PubNames); + IO.mapOptional("debug_pubtypes", DWARF.PubTypes); + IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames); + IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes); IO.mapOptional("debug_info", DWARF.CompileUnits); IO.mapOptional("debug_line", DWARF.DebugLines); IO.setContext(&oldContext); diff --git a/lib/ObjectYAML/MachOEmitter.cpp b/lib/ObjectYAML/MachOEmitter.cpp index f8661e0c3c3..c9bca43a4ef 100644 --- a/lib/ObjectYAML/MachOEmitter.cpp +++ b/lib/ObjectYAML/MachOEmitter.cpp @@ -295,11 +295,13 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { } else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) { DWARFYAML::EmitDebugRanges(OS, Obj.DWARF); } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) { - DWARFYAML::EmitPubSection(OS, Obj.DWARF.PubNames, - Obj.IsLittleEndian); + if (Obj.DWARF.PubNames) + DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubNames, + Obj.IsLittleEndian); } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { - DWARFYAML::EmitPubSection(OS, Obj.DWARF.PubTypes, - Obj.IsLittleEndian); + if (Obj.DWARF.PubTypes) + DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubTypes, + Obj.IsLittleEndian); } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) { DWARFYAML::EmitDebugInfo(OS, Obj.DWARF); } else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) { diff --git a/test/ObjectYAML/MachO/DWARF-pubsections.yaml b/test/ObjectYAML/MachO/DWARF-pubsections.yaml index f2eadd20d8a..4faac060c8a 100644 --- a/test/ObjectYAML/MachO/DWARF-pubsections.yaml +++ b/test/ObjectYAML/MachO/DWARF-pubsections.yaml @@ -1,3 +1,9 @@ +## This file contains test cases for generating .debug_pubnames/.debug_pubtypes +## section in object files from the DWARF entry of Mach-O YAML inputs + +## a) Test that yaml2obj emits the .debug_pubnames and .debug_pubtypes sections and +## obj2yaml converts them back. + # RUN: yaml2obj %s | obj2yaml | FileCheck %s --- !mach-o @@ -345,3 +351,87 @@ DWARF: #CHECK: - DieOffset: 0x00000071 #CHECK: Name: char #CHECK: ... + +## b) Test that yaml2obj will not emit the .debug_pubnames/.debug_pubtypes section's +## contents, if the "debug_pubnames"/"debug_pubtypes" entry doesn't exist in the +## "DWARF" entry. + +# RUN: yaml2obj --docnum=2 %s | obj2yaml | FileCheck %s --check-prefix=EMPTY + +# EMPTY: Sections: +# EMPTY-NEXT: - sectname: __debug_pubnames +# EMPTY-NEXT: segname: __DWARF +# EMPTY-NEXT: addr: 0x0000000000000000 +# EMPTY-NEXT: size: 0 +# EMPTY-NEXT: offset: 0x00000000 +# EMPTY-NEXT: align: 0 +# EMPTY-NEXT: reloff: 0x00000000 +# EMPTY-NEXT: nreloc: 0 +# EMPTY-NEXT: flags: 0x00000000 +# EMPTY-NEXT: reserved1: 0x00000000 +# EMPTY-NEXT: reserved2: 0x00000000 +# EMPTY-NEXT: reserved3: 0x00000000 +# EMPTY-NEXT: content: '' +# EMPTY-NEXT: - sectname: __debug_pubtypes +# EMPTY-NEXT: segname: __DWARF +# EMPTY-NEXT: addr: 0x0000000000000000 +# EMPTY-NEXT: size: 0 +# EMPTY-NEXT: offset: 0x00000720 +# EMPTY-NEXT: align: 0 +# EMPTY-NEXT: reloff: 0x00000000 +# EMPTY-NEXT: nreloc: 0 +# EMPTY-NEXT: flags: 0x00000000 +# EMPTY-NEXT: reserved1: 0x00000000 +# EMPTY-NEXT: reserved2: 0x00000000 +# EMPTY-NEXT: reserved3: 0x00000000 +# EMPTY-NEXT: content: '' +# EMPTY-NEXT: ... + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 1 + sizeofcmds: 1800 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DWARF + vmaddr: 0x00000000 + vmsize: 0x00000000 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 2 + flags: 0 + Sections: + - sectname: __debug_pubnames + segname: __DWARF + addr: 0x0000000000000000 + size: 0 + offset: 0x00000000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_pubtypes + segname: __DWARF + addr: 0x0000000000000000 + size: 0 + offset: 0x00000720 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +DWARF: diff --git a/tools/obj2yaml/dwarf2yaml.cpp b/tools/obj2yaml/dwarf2yaml.cpp index a007efe7e50..0a1cac8c73c 100644 --- a/tools/obj2yaml/dwarf2yaml.cpp +++ b/tools/obj2yaml/dwarf2yaml.cpp @@ -11,6 +11,7 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include @@ -135,17 +136,32 @@ void dumpPubSection(DWARFContext &DCtx, DWARFYAML::PubSection &Y, void dumpDebugPubSections(DWARFContext &DCtx, DWARFYAML::Data &Y) { const DWARFObject &D = DCtx.getDWARFObj(); - Y.PubNames.IsGNUStyle = false; - dumpPubSection(DCtx, Y.PubNames, D.getPubnamesSection()); - Y.PubTypes.IsGNUStyle = false; - dumpPubSection(DCtx, Y.PubTypes, D.getPubtypesSection()); + const DWARFSection PubNames = D.getPubnamesSection(); + if (!PubNames.Data.empty()) { + Y.PubNames.emplace(/*IsGNUStyle=*/false); + dumpPubSection(DCtx, *Y.PubNames, PubNames); + } - Y.GNUPubNames.IsGNUStyle = true; - dumpPubSection(DCtx, Y.GNUPubNames, D.getGnuPubnamesSection()); + const DWARFSection PubTypes = D.getPubtypesSection(); + if (!PubTypes.Data.empty()) { + Y.PubTypes.emplace(/*IsGNUStyle=*/false); + dumpPubSection(DCtx, *Y.PubTypes, PubTypes); + } - Y.GNUPubTypes.IsGNUStyle = true; - dumpPubSection(DCtx, Y.GNUPubTypes, D.getGnuPubtypesSection()); + const DWARFSection GNUPubNames = D.getGnuPubnamesSection(); + if (!GNUPubNames.Data.empty()) { + // TODO: Test dumping .debug_gnu_pubnames section. + Y.GNUPubNames.emplace(/*IsGNUStyle=*/true); + dumpPubSection(DCtx, *Y.GNUPubNames, GNUPubNames); + } + + const DWARFSection GNUPubTypes = D.getGnuPubtypesSection(); + if (!GNUPubTypes.Data.empty()) { + // TODO: Test dumping .debug_gnu_pubtypes section. + Y.GNUPubTypes.emplace(/*IsGNUStyle=*/true); + dumpPubSection(DCtx, *Y.GNUPubTypes, GNUPubTypes); + } } void dumpDebugInfo(DWARFContext &DCtx, DWARFYAML::Data &Y) {