forked from OSchip/llvm-project
[dsymutil] Add -verify option to run DWARF verifier after linking.
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 llvm-svn: 320033
This commit is contained in:
parent
e8a3475b89
commit
e385d00960
|
@ -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
|
|
@ -14,6 +14,7 @@ HELP: -o=<filename>
|
|||
HELP: -oso-prepend-path=<path>
|
||||
HELP: -symtab
|
||||
HELP: -verbose
|
||||
HELP: -verify
|
||||
HELP: -y
|
||||
HELP-NOT: -reverse-iterate
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue