diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -47,11 +47,6 @@ class MemoryBuffer; class raw_ostream; -/// Used as a return value for a error callback passed to DWARF context. -/// Callback should return Halt if client application wants to stop -/// object parsing, or should return Continue otherwise. -enum class ErrorPolicy { Halt, Continue }; - /// DWARFContext /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through DWARFObj. @@ -91,7 +86,8 @@ std::unique_ptr RegInfo; - std::function RecoverableErrorHandler = defaultErrorHandler; + std::function RecoverableErrorHandler = + WithColor::defaultErrorHandler; std::function WarningHandler = WithColor::defaultWarningHandler; /// Read compile units from the debug_info section (if necessary) @@ -110,7 +106,11 @@ public: DWARFContext(std::unique_ptr DObj, - std::string DWPName = ""); + std::string DWPName = "", + std::function RecoverableErrorHandler = + WithColor::defaultErrorHandler, + std::function WarningHandler = + WithColor::defaultWarningHandler); ~DWARFContext(); DWARFContext(DWARFContext &) = delete; @@ -352,18 +352,21 @@ function_ref 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 create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, - function_ref HandleError = defaultErrorHandler, - std::string DWPName = ""); + std::string DWPName = "", + std::function RecoverableErrorHandler = + WithColor::defaultErrorHandler, + std::function WarningHandler = + WithColor::defaultWarningHandler); static std::unique_ptr create(const StringMap> &Sections, - uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost); + uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost, + std::function RecoverableErrorHandler = + WithColor::defaultErrorHandler, + std::function WarningHandler = + WithColor::defaultWarningHandler); /// Loads register info for the architecture of the provided object file. /// Improves readability of dumped DWARF expressions. Requires the caller to diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -65,8 +65,12 @@ using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind; DWARFContext::DWARFContext(std::unique_ptr DObj, - std::string DWPName) - : DIContext(CK_DWARF), DWPName(std::move(DWPName)), DObj(std::move(DObj)) {} + std::string DWPName, + std::function RecoverableErrorHandler, + std::function WarningHandler) + : DIContext(CK_DWARF), DWPName(std::move(DWPName)), + RecoverableErrorHandler(RecoverableErrorHandler), + WarningHandler(WarningHandler), DObj(std::move(DObj)) {} DWARFContext::~DWARFContext() = default; @@ -1425,11 +1429,6 @@ return MachObj->isRelocationScattered(RelocInfo); } -ErrorPolicy DWARFContext::defaultErrorHandler(Error E) { - WithColor::defaultErrorHandler(std::move(E)); - return ErrorPolicy::Continue; -} - namespace { struct DWARFSectionMap final : public DWARFSection { RelocAddrMap Relocs; @@ -1581,7 +1580,7 @@ } } DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref HandleError) + function_ref HandleError) : IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()), Obj(&Obj) { @@ -1608,10 +1607,8 @@ StringRef Data; Expected SecOrErr = Section.getRelocatedSection(); if (!SecOrErr) { - ErrorPolicy EP = HandleError(createError( - "failed to get relocated section: ", SecOrErr.takeError())); - if (EP == ErrorPolicy::Halt) - return; + HandleError(createError("failed to get relocated section: ", + SecOrErr.takeError())); continue; } @@ -1629,10 +1626,8 @@ } if (auto Err = maybeDecompress(Section, Name, Data)) { - ErrorPolicy EP = HandleError(createError( - "failed to decompress '" + Name + "', ", std::move(Err))); - if (EP == ErrorPolicy::Halt) - return; + HandleError(createError("failed to decompress '" + Name + "', ", + std::move(Err))); continue; } @@ -1733,8 +1728,7 @@ Expected SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache); if (!SymInfoOrErr) { - if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) - return; + HandleError(SymInfoOrErr.takeError()); continue; } @@ -1754,10 +1748,8 @@ if (!I.second) { RelocAddrEntry &entry = I.first->getSecond(); if (entry.Reloc2) { - ErrorPolicy EP = HandleError(createError( + HandleError(createError( "At most two relocations per offset are supported")); - if (EP == ErrorPolicy::Halt) - return; } entry.Reloc2 = Reloc; entry.SymbolValue2 = SymInfoOrErr->Address; @@ -1765,11 +1757,9 @@ } else { SmallString<32> Type; Reloc.getTypeName(Type); - ErrorPolicy EP = HandleError( + HandleError( createError("failed to compute relocation: " + Type + ", ", errorCodeToError(object_error::parse_failed))); - if (EP == ErrorPolicy::Halt) - return; } } } @@ -1897,18 +1887,25 @@ std::unique_ptr DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, - function_ref HandleError, - std::string DWPName) { - auto DObj = std::make_unique(Obj, L, HandleError); - return std::make_unique(std::move(DObj), std::move(DWPName)); + std::string DWPName, + std::function RecoverableErrorHandler, + std::function WarningHandler) { + auto DObj = + std::make_unique(Obj, L, RecoverableErrorHandler); + return std::make_unique(std::move(DObj), std::move(DWPName), + RecoverableErrorHandler, + WarningHandler); } std::unique_ptr DWARFContext::create(const StringMap> &Sections, - uint8_t AddrSize, bool isLittleEndian) { + uint8_t AddrSize, bool isLittleEndian, + std::function RecoverableErrorHandler, + std::function WarningHandler) { auto DObj = std::make_unique(Sections, AddrSize, isLittleEndian); - return std::make_unique(std::move(DObj), ""); + return std::make_unique( + std::move(DObj), "", RecoverableErrorHandler, WarningHandler); } Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -66,8 +66,7 @@ if (I != Modules.end()) return symbolizeCodeCommon(I->second.get(), ModuleOffset); - std::unique_ptr Context = - DWARFContext::create(Obj, nullptr, DWARFContext::defaultErrorHandler); + std::unique_ptr Context = DWARFContext::create(Obj); Expected InfoOrErr = createModuleInfo(&Obj, std::move(Context), ModuleName); if (!InfoOrErr) @@ -564,9 +563,7 @@ } } if (!Context) - Context = - DWARFContext::create(*Objects.second, nullptr, - DWARFContext::defaultErrorHandler, Opts.DWPName); + Context = DWARFContext::create(*Objects.second, nullptr, Opts.DWPName); return createModuleInfo(Objects.first, std::move(Context), ModuleName); } diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -2529,26 +2529,14 @@ auto Obj = object::ObjectFile::createObjectFile(FileBuffer); EXPECT_TRUE((bool)Obj); - // Case 1: error handler handles all errors. That allows - // DWARFContext to parse whole file and find both two errors we know about. + // DWARFContext parses whole file and finds both two errors we know about. int Errors = 0; std::unique_ptr Ctx1 = - DWARFContext::create(**Obj, nullptr, [&](Error E) { + DWARFContext::create(**Obj, nullptr, "", [&](Error E) { ++Errors; consumeError(std::move(E)); - return ErrorPolicy::Continue; }); EXPECT_TRUE(Errors == 2); - - // Case 2: error handler stops parsing of object after first error. - Errors = 0; - std::unique_ptr Ctx2 = - DWARFContext::create(**Obj, nullptr, [&](Error E) { - ++Errors; - consumeError(std::move(E)); - return ErrorPolicy::Halt; - }); - EXPECT_TRUE(Errors == 1); } TEST(DWARFDebugInfo, TestDwarfVerifyCURangesIncomplete) {