1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02: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 PubSection;
void emitDebugAbbrev(raw_ostream &OS, const Data &DI);
void emitDebugStr(raw_ostream &OS, const Data &DI);
Error emitDebugAbbrev(raw_ostream &OS, const Data &DI);
Error 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 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<StringMap<std::unique_ptr<MemoryBuffer>>>
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);
}
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 @@ void DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
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 @@ void DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) {
}
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 @@ void DWARFYAML::emitDebugRanges(raw_ostream &OS, const DWARFYAML::Data &DI) {
}
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 @@ void DWARFYAML::emitPubSection(raw_ostream &OS,
OS.write(Entry.Name.data(), Entry.Name.size());
OS.write('\0');
}
return Error::success();
}
namespace {
@ -220,9 +230,11 @@ public:
};
} // 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 @@ static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) {
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 @@ 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,
StringRef Sec,
StringMap<std::unique_ptr<MemoryBuffer>> &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 @@ DWARFYAML::emitDebugSections(StringRef YAMLString, bool ApplyFixups,
}
StringMap<std::unique_ptr<MemoryBuffer>> 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);
}

View File

@ -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 @@ template <class ELFT> class ELFState {
bool HasError = false;
yaml::ErrorHandler ErrHandler;
void reportError(const Twine &Msg);
void reportError(Error Err);
std::vector<Elf_Sym> toELFSymbols(ArrayRef<ELFYAML::Symbol> Symbols,
const StringTableBuilder &Strtab);
@ -845,18 +847,24 @@ static bool shouldEmitDWARF(DWARFYAML::Data &DWARF, StringRef Name) {
}
template <class ELFT>
uint64_t emitDWARF(typename ELFT::Shdr &SHeader, StringRef Name,
const DWARFYAML::Data &DWARF, raw_ostream &OS) {
Expected<uint64_t> 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 @@ void ELFState<ELFT>::initDWARFSectionHeader(Elf_Shdr &SHeader, StringRef Name,
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<ELFT>(SHeader, Name, *Doc.DWARF, CBA.getOS());
else {
if (Expected<uint64_t> ShSizeOrErr =
emitDWARF<ELFT>(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 @@ template <class ELFT> void ELFState<ELFT>::reportError(const Twine &Msg) {
HasError = true;
}
template <class ELFT> void ELFState<ELFT>::reportError(Error Err) {
handleAllErrors(std::move(Err), [&](const ErrorInfoBase &Err) {
reportError(Err.message());
});
}
template <class ELFT>
std::vector<Fragment>
ELFState<ELFT>::getPhdrFragments(const ELFYAML::ProgramHeader &Phdr,

View File

@ -286,27 +286,32 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) {
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;
}