diff --git a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h --- a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h @@ -33,14 +33,18 @@ Error emitDebugAranges(raw_ostream &OS, const Data &DI); Error emitDebugRanges(raw_ostream &OS, const Data &DI); -Error emitPubSection(raw_ostream &OS, const PubSection &Sect, - bool IsLittleEndian, bool IsGNUPubSec = false); +Error emitDebugPubnames(raw_ostream &OS, const Data &DI); +Error emitDebugPubtypes(raw_ostream &OS, const Data &DI); +Error emitDebugGNUPubnames(raw_ostream &OS, const Data &DI); +Error emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI); Error emitDebugInfo(raw_ostream &OS, const Data &DI); Error emitDebugLine(raw_ostream &OS, const Data &DI); Error emitDebugAddr(raw_ostream &OS, const Data &DI); Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI); Error emitDebugRnglists(raw_ostream &OS, const Data &DI); +std::function +getDWARFEmitterByName(StringRef SecName); Expected>> emitDebugSections(StringRef YAMLString, bool IsLittleEndian = sys::IsLittleEndianHost); diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp --- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp +++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/ObjectYAML/DWARFYAML.h" #include "llvm/Support/Errc.h" @@ -209,9 +210,8 @@ return Error::success(); } -Error DWARFYAML::emitPubSection(raw_ostream &OS, - const DWARFYAML::PubSection &Sect, - bool IsLittleEndian, bool IsGNUPubSec) { +static Error emitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, + bool IsLittleEndian, bool IsGNUPubSec = false) { writeInitialLength(Sect.Length, OS, IsLittleEndian); writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); @@ -227,6 +227,28 @@ return Error::success(); } +Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) { + assert(DI.PubNames && "unexpected emitDebugPubnames() call"); + return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian); +} + +Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) { + assert(DI.PubTypes && "unexpected emitDebugPubtypes() call"); + return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian); +} + +Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) { + assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call"); + return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian, + /*IsGNUStyle=*/true); +} + +Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) { + assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call"); + return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian, + /*IsGNUStyle=*/true); +} + static Expected writeDIE(ArrayRef AbbrevDecls, const DWARFYAML::Unit &Unit, const DWARFYAML::Entry &Entry, @@ -741,14 +763,40 @@ OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize); } -using EmitFuncType = Error (*)(raw_ostream &, const DWARFYAML::Data &); +std::function +DWARFYAML::getDWARFEmitterByName(StringRef SecName) { + auto EmitFunc = + StringSwitch< + std::function>(SecName) + .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev) + .Case("debug_addr", DWARFYAML::emitDebugAddr) + .Case("debug_aranges", DWARFYAML::emitDebugAranges) + .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames) + .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes) + .Case("debug_info", DWARFYAML::emitDebugInfo) + .Case("debug_line", DWARFYAML::emitDebugLine) + .Case("debug_pubnames", DWARFYAML::emitDebugPubnames) + .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes) + .Case("debug_ranges", DWARFYAML::emitDebugRanges) + .Case("debug_rnglists", DWARFYAML::emitDebugRnglists) + .Case("debug_str", DWARFYAML::emitDebugStr) + .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets) + .Default([&](raw_ostream &, const DWARFYAML::Data &) { + return createStringError(errc::not_supported, + SecName + " is not supported"); + }); + + return EmitFunc; +} static Error -emitDebugSectionImpl(const DWARFYAML::Data &DI, EmitFuncType EmitFunc, - StringRef Sec, +emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, StringMap> &OutputBuffers) { std::string Data; raw_string_ostream DebugInfoStream(Data); + + auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec); + if (Error Err = EmitFunc(DebugInfoStream, DI)) return Err; DebugInfoStream.flush(); @@ -775,23 +823,12 @@ return createStringError(YIn.error(), GeneratedDiag.getMessage()); StringMap> DebugSections; - Error Err = emitDebugSectionImpl(DI, &DWARFYAML::emitDebugInfo, "debug_info", - DebugSections); - Err = joinErrors(std::move(Err), - emitDebugSectionImpl(DI, &DWARFYAML::emitDebugLine, - "debug_line", DebugSections)); - Err = joinErrors(std::move(Err), - emitDebugSectionImpl(DI, &DWARFYAML::emitDebugStr, - "debug_str", DebugSections)); - Err = joinErrors(std::move(Err), - emitDebugSectionImpl(DI, &DWARFYAML::emitDebugAbbrev, - "debug_abbrev", DebugSections)); - Err = joinErrors(std::move(Err), - emitDebugSectionImpl(DI, &DWARFYAML::emitDebugAranges, - "debug_aranges", DebugSections)); - Err = joinErrors(std::move(Err), - emitDebugSectionImpl(DI, &DWARFYAML::emitDebugRanges, - "debug_ranges", DebugSections)); + Error Err = Error::success(); + cantFail(std::move(Err)); + + for (StringRef SecName : DI.getNonEmptySectionNames()) + Err = joinErrors(std::move(Err), + emitDebugSectionImpl(DI, SecName, DebugSections)); if (Err) return std::move(Err); diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -949,39 +949,11 @@ return 0; uint64_t BeginOffset = CBA.tell(); - Error Err = Error::success(); - cantFail(std::move(Err)); - - if (Name == ".debug_str") - Err = DWARFYAML::emitDebugStr(*OS, DWARF); - else if (Name == ".debug_aranges") - Err = DWARFYAML::emitDebugAranges(*OS, DWARF); - else if (Name == ".debug_ranges") - Err = DWARFYAML::emitDebugRanges(*OS, DWARF); - else if (Name == ".debug_line") - Err = DWARFYAML::emitDebugLine(*OS, DWARF); - else if (Name == ".debug_addr") - Err = DWARFYAML::emitDebugAddr(*OS, DWARF); - else if (Name == ".debug_abbrev") - Err = DWARFYAML::emitDebugAbbrev(*OS, DWARF); - else if (Name == ".debug_info") - Err = DWARFYAML::emitDebugInfo(*OS, DWARF); - else if (Name == ".debug_pubnames") - Err = DWARFYAML::emitPubSection(*OS, *DWARF.PubNames, DWARF.IsLittleEndian); - else if (Name == ".debug_pubtypes") - Err = DWARFYAML::emitPubSection(*OS, *DWARF.PubTypes, DWARF.IsLittleEndian); - else if (Name == ".debug_gnu_pubnames") - Err = DWARFYAML::emitPubSection(*OS, *DWARF.GNUPubNames, - DWARF.IsLittleEndian, /*IsGNUStyle=*/true); - else if (Name == ".debug_gnu_pubtypes") - Err = DWARFYAML::emitPubSection(*OS, *DWARF.GNUPubTypes, - DWARF.IsLittleEndian, /*IsGNUStyle=*/true); - else if (Name == ".debug_str_offsets") - Err = DWARFYAML::emitDebugStrOffsets(*OS, DWARF); - else if (Name == ".debug_rnglists") - Err = DWARFYAML::emitDebugRnglists(*OS, DWARF); - else + + if (!Name.consume_front(".")) llvm_unreachable("unexpected emitDWARF() call"); + auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name); + Error Err = EmitFunc(*OS, DWARF); if (Err) return std::move(Err); diff --git a/llvm/lib/ObjectYAML/MachOEmitter.cpp b/llvm/lib/ObjectYAML/MachOEmitter.cpp --- a/llvm/lib/ObjectYAML/MachOEmitter.cpp +++ b/llvm/lib/ObjectYAML/MachOEmitter.cpp @@ -299,12 +299,10 @@ Err = DWARFYAML::emitDebugRanges(OS, Obj.DWARF); else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) { if (Obj.DWARF.PubNames) - Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubNames, - Obj.IsLittleEndian); + Err = DWARFYAML::emitDebugPubnames(OS, Obj.DWARF); } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { if (Obj.DWARF.PubTypes) - Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubTypes, - Obj.IsLittleEndian); + Err = DWARFYAML::emitDebugPubtypes(OS, Obj.DWARF); } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) Err = DWARFYAML::emitDebugInfo(OS, Obj.DWARF); else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16))