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 @@ -43,6 +43,8 @@ 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" @@ -762,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(); @@ -796,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,9 @@ 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::emitDebugPubnames(*OS, DWARF); - else if (Name == ".debug_pubtypes") - Err = DWARFYAML::emitDebugPubtypes(*OS, DWARF); - else if (Name == ".debug_gnu_pubnames") - Err = DWARFYAML::emitDebugGNUPubnames(*OS, DWARF); - else if (Name == ".debug_gnu_pubtypes") - Err = DWARFYAML::emitDebugGNUPubtypes(*OS, DWARF); - else if (Name == ".debug_str_offsets") - Err = DWARFYAML::emitDebugStrOffsets(*OS, DWARF); - else if (Name == ".debug_rnglists") - Err = DWARFYAML::emitDebugRnglists(*OS, DWARF); - else - llvm_unreachable("unexpected emitDWARF() call"); - if (Err) + auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Name.substr(1)); + if (Error Err = EmitFunc(*OS, DWARF)) return std::move(Err); return CBA.tell() - BeginOffset;