diff options
author | George Rimar <grimar@accesssoftek.com> | 2017-06-28 08:21:19 +0000 |
---|---|---|
committer | George Rimar <grimar@accesssoftek.com> | 2017-06-28 08:21:19 +0000 |
commit | 1af3cb2912bad7454db673721e22e3ef64850e6c (patch) | |
tree | ff62340e0a5ff6caa90197fe8ebb7b960098d2ce | |
parent | 99e376956d6fd12641f8515fb019e9220a2e477f (diff) | |
download | bcm5719-llvm-1af3cb2912bad7454db673721e22e3ef64850e6c.tar.gz bcm5719-llvm-1af3cb2912bad7454db673721e22e3ef64850e6c.zip |
Recommit "[ELF] - Add ability for DWARFContextInMemory to exit early when any error happen."
With fix in include folder character case:
#include "llvm/Codegen/AsmPrinter.h" -> #include "llvm/CodeGen/AsmPrinter.h"
Original commit message:
Change introduces error reporting policy for DWARFContextInMemory.
New callback provided by client is able to handle error on it's
side and return Halt or Continue.
That allows to either keep current behavior when parser prints all errors
but continues parsing object or implement something very different, like
stop parsing on a first error and report an error in a client style.
Differential revision: https://reviews.llvm.org/D34328
llvm-svn: 306517
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h | 14 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 30 | ||||
-rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp | 47 | ||||
-rw-r--r-- | llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h | 1 |
4 files changed, 81 insertions, 11 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h index 4bf34d52bcb..8850104db29 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -289,6 +289,11 @@ private: DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address); }; +/// 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 }; + /// DWARFContextInMemory is the simplest possible implementation of a /// DWARFContext. It assumes all content is available in memory and stores /// pointers to it. @@ -346,9 +351,14 @@ class DWARFContextInMemory : public DWARFContext { Error maybeDecompress(const object::SectionRef &Sec, StringRef Name, StringRef &Data); + /// 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); + public: - DWARFContextInMemory(const object::ObjectFile &Obj, - const LoadedObjectInfo *L = nullptr); + DWARFContextInMemory( + const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr, + function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler); DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize, diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 38147946175..fdd191e0cbf 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -870,13 +870,13 @@ static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj, Expected<uint64_t> SymAddrOrErr = Sym->getAddress(); if (!SymAddrOrErr) - return createError("error: failed to compute symbol address: ", + return createError("failed to compute symbol address: ", SymAddrOrErr.takeError()); // Also remember what section this symbol is in for later auto SectOrErr = Sym->getSection(); if (!SectOrErr) - return createError("error: failed to get symbol section: ", + return createError("failed to get symbol section: ", SectOrErr.takeError()); RSec = *SectOrErr; @@ -937,8 +937,14 @@ Error DWARFContextInMemory::maybeDecompress(const SectionRef &Sec, return Error::success(); } -DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, - const LoadedObjectInfo *L) +ErrorPolicy DWARFContextInMemory::defaultErrorHandler(Error E) { + errs() << "error: " + toString(std::move(E)) << '\n'; + return ErrorPolicy::Continue; +} + +DWARFContextInMemory::DWARFContextInMemory( + const object::ObjectFile &Obj, const LoadedObjectInfo *L, + function_ref<ErrorPolicy(Error)> HandleError) : FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()), AddressSize(Obj.getBytesInAddress()) { for (const SectionRef &Section : Obj.sections()) { @@ -961,9 +967,10 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, Section.getContents(data); if (auto Err = maybeDecompress(Section, name, data)) { - errs() << "error: failed to decompress '" + name + "', " + - toString(std::move(Err)) - << '\n'; + ErrorPolicy EP = HandleError( + createError("failed to decompress '" + name + "', ", std::move(Err))); + if (EP == ErrorPolicy::Halt) + return; continue; } @@ -1055,7 +1062,8 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache); if (!SymInfoOrErr) { - errs() << toString(SymInfoOrErr.takeError()) << '\n'; + if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt) + return; continue; } @@ -1064,7 +1072,11 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, if (V.error()) { SmallString<32> Name; Reloc.getTypeName(Name); - errs() << "error: failed to compute relocation: " << Name << "\n"; + ErrorPolicy EP = HandleError( + createError("failed to compute relocation: " + name + ", ", + errorCodeToError(object_error::parse_failed))); + if (EP == ErrorPolicy::Halt) + return; continue; } RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp index bf004d6ffc2..7f6492ee6d1 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -15,10 +15,14 @@ #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Config/llvm-config.h" +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/Object/ObjectFile.h" #include "llvm/ObjectYAML/DWARFEmitter.h" #include "llvm/ObjectYAML/DWARFYAML.h" @@ -2146,4 +2150,47 @@ TEST(DWARFDebugInfo, TestDwarfVerifyCUDontShareLineTable) { "offset:"); } +TEST(DWARFDebugInfo, TestErrorReportingPolicy) { + initLLVMIfNeeded(); + auto ExpectedDG = dwarfgen::Generator::create(Triple("x86_64-pc-linux"), + 4 /*DwarfVersion*/); + if (HandleExpectedError(ExpectedDG)) + return; + dwarfgen::Generator *DG = ExpectedDG.get().get(); + AsmPrinter *AP = DG->getAsmPrinter(); + MCContext *MC = DG->getMCContext(); + + // Emit two compressed sections with broken headers. + AP->OutStreamer->SwitchSection( + MC->getELFSection(".zdebug_foo", 0 /*Type*/, 0 /*Flags*/)); + AP->OutStreamer->EmitBytes("0"); + AP->OutStreamer->SwitchSection( + MC->getELFSection(".zdebug_bar", 0 /*Type*/, 0 /*Flags*/)); + AP->OutStreamer->EmitBytes("0"); + + MemoryBufferRef FileBuffer(DG->generate(), "dwarf"); + auto Obj = object::ObjectFile::createObjectFile(FileBuffer); + EXPECT_TRUE((bool)Obj); + + // Case 1: error handler handles all errors. That allows + // DWARFContextInMemory + // to parse whole file and find both two errors we know about. + int Errors = 0; + DWARFContextInMemory Ctx1(*Obj.get(), 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; + DWARFContextInMemory Ctx2(*Obj.get(), nullptr, [&](Error E) { + ++Errors; + consumeError(std::move(E)); + return ErrorPolicy::Halt; + }); + EXPECT_TRUE(Errors == 1); +} + } // end anonymous namespace diff --git a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h index 76665e5193e..dd7e8709638 100644 --- a/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h +++ b/llvm/unittests/DebugInfo/DWARF/DwarfGenerator.h @@ -215,6 +215,7 @@ public: BumpPtrAllocator &getAllocator() { return Allocator; } AsmPrinter *getAsmPrinter() const { return Asm.get(); } + MCContext *getMCContext() const { return MC.get(); } DIEAbbrevSet &getAbbrevSet() { return Abbreviations; } DwarfStringPool &getStringPool() { return *StringPool; } |