xref: /llvm-project/llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp (revision 2e7be2a65af2ffdd7ce378b54d16b9e3859ff3b5)
1 //===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "../tools/llvm-cfi-verify/lib/FileAnalysis.h"
11 #include "../tools/llvm-cfi-verify/lib/GraphBuilder.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14 
15 #include "llvm/BinaryFormat/ELF.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstPrinter.h"
21 #include "llvm/MC/MCInstrAnalysis.h"
22 #include "llvm/MC/MCInstrDesc.h"
23 #include "llvm/MC/MCInstrInfo.h"
24 #include "llvm/MC/MCObjectFileInfo.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/Object/Binary.h"
28 #include "llvm/Object/COFF.h"
29 #include "llvm/Object/ELFObjectFile.h"
30 #include "llvm/Object/ObjectFile.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/Error.h"
34 #include "llvm/Support/MemoryBuffer.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include "llvm/Support/TargetSelect.h"
37 #include "llvm/Support/raw_ostream.h"
38 
39 #include <cstdlib>
40 
41 using Instr = ::llvm::cfi_verify::FileAnalysis::Instr;
42 using ::testing::Eq;
43 using ::testing::Field;
44 
45 namespace llvm {
46 namespace cfi_verify {
47 namespace {
48 class ELFx86TestFileAnalysis : public FileAnalysis {
49 public:
50   ELFx86TestFileAnalysis()
51       : FileAnalysis(Triple("x86_64--"), SubtargetFeatures()) {}
52 
53   // Expose this method publicly for testing.
54   void parseSectionContents(ArrayRef<uint8_t> SectionBytes,
55                             uint64_t SectionAddress) {
56     FileAnalysis::parseSectionContents(SectionBytes, SectionAddress);
57   }
58 
59   Error initialiseDisassemblyMembers() {
60     return FileAnalysis::initialiseDisassemblyMembers();
61   }
62 };
63 
64 class BasicFileAnalysisTest : public ::testing::Test {
65 protected:
66   virtual void SetUp() {
67     IgnoreDWARFFlag = true;
68     SuccessfullyInitialised = true;
69     if (auto Err = Analysis.initialiseDisassemblyMembers()) {
70       handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {
71         SuccessfullyInitialised = false;
72         outs()
73             << "Note: CFIVerifyTests are disabled due to lack of x86 support "
74                "on this build.\n";
75       });
76     }
77   }
78 
79   bool SuccessfullyInitialised;
80   ELFx86TestFileAnalysis Analysis;
81 };
82 
83 TEST_F(BasicFileAnalysisTest, BasicDisassemblyTraversalTest) {
84   if (!SuccessfullyInitialised)
85     return;
86   Analysis.parseSectionContents(
87       {
88           0x90,                   // 0: nop
89           0xb0, 0x00,             // 1: mov $0x0, %al
90           0x48, 0x89, 0xe5,       // 3: mov %rsp, %rbp
91           0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp
92           0x48, 0xbe, 0xc4, 0x07, 0x40,
93           0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi
94           0x2f,                         // 20: (bad)
95           0x41, 0x0e,                   // 21: rex.B (bad)
96           0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
97       },
98       0xDEADBEEF);
99 
100   EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));
101   EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));
102 
103   // 0xDEADBEEF: nop
104   const auto *InstrMeta = Analysis.getInstruction(0xDEADBEEF);
105   EXPECT_NE(nullptr, InstrMeta);
106   EXPECT_EQ(0xDEADBEEF, InstrMeta->VMAddress);
107   EXPECT_EQ(1u, InstrMeta->InstructionSize);
108   EXPECT_TRUE(InstrMeta->Valid);
109 
110   const auto *NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
111   EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
112   const auto *PrevInstrMeta = InstrMeta;
113 
114   // 0xDEADBEEF + 1: mov $0x0, %al
115   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 1);
116   EXPECT_NE(nullptr, InstrMeta);
117   EXPECT_EQ(NextInstrMeta, InstrMeta);
118   EXPECT_EQ(0xDEADBEEF + 1, InstrMeta->VMAddress);
119   EXPECT_EQ(2u, InstrMeta->InstructionSize);
120   EXPECT_TRUE(InstrMeta->Valid);
121 
122   NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
123   EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
124   PrevInstrMeta = InstrMeta;
125 
126   // 0xDEADBEEF + 3: mov %rsp, %rbp
127   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 3);
128   EXPECT_NE(nullptr, InstrMeta);
129   EXPECT_EQ(NextInstrMeta, InstrMeta);
130   EXPECT_EQ(0xDEADBEEF + 3, InstrMeta->VMAddress);
131   EXPECT_EQ(3u, InstrMeta->InstructionSize);
132   EXPECT_TRUE(InstrMeta->Valid);
133 
134   NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
135   EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
136   PrevInstrMeta = InstrMeta;
137 
138   // 0xDEADBEEF + 6: sub $0x18, %rsp
139   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 6);
140   EXPECT_NE(nullptr, InstrMeta);
141   EXPECT_EQ(NextInstrMeta, InstrMeta);
142   EXPECT_EQ(0xDEADBEEF + 6, InstrMeta->VMAddress);
143   EXPECT_EQ(4u, InstrMeta->InstructionSize);
144   EXPECT_TRUE(InstrMeta->Valid);
145 
146   NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);
147   EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
148   PrevInstrMeta = InstrMeta;
149 
150   // 0xDEADBEEF + 10: movabs $0x4007c4, %rsi
151   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 10);
152   EXPECT_NE(nullptr, InstrMeta);
153   EXPECT_EQ(NextInstrMeta, InstrMeta);
154   EXPECT_EQ(0xDEADBEEF + 10, InstrMeta->VMAddress);
155   EXPECT_EQ(10u, InstrMeta->InstructionSize);
156   EXPECT_TRUE(InstrMeta->Valid);
157 
158   EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
159   EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
160   PrevInstrMeta = InstrMeta;
161 
162   // 0xDEADBEEF + 20: (bad)
163   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 20);
164   EXPECT_NE(nullptr, InstrMeta);
165   EXPECT_EQ(0xDEADBEEF + 20, InstrMeta->VMAddress);
166   EXPECT_EQ(1u, InstrMeta->InstructionSize);
167   EXPECT_FALSE(InstrMeta->Valid);
168 
169   EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
170   EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));
171 
172   // 0xDEADBEEF + 21: rex.B (bad)
173   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 21);
174   EXPECT_NE(nullptr, InstrMeta);
175   EXPECT_EQ(0xDEADBEEF + 21, InstrMeta->VMAddress);
176   EXPECT_EQ(2u, InstrMeta->InstructionSize);
177   EXPECT_FALSE(InstrMeta->Valid);
178 
179   EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
180   EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
181 
182   // 0xDEADBEEF + 6: (bad) {%k1}
183   InstrMeta = Analysis.getInstruction(0xDEADBEEF + 23);
184   EXPECT_NE(nullptr, InstrMeta);
185   EXPECT_EQ(0xDEADBEEF + 23, InstrMeta->VMAddress);
186   EXPECT_EQ(5u, InstrMeta->InstructionSize);
187   EXPECT_FALSE(InstrMeta->Valid);
188 
189   EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));
190   EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));
191 }
192 
193 TEST_F(BasicFileAnalysisTest, PrevAndNextFromBadInst) {
194   if (!SuccessfullyInitialised)
195     return;
196   Analysis.parseSectionContents(
197       {
198           0x90, // 0: nop
199           0x2f, // 1: (bad)
200           0x90  // 2: nop
201       },
202       0xDEADBEEF);
203   const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);
204   const auto *GoodInstrMeta =
205       Analysis.getPrevInstructionSequential(BadInstrMeta);
206   EXPECT_NE(nullptr, GoodInstrMeta);
207   EXPECT_EQ(0xDEADBEEF, GoodInstrMeta->VMAddress);
208   EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);
209 
210   GoodInstrMeta = Analysis.getNextInstructionSequential(BadInstrMeta);
211   EXPECT_NE(nullptr, GoodInstrMeta);
212   EXPECT_EQ(0xDEADBEEF + 2, GoodInstrMeta->VMAddress);
213   EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);
214 }
215 
216 TEST_F(BasicFileAnalysisTest, CFITrapTest) {
217   if (!SuccessfullyInitialised)
218     return;
219   Analysis.parseSectionContents(
220       {
221           0x90,                   // 0: nop
222           0xb0, 0x00,             // 1: mov $0x0, %al
223           0x48, 0x89, 0xe5,       // 3: mov %rsp, %rbp
224           0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp
225           0x48, 0xbe, 0xc4, 0x07, 0x40,
226           0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi
227           0x2f,                         // 20: (bad)
228           0x41, 0x0e,                   // 21: rex.B (bad)
229           0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}
230           0x0f, 0x0b                    // 28: ud2
231       },
232       0xDEADBEEF);
233 
234   EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));
235   EXPECT_FALSE(
236       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));
237   EXPECT_FALSE(
238       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));
239   EXPECT_FALSE(
240       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));
241   EXPECT_FALSE(
242       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 20)));
243   EXPECT_FALSE(
244       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 21)));
245   EXPECT_FALSE(
246       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 23)));
247   EXPECT_TRUE(
248       Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 28)));
249 }
250 
251 TEST_F(BasicFileAnalysisTest, FallThroughTest) {
252   if (!SuccessfullyInitialised)
253     return;
254   Analysis.parseSectionContents(
255       {
256           0x90,                         // 0: nop
257           0xb0, 0x00,                   // 1: mov $0x0, %al
258           0x2f,                         // 3: (bad)
259           0x0f, 0x0b,                   // 4: ud2
260           0xff, 0x20,                   // 6: jmpq *(%rax)
261           0xeb, 0x00,                   // 8: jmp +0
262           0xe8, 0x45, 0xfe, 0xff, 0xff, // 10: callq [some loc]
263           0xff, 0x10,                   // 15: callq *(rax)
264           0x75, 0x00,                   // 17: jne +0
265           0xc3,                         // 19: retq
266       },
267       0xDEADBEEF);
268 
269   EXPECT_TRUE(
270       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));
271   EXPECT_TRUE(
272       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 1)));
273   EXPECT_FALSE(
274       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));
275   EXPECT_FALSE(
276       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 4)));
277   EXPECT_FALSE(
278       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));
279   EXPECT_FALSE(
280       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 8)));
281   EXPECT_FALSE(
282       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));
283   EXPECT_FALSE(
284       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 15)));
285   EXPECT_TRUE(
286       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 17)));
287   EXPECT_FALSE(
288       Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 19)));
289 }
290 
291 TEST_F(BasicFileAnalysisTest, DefiniteNextInstructionTest) {
292   if (!SuccessfullyInitialised)
293     return;
294   Analysis.parseSectionContents(
295       {
296           0x90,                         // 0: nop
297           0xb0, 0x00,                   // 1: mov $0x0, %al
298           0x2f,                         // 3: (bad)
299           0x0f, 0x0b,                   // 4: ud2
300           0xff, 0x20,                   // 6: jmpq *(%rax)
301           0xeb, 0x00,                   // 8: jmp 10 [+0]
302           0xeb, 0x05,                   // 10: jmp 17 [+5]
303           0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]
304           0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]
305           0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]
306           0xff, 0x10,                   // 27: callq *(rax)
307           0x75, 0x00,                   // 29: jne 31 [+0]
308           0x75, 0xe0,                   // 31: jne 1 [-32]
309           0xc3,                         // 33: retq
310           0xeb, 0xdd,                   // 34: jmp 1 [-35]
311           0xeb, 0xdd,                   // 36: jmp 3 [-35]
312           0xeb, 0xdc,                   // 38: jmp 4 [-36]
313       },
314       0xDEADBEEF);
315 
316   const auto *Current = Analysis.getInstruction(0xDEADBEEF);
317   const auto *Next = Analysis.getDefiniteNextInstruction(*Current);
318   EXPECT_NE(nullptr, Next);
319   EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);
320 
321   Current = Analysis.getInstruction(0xDEADBEEF + 1);
322   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
323 
324   Current = Analysis.getInstruction(0xDEADBEEF + 3);
325   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
326 
327   Current = Analysis.getInstruction(0xDEADBEEF + 4);
328   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
329 
330   Current = Analysis.getInstruction(0xDEADBEEF + 6);
331   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
332 
333   Current = Analysis.getInstruction(0xDEADBEEF + 8);
334   Next = Analysis.getDefiniteNextInstruction(*Current);
335   EXPECT_NE(nullptr, Next);
336   EXPECT_EQ(0xDEADBEEF + 10, Next->VMAddress);
337 
338   Current = Analysis.getInstruction(0xDEADBEEF + 10);
339   Next = Analysis.getDefiniteNextInstruction(*Current);
340   EXPECT_NE(nullptr, Next);
341   EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);
342 
343   Current = Analysis.getInstruction(0xDEADBEEF + 12);
344   Next = Analysis.getDefiniteNextInstruction(*Current);
345   EXPECT_NE(nullptr, Next);
346   EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);
347 
348   Current = Analysis.getInstruction(0xDEADBEEF + 17);
349   // Note, definite next instruction address is out of range and should fail.
350   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
351   Next = Analysis.getDefiniteNextInstruction(*Current);
352 
353   Current = Analysis.getInstruction(0xDEADBEEF + 22);
354   Next = Analysis.getDefiniteNextInstruction(*Current);
355   EXPECT_NE(nullptr, Next);
356   EXPECT_EQ(0xDEADBEEF + 31, Next->VMAddress);
357 
358   Current = Analysis.getInstruction(0xDEADBEEF + 27);
359   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
360   Current = Analysis.getInstruction(0xDEADBEEF + 29);
361   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
362   Current = Analysis.getInstruction(0xDEADBEEF + 31);
363   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
364   Current = Analysis.getInstruction(0xDEADBEEF + 33);
365   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
366 
367   Current = Analysis.getInstruction(0xDEADBEEF + 34);
368   Next = Analysis.getDefiniteNextInstruction(*Current);
369   EXPECT_NE(nullptr, Next);
370   EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);
371 
372   Current = Analysis.getInstruction(0xDEADBEEF + 36);
373   EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));
374 
375   Current = Analysis.getInstruction(0xDEADBEEF + 38);
376   Next = Analysis.getDefiniteNextInstruction(*Current);
377   EXPECT_NE(nullptr, Next);
378   EXPECT_EQ(0xDEADBEEF + 4, Next->VMAddress);
379 }
380 
381 TEST_F(BasicFileAnalysisTest, ControlFlowXRefsTest) {
382   if (!SuccessfullyInitialised)
383     return;
384   Analysis.parseSectionContents(
385       {
386           0x90,                         // 0: nop
387           0xb0, 0x00,                   // 1: mov $0x0, %al
388           0x2f,                         // 3: (bad)
389           0x0f, 0x0b,                   // 4: ud2
390           0xff, 0x20,                   // 6: jmpq *(%rax)
391           0xeb, 0x00,                   // 8: jmp 10 [+0]
392           0xeb, 0x05,                   // 10: jmp 17 [+5]
393           0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]
394           0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]
395           0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]
396           0xff, 0x10,                   // 27: callq *(rax)
397           0x75, 0x00,                   // 29: jne 31 [+0]
398           0x75, 0xe0,                   // 31: jne 1 [-32]
399           0xc3,                         // 33: retq
400           0xeb, 0xdd,                   // 34: jmp 1 [-35]
401           0xeb, 0xdd,                   // 36: jmp 3 [-35]
402           0xeb, 0xdc,                   // 38: jmp 4 [-36]
403       },
404       0xDEADBEEF);
405   const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);
406   std::set<const Instr *> XRefs =
407       Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
408   EXPECT_TRUE(XRefs.empty());
409 
410   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 1);
411   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
412   EXPECT_THAT(XRefs, UnorderedElementsAre(
413                          Field(&Instr::VMAddress, Eq(0xDEADBEEF)),
414                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31)),
415                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 34))));
416 
417   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 3);
418   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
419   EXPECT_THAT(XRefs, UnorderedElementsAre(
420                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 1)),
421                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 36))));
422 
423   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 4);
424   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
425   EXPECT_THAT(XRefs, UnorderedElementsAre(
426                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 38))));
427 
428   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 6);
429   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
430 
431   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 8);
432   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
433   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
434 
435   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 10);
436   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
437   EXPECT_THAT(XRefs, UnorderedElementsAre(
438                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 8))));
439 
440   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 12);
441   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
442   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
443 
444   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 17);
445   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
446   EXPECT_THAT(XRefs, UnorderedElementsAre(
447                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 10)),
448                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 12))));
449 
450   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 22);
451   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
452   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
453 
454   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 27);
455   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
456   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
457 
458   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 29);
459   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
460   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
461 
462   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 31);
463   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
464   EXPECT_THAT(XRefs, UnorderedElementsAre(
465                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 22)),
466                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 29))));
467 
468   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 33);
469   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
470   EXPECT_THAT(XRefs, UnorderedElementsAre(
471                          Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31))));
472 
473   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 34);
474   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
475   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
476 
477   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 36);
478   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
479   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
480 
481   InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 38);
482   XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);
483   EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());
484 }
485 
486 TEST_F(BasicFileAnalysisTest, CFIProtectionInvalidTargets) {
487   if (!SuccessfullyInitialised)
488     return;
489   Analysis.parseSectionContents(
490       {
491           0x90,       // 0: nop
492           0x0f, 0x0b, // 1: ud2
493           0x75, 0x00, // 3: jne 5 [+0]
494       },
495       0xDEADBEEF);
496   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF);
497   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
498             Analysis.validateCFIProtection(Result));
499   Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 1);
500   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
501             Analysis.validateCFIProtection(Result));
502   Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
503   EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,
504             Analysis.validateCFIProtection(Result));
505   Result = GraphBuilder::buildFlowGraph(Analysis, 0x12345678);
506   EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,
507             Analysis.validateCFIProtection(Result));
508 }
509 
510 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {
511   if (!SuccessfullyInitialised)
512     return;
513   Analysis.parseSectionContents(
514       {
515           0x75, 0x02, // 0: jne 4 [+2]
516           0x0f, 0x0b, // 2: ud2
517           0xff, 0x10, // 4: callq *(%rax)
518       },
519       0xDEADBEEF);
520   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
521   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
522             Analysis.validateCFIProtection(Result));
523 }
524 
525 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicJumpToUd2) {
526   if (!SuccessfullyInitialised)
527     return;
528   Analysis.parseSectionContents(
529       {
530           0x75, 0x02, // 0: jne 4 [+2]
531           0xff, 0x10, // 2: callq *(%rax)
532           0x0f, 0x0b, // 4: ud2
533       },
534       0xDEADBEEF);
535   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
536   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
537             Analysis.validateCFIProtection(Result));
538 }
539 
540 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathUd2) {
541   if (!SuccessfullyInitialised)
542     return;
543   Analysis.parseSectionContents(
544       {
545           0x75, 0x03, // 0: jne 5 [+3]
546           0x90,       // 2: nop
547           0xff, 0x10, // 3: callq *(%rax)
548           0x0f, 0x0b, // 5: ud2
549           0x75, 0xf9, // 7: jne 2 [-7]
550           0x0f, 0x0b, // 9: ud2
551       },
552       0xDEADBEEF);
553   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
554   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
555             Analysis.validateCFIProtection(Result));
556 }
557 
558 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathSingleUd2) {
559   if (!SuccessfullyInitialised)
560     return;
561   Analysis.parseSectionContents(
562       {
563           0x75, 0x05, // 0: jne 7 [+5]
564           0x90,       // 2: nop
565           0xff, 0x10, // 3: callq *(%rax)
566           0x75, 0xfb, // 5: jne 2 [-5]
567           0x0f, 0x0b, // 7: ud2
568       },
569       0xDEADBEEF);
570   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 3);
571   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
572             Analysis.validateCFIProtection(Result));
573 }
574 
575 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitUpwards) {
576   if (!SuccessfullyInitialised)
577     return;
578   Analysis.parseSectionContents(
579       {
580           0x75, 0x06, // 0: jne 8 [+6]
581           0x90,       // 2: nop
582           0x90,       // 3: nop
583           0x90,       // 4: nop
584           0x90,       // 5: nop
585           0xff, 0x10, // 6: callq *(%rax)
586           0x0f, 0x0b, // 8: ud2
587       },
588       0xDEADBEEF);
589   uint64_t PrevSearchLengthForConditionalBranch =
590       SearchLengthForConditionalBranch;
591   SearchLengthForConditionalBranch = 2;
592 
593   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 6);
594   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
595             Analysis.validateCFIProtection(Result));
596 
597   SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch;
598 }
599 
600 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitDownwards) {
601   if (!SuccessfullyInitialised)
602     return;
603   Analysis.parseSectionContents(
604       {
605           0x75, 0x02, // 0: jne 4 [+2]
606           0xff, 0x10, // 2: callq *(%rax)
607           0x90,       // 4: nop
608           0x90,       // 5: nop
609           0x90,       // 6: nop
610           0x90,       // 7: nop
611           0x0f, 0x0b, // 8: ud2
612       },
613       0xDEADBEEF);
614   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
615   SearchLengthForUndef = 2;
616 
617   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 2);
618   EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
619             Analysis.validateCFIProtection(Result));
620 
621   SearchLengthForUndef = PrevSearchLengthForUndef;
622 }
623 
624 TEST_F(BasicFileAnalysisTest, CFIProtectionGoodAndBadPaths) {
625   if (!SuccessfullyInitialised)
626     return;
627   Analysis.parseSectionContents(
628       {
629           0xeb, 0x02, // 0: jmp 4 [+2]
630           0x75, 0x02, // 2: jne 6 [+2]
631           0xff, 0x10, // 4: callq *(%rax)
632           0x0f, 0x0b, // 6: ud2
633       },
634       0xDEADBEEF);
635   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
636   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
637             Analysis.validateCFIProtection(Result));
638 }
639 
640 TEST_F(BasicFileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {
641   if (!SuccessfullyInitialised)
642     return;
643   Analysis.parseSectionContents(
644       {
645           0x75, 0x04, // 0: jne 6 [+4]
646           0xeb, 0x00, // 2: jmp 4 [+0]
647           0xff, 0x10, // 4: callq *(%rax)
648           0x0f, 0x0b, // 6: ud2
649       },
650       0xDEADBEEF);
651   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
652   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
653             Analysis.validateCFIProtection(Result));
654 }
655 
656 TEST_F(BasicFileAnalysisTest, CFIProtectionComplexExample) {
657   if (!SuccessfullyInitialised)
658     return;
659   // See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this
660   // graph.
661   Analysis.parseSectionContents(
662       {
663           0x75, 0x12,                   // 0: jne 20 [+18]
664           0xeb, 0x03,                   // 2: jmp 7 [+3]
665           0x75, 0x10,                   // 4: jne 22 [+16]
666           0x90,                         // 6: nop
667           0x90,                         // 7: nop
668           0x90,                         // 8: nop
669           0xff, 0x10,                   // 9: callq *(%rax)
670           0xeb, 0xfc,                   // 11: jmp 9 [-4]
671           0x75, 0xfa,                   // 13: jne 9 [-6]
672           0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678]
673           0x90,                         // 20: nop
674           0x90,                         // 21: nop
675           0x0f, 0x0b,                   // 22: ud2
676       },
677       0xDEADBEEF);
678   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
679   SearchLengthForUndef = 5;
680   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
681   EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,
682             Analysis.validateCFIProtection(Result));
683   SearchLengthForUndef = PrevSearchLengthForUndef;
684 }
685 
686 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTest) {
687   Analysis.parseSectionContents(
688       {
689           0x77, 0x0d,                   // 0x688118: ja 0x688127 [+12]
690           0x48, 0x89, 0xdf,             // 0x68811a: mov %rbx, %rdi
691           0xff, 0xd0,                   // 0x68811d: callq *%rax
692           0x48, 0x89, 0xdf,             // 0x68811f: mov %rbx, %rdi
693           0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130
694           0x0f, 0x0b,                   // 0x688127: ud2
695       },
696       0x688118);
697   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
698   SearchLengthForUndef = 1;
699   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x68811d);
700   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
701             Analysis.validateCFIProtection(Result));
702   SearchLengthForUndef = PrevSearchLengthForUndef;
703 }
704 
705 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTestFarAway) {
706   Analysis.parseSectionContents(
707       {
708           0x74, 0x73,                         // 0x7759eb: je 0x775a60
709           0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e
710       },
711       0x7759eb);
712 
713   Analysis.parseSectionContents(
714       {
715           0x0f, 0x85, 0xb2, 0x03, 0x00, 0x00, // 0x775a56: jne    0x775e0e
716           0x48, 0x83, 0xc3, 0xf4, // 0x775a5c: add    $0xfffffffffffffff4,%rbx
717           0x48, 0x8b, 0x7c, 0x24, 0x10, // 0x775a60: mov    0x10(%rsp),%rdi
718           0x48, 0x89, 0xde,             // 0x775a65: mov    %rbx,%rsi
719           0xff, 0xd1,                   // 0x775a68: callq  *%rcx
720       },
721       0x775a56);
722 
723   Analysis.parseSectionContents(
724       {
725           0x0f, 0x0b, // 0x775e0e: ud2
726       },
727       0x775e0e);
728   uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;
729   SearchLengthForUndef = 1;
730   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
731   EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,
732             Analysis.validateCFIProtection(Result));
733   SearchLengthForUndef = 2;
734   Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
735   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
736             Analysis.validateCFIProtection(Result));
737   SearchLengthForUndef = 3;
738   Result = GraphBuilder::buildFlowGraph(Analysis, 0x775a68);
739   EXPECT_EQ(CFIProtectionStatus::PROTECTED,
740             Analysis.validateCFIProtection(Result));
741   SearchLengthForUndef = PrevSearchLengthForUndef;
742 }
743 
744 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {
745   if (!SuccessfullyInitialised)
746     return;
747   Analysis.parseSectionContents(
748       {
749           0x75, 0x02,                         // 0: jne 4 [+2]
750           0x0f, 0x0b,                         // 2: ud2
751           0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax
752           0xff, 0x10,                         // 10: callq *(%rax)
753       },
754       0xDEADBEEF);
755   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 10);
756   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
757             Analysis.validateCFIProtection(Result));
758 }
759 
760 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {
761   if (!SuccessfullyInitialised)
762     return;
763   Analysis.parseSectionContents(
764       {
765           0x75, 0x02,             // 0: jne 4 [+2]
766           0x0f, 0x0b,             // 2: ud2
767           0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax
768           0xff, 0x10,             // 8: callq *(%rax)
769       },
770       0xDEADBEEF);
771   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 8);
772   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
773             Analysis.validateCFIProtection(Result));
774 }
775 
776 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {
777   if (!SuccessfullyInitialised)
778     return;
779   Analysis.parseSectionContents(
780       {
781           0x75, 0x02,                   // 0: jne 4 [+2]
782           0x0f, 0x0b,                   // 2: ud2
783           0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax
784           0xff, 0x10,                   // 9: callq *(%rax)
785       },
786       0xDEADBEEF);
787   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 9);
788   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
789             Analysis.validateCFIProtection(Result));
790 }
791 
792 TEST_F(BasicFileAnalysisTest, CFIProtectionClobberDualPathImplicit) {
793   if (!SuccessfullyInitialised)
794     return;
795   Analysis.parseSectionContents(
796       {
797           0x75, 0x04, // 0: jne 6 [+4]
798           0x0f, 0x31, // 2: rdtsc (note: affects eax)
799           0xff, 0x10, // 4: callq *(%rax)
800           0x0f, 0x0b, // 6: ud2
801           0x75, 0xf9, // 8: jne 2 [-7]
802           0x0f, 0x0b, // 10: ud2
803       },
804       0xDEADBEEF);
805   GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, 0xDEADBEEF + 4);
806   EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,
807             Analysis.validateCFIProtection(Result));
808 }
809 
810 } // anonymous namespace
811 } // end namespace cfi_verify
812 } // end namespace llvm
813 
814 int main(int argc, char **argv) {
815   ::testing::InitGoogleTest(&argc, argv);
816   llvm::cl::ParseCommandLineOptions(argc, argv);
817 
818   llvm::InitializeAllTargetInfos();
819   llvm::InitializeAllTargetMCs();
820   llvm::InitializeAllAsmParsers();
821   llvm::InitializeAllDisassemblers();
822 
823   return RUN_ALL_TESTS();
824 }
825