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.
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,
- function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler);
+ DWARFContextInMemory(const object::ObjectFile &Obj,
+ const LoadedObjectInfo *L = nullptr);
DWARFContextInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
uint8_t AddrSize,
Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
if (!SymAddrOrErr)
- return createError("failed to compute symbol address: ",
+ return createError("error: 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("failed to get symbol section: ",
+ return createError("error: failed to get symbol section: ",
SectOrErr.takeError());
RSec = *SectOrErr;
return Error::success();
}
-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)
+DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
+ const LoadedObjectInfo *L)
: FileName(Obj.getFileName()), IsLittleEndian(Obj.isLittleEndian()),
AddressSize(Obj.getBytesInAddress()) {
for (const SectionRef &Section : Obj.sections()) {
Section.getContents(data);
if (auto Err = maybeDecompress(Section, name, data)) {
- ErrorPolicy EP = HandleError(
- createError("failed to decompress '" + name + "', ", std::move(Err)));
- if (EP == ErrorPolicy::Halt)
- return;
+ errs() << "error: failed to decompress '" + name + "', " +
+ toString(std::move(Err))
+ << '\n';
continue;
}
Expected<SymInfo> SymInfoOrErr = getSymbolInfo(Obj, Reloc, L, AddrCache);
if (!SymInfoOrErr) {
- if (HandleError(SymInfoOrErr.takeError()) == ErrorPolicy::Halt)
- return;
+ errs() << toString(SymInfoOrErr.takeError()) << '\n';
continue;
}
if (V.error()) {
SmallString<32> Name;
Reloc.getTypeName(Name);
- ErrorPolicy EP = HandleError(
- createError("failed to compute relocation: " + name + ", ",
- errorCodeToError(object_error::parse_failed)));
- if (EP == ErrorPolicy::Halt)
- return;
+ errs() << "error: failed to compute relocation: " << Name << "\n";
continue;
}
RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val};
#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"
"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
BumpPtrAllocator &getAllocator() { return Allocator; }
AsmPrinter *getAsmPrinter() const { return Asm.get(); }
- MCContext *getMCContext() const { return MC.get(); }
DIEAbbrevSet &getAbbrevSet() { return Abbreviations; }
DwarfStringPool &getStringPool() { return *StringPool; }