annotate unittests/tools/llvm-cfi-verify/GraphBuilder.cpp @ 131:f476a9ba4795

http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt
author mir3636
date Fri, 16 Feb 2018 21:02:11 +0900
parents 803732b1fca8
children 3a76565eade5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===- llvm/unittests/llvm-cfi-verify/GraphBuilder.cpp --------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
3 // The LLVM Compiler Infrastructure
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
4 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
5 // This file is distributed under the University of Illinois Open Source
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 // License. See LICENSE.TXT for details.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //===----------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 #include "../tools/llvm-cfi-verify/lib/GraphBuilder.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 #include "../tools/llvm-cfi-verify/lib/FileAnalysis.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12 #include "gmock/gmock.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 #include "gtest/gtest.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 #include "llvm/BinaryFormat/ELF.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16 #include "llvm/MC/MCAsmInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17 #include "llvm/MC/MCContext.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
19 #include "llvm/MC/MCInst.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 #include "llvm/MC/MCInstPrinter.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21 #include "llvm/MC/MCInstrAnalysis.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 #include "llvm/MC/MCInstrDesc.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23 #include "llvm/MC/MCInstrInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 #include "llvm/MC/MCObjectFileInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25 #include "llvm/MC/MCRegisterInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26 #include "llvm/MC/MCSubtargetInfo.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27 #include "llvm/Object/Binary.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28 #include "llvm/Object/COFF.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29 #include "llvm/Object/ELFObjectFile.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30 #include "llvm/Object/ObjectFile.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31 #include "llvm/Support/Casting.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 #include "llvm/Support/CommandLine.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33 #include "llvm/Support/Error.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 #include "llvm/Support/MemoryBuffer.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35 #include "llvm/Support/TargetRegistry.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36 #include "llvm/Support/TargetSelect.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37 #include "llvm/Support/raw_ostream.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39 #include <cstdlib>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40 #include <sstream>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42 using Instr = ::llvm::cfi_verify::FileAnalysis::Instr;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43 using ::testing::AllOf;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44 using ::testing::Each;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45 using ::testing::ElementsAre;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46 using ::testing::Eq;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47 using ::testing::Field;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48 using ::testing::IsEmpty;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49 using ::testing::Matches;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 using ::testing::Pair;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 using ::testing::PrintToString;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 using ::testing::Property;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53 using ::testing::SizeIs;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54 using ::testing::UnorderedElementsAre;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55 using ::testing::Value;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57 namespace llvm {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58 namespace cfi_verify {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59 // Printing helpers for gtest.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60 std::string HexStringifyContainer(const std::vector<uint64_t> &C) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61 std::stringstream Stream;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62 if (C.empty()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63 return "{ }";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66 Stream << "{ ";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 const auto &LastElemIt = std::end(C) - 1;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
68
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
69 for (auto It = std::begin(C); It != LastElemIt; ++It) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70 Stream << "0x" << std::hex << *It << ", ";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72 Stream << "0x" << std::hex << *LastElemIt << " }";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 return Stream.str();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
76 void PrintTo(const ConditionalBranchNode &BranchNode, ::std::ostream *os) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
77 *os << "ConditionalBranchNode<Address: 0x" << std::hex << BranchNode.Address
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 << ", Target: 0x" << BranchNode.Target << ", Fallthrough: 0x"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79 << BranchNode.Fallthrough
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 << ", CFIProtection: " << BranchNode.CFIProtection << ">";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
82
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
83 void PrintTo(const GraphResult &Result, ::std::ostream *os) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84 *os << "Result BaseAddress: 0x" << std::hex << Result.BaseAddress << "\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86 if (Result.ConditionalBranchNodes.empty())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 *os << " (No conditional branch nodes)\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89 for (const auto &Node : Result.ConditionalBranchNodes) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 *os << " ";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91 PrintTo(Node, os);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 *os << "\n Fallthrough Path: " << std::hex
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 << HexStringifyContainer(Result.flattenAddress(Node.Fallthrough))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94 << "\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 *os << " Target Path: " << std::hex
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 << HexStringifyContainer(Result.flattenAddress(Node.Target)) << "\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99 if (Result.OrphanedNodes.empty())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100 *os << " (No orphaned nodes)";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 for (const auto &Orphan : Result.OrphanedNodes) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103 *os << " Orphan (0x" << std::hex << Orphan
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 << ") Path: " << HexStringifyContainer(Result.flattenAddress(Orphan))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105 << "\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109 namespace {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 class ELFx86TestFileAnalysis : public FileAnalysis {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 public:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112 ELFx86TestFileAnalysis()
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113 : FileAnalysis(Triple("x86_64--"), SubtargetFeatures()) {}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 // Expose this method publicly for testing.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
116 void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
117 uint64_t SectionAddress) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118 FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
120
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121 Error initialiseDisassemblyMembers() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 return FileAnalysis::initialiseDisassemblyMembers();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
123 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
124 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
125
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
126 class BasicGraphBuilderTest : public ::testing::Test {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
127 protected:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
128 virtual void SetUp() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
129 SuccessfullyInitialised = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130 if (auto Err = Analysis.initialiseDisassemblyMembers()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
132 SuccessfullyInitialised = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133 outs()
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 << "Note: CFIVerifyTests are disabled due to lack of x86 support "
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135 "on this build.\n";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136 });
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 bool SuccessfullyInitialised;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141 ELFx86TestFileAnalysis Analysis;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 MATCHER_P2(HasPath, Result, Matcher, "has path " + PrintToString(Matcher)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 const auto &Path = Result.flattenAddress(arg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146 *result_listener << "the path is " << PrintToString(Path);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147 return Matches(Matcher)(Path);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
148 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
149
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
150 TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathFallthroughUd2) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
151 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
153 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
154 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
155 0x75, 0x02, // 0: jne 4 [+2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
156 0x0f, 0x0b, // 2: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
157 0xff, 0x10, // 4: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
158 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
159 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
160 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
161
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
162 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
163 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
164 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
165 Each(Field(&ConditionalBranchNode::CFIProtection, Eq(true))));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
166 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
167 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
168 Contains(AllOf(Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
169 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
170 HasPath(Result, ElementsAre(0xDEADBEEF + 4))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
171 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
172 HasPath(Result, ElementsAre(0xDEADBEEF + 2))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
173 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
174 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
175
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
176 TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestSinglePathJumpUd2) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
177 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
178 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
179 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
180 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
181 0x75, 0x02, // 0: jne 4 [+2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
182 0xff, 0x10, // 2: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
183 0x0f, 0x0b, // 4: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
184 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
185 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
186 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
187
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
188 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
189 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
190 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
191 Each(Field(&ConditionalBranchNode::CFIProtection, Eq(true))));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
192 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
193 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
194 Contains(AllOf(Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
195 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
196 HasPath(Result, ElementsAre(0xDEADBEEF + 4))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
197 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
198 HasPath(Result, ElementsAre(0xDEADBEEF + 2))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
199 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
200 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
201
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
202 TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathDualUd2) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
203 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
204 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
205 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
206 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
207 0x75, 0x03, // 0: jne 5 [+3]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
208 0x90, // 2: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
209 0xff, 0x10, // 3: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
210 0x0f, 0x0b, // 5: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
211 0x75, 0xf9, // 7: jne 2 [-7]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
212 0x0f, 0x0b, // 9: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
213 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
214 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
215 const auto Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
216
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
217 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
218 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
219 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
220 Each(Field(&ConditionalBranchNode::CFIProtection, Eq(true))));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
221 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
222 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
223 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
224 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
225 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
226 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
227 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
228 HasPath(Result, ElementsAre(0xDEADBEEF + 5))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
229 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
230 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
231 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
232 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
233 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF + 7)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
234 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
235 HasPath(Result, ElementsAre(0xDEADBEEF + 9))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
236 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
237 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
238 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
239 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
240
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
241 TEST_F(BasicGraphBuilderTest, BuildFlowGraphTestDualPathSingleUd2) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
242 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
243 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
244 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
245 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
246 0x75, 0x05, // 0: jne 7 [+5]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
247 0x90, // 2: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
248 0xff, 0x10, // 3: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
249 0x75, 0xfb, // 5: jne 2 [-5]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
250 0x0f, 0x0b, // 7: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
251 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
252 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
253 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
254
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
255 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
256 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
257 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
258 Each(Field(&ConditionalBranchNode::CFIProtection, Eq(true))));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
259 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
260 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
261 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
262 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
263 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
264 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
265 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
266 HasPath(Result, ElementsAre(0xDEADBEEF + 7))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
267 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
268 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
269 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
270 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
271 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF + 5)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
272 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
273 HasPath(Result, ElementsAre(0xDEADBEEF + 7))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
274 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
275 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
276 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
277 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
278
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
279 TEST_F(BasicGraphBuilderTest, BuildFlowGraphFailures) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
280 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
281 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
282 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
283 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
284 0x90, // 0: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
285 0x75, 0xfe, // 1: jne 1 [-2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
286 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
287 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
288 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
289 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
290 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
291
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
292 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
293 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
294 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
295
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
296 Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADC0DE);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
297 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
298 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
299 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
300
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
301 TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoXrefs) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
302 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
303 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
304 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
305 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
306 0xeb, 0xfe, // 0: jmp 0 [-2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
307 0xff, 0x10, // 2: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
308 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
309 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
310 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
311 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
312 EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 2));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
313 EXPECT_THAT(Result.IntermediateNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
314 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
315
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
316 TEST_F(BasicGraphBuilderTest, BuildFlowGraphConditionalInfiniteLoop) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
317 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
318 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
319 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
320 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
321 0x75, 0xfe, // 0: jne 0 [-2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
322 0xff, 0x10, // 2: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
323 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
324 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
325 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
326 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
327 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
328 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
329 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
330 Each(AllOf(Field(&ConditionalBranchNode::CFIProtection, Eq(false)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
331 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
332 HasPath(Result, ElementsAre(0xDEADBEEF))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
333 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
334 HasPath(Result, ElementsAre(0xDEADBEEF + 2))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
335 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
336 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
337
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
338 TEST_F(BasicGraphBuilderTest, BuildFlowGraphUnconditionalInfiniteLoop) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
339 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
340 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
341 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
342 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
343 0x75, 0x02, // 0: jne 4 [+2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
344 0xeb, 0xfc, // 2: jmp 0 [-4]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
345 0xff, 0x10, // 4: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
346 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
347 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
348 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
349 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
350 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
351 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
352 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
353 Contains(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
354 AllOf(Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
355 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
356 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
357 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
358 HasPath(Result, ElementsAre(0xDEADBEEF + 4))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
359 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
360 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
361
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
362 TEST_F(BasicGraphBuilderTest, BuildFlowGraphNoFlowsToIndirection) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
363 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
364 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
365 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
366 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
367 0x75, 0x00, // 0: jne 2 [+0]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
368 0xeb, 0xfc, // 2: jmp 0 [-4]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
369 0xff, 0x10, // 4: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
370 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
371 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
372 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
373 EXPECT_THAT(Result.OrphanedNodes, ElementsAre(0xDEADBEEF + 4));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
374 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
375 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
376
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
377 TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededUpwards) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
378 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
379 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
380 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
381 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
382 0x75, 0x06, // 0: jne 8 [+6]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
383 0x90, // 2: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
384 0x90, // 3: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
385 0x90, // 4: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
386 0x90, // 5: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
387 0xff, 0x10, // 6: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
388 0x0f, 0x0b, // 8: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
389 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
390 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
391 uint64_t PrevSearchLengthForConditionalBranch =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
392 SearchLengthForConditionalBranch;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
393 SearchLengthForConditionalBranch = 2;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
394
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
395 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
396 EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
397 EXPECT_THAT(Result.OrphanedNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
398 Each(HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
399 0xDEADBEEF + 6))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
400 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
401 EXPECT_THAT(Result.ConditionalBranchNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
402
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
403 SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
404 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
405
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
406 TEST_F(BasicGraphBuilderTest, BuildFlowGraphLengthExceededDownwards) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
407 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
408 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
409 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
410 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
411 0x75, 0x02, // 0: jne 4 [+2]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
412 0xff, 0x10, // 2: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
413 0x90, // 4: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
414 0x90, // 5: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
415 0x90, // 6: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
416 0x90, // 7: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
417 0x0f, 0x0b, // 8: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
418 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
419 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
420 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
421 SearchLengthForUndef = 2;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
422
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
423 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
424 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
425 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
426 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
427 Each(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
428 Field(&ConditionalBranchNode::CFIProtection, Eq(false)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
429 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
430 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
431 HasPath(Result, ElementsAre(0xDEADBEEF + 4, 0xDEADBEEF + 5))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
432 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
433 HasPath(Result, ElementsAre(0xDEADBEEF + 2))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
434 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
435
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
436 SearchLengthForUndef = PrevSearchLengthForUndef;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
437 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
438
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
439 // This test ensures when avoiding doing repeated work we still generate the
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
440 // paths correctly. We don't need to recalculate the flow from 0x2 -> 0x3 as it
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
441 // should only need to be generated once.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
442 TEST_F(BasicGraphBuilderTest, BuildFlowGraphWithRepeatedWork) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
443 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
444 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
445 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
446 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
447 0x75, 0x05, // 0: jne 7 [+5]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
448 0x90, // 2: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
449 0xff, 0x10, // 3: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
450 0x75, 0xfb, // 5: jne 2 [-5]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
451 0x0f, 0x0b, // 7: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
452 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
453 0xDEADBEEF);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
454 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
455 EXPECT_THAT(Result.OrphanedNodes, IsEmpty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
456 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(2));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
457 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
458 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
459 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
460 Field(&ConditionalBranchNode::CFIProtection, Eq(true)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
461 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
462 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
463 HasPath(Result, ElementsAre(0xDEADBEEF + 7))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
464 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
465 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
466 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
467 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
468 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
469 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
470 Field(&ConditionalBranchNode::CFIProtection, Eq(true)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
471 Field(&ConditionalBranchNode::Address, Eq(0xDEADBEEF + 5)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
472 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
473 HasPath(Result, ElementsAre(0xDEADBEEF + 2, 0xDEADBEEF + 3))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
474 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
475 HasPath(Result, ElementsAre(0xDEADBEEF + 7))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
476 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
477 EXPECT_THAT(Result.IntermediateNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
478 EXPECT_THAT(Result.IntermediateNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
479 UnorderedElementsAre(Pair(0xDEADBEEF + 2, 0xDEADBEEF + 3)));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
480 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
481
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
482 TEST_F(BasicGraphBuilderTest, BuildFlowGraphComplexExample) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
483 if (!SuccessfullyInitialised)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
484 return;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
485 // The following code has this graph:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
486 // +----------+ +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
487 // | 20 | <--- | 0 |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
488 // +----------+ +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
489 // | |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
490 // v v
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
491 // +----------+ +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
492 // | 21 | | 2 |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
493 // +----------+ +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
494 // | |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
495 // v v
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
496 // +----------+ +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
497 // | 22 (ud2) | +-> | 7 |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
498 // +----------+ | +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
499 // ^ | |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
500 // | | v
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
501 // +----------+ | +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
502 // | 4 | | | 8 |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
503 // +----------+ | +--------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
504 // | | |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
505 // v | v
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
506 // +----------+ | +--------------+ +------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
507 // | 6 | -+ | 9 (indirect) | <- | 13 |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
508 // +----------+ +--------------+ +------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
509 // ^ |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
510 // | v
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
511 // +--------------+ +------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
512 // | 11 | | 15 (error) |
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
513 // +--------------+ +------------+
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
514 // Or, in image format: https://i.imgur.com/aX5fCoi.png
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
515
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
516 Analysis.parseSectionContents(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
517 {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
518 0x75, 0x12, // 0: jne 20 [+18]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
519 0xeb, 0x03, // 2: jmp 7 [+3]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
520 0x75, 0x10, // 4: jne 22 [+16]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
521 0x90, // 6: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
522 0x90, // 7: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
523 0x90, // 8: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
524 0xff, 0x10, // 9: callq *(%rax)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
525 0xeb, 0xfc, // 11: jmp 9 [-4]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
526 0x75, 0xfa, // 13: jne 9 [-6]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
527 0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
528 0x90, // 20: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
529 0x90, // 21: nop
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
530 0x0f, 0x0b, // 22: ud2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
531 },
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
532 0x1000);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
533 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
534 SearchLengthForUndef = 5;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
535
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
536 GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x1000 + 9);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
537
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
538 EXPECT_THAT(Result.OrphanedNodes, SizeIs(1));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
539 EXPECT_THAT(Result.ConditionalBranchNodes, SizeIs(3));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
540
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
541 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
542 Result.OrphanedNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
543 Each(AllOf(Eq(0x1000u + 11),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
544 HasPath(Result, ElementsAre(0x1000 + 11, 0x1000 + 9)))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
545 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
546
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
547 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
548 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
549 Field(&ConditionalBranchNode::CFIProtection, Eq(true)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
550 Field(&ConditionalBranchNode::Address, Eq(0x1000u)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
551 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
552 HasPath(Result, ElementsAre(0x1000 + 20, 0x1000 + 21,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
553 0x1000 + 22))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
554 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
555 HasPath(Result, ElementsAre(0x1000 + 2, 0x1000 + 7,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
556 0x1000 + 8, 0x1000 + 9))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
557 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
558
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
559 EXPECT_THAT(Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
560 Contains(AllOf(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
561 Field(&ConditionalBranchNode::CFIProtection, Eq(true)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
562 Field(&ConditionalBranchNode::Address, Eq(0x1000u + 4)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
563 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
564 HasPath(Result, ElementsAre(0x1000 + 22))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
565 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
566 HasPath(Result, ElementsAre(0x1000 + 6, 0x1000 + 7,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
567 0x1000 + 8, 0x1000 + 9))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
568 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
569
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
570 EXPECT_THAT(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
571 Result.ConditionalBranchNodes,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
572 Contains(AllOf(Field(&ConditionalBranchNode::CFIProtection, Eq(false)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
573 Field(&ConditionalBranchNode::Address, Eq(0x1000u + 13)),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
574 Field(&ConditionalBranchNode::Target,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
575 HasPath(Result, ElementsAre(0x1000 + 9))),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
576 Field(&ConditionalBranchNode::Fallthrough,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
577 HasPath(Result, ElementsAre(0x1000 + 15))))))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
578 << PrintToString(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
579
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
580 SearchLengthForUndef = PrevSearchLengthForUndef;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
581 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
582
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
583 } // anonymous namespace
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
584 } // end namespace cfi_verify
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
585 } // end namespace llvm