mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[Debuginfo][NFC] Create common error handlers for DWARFContext.
Summary: this review is extracted from D74308. It creates two error handlers which allow to redefine error reporting routine and should be used for all places where errors are reported: std::function<void(Error)> RecoverableErrorHandler = defaultErrorHandler; std::function<void(Error)> WarningHandler = defaultWarningHandler; It also creates accessors to above handlers which should be used to report errors. function_ref<void(Error)> getRecoverableErrorHandler() { return RecoverableErrorHandler; } function_ref<void(Error)> getWarningHandler() { return WarningHandler; } It patches all error reporting places inside DWARFContext and DWARLinker. Reviewers: jhenderson, dblaikie, probinson, aprantl, JDevlieghere Reviewed By: jhenderson, JDevlieghere Subscribers: hiraditya, llvm-commits Tags: #llvm, #debug-info Differential Revision: https://reviews.llvm.org/D74481
This commit is contained in:
parent
795d2346ea
commit
d1dbbf13e4
@ -16,6 +16,7 @@
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
@ -204,6 +205,10 @@ struct DIDumpOptions {
|
||||
Opts.ParentRecurseDepth = 0;
|
||||
return Opts;
|
||||
}
|
||||
|
||||
std::function<void(Error)> RecoverableErrorHandler =
|
||||
WithColor::defaultErrorHandler;
|
||||
std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
|
||||
};
|
||||
|
||||
class DIContext {
|
||||
|
@ -91,6 +91,9 @@ class DWARFContext : public DIContext {
|
||||
|
||||
std::unique_ptr<MCRegisterInfo> RegInfo;
|
||||
|
||||
std::function<void(Error)> RecoverableErrorHandler = defaultErrorHandler;
|
||||
std::function<void(Error)> WarningHandler = WithColor::defaultWarningHandler;
|
||||
|
||||
/// Read compile units from the debug_info section (if necessary)
|
||||
/// and type units from the debug_types sections (if necessary)
|
||||
/// and store them in NormalUnits.
|
||||
@ -343,9 +346,16 @@ public:
|
||||
|
||||
const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
|
||||
|
||||
function_ref<void(Error)> getRecoverableErrorHandler() {
|
||||
return RecoverableErrorHandler;
|
||||
}
|
||||
|
||||
function_ref<void(Error)> getWarningHandler() { return WarningHandler; }
|
||||
|
||||
/// Function used to handle default error reporting policy. Prints a error
|
||||
/// message and returns Continue, so DWARF context ignores the error.
|
||||
static ErrorPolicy defaultErrorHandler(Error E);
|
||||
|
||||
static std::unique_ptr<DWARFContext>
|
||||
create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
|
||||
function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
|
||||
@ -364,9 +374,6 @@ public:
|
||||
/// TODO: refactor compile_units() to make this const.
|
||||
uint8_t getCUAddrSize();
|
||||
|
||||
/// Dump Error as warning message to stderr.
|
||||
static void dumpWarning(Error Warning);
|
||||
|
||||
Triple::ArchType getArch() const {
|
||||
return getDWARFObj().getFile()->getArch();
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -108,6 +109,9 @@ public:
|
||||
/// Reset the colors to terminal defaults. Call this when you are done
|
||||
/// outputting colored text, or before program exit.
|
||||
WithColor &resetColor();
|
||||
|
||||
static void defaultErrorHandler(Error Err);
|
||||
static void defaultWarningHandler(Error Warning);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -1548,9 +1548,10 @@ void DWARFLinker::patchLineTableForUnit(CompileUnit &Unit,
|
||||
if (needToTranslateStrings())
|
||||
return TheDwarfEmitter->translateLineTable(LineExtractor, StmtOffset);
|
||||
|
||||
Error Err = LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf,
|
||||
&Unit.getOrigUnit(), DWARFContext::dumpWarning);
|
||||
DWARFContext::dumpWarning(std::move(Err));
|
||||
if (Error Err =
|
||||
LineTable.parse(LineExtractor, &StmtOffset, OrigDwarf,
|
||||
&Unit.getOrigUnit(), OrigDwarf.getWarningHandler()))
|
||||
OrigDwarf.getWarningHandler()(std::move(Err));
|
||||
|
||||
// This vector is the output line table.
|
||||
std::vector<DWARFDebugLine::Row> NewRows;
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/WithColor.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
@ -131,9 +130,10 @@ collectContributionData(DWARFContext::unit_iterator_range Units) {
|
||||
}
|
||||
|
||||
static void dumpDWARFv5StringOffsetsSection(
|
||||
raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj,
|
||||
const DWARFSection &StringOffsetsSection, StringRef StringSection,
|
||||
DWARFContext::unit_iterator_range Units, bool LittleEndian) {
|
||||
raw_ostream &OS, DIDumpOptions DumpOpts, StringRef SectionName,
|
||||
const DWARFObject &Obj, const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection, DWARFContext::unit_iterator_range Units,
|
||||
bool LittleEndian) {
|
||||
auto Contributions = collectContributionData(Units);
|
||||
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
|
||||
DataExtractor StrData(StringSection, LittleEndian, 0);
|
||||
@ -159,10 +159,10 @@ static void dumpDWARFv5StringOffsetsSection(
|
||||
|
||||
// Detect overlapping contributions.
|
||||
if (Offset > ContributionHeader) {
|
||||
WithColor::error()
|
||||
<< "overlapping contributions to string offsets table in section ."
|
||||
<< SectionName << ".\n";
|
||||
return;
|
||||
DumpOpts.RecoverableErrorHandler(createStringError(
|
||||
errc::invalid_argument,
|
||||
"overlapping contributions to string offsets table in section .%s.",
|
||||
SectionName.data()));
|
||||
}
|
||||
// Report a gap in the table.
|
||||
if (Offset < ContributionHeader) {
|
||||
@ -204,7 +204,8 @@ static void dumpDWARFv5StringOffsetsSection(
|
||||
// a header containing size and version number. Alternatively, it may be a
|
||||
// monolithic series of string offsets, as generated by the pre-DWARF v5
|
||||
// implementation of split DWARF.
|
||||
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
|
||||
static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
StringRef SectionName,
|
||||
const DWARFObject &Obj,
|
||||
const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection,
|
||||
@ -214,8 +215,9 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
|
||||
// we assume that the section is formatted like a DWARF v5 string offsets
|
||||
// section.
|
||||
if (MaxVersion >= 5)
|
||||
dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection,
|
||||
StringSection, Units, LittleEndian);
|
||||
dumpDWARFv5StringOffsetsSection(OS, DumpOpts, SectionName, Obj,
|
||||
StringOffsetsSection, StringSection, Units,
|
||||
LittleEndian);
|
||||
else {
|
||||
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
|
||||
uint64_t offset = 0;
|
||||
@ -248,8 +250,8 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
|
||||
DWARFDebugAddrTable AddrTable;
|
||||
uint64_t TableOffset = Offset;
|
||||
if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
|
||||
DWARFContext::dumpWarning)) {
|
||||
WithColor::error() << toString(std::move(Err)) << '\n';
|
||||
DumpOpts.WarningHandler)) {
|
||||
DumpOpts.RecoverableErrorHandler(std::move(Err));
|
||||
// Keep going after an error, if we can, assuming that the length field
|
||||
// could be read. If it couldn't, stop reading the section.
|
||||
if (auto TableLength = AddrTable.getFullLength()) {
|
||||
@ -273,7 +275,7 @@ static void dumpRnglistsSection(
|
||||
llvm::DWARFDebugRnglistTable Rnglists;
|
||||
uint64_t TableOffset = Offset;
|
||||
if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
|
||||
WithColor::error() << toString(std::move(Err)) << '\n';
|
||||
DumpOpts.RecoverableErrorHandler(std::move(Err));
|
||||
uint64_t Length = Rnglists.length();
|
||||
// Keep going after an error, if we can, assuming that the length field
|
||||
// could be read. If it couldn't, stop reading the section.
|
||||
@ -296,7 +298,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
while (Data.isValidOffset(Offset)) {
|
||||
DWARFListTableHeader Header(".debug_loclists", "locations");
|
||||
if (Error E = Header.extract(Data, &Offset)) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
DumpOpts.RecoverableErrorHandler(std::move(E));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -323,7 +325,6 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
void DWARFContext::dump(
|
||||
raw_ostream &OS, DIDumpOptions DumpOpts,
|
||||
std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
|
||||
|
||||
uint64_t DumpType = DumpOpts.DumpType;
|
||||
|
||||
StringRef Extension = sys::path::extension(DObj->getFileName());
|
||||
@ -456,7 +457,7 @@ void DWARFContext::dump(
|
||||
DWARFDebugArangeSet set;
|
||||
while (arangesData.isValidOffset(offset)) {
|
||||
if (Error E = set.extract(arangesData, &offset)) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
RecoverableErrorHandler(std::move(E));
|
||||
break;
|
||||
}
|
||||
set.dump(OS);
|
||||
@ -468,16 +469,16 @@ void DWARFContext::dump(
|
||||
Optional<uint64_t> DumpOffset) {
|
||||
while (!Parser.done()) {
|
||||
if (DumpOffset && Parser.getOffset() != *DumpOffset) {
|
||||
Parser.skip(dumpWarning, dumpWarning);
|
||||
Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
|
||||
continue;
|
||||
}
|
||||
OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
|
||||
<< "]\n";
|
||||
if (DumpOpts.Verbose) {
|
||||
Parser.parseNext(dumpWarning, dumpWarning, &OS);
|
||||
Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS);
|
||||
} else {
|
||||
DWARFDebugLine::LineTable LineTable =
|
||||
Parser.parseNext(dumpWarning, dumpWarning);
|
||||
Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
|
||||
LineTable.dump(OS, DumpOpts);
|
||||
}
|
||||
}
|
||||
@ -561,7 +562,7 @@ void DWARFContext::dump(
|
||||
DWARFDebugRangeList rangeList;
|
||||
while (rangesData.isValidOffset(offset)) {
|
||||
if (Error E = rangeList.extract(rangesData, &offset)) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
DumpOpts.RecoverableErrorHandler(std::move(E));
|
||||
break;
|
||||
}
|
||||
rangeList.dump(OS);
|
||||
@ -614,13 +615,13 @@ void DWARFContext::dump(
|
||||
|
||||
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
|
||||
DObj->getStrOffsetsSection().Data))
|
||||
dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
|
||||
dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets", *DObj,
|
||||
DObj->getStrOffsetsSection(),
|
||||
DObj->getStrSection(), normal_units(),
|
||||
isLittleEndian(), getMaxVersion());
|
||||
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
|
||||
DObj->getStrOffsetsDWOSection().Data))
|
||||
dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
|
||||
dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
|
||||
DObj->getStrOffsetsDWOSection(),
|
||||
DObj->getStrDWOSection(), dwo_units(),
|
||||
isLittleEndian(), getMaxDWOVersion());
|
||||
@ -871,9 +872,9 @@ const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
|
||||
const DWARFDebugLine::LineTable *
|
||||
DWARFContext::getLineTableForUnit(DWARFUnit *U) {
|
||||
Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
|
||||
getLineTableForUnit(U, dumpWarning);
|
||||
getLineTableForUnit(U, WarningHandler);
|
||||
if (!ExpectedLineTable) {
|
||||
dumpWarning(ExpectedLineTable.takeError());
|
||||
WarningHandler(ExpectedLineTable.takeError());
|
||||
return nullptr;
|
||||
}
|
||||
return *ExpectedLineTable;
|
||||
@ -1425,7 +1426,7 @@ static bool isRelocScattered(const object::ObjectFile &Obj,
|
||||
}
|
||||
|
||||
ErrorPolicy DWARFContext::defaultErrorHandler(Error E) {
|
||||
WithColor::error() << toString(std::move(E)) << '\n';
|
||||
WithColor::defaultErrorHandler(std::move(E));
|
||||
return ErrorPolicy::Continue;
|
||||
}
|
||||
|
||||
@ -1941,8 +1942,3 @@ uint8_t DWARFContext::getCUAddrSize() {
|
||||
return Addr;
|
||||
}
|
||||
|
||||
void DWARFContext::dumpWarning(Error Warning) {
|
||||
handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
|
||||
WithColor::warning() << Info.message() << '\n';
|
||||
});
|
||||
}
|
||||
|
@ -118,3 +118,15 @@ WithColor &WithColor::resetColor() {
|
||||
}
|
||||
|
||||
WithColor::~WithColor() { resetColor(); }
|
||||
|
||||
void WithColor::defaultErrorHandler(Error Err) {
|
||||
handleAllErrors(std::move(Err), [](ErrorInfoBase &Info) {
|
||||
WithColor::error() << Info.message() << '\n';
|
||||
});
|
||||
}
|
||||
|
||||
void WithColor::defaultWarningHandler(Error Warning) {
|
||||
handleAllErrors(std::move(Warning), [](ErrorInfoBase &Info) {
|
||||
WithColor::warning() << Info.message() << '\n';
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user