1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[ObjectYAML] Add support for error handling in DWARFYAML. NFC.

This patch intends to be an NFC-patch. Test cases will be added in a follow-up patch.

Reviewed By: jhenderson, grimar

Differential Revision: https://reviews.llvm.org/D81356
This commit is contained in:
Xing GUO 2020-06-08 22:48:32 +08:00
parent 00cbb7405f
commit 32d5a272f8
4 changed files with 106 additions and 57 deletions

View File

@ -28,15 +28,15 @@ namespace DWARFYAML {
struct Data; struct Data;
struct PubSection; struct PubSection;
void emitDebugAbbrev(raw_ostream &OS, const Data &DI); Error emitDebugAbbrev(raw_ostream &OS, const Data &DI);
void emitDebugStr(raw_ostream &OS, const Data &DI); Error emitDebugStr(raw_ostream &OS, const Data &DI);
void emitDebugAranges(raw_ostream &OS, const Data &DI); Error emitDebugAranges(raw_ostream &OS, const Data &DI);
void emitDebugRanges(raw_ostream &OS, const Data &DI); Error emitDebugRanges(raw_ostream &OS, const Data &DI);
void emitPubSection(raw_ostream &OS, const PubSection &Sect, Error emitPubSection(raw_ostream &OS, const PubSection &Sect,
bool IsLittleEndian); bool IsLittleEndian);
void emitDebugInfo(raw_ostream &OS, const Data &DI); Error emitDebugInfo(raw_ostream &OS, const Data &DI);
void emitDebugLine(raw_ostream &OS, const Data &DI); Error emitDebugLine(raw_ostream &OS, const Data &DI);
Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
emitDebugSections(StringRef YAMLString, bool ApplyFixups = false, emitDebugSections(StringRef YAMLString, bool ApplyFixups = false,

View File

@ -69,14 +69,16 @@ static void writeInitialLength(const DWARFYAML::InitialLength &Length,
writeInteger((uint64_t)Length.TotalLength64, OS, IsLittleEndian); 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) { for (auto Str : DI.DebugStrings) {
OS.write(Str.data(), Str.size()); OS.write(Str.data(), Str.size());
OS.write('\0'); 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) { for (auto AbbrevDecl : DI.AbbrevDecls) {
encodeULEB128(AbbrevDecl.Code, OS); encodeULEB128(AbbrevDecl.Code, OS);
encodeULEB128(AbbrevDecl.Tag, OS); encodeULEB128(AbbrevDecl.Tag, OS);
@ -90,9 +92,11 @@ void DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
encodeULEB128(0, OS); encodeULEB128(0, OS);
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) { for (auto Range : DI.ARanges) {
auto HeaderStart = OS.tell(); auto HeaderStart = OS.tell();
if (Range.Format == dwarf::DWARF64) { if (Range.Format == dwarf::DWARF64) {
@ -117,9 +121,11 @@ void DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
} }
ZeroFillBytes(OS, Range.AddrSize * 2); 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(); const size_t RangesOffset = OS.tell();
for (auto DebugRanges : DI.DebugRanges) { for (auto DebugRanges : DI.DebugRanges) {
const size_t CurrOffset = OS.tell() - RangesOffset; const size_t CurrOffset = OS.tell() - RangesOffset;
@ -136,11 +142,13 @@ void DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
} }
ZeroFillBytes(OS, DebugRanges.AddrSize * 2); ZeroFillBytes(OS, DebugRanges.AddrSize * 2);
} }
return Error::success();
} }
void DWARFYAML::emitPubSection(raw_ostream &OS, Error DWARFYAML::emitPubSection(raw_ostream &OS,
const DWARFYAML::PubSection &Sect, const DWARFYAML::PubSection &Sect,
bool IsLittleEndian) { bool IsLittleEndian) {
writeInitialLength(Sect.Length, OS, IsLittleEndian); writeInitialLength(Sect.Length, OS, IsLittleEndian);
writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian);
writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian);
@ -152,6 +160,8 @@ void DWARFYAML::emitPubSection(raw_ostream &OS,
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();
} }
namespace { namespace {
@ -220,9 +230,11 @@ public:
}; };
} // namespace } // 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); DumpVisitor Visitor(DI, OS);
Visitor.traverseDebugInfo(); Visitor.traverseDebugInfo();
return Error::success();
} }
static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
@ -233,7 +245,7 @@ static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
encodeULEB128(File.Length, OS); 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) { for (const auto &LineTable : DI.DebugLines) {
writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian); writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian);
uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4; uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4;
@ -314,20 +326,25 @@ void DWARFYAML::emitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) {
} }
} }
} }
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, emitDebugSectionImpl(const DWARFYAML::Data &DI, EmitFuncType EmitFunc,
StringRef Sec, 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);
EmitFunc(DebugInfoStream, DI); if (Error Err = EmitFunc(DebugInfoStream, DI))
return Err;
DebugInfoStream.flush(); DebugInfoStream.flush();
if (!Data.empty()) if (!Data.empty())
OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data); OutputBuffers[Sec] = MemoryBuffer::getMemBufferCopy(Data);
return Error::success();
} }
namespace { namespace {
@ -391,17 +408,25 @@ DWARFYAML::emitDebugSections(StringRef YAMLString, bool ApplyFixups,
} }
StringMap<std::unique_ptr<MemoryBuffer>> DebugSections; StringMap<std::unique_ptr<MemoryBuffer>> DebugSections;
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugInfo, "debug_info", Error Err = emitDebugSectionImpl(DI, &DWARFYAML::emitDebugInfo, "debug_info",
DebugSections); DebugSections);
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugLine, "debug_line", Err = joinErrors(std::move(Err),
DebugSections); emitDebugSectionImpl(DI, &DWARFYAML::emitDebugLine,
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugStr, "debug_str", "debug_line", DebugSections));
DebugSections); Err = joinErrors(std::move(Err),
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugAbbrev, "debug_abbrev", emitDebugSectionImpl(DI, &DWARFYAML::emitDebugStr,
DebugSections); "debug_str", DebugSections));
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugAranges, "debug_aranges", Err = joinErrors(std::move(Err),
DebugSections); emitDebugSectionImpl(DI, &DWARFYAML::emitDebugAbbrev,
emitDebugSectionImpl(DI, &DWARFYAML::emitDebugRanges, "debug_ranges", "debug_abbrev", DebugSections));
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); return std::move(DebugSections);
} }

