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 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,
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user