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 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF)); 497 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 1)); 498 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 3)); 499 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADC0DE)); 500 } 501 502 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicFallthroughToUd2) { 503 if (!SuccessfullyInitialised) 504 return; 505 Analysis.parseSectionContents( 506 { 507 0x75, 0x02, // 0: jne 4 [+2] 508 0x0f, 0x0b, // 2: ud2 509 0xff, 0x10, // 4: callq *(%rax) 510 }, 511 0xDEADBEEF); 512 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 4)); 513 } 514 515 TEST_F(BasicFileAnalysisTest, CFIProtectionBasicJumpToUd2) { 516 if (!SuccessfullyInitialised) 517 return; 518 Analysis.parseSectionContents( 519 { 520 0x75, 0x02, // 0: jne 4 [+2] 521 0xff, 0x10, // 2: callq *(%rax) 522 0x0f, 0x0b, // 4: ud2 523 }, 524 0xDEADBEEF); 525 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 2)); 526 } 527 528 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathUd2) { 529 if (!SuccessfullyInitialised) 530 return; 531 Analysis.parseSectionContents( 532 { 533 0x75, 0x03, // 0: jne 5 [+3] 534 0x90, // 2: nop 535 0xff, 0x10, // 3: callq *(%rax) 536 0x0f, 0x0b, // 5: ud2 537 0x75, 0xf9, // 7: jne 2 [-7] 538 0x0f, 0x0b, // 9: ud2 539 }, 540 0xDEADBEEF); 541 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 3)); 542 } 543 544 TEST_F(BasicFileAnalysisTest, CFIProtectionDualPathSingleUd2) { 545 if (!SuccessfullyInitialised) 546 return; 547 Analysis.parseSectionContents( 548 { 549 0x75, 0x05, // 0: jne 7 [+5] 550 0x90, // 2: nop 551 0xff, 0x10, // 3: callq *(%rax) 552 0x75, 0xfb, // 5: jne 2 [-5] 553 0x0f, 0x0b, // 7: ud2 554 }, 555 0xDEADBEEF); 556 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 3)); 557 } 558 559 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitUpwards) { 560 if (!SuccessfullyInitialised) 561 return; 562 Analysis.parseSectionContents( 563 { 564 0x75, 0x06, // 0: jne 8 [+6] 565 0x90, // 2: nop 566 0x90, // 3: nop 567 0x90, // 4: nop 568 0x90, // 5: nop 569 0xff, 0x10, // 6: callq *(%rax) 570 0x0f, 0x0b, // 8: ud2 571 }, 572 0xDEADBEEF); 573 uint64_t PrevSearchLengthForConditionalBranch = 574 SearchLengthForConditionalBranch; 575 SearchLengthForConditionalBranch = 2; 576 577 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 6)); 578 579 SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch; 580 } 581 582 TEST_F(BasicFileAnalysisTest, CFIProtectionDualFailLimitDownwards) { 583 if (!SuccessfullyInitialised) 584 return; 585 Analysis.parseSectionContents( 586 { 587 0x75, 0x02, // 0: jne 4 [+2] 588 0xff, 0x10, // 2: callq *(%rax) 589 0x90, // 4: nop 590 0x90, // 5: nop 591 0x90, // 6: nop 592 0x90, // 7: nop 593 0x0f, 0x0b, // 8: ud2 594 }, 595 0xDEADBEEF); 596 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 597 SearchLengthForUndef = 2; 598 599 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 2)); 600 601 SearchLengthForUndef = PrevSearchLengthForUndef; 602 } 603 604 TEST_F(BasicFileAnalysisTest, CFIProtectionGoodAndBadPaths) { 605 if (!SuccessfullyInitialised) 606 return; 607 Analysis.parseSectionContents( 608 { 609 0xeb, 0x02, // 0: jmp 4 [+2] 610 0x75, 0x02, // 2: jne 6 [+2] 611 0xff, 0x10, // 4: callq *(%rax) 612 0x0f, 0x0b, // 6: ud2 613 }, 614 0xDEADBEEF); 615 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 4)); 616 } 617 618 TEST_F(BasicFileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) { 619 if (!SuccessfullyInitialised) 620 return; 621 Analysis.parseSectionContents( 622 { 623 0x75, 0x04, // 0: jne 6 [+4] 624 0xeb, 0x00, // 2: jmp 4 [+0] 625 0xff, 0x10, // 4: callq *(%rax) 626 0x0f, 0x0b, // 6: ud2 627 }, 628 0xDEADBEEF); 629 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 4)); 630 } 631 632 TEST_F(BasicFileAnalysisTest, CFIProtectionComplexExample) { 633 if (!SuccessfullyInitialised) 634 return; 635 // See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this 636 // graph. 637 Analysis.parseSectionContents( 638 { 639 0x75, 0x12, // 0: jne 20 [+18] 640 0xeb, 0x03, // 2: jmp 7 [+3] 641 0x75, 0x10, // 4: jne 22 [+16] 642 0x90, // 6: nop 643 0x90, // 7: nop 644 0x90, // 8: nop 645 0xff, 0x10, // 9: callq *(%rax) 646 0xeb, 0xfc, // 11: jmp 9 [-4] 647 0x75, 0xfa, // 13: jne 9 [-6] 648 0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678] 649 0x90, // 20: nop 650 0x90, // 21: nop 651 0x0f, 0x0b, // 22: ud2 652 }, 653 0xDEADBEEF); 654 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 655 SearchLengthForUndef = 5; 656 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0xDEADBEEF + 9)); 657 SearchLengthForUndef = PrevSearchLengthForUndef; 658 } 659 660 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTest) { 661 Analysis.parseSectionContents( 662 { 663 0x77, 0x0d, // 0x688118: ja 0x688127 [+12] 664 0x48, 0x89, 0xdf, // 0x68811a: mov %rbx, %rdi 665 0xff, 0xd0, // 0x68811d: callq *%rax 666 0x48, 0x89, 0xdf, // 0x68811f: mov %rbx, %rdi 667 0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130 668 0x0f, 0x0b, // 0x688127: ud2 669 }, 670 0x688118); 671 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 672 SearchLengthForUndef = 1; 673 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0x68811d)); 674 SearchLengthForUndef = PrevSearchLengthForUndef; 675 } 676 677 TEST_F(BasicFileAnalysisTest, UndefSearchLengthOneTestFarAway) { 678 Analysis.parseSectionContents( 679 { 680 0x74, 0x73, // 0x7759eb: je 0x775a60 681 0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e 682 }, 683 0x7759eb); 684 685 Analysis.parseSectionContents( 686 { 687 0x0f, 0x85, 0xb2, 0x03, 0x00, 0x00, // 0x775a56: jne 0x775e0e 688 0x48, 0x83, 0xc3, 0xf4, // 0x775a5c: add $0xfffffffffffffff4,%rbx 689 0x48, 0x8b, 0x7c, 0x24, 0x10, // 0x775a60: mov 0x10(%rsp),%rdi 690 0x48, 0x89, 0xde, // 0x775a65: mov %rbx,%rsi 691 0xff, 0xd1, // 0x775a68: callq *%rcx 692 }, 693 0x775a56); 694 695 Analysis.parseSectionContents( 696 { 697 0x0f, 0x0b, // 0x775e0e: ud2 698 }, 699 0x775e0e); 700 uint64_t PrevSearchLengthForUndef = SearchLengthForUndef; 701 SearchLengthForUndef = 1; 702 EXPECT_FALSE(Analysis.isIndirectInstructionCFIProtected(0x775a68)); 703 SearchLengthForUndef = 2; 704 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0x775a68)); 705 SearchLengthForUndef = 3; 706 EXPECT_TRUE(Analysis.isIndirectInstructionCFIProtected(0x775a68)); 707 SearchLengthForUndef = PrevSearchLengthForUndef; 708 } 709 710 } // anonymous namespace 711 } // end namespace cfi_verify 712 } // end namespace llvm 713 714 int main(int argc, char **argv) { 715 ::testing::InitGoogleTest(&argc, argv); 716 llvm::cl::ParseCommandLineOptions(argc, argv); 717 718 llvm::InitializeAllTargetInfos(); 719 llvm::InitializeAllTargetMCs(); 720 llvm::InitializeAllAsmParsers(); 721 llvm::InitializeAllDisassemblers(); 722 723 return RUN_ALL_TESTS(); 724 } 725