Changeset View
Standalone View
llvm/lib/ObjectYAML/DWARFEmitter.cpp
Show First 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, | static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, | ||||
raw_ostream &OS, bool IsLittleEndian) { | raw_ostream &OS, bool IsLittleEndian) { | ||||
cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4, | cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4, | ||||
OS, IsLittleEndian)); | OS, IsLittleEndian)); | ||||
} | } | ||||
Error DWARFYAML::emitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugStr(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
for (auto Str : DI.DebugStrings) { | for (auto Str : DI.DebugStrings) { | ||||
labath: If you'd do all this work in the factory function and then just pass in a finished map to the… | |||||
DWARFYAML::DWARFState is merged into DWARFYAML::Data, so we don't need ErrorAsOutParameter any more. Higuoxing: `DWARFYAML::DWARFState` is merged into `DWARFYAML::Data`, so we don't need… | |||||
OS.write(Str.data(), Str.size()); | OS.write(Str.data(), Str.size()); | ||||
OS.write('\0'); | OS.write('\0'); | ||||
consider: for (auto &Abbr : enumerate(DI.DebugAbbrev)) labath: consider: `for (auto &Abbr : enumerate(DI.DebugAbbrev))` | |||||
} | } | ||||
Maybe to avoid weird errors, it might make sense to disallow mixing the two methods, i.e. if one table has an explicit ID, the others all must do too. What do you think? It may not be worth it if the code is more complex, I don't know. jhenderson: Maybe to avoid weird errors, it might make sense to disallow mixing the two methods, i.e. if… | |||||
I think it's a little bit difficult to distinguish these 2 situations. Besides, sometimes we might want to add one compilation unit to a test case and let it reference an existing abbrev table. We don't need to mutate the whole test case to add IDs. What do think of it? Higuoxing: I think it's a little bit difficult to distinguish these 2 situations. Besides, sometimes we… | |||||
Leave it as is. I wasn't convinced by my own statement, so I think what you've got is fine. jhenderson: Leave it as is. I wasn't convinced by my own statement, so I think what you've got is fine. | |||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
ID = DI.DebugAbbrev[I].ID.getValueOr(I) labath: `ID = DI.DebugAbbrev[I].ID.getValueOr(I)` | |||||
Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
uint64_t AbbrevCode = 0; | uint64_t AbbrevCode = 0; | ||||
for (const DWARFYAML::AbbrevTable &AbbrevTable : DI.DebugAbbrev) { | for (const DWARFYAML::AbbrevTable &AbbrevTable : DI.DebugAbbrev) { | ||||
for (const DWARFYAML::Abbrev &AbbrevDecl : AbbrevTable.Table) { | for (const DWARFYAML::Abbrev &AbbrevDecl : AbbrevTable.Table) { | ||||
AbbrevCode = | AbbrevCode = | ||||
AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1; | AbbrevDecl.Code ? (uint64_t)*AbbrevDecl.Code : AbbrevCode + 1; | ||||
encodeULEB128(AbbrevCode, OS); | encodeULEB128(AbbrevCode, OS); | ||||
encodeULEB128(AbbrevDecl.Tag, OS); | encodeULEB128(AbbrevDecl.Tag, OS); | ||||
OS.write(AbbrevDecl.Children); | OS.write(AbbrevDecl.Children); | ||||
Could you use the return value of insert to identify whether the key already exists in the map? That way, you don't need the explicit count call. jhenderson: Could you use the return value of `insert` to identify whether the key already exists in the… | |||||
for (auto Attr : AbbrevDecl.Attributes) { | for (auto Attr : AbbrevDecl.Attributes) { | ||||
encodeULEB128(Attr.Attribute, OS); | encodeULEB128(Attr.Attribute, OS); | ||||
encodeULEB128(Attr.Form, OS); | encodeULEB128(Attr.Form, OS); | ||||
if (Attr.Form == dwarf::DW_FORM_implicit_const) | if (Attr.Form == dwarf::DW_FORM_implicit_const) | ||||
encodeSLEB128(Attr.Value, OS); | encodeSLEB128(Attr.Value, OS); | ||||
} | } | ||||
encodeULEB128(0, OS); | encodeULEB128(0, OS); | ||||
encodeULEB128(0, OS); | encodeULEB128(0, OS); | ||||
} | } | ||||
// The abbreviations for a given compilation unit end with an entry | // The abbreviations for a given compilation unit end with an entry | ||||
// consisting of a 0 byte for the abbreviation code. | // consisting of a 0 byte for the abbreviation code. | ||||
OS.write_zeros(1); | OS.write_zeros(1); | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugAranges(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.DebugAranges && "unexpected emitDebugAranges() call"); | assert(DI.DebugAranges && "unexpected emitDebugAranges() call"); | ||||
for (auto Range : *DI.DebugAranges) { | for (auto Range : *DI.DebugAranges) { | ||||
uint8_t AddrSize; | uint8_t AddrSize; | ||||
if (Range.AddrSize) | if (Range.AddrSize) | ||||
AddrSize = *Range.AddrSize; | AddrSize = *Range.AddrSize; | ||||
else | else | ||||
AddrSize = DI.Is64BitAddrSize ? 8 : 4; | AddrSize = DI.Is64BitAddrSize ? 8 : 4; | ||||
Show All 32 Lines | for (auto Descriptor : Range.Descriptors) { | ||||
DI.IsLittleEndian)); | DI.IsLittleEndian)); | ||||
} | } | ||||
ZeroFillBytes(OS, AddrSize * 2); | ZeroFillBytes(OS, AddrSize * 2); | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugRanges(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
const size_t RangesOffset = OS.tell(); | const size_t RangesOffset = OS.tell(); | ||||
uint64_t EntryIndex = 0; | uint64_t EntryIndex = 0; | ||||
for (auto DebugRanges : DI.DebugRanges) { | for (auto DebugRanges : DI.DebugRanges) { | ||||
const size_t CurrOffset = OS.tell() - RangesOffset; | const size_t CurrOffset = OS.tell() - RangesOffset; | ||||
if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset) | if (DebugRanges.Offset && (uint64_t)*DebugRanges.Offset < CurrOffset) | ||||
return createStringError(errc::invalid_argument, | return createStringError(errc::invalid_argument, | ||||
"'Offset' for 'debug_ranges' with index " + | "'Offset' for 'debug_ranges' with index " + | ||||
Twine(EntryIndex) + | Twine(EntryIndex) + | ||||
Show All 37 Lines | if (IsGNUPubSec) | ||||
writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian); | writeInteger((uint8_t)Entry.Descriptor, OS, IsLittleEndian); | ||||
OS.write(Entry.Name.data(), Entry.Name.size()); | OS.write(Entry.Name.data(), Entry.Name.size()); | ||||
OS.write('\0'); | OS.write('\0'); | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugPubnames(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.PubNames && "unexpected emitDebugPubnames() call"); | assert(DI.PubNames && "unexpected emitDebugPubnames() call"); | ||||
return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian); | return emitPubSection(OS, *DI.PubNames, DI.IsLittleEndian); | ||||
} | } | ||||
Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugPubtypes(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.PubTypes && "unexpected emitDebugPubtypes() call"); | assert(DI.PubTypes && "unexpected emitDebugPubtypes() call"); | ||||
return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian); | return emitPubSection(OS, *DI.PubTypes, DI.IsLittleEndian); | ||||
} | } | ||||
Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugGNUPubnames(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call"); | assert(DI.GNUPubNames && "unexpected emitDebugGNUPubnames() call"); | ||||
return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian, | return emitPubSection(OS, *DI.GNUPubNames, DI.IsLittleEndian, | ||||
/*IsGNUStyle=*/true); | /*IsGNUStyle=*/true); | ||||
} | } | ||||
Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugGNUPubtypes(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call"); | assert(DI.GNUPubTypes && "unexpected emitDebugGNUPubtypes() call"); | ||||
return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian, | return emitPubSection(OS, *DI.GNUPubTypes, DI.IsLittleEndian, | ||||
/*IsGNUStyle=*/true); | /*IsGNUStyle=*/true); | ||||
} | } | ||||
static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::AbbrevTable> AbbrevTable, | static Expected<uint64_t> writeDIE(DWARFYAML::Data &DI, uint64_t AbbrevTableID, | ||||
const dwarf::FormParams &Params, | const dwarf::FormParams &Params, | ||||
const DWARFYAML::Entry &Entry, | const DWARFYAML::Entry &Entry, | ||||
raw_ostream &OS, bool IsLittleEndian) { | raw_ostream &OS, bool IsLittleEndian) { | ||||
uint64_t EntryBegin = OS.tell(); | uint64_t EntryBegin = OS.tell(); | ||||
encodeULEB128(Entry.AbbrCode, OS); | encodeULEB128(Entry.AbbrCode, OS); | ||||
uint32_t AbbrCode = Entry.AbbrCode; | uint32_t AbbrCode = Entry.AbbrCode; | ||||
if (AbbrCode == 0 || Entry.Values.empty()) | if (AbbrCode == 0 || Entry.Values.empty()) | ||||
return OS.tell() - EntryBegin; | return OS.tell() - EntryBegin; | ||||
if (AbbrevTable.empty()) | Expected<uint64_t> AbbrevTableIndexOrErr = | ||||
return createStringError( | DI.getAbbrevTableIndexByID(AbbrevTableID); | ||||
errc::invalid_argument, | if (!AbbrevTableIndexOrErr) | ||||
"non-empty compilation unit should have an associated abbrev table"); | return AbbrevTableIndexOrErr.takeError(); | ||||
ArrayRef<DWARFYAML::Abbrev> AbbrevDecls( | |||||
ArrayRef<DWARFYAML::Abbrev> AbbrevDecls(AbbrevTable[0].Table); | DI.DebugAbbrev[*AbbrevTableIndexOrErr].Table); | ||||
if (AbbrCode > AbbrevDecls.size()) | if (AbbrCode > AbbrevDecls.size()) | ||||
It might make more sense to do this work in the caller of this function, and to maintain this function's interface. jhenderson: It might make more sense to do this work in the caller of this function, and to maintain this… | |||||
This is discussed in D86194 Higuoxing: This is discussed in [D86194](https://reviews.llvm.org/D86194#inline-796173) | |||||
return createStringError( | return createStringError( | ||||
errc::invalid_argument, | errc::invalid_argument, | ||||
"abbrev code must be less than or equal to the number of " | "abbrev code must be less than or equal to the number of " | ||||
"entries in abbreviation table"); | "entries in abbreviation table"); | ||||
const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1]; | const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1]; | ||||
auto FormVal = Entry.Values.begin(); | auto FormVal = Entry.Values.begin(); | ||||
auto AbbrForm = Abbrev.Attributes.begin(); | auto AbbrForm = Abbrev.Attributes.begin(); | ||||
for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); | for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); | ||||
▲ Show 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | do { | ||||
break; | break; | ||||
} | } | ||||
} while (Indirect); | } while (Indirect); | ||||
} | } | ||||
return OS.tell() - EntryBegin; | return OS.tell() - EntryBegin; | ||||
} | } | ||||
Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugInfo(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
for (const DWARFYAML::Unit &Unit : DI.CompileUnits) { | for (uint64_t I = 0; I < DI.CompileUnits.size(); ++I) { | ||||
const DWARFYAML::Unit &Unit = DI.CompileUnits[I]; | |||||
uint8_t AddrSize; | uint8_t AddrSize; | ||||
if (Unit.AddrSize) | if (Unit.AddrSize) | ||||
AddrSize = *Unit.AddrSize; | AddrSize = *Unit.AddrSize; | ||||
else | else | ||||
AddrSize = DI.Is64BitAddrSize ? 8 : 4; | AddrSize = DI.Is64BitAddrSize ? 8 : 4; | ||||
dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format}; | dwarf::FormParams Params = {Unit.Version, AddrSize, Unit.Format}; | ||||
uint64_t Length = 3; // sizeof(version) + sizeof(address_size) | uint64_t Length = 3; // sizeof(version) + sizeof(address_size) | ||||
Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type) | Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type) | ||||
Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset) | Length += Params.getDwarfOffsetByteSize(); // sizeof(debug_abbrev_offset) | ||||
// Since the length of the current compilation unit is undetermined yet, we | // Since the length of the current compilation unit is undetermined yet, we | ||||
// firstly write the content of the compilation unit to a buffer to | // firstly write the content of the compilation unit to a buffer to | ||||
// calculate it and then serialize the buffer content to the actual output | // calculate it and then serialize the buffer content to the actual output | ||||
// stream. | // stream. | ||||
std::string EntryBuffer; | std::string EntryBuffer; | ||||
raw_string_ostream EntryBufferOS(EntryBuffer); | raw_string_ostream EntryBufferOS(EntryBuffer); | ||||
uint64_t AbbrevTableID = Unit.AbbrevTableID.getValueOr(I); | |||||
for (const DWARFYAML::Entry &Entry : Unit.Entries) { | for (const DWARFYAML::Entry &Entry : Unit.Entries) { | ||||
if (Expected<uint64_t> EntryLength = writeDIE( | if (Expected<uint64_t> EntryLength = | ||||
DI.DebugAbbrev, Params, Entry, EntryBufferOS, DI.IsLittleEndian)) | writeDIE(DI, AbbrevTableID, Params, Entry, EntryBufferOS, | ||||
DI.IsLittleEndian)) | |||||
Length += *EntryLength; | Length += *EntryLength; | ||||
else | else | ||||
return EntryLength.takeError(); | return EntryLength.takeError(); | ||||
} | } | ||||
// If the length is specified in the YAML description, we use it instead of | // If the length is specified in the YAML description, we use it instead of | ||||
// the actual length. | // the actual length. | ||||
if (Unit.Length) | if (Unit.Length) | ||||
Show All 19 Lines | |||||
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { | static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { | ||||
OS.write(File.Name.data(), File.Name.size()); | OS.write(File.Name.data(), File.Name.size()); | ||||
OS.write('\0'); | OS.write('\0'); | ||||
encodeULEB128(File.DirIdx, OS); | encodeULEB128(File.DirIdx, OS); | ||||
encodeULEB128(File.ModTime, OS); | encodeULEB128(File.ModTime, OS); | ||||
encodeULEB128(File.Length, OS); | encodeULEB128(File.Length, OS); | ||||
} | } | ||||
Error DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { | Error DWARFYAML::emitDebugLine(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
for (const auto &LineTable : DI.DebugLines) { | for (const auto &LineTable : DI.DebugLines) { | ||||
writeInitialLength(LineTable.Format, LineTable.Length, OS, | writeInitialLength(LineTable.Format, LineTable.Length, OS, | ||||
DI.IsLittleEndian); | DI.IsLittleEndian); | ||||
uint64_t SizeOfPrologueLength = LineTable.Format == dwarf::DWARF64 ? 8 : 4; | uint64_t SizeOfPrologueLength = LineTable.Format == dwarf::DWARF64 ? 8 : 4; | ||||
writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); | writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); | ||||
cantFail(writeVariableSizedInteger( | cantFail(writeVariableSizedInteger( | ||||
LineTable.PrologueLength, SizeOfPrologueLength, OS, DI.IsLittleEndian)); | LineTable.PrologueLength, SizeOfPrologueLength, OS, DI.IsLittleEndian)); | ||||
writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian); | writeInteger((uint8_t)LineTable.MinInstLength, OS, DI.IsLittleEndian); | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | for (auto Op : LineTable.Opcodes) { | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugAddr(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugAddr(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
for (const AddrTableEntry &TableEntry : DI.DebugAddr) { | for (const AddrTableEntry &TableEntry : DI.DebugAddr) { | ||||
uint8_t AddrSize; | uint8_t AddrSize; | ||||
if (TableEntry.AddrSize) | if (TableEntry.AddrSize) | ||||
AddrSize = *TableEntry.AddrSize; | AddrSize = *TableEntry.AddrSize; | ||||
else | else | ||||
AddrSize = DI.Is64BitAddrSize ? 8 : 4; | AddrSize = DI.Is64BitAddrSize ? 8 : 4; | ||||
uint64_t Length; | uint64_t Length; | ||||
Show All 24 Lines | for (const SegAddrPair &Pair : TableEntry.SegAddrPairs) { | ||||
"unable to write debug_addr address: %s", | "unable to write debug_addr address: %s", | ||||
toString(std::move(Err)).c_str()); | toString(std::move(Err)).c_str()); | ||||
} | } | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugStrOffsets(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call"); | assert(DI.DebugStrOffsets && "unexpected emitDebugStrOffsets() call"); | ||||
for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) { | for (const DWARFYAML::StringOffsetsTable &Table : *DI.DebugStrOffsets) { | ||||
uint64_t Length; | uint64_t Length; | ||||
if (Table.Length) | if (Table.Length) | ||||
Length = *Table.Length; | Length = *Table.Length; | ||||
else | else | ||||
// sizeof(version) + sizeof(padding) = 4 | // sizeof(version) + sizeof(padding) = 4 | ||||
Length = | Length = | ||||
▲ Show 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | else if (OffsetEntryCount != 0) | ||||
EmitOffsets(Offsets, OffsetsSize); | EmitOffsets(Offsets, OffsetsSize); | ||||
OS.write(ListBuffer.data(), ListBuffer.size()); | OS.write(ListBuffer.data(), ListBuffer.size()); | ||||
} | } | ||||
return Error::success(); | return Error::success(); | ||||
} | } | ||||
Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call"); | assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call"); | ||||
return writeDWARFLists<DWARFYAML::RnglistEntry>( | return writeDWARFLists<DWARFYAML::RnglistEntry>( | ||||
OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize); | OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize); | ||||
} | } | ||||
Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) { | Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, DWARFYAML::Data &DI) { | ||||
assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call"); | assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call"); | ||||
return writeDWARFLists<DWARFYAML::LoclistEntry>( | return writeDWARFLists<DWARFYAML::LoclistEntry>( | ||||
OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize); | OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize); | ||||
} | } | ||||
std::function<Error(raw_ostream &, const DWARFYAML::Data &)> | std::function<Error(raw_ostream &, DWARFYAML::Data &)> | ||||
DWARFYAML::getDWARFEmitterByName(StringRef SecName) { | DWARFYAML::getDWARFEmitterByName(StringRef SecName) { | ||||
auto EmitFunc = | auto EmitFunc = | ||||
StringSwitch< | StringSwitch<std::function<Error(raw_ostream &, DWARFYAML::Data &)>>( | ||||
std::function<Error(raw_ostream &, const DWARFYAML::Data &)>>(SecName) | SecName) | ||||
.Case("debug_abbrev", DWARFYAML::emitDebugAbbrev) | .Case("debug_abbrev", DWARFYAML::emitDebugAbbrev) | ||||
.Case("debug_addr", DWARFYAML::emitDebugAddr) | .Case("debug_addr", DWARFYAML::emitDebugAddr) | ||||
.Case("debug_aranges", DWARFYAML::emitDebugAranges) | .Case("debug_aranges", DWARFYAML::emitDebugAranges) | ||||
.Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames) | .Case("debug_gnu_pubnames", DWARFYAML::emitDebugGNUPubnames) | ||||
.Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes) | .Case("debug_gnu_pubtypes", DWARFYAML::emitDebugGNUPubtypes) | ||||
.Case("debug_info", DWARFYAML::emitDebugInfo) | .Case("debug_info", DWARFYAML::emitDebugInfo) | ||||
.Case("debug_line", DWARFYAML::emitDebugLine) | .Case("debug_line", DWARFYAML::emitDebugLine) | ||||
.Case("debug_loclists", DWARFYAML::emitDebugLoclists) | .Case("debug_loclists", DWARFYAML::emitDebugLoclists) | ||||
.Case("debug_pubnames", DWARFYAML::emitDebugPubnames) | .Case("debug_pubnames", DWARFYAML::emitDebugPubnames) | ||||
.Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes) | .Case("debug_pubtypes", DWARFYAML::emitDebugPubtypes) | ||||
.Case("debug_ranges", DWARFYAML::emitDebugRanges) | .Case("debug_ranges", DWARFYAML::emitDebugRanges) | ||||
.Case("debug_rnglists", DWARFYAML::emitDebugRnglists) | .Case("debug_rnglists", DWARFYAML::emitDebugRnglists) | ||||
.Case("debug_str", DWARFYAML::emitDebugStr) | .Case("debug_str", DWARFYAML::emitDebugStr) | ||||
.Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets) | .Case("debug_str_offsets", DWARFYAML::emitDebugStrOffsets) | ||||
.Default([&](raw_ostream &, const DWARFYAML::Data &) { | .Default([&](raw_ostream &, DWARFYAML::Data &) { | ||||
return createStringError(errc::not_supported, | return createStringError(errc::not_supported, | ||||
SecName + " is not supported"); | SecName + " is not supported"); | ||||
}); | }); | ||||
return EmitFunc; | return EmitFunc; | ||||
} | } | ||||
static Error | static Error | ||||
emitDebugSectionImpl(const DWARFYAML::Data &DI, StringRef Sec, | emitDebugSectionImpl(DWARFYAML::Data &DI, StringRef Sec, | ||||
StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) { | StringMap<std::unique_ptr<MemoryBuffer>> &OutputBuffers) { | ||||
std::string Data; | std::string Data; | ||||
raw_string_ostream DebugInfoStream(Data); | raw_string_ostream DebugInfoStream(Data); | ||||
auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec); | auto EmitFunc = DWARFYAML::getDWARFEmitterByName(Sec); | ||||
if (Error Err = EmitFunc(DebugInfoStream, DI)) | if (Error Err = EmitFunc(DebugInfoStream, DI)) | ||||
return Err; | return Err; | ||||
Show All 38 Lines |
If you'd do all this work in the factory function and then just pass in a finished map to the constructor, there'd be no need for the ErrorAsOutParameter thingy.