Index: tools/llvm-cfi-verify/lib/FileAnalysis.h =================================================================== --- tools/llvm-cfi-verify/lib/FileAnalysis.h +++ tools/llvm-cfi-verify/lib/FileAnalysis.h @@ -171,6 +171,9 @@ class UnsupportedDisassembly : public ErrorInfo { public: static char ID; + std::string Text; + + UnsupportedDisassembly(StringRef Text); void log(raw_ostream &OS) const override; std::error_code convertToErrorCode() const override; Index: tools/llvm-cfi-verify/lib/FileAnalysis.cpp =================================================================== --- tools/llvm-cfi-verify/lib/FileAnalysis.cpp +++ tools/llvm-cfi-verify/lib/FileAnalysis.cpp @@ -54,7 +54,7 @@ Analysis.Object = dyn_cast(Analysis.Binary.getBinary()); if (!Analysis.Object) - return make_error(); + return make_error("Failed to cast object"); Analysis.ObjectTriple = Analysis.Object->makeTriple(); Analysis.Features = Analysis.Object->getFeatures(); @@ -224,31 +224,28 @@ ObjectTarget = TargetRegistry::lookupTarget(ArchName, ObjectTriple, ErrorString); if (!ObjectTarget) - return make_error(Twine("Couldn't find target \"") + - ObjectTriple.getTriple() + - "\", failed with error: " + ErrorString, - inconvertibleErrorCode()); + return make_error( + (Twine("Couldn't find target \"") + ObjectTriple.getTriple() + + "\", failed with error: " + ErrorString).str()); RegisterInfo.reset(ObjectTarget->createMCRegInfo(TripleName)); if (!RegisterInfo) - return make_error("Failed to initialise RegisterInfo.", - inconvertibleErrorCode()); + return make_error( + "Failed to initialise RegisterInfo."); AsmInfo.reset(ObjectTarget->createMCAsmInfo(*RegisterInfo, TripleName)); if (!AsmInfo) - return make_error("Failed to initialise AsmInfo.", - inconvertibleErrorCode()); + return make_error("Failed to initialise AsmInfo."); SubtargetInfo.reset(ObjectTarget->createMCSubtargetInfo( TripleName, MCPU, Features.getString())); if (!SubtargetInfo) - return make_error("Failed to initialise SubtargetInfo.", - inconvertibleErrorCode()); + return make_error( + "Failed to initialise SubtargetInfo."); MII.reset(ObjectTarget->createMCInstrInfo()); if (!MII) - return make_error("Failed to initialise MII.", - inconvertibleErrorCode()); + return make_error("Failed to initialise MII."); Context.reset(new MCContext(AsmInfo.get(), RegisterInfo.get(), &MOFI)); @@ -256,8 +253,8 @@ ObjectTarget->createMCDisassembler(*SubtargetInfo, *Context)); if (!Disassembler) - return make_error("No disassembler available for target", - inconvertibleErrorCode()); + return make_error( + "No disassembler available for target"); MIA.reset(ObjectTarget->createMCInstrAnalysis(MII.get())); @@ -341,9 +338,11 @@ } } +UnsupportedDisassembly::UnsupportedDisassembly(StringRef Text) : Text(Text) {} + char UnsupportedDisassembly::ID; void UnsupportedDisassembly::log(raw_ostream &OS) const { - OS << "Dissassembling of non-objects not currently supported.\n"; + OS << "Could not initialise disassembler: " << Text; } std::error_code UnsupportedDisassembly::convertToErrorCode() const { Index: unittests/tools/llvm-cfi-verify/CMakeLists.txt =================================================================== --- unittests/tools/llvm-cfi-verify/CMakeLists.txt +++ unittests/tools/llvm-cfi-verify/CMakeLists.txt @@ -11,9 +11,6 @@ Support ) -list(FIND LLVM_TARGETS_TO_BUILD "X86" x86_idx) -if (NOT x86_idx LESS 0) - add_llvm_unittest(CFIVerifyTests - FileAnalysis.cpp - GraphBuilder.cpp) -endif() +add_llvm_unittest(CFIVerifyTests + FileAnalysis.cpp + GraphBuilder.cpp) Index: unittests/tools/llvm-cfi-verify/FileAnalysis.cpp =================================================================== --- unittests/tools/llvm-cfi-verify/FileAnalysis.cpp +++ unittests/tools/llvm-cfi-verify/FileAnalysis.cpp @@ -63,15 +63,22 @@ class BasicFileAnalysisTest : public ::testing::Test { protected: virtual void SetUp() { - if (Analysis.initialiseDisassemblyMembers()) { - FAIL() << "Failed to initialise FileAnalysis."; + SuccessfullyInitialised = true; + if (auto Err = Analysis.initialiseDisassemblyMembers()) { + handleAllErrors(std::move(Err), [](const UnsupportedDisassembly &E) {}); + SuccessfullyInitialised = false; + outs() << "Note: CFIVerifyTests are disabled due to lack of x86 support " + "on this build.\n"; } } + bool SuccessfullyInitialised; ELFx86TestFileAnalysis Analysis; }; TEST_F(BasicFileAnalysisTest, BasicDisassemblyTraversalTest) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -180,6 +187,8 @@ } TEST_F(BasicFileAnalysisTest, PrevAndNextFromBadInst) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -201,6 +210,8 @@ } TEST_F(BasicFileAnalysisTest, CFITrapTest) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -234,6 +245,8 @@ } TEST_F(BasicFileAnalysisTest, FallThroughTest) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -272,6 +285,8 @@ } TEST_F(BasicFileAnalysisTest, DefiniteNextInstructionTest) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -360,6 +375,8 @@ } TEST_F(BasicFileAnalysisTest, ControlFlowXRefsTest) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop Index: unittests/tools/llvm-cfi-verify/GraphBuilder.cpp =================================================================== --- unittests/tools/llvm-cfi-verify/GraphBuilder.cpp +++ unittests/tools/llvm-cfi-verify/GraphBuilder.cpp @@ -126,11 +126,16 @@ class BasicGraphBuilderTest : public ::testing::Test { protected: virtual void SetUp() { - if (Analysis.initialiseDisassemblyMembers()) { - FAIL() << "Failed to initialise FileAnalysis."; + SuccessfullyInitialised = true; + if (auto Err = Analysis.initialiseDisassemblyMembers()) { + handleAllErrors(std::move(Err), [](const UnsupportedDisassembly &E) {}); + SuccessfullyInitialised = false; + outs() << "Note: CFIVerifyTests are disabled due to lack of x86 support " + "on this build.\n"; } } + bool SuccessfullyInitialised; ELFx86TestFileAnalysis Analysis; }; @@ -141,6 +146,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathFallthroughUd2) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x02, // 0: jne 4 [+2] @@ -165,6 +172,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathJumpUd2) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x02, // 0: jne 4 [+2] @@ -189,6 +198,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathDualUd2) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x03, // 0: jne 5 [+3] @@ -226,6 +237,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathSingleUd2) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x05, // 0: jne 7 [+5] @@ -262,6 +275,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphFailures) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x90, // 0: nop @@ -282,6 +297,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoXrefs) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0xeb, 0xfe, // 0: jmp 0 [-2] @@ -295,6 +312,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphConditionalInfiniteLoop) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0xfe, // 0: jne 0 [-2] @@ -315,6 +334,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphUnconditionalInfiniteLoop) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x02, // 0: jne 4 [+2] @@ -337,6 +358,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoFlowsToIndirection) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x00, // 0: jne 2 [+0] @@ -350,6 +373,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededUpwards) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x06, // 0: jne 8 [+6] @@ -377,6 +402,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededDownwards) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x02, // 0: jne 4 [+2] @@ -411,6 +438,8 @@ // paths correctly. We don't need to recalculate the flow from 0x2 -> 0x3 as it // should only need to be generated once. TEST_F(BasicGraphBuilderTest, BuildFlowGraphWithRepeatedWork) { + if (!SuccessfullyInitialised) + return; Analysis.parseSectionContents( { 0x75, 0x05, // 0: jne 7 [+5] @@ -449,6 +478,8 @@ } TEST_F(BasicGraphBuilderTest, BuildFlowGraphComplexExample) { + if (!SuccessfullyInitialised) + return; // The following code has this graph: // +----------+ +--------------+ // | 20 | <--- | 0 |