summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/tools
diff options
context:
space:
mode:
authorJoel Galenson <jgalenson@google.com>2018-07-13 15:19:33 +0000
committerJoel Galenson <jgalenson@google.com>2018-07-13 15:19:33 +0000
commit06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0 (patch)
tree28217e428500e88e450e60f95ae2051a756e9f83 /llvm/unittests/tools
parent02695fa8a7f2337bc4524dc877f618e0e2045e16 (diff)
downloadbcm5719-llvm-06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0.tar.gz
bcm5719-llvm-06e7e5798fa4efdcbc9598427fb8ccb6942d6cb0.zip
[cfi-verify] Support AArch64.
This patch adds support for AArch64 to cfi-verify. This required three changes to cfi-verify. First, it generalizes checking if an instruction is a trap by adding a new isTrap flag to TableGen (and defining it for x86 and AArch64). Second, the code that ensures that the operand register is not clobbered between the CFI check and the indirect call needs to allow a single dereference (in x86 this happens as part of the jump instruction). Third, we needed to ensure that return instructions are not counted as indirect branches. Technically, returns are indirect branches and can be covered by CFI, but LLVM's forward-edge CFI does not protect them, and x86 does not consider them, so we keep that behavior. In addition, we had to improve AArch64's code to evaluate the branch target of a MCInst to handle calls where the destination is not the first operand (which it often is not). Differential Revision: https://reviews.llvm.org/D48836 llvm-svn: 337007
Diffstat (limited to 'llvm/unittests/tools')
-rw-r--r--llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp303
1 files changed, 276 insertions, 27 deletions
diff --git a/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp b/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
index 27275d6e231..05880fcec80 100644
--- a/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
+++ b/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp
@@ -45,10 +45,10 @@ using ::testing::Field;
namespace llvm {
namespace cfi_verify {
namespace {
-class ELFx86TestFileAnalysis : public FileAnalysis {
+class ELFTestFileAnalysis : public FileAnalysis {
public:
- ELFx86TestFileAnalysis()
- : FileAnalysis(Triple("x86_64--"), SubtargetFeatures()) {}
+ ELFTestFileAnalysis(StringRef Trip)
+ : FileAnalysis(Triple(Trip), SubtargetFeatures()) {}
// Expose this method publicly for testing.
void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
@@ -62,6 +62,8 @@ public:
};
class BasicFileAnalysisTest : public ::testing::Test {
+public:
+ BasicFileAnalysisTest(StringRef Trip) : Analysis(Trip) {}
protected:
virtual void SetUp() {
IgnoreDWARFFlag = true;
@@ -70,17 +72,27 @@ protected:
handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {
SuccessfullyInitialised = false;
outs()
- << "Note: CFIVerifyTests are disabled due to lack of x86 support "
+ << "Note: CFIVerifyTests are disabled due to lack of support "
"on this build.\n";
});
}
}
bool SuccessfullyInitialised;
- ELFx86TestFileAnalysis Analysis;
+ ELFTestFileAnalysis Analysis;
+};
+
+class BasicX86FileAnalysisTest : public BasicFileAnalysisTest {
+public:
+ BasicX86FileAnalysisTest() : BasicFileAnalysisTest("x86_64--") {}
+};
+
+class BasicAArch64FileAnalysisTest : public BasicFileAnalysisTest {
+public:
+ BasicAArch64FileAnalysisTest() : BasicFileAnalysisTest("aarch64--") {}
};
-TEST_F(BasicFileAnalysisTest, BasicDisassemblyTraversalTest) {
+TEST_F(BasicX86FileAnalysisTest, BasicDisassemblyTraversalTest) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -190,7 +202,7 @@ TEST_F(BasicFileAnalysisTest, BasicDisassemblyTraversalTest) {
EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
}
-TEST_F(BasicFileAnalysisTest, PrevAndNextFromBadInst) {
+TEST_F(BasicX86FileAnalysisTest, PrevAndNextFromBadInst) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -213,7 +225,7 @@ TEST_F(BasicFileAnalysisTest, PrevAndNextFromBadInst) {
EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);
}
-TEST_F(BasicFileAnalysisTest, CFITrapTest) {
+TEST_F(BasicX86FileAnalysisTest, CFITrapTest) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -248,7 +260,7 @@ TEST_F(BasicFileAnalysisTest, CFITrapTest) {
Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 28)));
}
-TEST_F(BasicFileAnalysisTest, FallThroughTest) {
+TEST_F(BasicX86FileAnalysisTest, FallThroughTest) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -288,7 +300,7 @@ TEST_F(BasicFileAnalysisTest, FallThroughTest) {
Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 19)));
}
-TEST_F(BasicFileAnalysisTest, DefiniteNextInstructionTest) {
+TEST_F(BasicX86FileAnalysisTest, DefiniteNextInstructionTest) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -378,7 +390,7 @@ TEST_F(BasicFileAnalysisTest, DefiniteNextInstructionTest) {
EXPECT_EQ(0xDEADBEEF + 4, Next->VMAddress);
}
-TEST_F(BasicFileAnalysisTest, ControlFlowXRefsTest) {
+TEST_F(BasicX86FileAnalysisTest, ControlFlowXRefsTest) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -483,7 +495,7 @@ TEST_F(BasicFileAnalysisTest, ControlFlowXRefsTest) {
EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionInvalidTargets) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionInvalidTargets) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -507,7 +519,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionInvalidTargets) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -522,7 +534,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionBasicJumpToUd2) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicJumpToUd2) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -537,7 +549,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionBasicJumpToUd2) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathUd2) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathUd2) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -555,7 +567,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathUd2) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathSingleUd2) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathSingleUd2) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -572,7 +584,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathSingleUd2) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -597,7 +609,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch;
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -621,7 +633,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
SearchLengthForUndef = PrevSearchLengthForUndef;
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionGoodAndBadPaths) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionGoodAndBadPaths) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -637,7 +649,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionGoodAndBadPaths) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -653,7 +665,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionComplexExample) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionComplexExample) {
if (!SuccessfullyInitialised)
return;
// See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this
@@ -683,7 +695,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionComplexExample) {
SearchLengthForUndef = PrevSearchLengthForUndef;
}
-TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTest) {
+TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTest) {
Analysis.parseSectionContents(
{
0x77, 0x0d, // 0x688118: ja 0x688127 [+12]
@@ -702,7 +714,7 @@ TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTest) {
SearchLengthForUndef = PrevSearchLengthForUndef;
}
-TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTestFarAway) {
+TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTestFarAway) {
Analysis.parseSectionContents(
{
0x74, 0x73, // 0x7759eb: je 0x775a60
@@ -741,7 +753,7 @@ TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTestFarAway) {
SearchLengthForUndef = PrevSearchLengthForUndef;
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -757,7 +769,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -773,7 +785,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -789,7 +801,7 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
Analysis.validateCFIProtection(Result));
}
-TEST_F(BasicFileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
+TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
if (!SuccessfullyInitialised)
return;
Analysis.parseSectionContents(
@@ -807,6 +819,243 @@ TEST_F(BasicFileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
Analysis.validateCFIProtection(Result));
}
+TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicUnprotected) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x00, 0x01, 0x3f, 0xd6, // 0: blr x8
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicProtected) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x00, 0x01, 0x3f, 0xd6, // 8: blr x8
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberBasic) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1
+ 0x00, 0x01, 0x3f, 0xd6, // 12: blr x8
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberOneLoad) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddGood) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x21, 0x04, 0x00, 0x91, // 8: add x1, x1, #1
+ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
+ 0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad2) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x29, 0x04, 0x00, 0x91, // 16: add x9, x1, #1
+ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberTwoLoads) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
+ 0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedSecondLoad) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]
+ 0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedLoads) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x49, 0x00, 0x00, 0x54, // 0: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1
+ 0x22, 0x09, 0x40, 0xf9, // 8: ldr x2, [x9,#16]
+ 0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 16: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 16);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64GoodAndBadPaths) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0x03, 0x00, 0x00, 0x14, // 0: b 12
+ 0x49, 0x00, 0x00, 0x54, // 4: b.ls 8
+ 0x20, 0x00, 0x20, 0xd4, // 8: brk #0x1
+ 0x20, 0x00, 0x1f, 0xd6, // 12: br x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 12);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPaths) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0xc9, 0x00, 0x00, 0x54, // 0: b.ls 24
+ 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
+ 0x03, 0x00, 0x00, 0x14, // 8: b 12
+ 0x69, 0x00, 0x00, 0x54, // 12: b.ls 12
+ 0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 20: br x1
+ 0x20, 0x00, 0x20, 0xd4, // 24: brk #0x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 20);
+ EXPECT_EQ(CFIProtectionStatus::PROTECTED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad1) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0xe9, 0x00, 0x00, 0x54, // 0: b.ls 28
+ 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
+ 0x21, 0x08, 0x40, 0xf9, // 8: ldr x1, [x1,#16]
+ 0x03, 0x00, 0x00, 0x14, // 12: b 12
+ 0x69, 0x00, 0x00, 0x54, // 16: b.ls 12
+ 0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
+ 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
+TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad2) {
+ if (!SuccessfullyInitialised)
+ return;
+ Analysis.parseSectionContents(
+ {
+ 0xe9, 0x00, 0x00, 0x54, // 0: b.ls 28
+ 0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]
+ 0x03, 0x00, 0x00, 0x14, // 8: b 12
+ 0x89, 0x00, 0x00, 0x54, // 12: b.ls 16
+ 0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]
+ 0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]
+ 0x20, 0x00, 0x1f, 0xd6, // 24: br x1
+ 0x20, 0x00, 0x20, 0xd4, // 28: brk #0x1
+ },
+ 0xDEADBEEF);
+ GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 24);
+ EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
+ Analysis.validateCFIProtection(Result));
+}
+
} // anonymous namespace
} // end namespace cfi_verify
} // end namespace llvm
OpenPOWER on IntegriCloud