View File

@ -23,6 +23,7 @@
#include "llvm/ObjectYAML/ELFYAML.h" #include "llvm/ObjectYAML/ELFYAML.h"
#include "llvm/ObjectYAML/yaml2obj.h" #include "llvm/ObjectYAML/yaml2obj.h"
#include "llvm/Support/EndianStream.h" #include "llvm/Support/EndianStream.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/LEB128.h" #include "llvm/Support/LEB128.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/WithColor.h" #include "llvm/Support/WithColor.h"
@ -134,6 +135,7 @@ template <class ELFT> class ELFState {
bool HasError = false; bool HasError = false;
yaml::ErrorHandler ErrHandler; yaml::ErrorHandler ErrHandler;
void reportError(const Twine &Msg); void reportError(const Twine &Msg);
void reportError(Error Err);
std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols, std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
const StringTableBuilder &Strtab); const StringTableBuilder &Strtab);
@ -845,18 +847,24 @@ static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
} }
template <class ELFT> template <class ELFT>
uint64_t emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name, Expected<uint64_t> emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
const DWARFYAML::Data &DWARF, raw_ostream &OS) { const DWARFYAML::Data &DWARF, raw_ostream &OS) {
uint64_t BeginOffset = OS.tell(); uint64_t BeginOffset = OS.tell();
Error Err = Error::success();
cantFail(std::move(Err));
if (Name == ".debug_str") if (Name == ".debug_str")
DWARFYAML::emitDebugStr(OS, DWARF); Err = DWARFYAML::emitDebugStr(OS, DWARF);
else if (Name == ".debug_aranges") else if (Name == ".debug_aranges")
DWARFYAML::emitDebugAranges(OS, DWARF); Err = DWARFYAML::emitDebugAranges(OS, DWARF);
else if (Name == ".debug_ranges") else if (Name == ".debug_ranges")
DWARFYAML::emitDebugRanges(OS, DWARF); Err = DWARFYAML::emitDebugRanges(OS, DWARF);
else else
llvm_unreachable("unexpected emitDWARF() call"); llvm_unreachable("unexpected emitDWARF() call");
if (Err)
return std::move(Err);
return OS.tell() - BeginOffset; return OS.tell() - BeginOffset;
} }
@ -878,8 +886,13 @@ void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
reportError("cannot specify section '" + Name + reportError("cannot specify section '" + Name +
"' contents in the 'DWARF' entry and the 'Content' " "' contents in the 'DWARF' entry and the 'Content' "
"or 'Size' in the 'Sections' entry at the same time"); "or 'Size' in the 'Sections' entry at the same time");
else else {
SHeader.sh_size = emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA.getOS()); if (Expected<uint64_t> ShSizeOrErr =
emitDWARF<ELFT>(SHeader, Name, *Doc.DWARF, CBA.getOS()))
SHeader.sh_size = *ShSizeOrErr;
else
reportError(ShSizeOrErr.takeError());
}
} else if (RawSec) } else if (RawSec)
SHeader.sh_size = writeContent(CBA.getOS(), RawSec->Content, RawSec->Size); SHeader.sh_size = writeContent(CBA.getOS(), RawSec->Content, RawSec->Size);
else else
@ -910,6 +923,12 @@ template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
HasError = true; HasError = true;
} }
template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {
reportError(Err.message());
});
}
template <class ELFT> template <class ELFT>
std::vector<Fragment> std::vector<Fragment>
ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr, ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,

