1
0
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:
Alexey Lapshin 2020-02-11 18:32:27 +03:00
parent 795d2346ea
commit d1dbbf13e4
6 changed files with 62 additions and 37 deletions

View File

@ -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 {

View File

@ -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();
}

View File

@ -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

View File

@ -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;

View File

@ -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';
});
}

View File

@ -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';
});
}