llvm-dwarfdump: Return non-zero on error

Makes it easier to test "this doesn't produce an error" (& indeed makes
that the implied default so we don't accidentally write tests that have
silent/sneaky errors as well as the positive behavior we're testing for)

Though the support for applying relocations is patchy enough that a
bunch of tests treat lack of relocation application as more of a warning
than an error - so rather than me trying to figure out how to add
support for a bunch of relocation types, let's degrade that to a warning
to match the usage (& indeed, it's sort of more of a tool warning anyway
- it's not that the DWARF is wrong, just that the tool can't fully cope
with it - and it's not like the tool won't dump the DWARF, it just won't
follow/render certain relocations - I guess in the most general case it
might try to render an unrelocated value & instead render something
bogus... but mostly seems to be about interesting relocations used in
eh_frame (& honestly it might be nice if we were lazier about doing this
relocation resolution anyway - if you're not dumping eh_frame, should we
really be erroring about the relocations in it?))
This commit is contained in:
David Blaikie
2020-04-09 20:53:58 -07:00
parent be54ea52f1
commit e0fd87cc64
11 changed files with 34 additions and 28 deletions

View File

@@ -1620,7 +1620,7 @@ public:
}
}
DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
function_ref<void(Error)> HandleError)
function_ref<void(Error)> HandleError, function_ref<void(Error)> HandleWarning )
: IsLittleEndian(Obj.isLittleEndian()),
AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
Obj(&Obj) {
@@ -1797,7 +1797,8 @@ public:
} else {
SmallString<32> Type;
Reloc.getTypeName(Type);
HandleError(
// FIXME: Support more relocations & change this to an error
HandleWarning(
createError("failed to compute relocation: " + Type + ", ",
errorCodeToError(object_error::parse_failed)));
}
@@ -1932,7 +1933,7 @@ DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
std::function<void(Error)> RecoverableErrorHandler,
std::function<void(Error)> WarningHandler) {
auto DObj =
std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler);
std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler, WarningHandler);
return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
RecoverableErrorHandler,
WarningHandler);

View File

@@ -1,5 +1,5 @@
# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
# RUN: llvm-dwarfdump %t | FileCheck %s
# RUN: not llvm-dwarfdump %t | FileCheck %s
# CHECK: DW_AT_name ("x0")
# CHECK-NEXT: DW_AT_location (0x0000000c

View File

@@ -1,7 +1,7 @@
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
# RUN: llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
# RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
# RUN: llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
# RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
# Test object to verify dwarfdump handles v5 range lists in 64-bit DWARF format.

View File

@@ -1,7 +1,7 @@
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
# RUN: llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
# RUN: not llvm-dwarfdump -v -debug-info %t.o 2> %t.err | FileCheck %s
# RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
# RUN: llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
# RUN: not llvm-dwarfdump -lookup 10 %t.o 2> %t2.err
# RUN: FileCheck %s --input-file %t2.err --check-prefix=ERR
# Test object to verify dwarfdump handles v5 range lists.

View File

@@ -1,5 +1,5 @@
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
# RUN: llvm-dwarfdump -v %t.o 2>&1 | FileCheck %s
# RUN: not llvm-dwarfdump -v %t.o 2>&1 | FileCheck %s
#
# Test object to verify that llvm-dwarfdump handles an invalid string offsets
# table.

View File

@@ -1,6 +1,6 @@
REQUIRES: zlib
// dwarfdump-decompression-corrupt.elf-x86-64 is fuzzer output
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-decompression-corrupt.elf-x86-64 2>&1 | FileCheck %s
RUN: not llvm-dwarfdump %p/Inputs/dwarfdump-decompression-corrupt.elf-x86-64 2>&1 | FileCheck %s
CHECK: error: failed to decompress '', corrupted compressed section header

View File

@@ -10,6 +10,6 @@ REQUIRES: zlib
// After that result object was modified manually. One random byte in compressed
// content of .debug_info section was changed to 0xff. That breaks normal
// decompression flow in runtime.
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-decompression-error.elf-x86-64 2>&1 | FileCheck %s
RUN: not llvm-dwarfdump %p/Inputs/dwarfdump-decompression-error.elf-x86-64 2>&1 | FileCheck %s
CHECK: error: failed to decompress '.debug_info', zlib error: Z_DATA_ERROR

View File