View File

@ -286,27 +286,32 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
errc::invalid_argument, errc::invalid_argument,
"wrote too much data somewhere, section offsets don't line up"); "wrote too much data somewhere, section offsets don't line up");
if (0 == strncmp(&Sec.segname[0], "__DWARF", 16)) { if (0 == strncmp(&Sec.segname[0], "__DWARF", 16)) {
if (0 == strncmp(&Sec.sectname[0], "__debug_str", 16)) { Error Err = Error::success();
DWARFYAML::emitDebugStr(OS, Obj.DWARF); cantFail(std::move(Err));
} else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16)) {
DWARFYAML::emitDebugAbbrev(OS, Obj.DWARF); if (0 == strncmp(&Sec.sectname[0], "__debug_str", 16))
} else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16)) { Err = DWARFYAML::emitDebugStr(OS, Obj.DWARF);
DWARFYAML::emitDebugAranges(OS, Obj.DWARF); else if (0 == strncmp(&Sec.sectname[0], "__debug_abbrev", 16))
} else if (0 == strncmp(&Sec.sectname[0], "__debug_ranges", 16)) { Err = DWARFYAML::emitDebugAbbrev(OS, Obj.DWARF);
DWARFYAML::emitDebugRanges(OS, Obj.DWARF); else if (0 == strncmp(&Sec.sectname[0], "__debug_aranges", 16))
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubnames", 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) if (Obj.DWARF.PubNames)
DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubNames, Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubNames,
Obj.IsLittleEndian); Obj.IsLittleEndian);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) {
if (Obj.DWARF.PubTypes) if (Obj.DWARF.PubTypes)
DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubTypes, Err = DWARFYAML::emitPubSection(OS, *Obj.DWARF.PubTypes,
Obj.IsLittleEndian); Obj.IsLittleEndian);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) { } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16))
DWARFYAML::emitDebugInfo(OS, Obj.DWARF); Err = DWARFYAML::emitDebugInfo(OS, Obj.DWARF);
} else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16)) { else if (0 == strncmp(&Sec.sectname[0], "__debug_line", 16))
DWARFYAML::emitDebugLine(OS, Obj.DWARF); Err = DWARFYAML::emitDebugLine(OS, Obj.DWARF);
}
if (Err)
return Err;
continue; continue;
} }