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:
parent
00cbb7405f
commit
32d5a272f8
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user