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 @@ -28,15 +28,15 @@ struct Data; struct PubSection; -void EmitDebugAbbrev(raw_ostream &OS, const Data &DI); -void EmitDebugStr(raw_ostream &OS, const Data &DI); - -void EmitDebugAranges(raw_ostream &OS, const Data &DI); -void EmitDebugRanges(raw_ostream &OS, const Data &DI); -void EmitPubSection(raw_ostream &OS, const PubSection &Sect, - bool IsLittleEndian); -void EmitDebugInfo(raw_ostream &OS, const Data &DI); -void EmitDebugLine(raw_ostream &OS, const Data &DI); +Error EmitDebugAbbrev(raw_ostream &OS, const Data &DI); +Error EmitDebugStr(raw_ostream &OS, const Data &DI); + +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); +Error EmitDebugInfo(raw_ostream &OS, const Data &DI); +Error EmitDebugLine(raw_ostream &OS, const Data &DI); Expected>> EmitDebugSections(StringRef YAMLString, bool ApplyFixups = false, 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 @@ -69,14 +69,16 @@ writeInteger((uint64_t)Length.TotalLength64, OS, IsLittleEndian); } -void DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto Str : DI.DebugStrings) { OS.write(Str.data(), Str.size()); OS.write('\0'); } + + return Error::success(); } -void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto AbbrevDecl : DI.AbbrevDecls) { encodeULEB128(AbbrevDecl.Code, OS); encodeULEB128(AbbrevDecl.Tag, OS); @@ -90,9 +92,11 @@ encodeULEB128(0, OS); encodeULEB128(0, OS); } + + return Error::success(); } -void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto Range : DI.ARanges) { auto HeaderStart = OS.tell(); if (Range.Format == dwarf::DWARF64) { @@ -117,9 +121,11 @@ } ZeroFillBytes(OS, Range.AddrSize * 2); } + + return Error::success(); } -void DWARFYAML::EmitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) { const size_t RangesOffset = OS.tell(); for (auto DebugRanges : DI.DebugRanges) { const size_t CurrOffset = OS.tell() - RangesOffset; @@ -136,11 +142,13 @@ } ZeroFillBytes(OS, DebugRanges.AddrSize * 2); } + + return Error::success(); } -void DWARFYAML::EmitPubSection(raw_ostream &OS, - const DWARFYAML::PubSection &Sect, - bool IsLittleEndian) { +Error DWARFYAML::EmitPubSection(raw_ostream &OS, + const DWARFYAML::PubSection &Sect, + bool IsLittleEndian) { writeInitialLength(Sect.Length, OS, IsLittleEndian); writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); @@ -152,6 +160,8 @@ OS.write(Entry.Name.data(), Entry.Name.size()); OS.write('\0'); } + + return Error::success(); } namespace { @@ -220,9 +230,11 @@ }; } // namespace -void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { DumpVisitor Visitor(DI, OS); Visitor.traverseDebugInfo(); + + return Error::success(); } static void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { @@ -233,7 +245,7 @@ encodeULEB128(File.Length, OS); } -void DWARFYAML::EmitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { +Error DWARFYAML::EmitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { for (const auto &LineTable : DI.DebugLines) { writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian); uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4; @@ -314,20 +326,25 @@ } } } + + return Error::success(); } -using EmitFuncType = void (*)(raw_ostream &, const DWARFYAML::Data &); +using EmitFuncType = Error (*)(raw_ostream &, const DWARFYAML::Data &); -static void +static Error EmitDebugSectionImpl(const DWARFYAML::Data &DI, EmitFuncType EmitFunc, StringRef Sec, StringMap> &OutputBuffers) { std::string Data; raw_string_ostream DebugInfoStream(Data); - EmitFunc(DebugInfoStream, DI); + if (Error Err = EmitFunc(DebugInfoStream, DI)) + return Err; DebugInfoStream.flush(); if (!Data.empty()) OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data); + + return Error::success(); } namespace { @@ -391,17 +408,23 @@ } StringMap> DebugSections; - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugInfo, "debug_info", - DebugSections); - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugLine, "debug_line", - DebugSections); - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugStr, "debug_str", - DebugSections); - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAbbrev, "debug_abbrev", - DebugSections); - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, "debug_aranges", - DebugSections); - EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugRanges, "debug_ranges", - DebugSections); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugInfo, + "debug_info", DebugSections)) + return std::move(Err); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugLine, + "debug_line", DebugSections)) + return std::move(Err); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugStr, + "debug_str", DebugSections)) + return std::move(Err); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAbbrev, + "debug_abbrev", DebugSections)) + return std::move(Err); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugAranges, + "debug_aranges", DebugSections)) + return std::move(Err); + if (Error Err = EmitDebugSectionImpl(DI, &DWARFYAML::EmitDebugRanges, + "debug_ranges", DebugSections)) + return std::move(Err); return std::move(DebugSections); } 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 @@ -23,6 +23,7 @@ #include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/Support/EndianStream.h" +#include "llvm/Support/Error.h" #include "llvm/Support/LEB128.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/WithColor.h" @@ -845,16 +846,19 @@ } template -uint64_t emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, - const DWARFYAML::Data &DWARF, raw_ostream &OS) { +Expected emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, + const DWARFYAML::Data &DWARF, raw_ostream &OS) { uint64_t BeginOffset = OS.tell(); - if (Name == ".debug_str") - DWARFYAML::EmitDebugStr(OS, DWARF); - else if (Name == ".debug_aranges") - DWARFYAML::EmitDebugAranges(OS, DWARF); - else if (Name == ".debug_ranges") - DWARFYAML::EmitDebugRanges(OS, DWARF); - else + if (Name == ".debug_str") { + if (Error Err = DWARFYAML::EmitDebugStr(OS, DWARF)) + return std::move(Err); + } else if (Name == ".debug_aranges") { + if (Error Err = DWARFYAML::EmitDebugAranges(OS, DWARF)) + return std::move(Err); + } else if (Name == ".debug_ranges") { + if (Error Err = DWARFYAML::EmitDebugRanges(OS, DWARF)) + return std::move(Err); + } else llvm_unreachable("unexpected emitDWARF() call"); return OS.tell() - BeginOffset; @@ -878,8 +882,15 @@ reportError("cannot specify section '" + Name + "' contents in the 'DWARF' entry and the 'Content' " "or 'Size' in the 'Sections' entry at the same time"); - else - SHeader.sh_size = emitDWARF(SHeader, Name, *Doc.DWARF, CBA.getOS()); + else { + if (Expected ShSizeOrErr = + emitDWARF(SHeader, Name, *Doc.DWARF, CBA.getOS())) + SHeader.sh_size = *ShSizeOrErr; + else + handleAllErrors( + std::move(ShSizeOrErr.takeError()), + [&](const ErrorInfoBase &Err) { reportError(Err.message()); }); + } } else if (RawSec) SHeader.sh_size = writeContent(CBA.getOS(), RawSec->Content, RawSec->Size); else 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 @@ -287,25 +287,33 @@ "wrote too much data somewhere, section offsets don't line up"); if (0 == strncmp(&Sec.segname[0], "__DWARF", 16)) { if (0 == strncmp(&Sec.sectname[0], "__debug_str", 16)) { - DWARFYAML::EmitDebugStr(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugStr(OS, Obj.DWARF)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16)) { - DWARFYAML::EmitDebugAbbrev(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugAbbrev(OS, Obj.DWARF)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) { - DWARFYAML::EmitDebugAranges(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugAranges(OS, Obj.DWARF)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) { - DWARFYAML::EmitDebugRanges(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugRanges(OS, Obj.DWARF)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) { if (Obj.DWARF.PubNames) - DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubNames, - Obj.IsLittleEndian); + if (Error Err = DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubNames, + Obj.IsLittleEndian)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { if (Obj.DWARF.PubTypes) - DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubTypes, - Obj.IsLittleEndian); + if (Error Err = DWARFYAML::EmitPubSection(OS, *Obj.DWARF.PubTypes, + Obj.IsLittleEndian)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) { - DWARFYAML::EmitDebugInfo(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugInfo(OS, Obj.DWARF)) + return Err; } else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) { - DWARFYAML::EmitDebugLine(OS, Obj.DWARF); + if (Error Err = DWARFYAML::EmitDebugLine(OS, Obj.DWARF)) + return Err; } continue;