Skip to content

Commit

Permalink
[dsymutil] Add -verify option to run DWARF verifier after linking.
Browse files Browse the repository at this point in the history
This patch adds support for running the DWARF verifier on the linked
debug info files. If the -verify options is specified and verification
fails, dsymutil exists with abort with non-zero exit code. This behavior
is *not* enabled by default.

Differential revision: https://reviews.llvm.org/D40777

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@320033 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
JDevlieghere committed Dec 7, 2017
1 parent 9fb4beb commit 5eb1a17
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 0 deletions.
8 changes: 8 additions & 0 deletions test/tools/dsymutil/X86/verify.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Multiple inputs in flat mode
RUN: not llvm-dsymutil -verify -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefix=QUIET
RUN: not llvm-dsymutil -verify -verbose -oso-prepend-path=%p/.. %p/../Inputs/basic.macho.x86_64 %p/../Inputs/basic-archive.macho.x86_64 %p/../Inputs/basic-lto.macho.x86_64 %p/../Inputs/basic-lto-dw4.macho.x86_64 -o %t 2>&1 | FileCheck %s --check-prefix=QUIET --check-prefix=VERBOSE

VERBOSE: Verifying DWARF for architecture: x86_64
VERBOSE: error: DIE has invalid DW_AT_location encoding:
VERBOSE: error: DIE has invalid DW_AT_location encoding:
QUIET: error: verification failed
1 change: 1 addition & 0 deletions test/tools/dsymutil/cmdline.test
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ HELP: -o=<filename>
HELP: -oso-prepend-path=<path>
HELP: -symtab
HELP: -verbose
HELP: -verify
HELP: -y
HELP-NOT: -reverse-iterate

Expand Down
41 changes: 41 additions & 0 deletions tools/dsymutil/dsymutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/Object/Binary.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
Expand All @@ -40,6 +44,7 @@
using namespace llvm;
using namespace llvm::cl;
using namespace llvm::dsymutil;
using namespace object;

static OptionCategory DsymCategory("Specific Options");
static opt<bool> Help("h", desc("Alias for -help"), Hidden);
Expand Down Expand Up @@ -114,6 +119,9 @@ static opt<bool> InputIsYAMLDebugMap(
"y", desc("Treat the input file is a YAML debug map rather than a binary."),
init(false), cat(DsymCategory));

static opt<bool> Verify("verify", desc("Verify the linked DWARF debug info."),
cat(DsymCategory));

static bool createPlistFile(llvm::StringRef Bin, llvm::StringRef BundleRoot) {
if (NoOutput)
return true;
Expand Down Expand Up @@ -184,6 +192,34 @@ static bool createBundleDir(llvm::StringRef BundleBase) {
return true;
}

static bool verify(llvm::StringRef OutputFile, llvm::StringRef Arch) {
if (OutputFile == "-") {
llvm::errs() << "warning: verification skipped for " << Arch
<< "because writing to stdout.\n";
return true;
}

Expected<OwningBinary<Binary>> BinOrErr = createBinary(OutputFile);
if (!BinOrErr) {
errs() << OutputFile << ": " << toString(BinOrErr.takeError());
return false;
}

Binary &Binary = *BinOrErr.get().getBinary();
if (auto *Obj = dyn_cast<MachOObjectFile>(&Binary)) {
raw_ostream &os = Verbose ? errs() : nulls();
os << "Verifying DWARF for architecture: " << Arch << "\n";
std::unique_ptr<DWARFContext> DICtx = DWARFContext::create(*Obj);
DIDumpOptions DumpOpts;
bool success = DICtx->verify(os, DumpOpts.noImplicitRecursion());
if (!success)
errs() << "error: verification failed for " << Arch << '\n';
return success;
}

return false;
}

static std::string getOutputFileName(llvm::StringRef InputFile) {
if (FlatOut) {
// If a flat dSYM has been requested, things are pretty simple.
Expand Down Expand Up @@ -361,6 +397,7 @@ int main(int argc, char **argv) {
std::atomic_char AllOK(1);
auto LinkLambda = [&]() {
AllOK.fetch_and(linkDwarf(*OS, *Map, Options));
OS->flush();
};

// FIXME: The DwarfLinker can have some very deep recursion that can max
Expand All @@ -376,6 +413,10 @@ int main(int argc, char **argv) {
if (!AllOK)
return 1;

if (Verify && !NoOutput &&
!verify(OutputFile, Map->getTriple().getArchName()))
return 1;

if (NeedsTempFiles)
TempFiles.emplace_back(Map->getTriple().getArchName().str(),
OutputFile);
Expand Down

0 comments on commit 5eb1a17

Please sign in to comment.