@@ -1,6 +1,6 @@
# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o
# RUN: llvm-dwarfdump -debug-aranges %t.o 2>&1 | FileCheck %s
# RUN: llvm-dwarfdump -lookup 10 %t.o 2>&1 | FileCheck %s
# RUN: not llvm-dwarfdump -debug-aranges %t.o 2>&1 | FileCheck %s
# RUN: not llvm-dwarfdump -lookup 10 %t.o 2>&1 | FileCheck %s
## This checks that llvm-dwarfdump shows parsing errors in .debug_aranges.
## For more error cases see unittests/DebugInfo/DWARF/DWARFDebugArangeSetTest.cpp.

View File

@@ -1,10 +1,10 @@
# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
# RUN: | llvm-dwarfdump -lookup=0xffffffff - | \
# RUN: | not llvm-dwarfdump -lookup=0xffffffff - | \
# RUN: FileCheck %s --check-prefix=EMPTY --allow-empty
# EMPTY: {{^$}}
# RUN: llvm-mc %s -filetype obj -triple x86_64-apple-darwin -o - \
# RUN: | llvm-dwarfdump -lookup=0xffffffffffffffff - | \
# RUN: | not llvm-dwarfdump -lookup=0xffffffffffffffff - | \
# RUN: FileCheck %s --check-prefix=EMPTY --allow-empty
# EMPTY: {{^$}}

View File

@@ -2,7 +2,7 @@
## sh_info field of a relocation section is invalid.
# RUN: yaml2obj %s -o %t
# RUN: llvm-dwarfdump %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# RUN: not llvm-dwarfdump %t 2>&1 | FileCheck %s -DFILE=%t --check-prefix=ERR
# ERR: error: failed to get relocated section: invalid section index: 255

View File

@@ -29,6 +29,7 @@
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
using namespace llvm;
using namespace object;
@@ -496,10 +497,15 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
error(Filename, errorToErrorCode(BinOrErr.takeError()));
bool Result = true;
auto RecoverableErrorHandler = [&](Error E) {
Result = false;
WithColor::defaultErrorHandler(std::move(E));
};
if (auto *Obj = dyn_cast<ObjectFile>(BinOrErr->get())) {
if (filterArch(*Obj)) {
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
Result = HandleObj(*Obj, *DICtx, Filename, OS);
std::unique_ptr<DWARFContext> DICtx =
DWARFContext::create(*Obj, nullptr, "", RecoverableErrorHandler);
Result &= HandleObj(*Obj, *DICtx, Filename, OS);
}
}
else if (auto *Fat = dyn_cast<MachOUniversalBinary>(BinOrErr->get()))
@@ -509,7 +515,8 @@ static bool handleBuffer(StringRef Filename, MemoryBufferRef Buffer,
if (auto MachOOrErr = ObjForArch.getAsObjectFile()) {
auto &Obj = **MachOOrErr;
if (filterArch(Obj)) {
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(Obj);
std::unique_ptr<DWARFContext> DICtx =
DWARFContext::create(Obj, nullptr, "", RecoverableErrorHandler);
Result &= HandleObj(Obj, *DICtx, ObjName, OS);
}
continue;
@@ -637,22 +644,20 @@ int main(int argc, char **argv) {
Objects.insert(Objects.end(), Objs.begin(), Objs.end());
}
bool Success = true;
if (Verify) {
// If we encountered errors during verify, exit with a non-zero exit status.
if (!all_of(Objects, [&](std::string Object) {
return handleFile(Object, verifyObjectFile, OutputFile.os());
}))
return 1;
for (auto Object : Objects)
Success &= handleFile(Object, verifyObjectFile, OutputFile.os());
} else if (Statistics) {
for (auto Object : Objects)
handleFile(Object, collectStatsForObjectFile, OutputFile.os());
Success &= handleFile(Object, collectStatsForObjectFile, OutputFile.os());
} else if (ShowSectionSizes) {
for (auto Object : Objects)
handleFile(Object, collectObjectSectionSizes, OutputFile.os());
Success &= handleFile(Object, collectObjectSectionSizes, OutputFile.os());
} else {
for (auto Object : Objects)
handleFile(Object, dumpObjectFile, OutputFile.os());
Success &= handleFile(Object, dumpObjectFile, OutputFile.os());
}
return EXIT_SUCCESS;
return Success ? EXIT_SUCCESS : EXIT_FAILURE;
}