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,25 @@ } 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); + 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)); + + if (Err) + 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" @@ -134,6 +135,7 @@ bool HasError = false; yaml::ErrorHandler ErrHandler; void reportError(const Twine &Msg); + void reportError(Error Err); std::vector toELFSymbols(ArrayRef Symbols, const StringTableBuilder &Strtab); @@ -845,18 +847,24 @@ } 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(); + Error Err = Error::success(); + cantFail(std::move(Err)); + if (Name == ".debug_str") - DWARFYAML::emitDebugStr(OS, DWARF); + Err = DWARFYAML::emitDebugStr(OS, DWARF); else if (Name == ".debug_aranges") - DWARFYAML::emitDebugAranges(OS, DWARF); + Err = DWARFYAML::emitDebugAranges(OS, DWARF); else if (Name == ".debug_ranges") - DWARFYAML::emitDebugRanges(OS, DWARF); + Err = DWARFYAML::emitDebugRanges(OS, DWARF); else llvm_unreachable("unexpected emitDWARF() call"); + if (Err) + return std::move(Err); + return OS.tell() - BeginOffset; } @@ -878,8 +886,13 @@ 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 + reportError(ShSizeOrErr.takeError()); + } } else if (RawSec) SHeader.sh_size = writeContent(CBA.getOS(), RawSec->Content, RawSec->Size); else @@ -910,6 +923,12 @@ HasError = true; } +template void ELFState::reportError(Error Err) { + handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) { + reportError(Err.message()); + }); +} + template std::vector ELFState::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, 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 @@ -286,27 +286,32 @@ errc::invalid_argument, "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); - } else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16)) { - DWARFYAML::emitDebugAbbrev(OS, Obj.DWARF); - } else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) { - DWARFYAML::emitDebugAranges(OS, Obj.DWARF); - } 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)) { + Error Err = Error::success(); + cantFail(std::move(Err)); + + if (0 == strncmp(&Sec.sectname[0], "__debug_str", 16)) + Err = DWARFYAML::emitDebugStr(OS, Obj.DWARF); + else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16)) + Err = DWARFYAML::emitDebugAbbrev(OS, Obj.DWARF); + else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) + Err = DWARFYAML::emitDebugAranges(OS, Obj.DWARF); + else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) + Err = DWARFYAML::emitDebugRanges(OS, Obj.DWARF); + else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 16)) { if (Obj.DWARF.PubNames) - DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubNames, - Obj.IsLittleEndian); + Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubNames, + Obj.IsLittleEndian); } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { 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)) { - DWARFYAML::emitDebugLine(OS, Obj.DWARF); - } + Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubTypes, + Obj.IsLittleEndian); + } 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)) + Err = DWARFYAML::emitDebugLine(OS, Obj.DWARF); + + if (Err) + return Err; continue; }