brintos

brintos / llvm-project-archived public Read only

0
0
Text · 41.0 KiB · e46cbbd Raw
1107 lines · cpp
1//===- llvm/unittests/tools/llvm-cfi-verify/FileAnalysis.cpp --------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "../tools/llvm-cfi-verify/lib/FileAnalysis.h"10#include "../tools/llvm-cfi-verify/lib/GraphBuilder.h"11#include "gmock/gmock.h"12#include "gtest/gtest.h"13 14#include "llvm/BinaryFormat/ELF.h"15#include "llvm/DebugInfo/Symbolize/SymbolizableModule.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/MC/TargetRegistry.h"28#include "llvm/Object/Binary.h"29#include "llvm/Object/COFF.h"30#include "llvm/Object/ELFObjectFile.h"31#include "llvm/Object/ObjectFile.h"32#include "llvm/Support/Casting.h"33#include "llvm/Support/CommandLine.h"34#include "llvm/Support/Error.h"35#include "llvm/Support/MemoryBuffer.h"36#include "llvm/Support/TargetSelect.h"37#include "llvm/Support/raw_ostream.h"38 39#include <cstdlib>40 41using Instr = ::llvm::cfi_verify::FileAnalysis::Instr;42using ::testing::Eq;43using ::testing::Field;44 45namespace llvm {46namespace cfi_verify {47namespace {48class ELFTestFileAnalysis : public FileAnalysis {49public:50  ELFTestFileAnalysis(StringRef Trip)51      : FileAnalysis(Triple(Trip), SubtargetFeatures()) {}52 53  // Expose this method publicly for testing.54  void parseSectionContents(ArrayRef<uint8_t> SectionBytes,55                            object::SectionedAddress Address) {56    FileAnalysis::parseSectionContents(SectionBytes, Address);57  }58 59  Error initialiseDisassemblyMembers() {60    return FileAnalysis::initialiseDisassemblyMembers();61  }62};63 64class BasicFileAnalysisTest : public ::testing::Test {65public:66  BasicFileAnalysisTest(StringRef Trip)67      : SuccessfullyInitialised(false), Analysis(Trip) {}68protected:69  void SetUp() override {70    IgnoreDWARFFlag = true;71    SuccessfullyInitialised = true;72    if (auto Err = Analysis.initialiseDisassemblyMembers()) {73      handleAllErrors(std::move(Err), [&](const UnsupportedDisassembly &E) {74        SuccessfullyInitialised = false;75        outs()76            << "Note: CFIVerifyTests are disabled due to lack of support "77               "on this build.\n";78      });79    }80  }81 82  bool SuccessfullyInitialised;83  ELFTestFileAnalysis Analysis;84};85 86class BasicX86FileAnalysisTest : public BasicFileAnalysisTest {87public:88  BasicX86FileAnalysisTest() : BasicFileAnalysisTest("x86_64--") {}89};90 91class BasicAArch64FileAnalysisTest : public BasicFileAnalysisTest {92public:93  BasicAArch64FileAnalysisTest() : BasicFileAnalysisTest("aarch64--") {}94};95 96TEST_F(BasicX86FileAnalysisTest, BasicDisassemblyTraversalTest) {97  if (!SuccessfullyInitialised)98    GTEST_SKIP();99  Analysis.parseSectionContents(100      {101          0x90,                   // 0: nop102          0xb0, 0x00,             // 1: mov $0x0, %al103          0x48, 0x89, 0xe5,       // 3: mov %rsp, %rbp104          0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp105          0x48, 0xbe, 0xc4, 0x07, 0x40,106          0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi107          0x2f,                         // 20: (bad)108          0x41, 0x0e,                   // 21: rex.B (bad)109          0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}110      },111      {0xDEADBEEF, 0x0});112 113  EXPECT_EQ(nullptr, Analysis.getInstruction(0x0));114  EXPECT_EQ(nullptr, Analysis.getInstruction(0x1000));115 116  // 0xDEADBEEF: nop117  const auto *InstrMeta = Analysis.getInstruction(0xDEADBEEF);118  EXPECT_NE(nullptr, InstrMeta);119  EXPECT_EQ(0xDEADBEEF, InstrMeta->VMAddress);120  EXPECT_EQ(1u, InstrMeta->InstructionSize);121  EXPECT_TRUE(InstrMeta->Valid);122 123  const auto *NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);124  EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));125  const auto *PrevInstrMeta = InstrMeta;126 127  // 0xDEADBEEF + 1: mov $0x0, %al128  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 1);129  EXPECT_NE(nullptr, InstrMeta);130  EXPECT_EQ(NextInstrMeta, InstrMeta);131  EXPECT_EQ(0xDEADBEEF + 1, InstrMeta->VMAddress);132  EXPECT_EQ(2u, InstrMeta->InstructionSize);133  EXPECT_TRUE(InstrMeta->Valid);134 135  NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);136  EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));137  PrevInstrMeta = InstrMeta;138 139  // 0xDEADBEEF + 3: mov %rsp, %rbp140  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 3);141  EXPECT_NE(nullptr, InstrMeta);142  EXPECT_EQ(NextInstrMeta, InstrMeta);143  EXPECT_EQ(0xDEADBEEF + 3, InstrMeta->VMAddress);144  EXPECT_EQ(3u, InstrMeta->InstructionSize);145  EXPECT_TRUE(InstrMeta->Valid);146 147  NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);148  EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));149  PrevInstrMeta = InstrMeta;150 151  // 0xDEADBEEF + 6: sub $0x18, %rsp152  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 6);153  EXPECT_NE(nullptr, InstrMeta);154  EXPECT_EQ(NextInstrMeta, InstrMeta);155  EXPECT_EQ(0xDEADBEEF + 6, InstrMeta->VMAddress);156  EXPECT_EQ(4u, InstrMeta->InstructionSize);157  EXPECT_TRUE(InstrMeta->Valid);158 159  NextInstrMeta = Analysis.getNextInstructionSequential(*InstrMeta);160  EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));161  PrevInstrMeta = InstrMeta;162 163  // 0xDEADBEEF + 10: movabs $0x4007c4, %rsi164  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 10);165  EXPECT_NE(nullptr, InstrMeta);166  EXPECT_EQ(NextInstrMeta, InstrMeta);167  EXPECT_EQ(0xDEADBEEF + 10, InstrMeta->VMAddress);168  EXPECT_EQ(10u, InstrMeta->InstructionSize);169  EXPECT_TRUE(InstrMeta->Valid);170 171  EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));172  EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));173  PrevInstrMeta = InstrMeta;174 175  // 0xDEADBEEF + 20: (bad)176  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 20);177  EXPECT_NE(nullptr, InstrMeta);178  EXPECT_EQ(0xDEADBEEF + 20, InstrMeta->VMAddress);179  EXPECT_EQ(1u, InstrMeta->InstructionSize);180  EXPECT_FALSE(InstrMeta->Valid);181 182  EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));183  EXPECT_EQ(PrevInstrMeta, Analysis.getPrevInstructionSequential(*InstrMeta));184 185  // 0xDEADBEEF + 21: rex.B (bad)186  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 21);187  EXPECT_NE(nullptr, InstrMeta);188  EXPECT_EQ(0xDEADBEEF + 21, InstrMeta->VMAddress);189  EXPECT_EQ(2u, InstrMeta->InstructionSize);190  EXPECT_FALSE(InstrMeta->Valid);191 192  EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));193  EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));194 195  // 0xDEADBEEF + 6: (bad) {%k1}196  InstrMeta = Analysis.getInstruction(0xDEADBEEF + 23);197  EXPECT_NE(nullptr, InstrMeta);198  EXPECT_EQ(0xDEADBEEF + 23, InstrMeta->VMAddress);199  EXPECT_EQ(5u, InstrMeta->InstructionSize);200  EXPECT_FALSE(InstrMeta->Valid);201 202  EXPECT_EQ(nullptr, Analysis.getNextInstructionSequential(*InstrMeta));203  EXPECT_EQ(nullptr, Analysis.getPrevInstructionSequential(*InstrMeta));204}205 206TEST_F(BasicX86FileAnalysisTest, PrevAndNextFromBadInst) {207  if (!SuccessfullyInitialised)208    GTEST_SKIP();209  Analysis.parseSectionContents(210      {211          0x90, // 0: nop212          0x2f, // 1: (bad)213          0x90  // 2: nop214      },215      {0xDEADBEEF, 0x0});216  const auto &BadInstrMeta = Analysis.getInstructionOrDie(0xDEADBEEF + 1);217  const auto *GoodInstrMeta =218      Analysis.getPrevInstructionSequential(BadInstrMeta);219  EXPECT_NE(nullptr, GoodInstrMeta);220  EXPECT_EQ(0xDEADBEEF, GoodInstrMeta->VMAddress);221  EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);222 223  GoodInstrMeta = Analysis.getNextInstructionSequential(BadInstrMeta);224  EXPECT_NE(nullptr, GoodInstrMeta);225  EXPECT_EQ(0xDEADBEEF + 2, GoodInstrMeta->VMAddress);226  EXPECT_EQ(1u, GoodInstrMeta->InstructionSize);227}228 229TEST_F(BasicX86FileAnalysisTest, CFITrapTest) {230  if (!SuccessfullyInitialised)231    GTEST_SKIP();232  Analysis.parseSectionContents(233      {234          0x90,                   // 0: nop235          0xb0, 0x00,             // 1: mov $0x0, %al236          0x48, 0x89, 0xe5,       // 3: mov %rsp, %rbp237          0x48, 0x83, 0xec, 0x18, // 6: sub $0x18, %rsp238          0x48, 0xbe, 0xc4, 0x07, 0x40,239          0x00, 0x00, 0x00, 0x00, 0x00, // 10: movabs $0x4007c4, %rsi240          0x2f,                         // 20: (bad)241          0x41, 0x0e,                   // 21: rex.B (bad)242          0x62, 0x72, 0x65, 0x61, 0x6b, // 23: (bad) {%k1}243          0x0f, 0x0b                    // 28: ud2244      },245      {0xDEADBEEF, 0x0});246 247  EXPECT_FALSE(Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF)));248  EXPECT_FALSE(249      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));250  EXPECT_FALSE(251      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));252  EXPECT_FALSE(253      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));254  EXPECT_FALSE(255      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 20)));256  EXPECT_FALSE(257      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 21)));258  EXPECT_FALSE(259      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 23)));260  EXPECT_TRUE(261      Analysis.isCFITrap(Analysis.getInstructionOrDie(0xDEADBEEF + 28)));262}263 264TEST_F(BasicX86FileAnalysisTest, FallThroughTest) {265  if (!SuccessfullyInitialised)266    GTEST_SKIP();267  Analysis.parseSectionContents(268      {269          0x90,                         // 0: nop270          0xb0, 0x00,                   // 1: mov $0x0, %al271          0x2f,                         // 3: (bad)272          0x0f, 0x0b,                   // 4: ud2273          0xff, 0x20,                   // 6: jmpq *(%rax)274          0xeb, 0x00,                   // 8: jmp +0275          0xe8, 0x45, 0xfe, 0xff, 0xff, // 10: callq [some loc]276          0xff, 0x10,                   // 15: callq *(rax)277          0x75, 0x00,                   // 17: jne +0278          0xc3,                         // 19: retq279      },280      {0xDEADBEEF, 0x0});281 282  EXPECT_TRUE(283      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF)));284  EXPECT_TRUE(285      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 1)));286  EXPECT_FALSE(287      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 3)));288  EXPECT_FALSE(289      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 4)));290  EXPECT_FALSE(291      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 6)));292  EXPECT_FALSE(293      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 8)));294  EXPECT_FALSE(295      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 10)));296  EXPECT_FALSE(297      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 15)));298  EXPECT_TRUE(299      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 17)));300  EXPECT_FALSE(301      Analysis.canFallThrough(Analysis.getInstructionOrDie(0xDEADBEEF + 19)));302}303 304TEST_F(BasicX86FileAnalysisTest, DefiniteNextInstructionTest) {305  if (!SuccessfullyInitialised)306    GTEST_SKIP();307  Analysis.parseSectionContents(308      {309          0x90,                         // 0: nop310          0xb0, 0x00,                   // 1: mov $0x0, %al311          0x2f,                         // 3: (bad)312          0x0f, 0x0b,                   // 4: ud2313          0xff, 0x20,                   // 6: jmpq *(%rax)314          0xeb, 0x00,                   // 8: jmp 10 [+0]315          0xeb, 0x05,                   // 10: jmp 17 [+5]316          0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]317          0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]318          0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]319          0xff, 0x10,                   // 27: callq *(rax)320          0x75, 0x00,                   // 29: jne 31 [+0]321          0x75, 0xe0,                   // 31: jne 1 [-32]322          0xc3,                         // 33: retq323          0xeb, 0xdd,                   // 34: jmp 1 [-35]324          0xeb, 0xdd,                   // 36: jmp 3 [-35]325          0xeb, 0xdc,                   // 38: jmp 4 [-36]326      },327      {0xDEADBEEF, 0x0});328 329  const auto *Current = Analysis.getInstruction(0xDEADBEEF);330  const auto *Next = Analysis.getDefiniteNextInstruction(*Current);331  EXPECT_NE(nullptr, Next);332  EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);333 334  Current = Analysis.getInstruction(0xDEADBEEF + 1);335  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));336 337  Current = Analysis.getInstruction(0xDEADBEEF + 3);338  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));339 340  Current = Analysis.getInstruction(0xDEADBEEF + 4);341  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));342 343  Current = Analysis.getInstruction(0xDEADBEEF + 6);344  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));345 346  Current = Analysis.getInstruction(0xDEADBEEF + 8);347  Next = Analysis.getDefiniteNextInstruction(*Current);348  EXPECT_NE(nullptr, Next);349  EXPECT_EQ(0xDEADBEEF + 10, Next->VMAddress);350 351  Current = Analysis.getInstruction(0xDEADBEEF + 10);352  Next = Analysis.getDefiniteNextInstruction(*Current);353  EXPECT_NE(nullptr, Next);354  EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);355 356  Current = Analysis.getInstruction(0xDEADBEEF + 12);357  Next = Analysis.getDefiniteNextInstruction(*Current);358  EXPECT_NE(nullptr, Next);359  EXPECT_EQ(0xDEADBEEF + 17, Next->VMAddress);360 361  Current = Analysis.getInstruction(0xDEADBEEF + 17);362  // Note, definite next instruction address is out of range and should fail.363  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));364  Next = Analysis.getDefiniteNextInstruction(*Current);365 366  Current = Analysis.getInstruction(0xDEADBEEF + 22);367  Next = Analysis.getDefiniteNextInstruction(*Current);368  EXPECT_NE(nullptr, Next);369  EXPECT_EQ(0xDEADBEEF + 31, Next->VMAddress);370 371  Current = Analysis.getInstruction(0xDEADBEEF + 27);372  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));373  Current = Analysis.getInstruction(0xDEADBEEF + 29);374  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));375  Current = Analysis.getInstruction(0xDEADBEEF + 31);376  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));377  Current = Analysis.getInstruction(0xDEADBEEF + 33);378  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));379 380  Current = Analysis.getInstruction(0xDEADBEEF + 34);381  Next = Analysis.getDefiniteNextInstruction(*Current);382  EXPECT_NE(nullptr, Next);383  EXPECT_EQ(0xDEADBEEF + 1, Next->VMAddress);384 385  Current = Analysis.getInstruction(0xDEADBEEF + 36);386  EXPECT_EQ(nullptr, Analysis.getDefiniteNextInstruction(*Current));387 388  Current = Analysis.getInstruction(0xDEADBEEF + 38);389  Next = Analysis.getDefiniteNextInstruction(*Current);390  EXPECT_NE(nullptr, Next);391  EXPECT_EQ(0xDEADBEEF + 4, Next->VMAddress);392}393 394TEST_F(BasicX86FileAnalysisTest, ControlFlowXRefsTest) {395  if (!SuccessfullyInitialised)396    GTEST_SKIP();397  Analysis.parseSectionContents(398      {399          0x90,                         // 0: nop400          0xb0, 0x00,                   // 1: mov $0x0, %al401          0x2f,                         // 3: (bad)402          0x0f, 0x0b,                   // 4: ud2403          0xff, 0x20,                   // 6: jmpq *(%rax)404          0xeb, 0x00,                   // 8: jmp 10 [+0]405          0xeb, 0x05,                   // 10: jmp 17 [+5]406          0xe8, 0x00, 0x00, 0x00, 0x00, // 12: callq 17 [+0]407          0xe8, 0x78, 0x56, 0x34, 0x12, // 17: callq 0x1234569f [+0x12345678]408          0xe8, 0x04, 0x00, 0x00, 0x00, // 22: callq 31 [+4]409          0xff, 0x10,                   // 27: callq *(rax)410          0x75, 0x00,                   // 29: jne 31 [+0]411          0x75, 0xe0,                   // 31: jne 1 [-32]412          0xc3,                         // 33: retq413          0xeb, 0xdd,                   // 34: jmp 1 [-35]414          0xeb, 0xdd,                   // 36: jmp 3 [-35]415          0xeb, 0xdc,                   // 38: jmp 4 [-36]416      },417      {0xDEADBEEF, 0x0});418  const auto *InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF);419  std::set<const Instr *> XRefs =420      Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);421  EXPECT_TRUE(XRefs.empty());422 423  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 1);424  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);425  EXPECT_THAT(XRefs, UnorderedElementsAre(426                         Field(&Instr::VMAddress, Eq(0xDEADBEEF)),427                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31)),428                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 34))));429 430  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 3);431  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);432  EXPECT_THAT(XRefs, UnorderedElementsAre(433                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 1)),434                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 36))));435 436  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 4);437  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);438  EXPECT_THAT(XRefs, UnorderedElementsAre(439                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 38))));440 441  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 6);442  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());443 444  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 8);445  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);446  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());447 448  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 10);449  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);450  EXPECT_THAT(XRefs, UnorderedElementsAre(451                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 8))));452 453  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 12);454  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);455  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());456 457  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 17);458  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);459  EXPECT_THAT(XRefs, UnorderedElementsAre(460                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 10)),461                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 12))));462 463  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 22);464  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);465  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());466 467  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 27);468  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);469  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());470 471  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 29);472  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);473  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());474 475  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 31);476  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);477  EXPECT_THAT(XRefs, UnorderedElementsAre(478                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 22)),479                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 29))));480 481  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 33);482  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);483  EXPECT_THAT(XRefs, UnorderedElementsAre(484                         Field(&Instr::VMAddress, Eq(0xDEADBEEF + 31))));485 486  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 34);487  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);488  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());489 490  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 36);491  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);492  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());493 494  InstrMetaPtr = &Analysis.getInstructionOrDie(0xDEADBEEF + 38);495  XRefs = Analysis.getDirectControlFlowXRefs(*InstrMetaPtr);496  EXPECT_TRUE(Analysis.getDirectControlFlowXRefs(*InstrMetaPtr).empty());497}498 499TEST_F(BasicX86FileAnalysisTest, CFIProtectionInvalidTargets) {500  if (!SuccessfullyInitialised)501    GTEST_SKIP();502  Analysis.parseSectionContents(503      {504          0x90,       // 0: nop505          0x0f, 0x0b, // 1: ud2506          0x75, 0x00, // 3: jne 5 [+0]507      },508      {0xDEADBEEF, 0x0});509  GraphResult Result =510      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});511  EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,512            Analysis.validateCFIProtection(Result));513  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 1, 0x0});514  EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,515            Analysis.validateCFIProtection(Result));516  Result = GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});517  EXPECT_EQ(CFIProtectionStatus::FAIL_NOT_INDIRECT_CF,518            Analysis.validateCFIProtection(Result));519  Result = GraphBuilder::buildFlowGraph(Analysis, {0x12345678, 0x0});520  EXPECT_EQ(CFIProtectionStatus::FAIL_INVALID_INSTRUCTION,521            Analysis.validateCFIProtection(Result));522}523 524TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicFallthroughToUd2) {525  if (!SuccessfullyInitialised)526    GTEST_SKIP();527  Analysis.parseSectionContents(528      {529          0x75, 0x02, // 0: jne 4 [+2]530          0x0f, 0x0b, // 2: ud2531          0xff, 0x10, // 4: callq *(%rax)532      },533      {0xDEADBEEF, 0x0});534  GraphResult Result =535      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});536  EXPECT_EQ(CFIProtectionStatus::PROTECTED,537            Analysis.validateCFIProtection(Result));538}539 540TEST_F(BasicX86FileAnalysisTest, CFIProtectionBasicJumpToUd2) {541  if (!SuccessfullyInitialised)542    GTEST_SKIP();543  Analysis.parseSectionContents(544      {545          0x75, 0x02, // 0: jne 4 [+2]546          0xff, 0x10, // 2: callq *(%rax)547          0x0f, 0x0b, // 4: ud2548      },549      {0xDEADBEEF, 0x0});550  GraphResult Result =551      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});552  EXPECT_EQ(CFIProtectionStatus::PROTECTED,553            Analysis.validateCFIProtection(Result));554}555 556TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathUd2) {557  if (!SuccessfullyInitialised)558    GTEST_SKIP();559  Analysis.parseSectionContents(560      {561          0x75, 0x03, // 0: jne 5 [+3]562          0x90,       // 2: nop563          0xff, 0x10, // 3: callq *(%rax)564          0x0f, 0x0b, // 5: ud2565          0x75, 0xf9, // 7: jne 2 [-7]566          0x0f, 0x0b, // 9: ud2567      },568      {0xDEADBEEF, 0x0});569  GraphResult Result =570      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});571  EXPECT_EQ(CFIProtectionStatus::PROTECTED,572            Analysis.validateCFIProtection(Result));573}574 575TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualPathSingleUd2) {576  if (!SuccessfullyInitialised)577    GTEST_SKIP();578  Analysis.parseSectionContents(579      {580          0x75, 0x05, // 0: jne 7 [+5]581          0x90,       // 2: nop582          0xff, 0x10, // 3: callq *(%rax)583          0x75, 0xfb, // 5: jne 2 [-5]584          0x0f, 0x0b, // 7: ud2585      },586      {0xDEADBEEF, 0x0});587  GraphResult Result =588      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 3, 0x0});589  EXPECT_EQ(CFIProtectionStatus::PROTECTED,590            Analysis.validateCFIProtection(Result));591}592 593TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitUpwards) {594  if (!SuccessfullyInitialised)595    GTEST_SKIP();596  Analysis.parseSectionContents(597      {598          0x75, 0x06, // 0: jne 8 [+6]599          0x90,       // 2: nop600          0x90,       // 3: nop601          0x90,       // 4: nop602          0x90,       // 5: nop603          0xff, 0x10, // 6: callq *(%rax)604          0x0f, 0x0b, // 8: ud2605      },606      {0xDEADBEEF, 0x0});607  uint64_t PrevSearchLengthForConditionalBranch =608      SearchLengthForConditionalBranch;609  SearchLengthForConditionalBranch = 2;610 611  GraphResult Result =612      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 6, 0x0});613  EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,614            Analysis.validateCFIProtection(Result));615 616  SearchLengthForConditionalBranch = PrevSearchLengthForConditionalBranch;617}618 619TEST_F(BasicX86FileAnalysisTest, CFIProtectionDualFailLimitDownwards) {620  if (!SuccessfullyInitialised)621    GTEST_SKIP();622  Analysis.parseSectionContents(623      {624          0x75, 0x02, // 0: jne 4 [+2]625          0xff, 0x10, // 2: callq *(%rax)626          0x90,       // 4: nop627          0x90,       // 5: nop628          0x90,       // 6: nop629          0x90,       // 7: nop630          0x0f, 0x0b, // 8: ud2631      },632      {0xDEADBEEF, 0x0});633  uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;634  SearchLengthForUndef = 2;635 636  GraphResult Result =637      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 2, 0x0});638  EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,639            Analysis.validateCFIProtection(Result));640 641  SearchLengthForUndef = PrevSearchLengthForUndef;642}643 644TEST_F(BasicX86FileAnalysisTest, CFIProtectionGoodAndBadPaths) {645  if (!SuccessfullyInitialised)646    GTEST_SKIP();647  Analysis.parseSectionContents(648      {649          0xeb, 0x02, // 0: jmp 4 [+2]650          0x75, 0x02, // 2: jne 6 [+2]651          0xff, 0x10, // 4: callq *(%rax)652          0x0f, 0x0b, // 6: ud2653      },654      {0xDEADBEEF, 0x0});655  GraphResult Result =656      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});657  EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,658            Analysis.validateCFIProtection(Result));659}660 661TEST_F(BasicX86FileAnalysisTest, CFIProtectionWithUnconditionalJumpInFallthrough) {662  if (!SuccessfullyInitialised)663    GTEST_SKIP();664  Analysis.parseSectionContents(665      {666          0x75, 0x04, // 0: jne 6 [+4]667          0xeb, 0x00, // 2: jmp 4 [+0]668          0xff, 0x10, // 4: callq *(%rax)669          0x0f, 0x0b, // 6: ud2670      },671      {0xDEADBEEF, 0x0});672  GraphResult Result =673      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});674  EXPECT_EQ(CFIProtectionStatus::PROTECTED,675            Analysis.validateCFIProtection(Result));676}677 678TEST_F(BasicX86FileAnalysisTest, CFIProtectionComplexExample) {679  if (!SuccessfullyInitialised)680    GTEST_SKIP();681  // See unittests/GraphBuilder.cpp::BuildFlowGraphComplexExample for this682  // graph.683  Analysis.parseSectionContents(684      {685          0x75, 0x12,                   // 0: jne 20 [+18]686          0xeb, 0x03,                   // 2: jmp 7 [+3]687          0x75, 0x10,                   // 4: jne 22 [+16]688          0x90,                         // 6: nop689          0x90,                         // 7: nop690          0x90,                         // 8: nop691          0xff, 0x10,                   // 9: callq *(%rax)692          0xeb, 0xfc,                   // 11: jmp 9 [-4]693          0x75, 0xfa,                   // 13: jne 9 [-6]694          0xe8, 0x78, 0x56, 0x34, 0x12, // 15: callq OUTOFBOUNDS [+0x12345678]695          0x90,                         // 20: nop696          0x90,                         // 21: nop697          0x0f, 0x0b,                   // 22: ud2698      },699      {0xDEADBEEF, 0x0});700  uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;701  SearchLengthForUndef = 5;702  GraphResult Result =703      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});704  EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,705            Analysis.validateCFIProtection(Result));706  SearchLengthForUndef = PrevSearchLengthForUndef;707}708 709TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTest) {710  if (!SuccessfullyInitialised)711    GTEST_SKIP();712  Analysis.parseSectionContents(713      {714          0x77, 0x0d,                   // 0x688118: ja 0x688127 [+12]715          0x48, 0x89, 0xdf,             // 0x68811a: mov %rbx, %rdi716          0xff, 0xd0,                   // 0x68811d: callq *%rax717          0x48, 0x89, 0xdf,             // 0x68811f: mov %rbx, %rdi718          0xe8, 0x09, 0x00, 0x00, 0x00, // 0x688122: callq 0x688130719          0x0f, 0x0b,                   // 0x688127: ud2720      },721      {0x688118, 0x0});722  uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;723  SearchLengthForUndef = 1;724  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x68811d, 0x0});725  EXPECT_EQ(CFIProtectionStatus::PROTECTED,726            Analysis.validateCFIProtection(Result));727  SearchLengthForUndef = PrevSearchLengthForUndef;728}729 730TEST_F(BasicX86FileAnalysisTest, UndefSearchLengthOneTestFarAway) {731  if (!SuccessfullyInitialised)732    GTEST_SKIP();733  Analysis.parseSectionContents(734      {735          0x74, 0x73,                         // 0x7759eb: je 0x775a60736          0xe9, 0x1c, 0x04, 0x00, 0x00, 0x00, // 0x7759ed: jmpq 0x775e0e737      },738      {0x7759eb, 0x0});739 740  Analysis.parseSectionContents(741      {742          0x0f, 0x85, 0xb2, 0x03, 0x00, 0x00, // 0x775a56: jne    0x775e0e743          0x48, 0x83, 0xc3, 0xf4, // 0x775a5c: add    $0xfffffffffffffff4,%rbx744          0x48, 0x8b, 0x7c, 0x24, 0x10, // 0x775a60: mov    0x10(%rsp),%rdi745          0x48, 0x89, 0xde,             // 0x775a65: mov    %rbx,%rsi746          0xff, 0xd1,                   // 0x775a68: callq  *%rcx747      },748      {0x775a56, 0x0});749 750  Analysis.parseSectionContents(751      {752          0x0f, 0x0b, // 0x775e0e: ud2753      },754      {0x775e0e, 0x0});755  uint64_t PrevSearchLengthForUndef = SearchLengthForUndef;756  SearchLengthForUndef = 1;757  GraphResult Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});758  EXPECT_EQ(CFIProtectionStatus::FAIL_BAD_CONDITIONAL_BRANCH,759            Analysis.validateCFIProtection(Result));760  SearchLengthForUndef = 2;761  Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});762  EXPECT_EQ(CFIProtectionStatus::PROTECTED,763            Analysis.validateCFIProtection(Result));764  SearchLengthForUndef = 3;765  Result = GraphBuilder::buildFlowGraph(Analysis, {0x775a68, 0x0});766  EXPECT_EQ(CFIProtectionStatus::PROTECTED,767            Analysis.validateCFIProtection(Result));768  SearchLengthForUndef = PrevSearchLengthForUndef;769}770 771TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit) {772  if (!SuccessfullyInitialised)773    GTEST_SKIP();774  Analysis.parseSectionContents(775      {776          0x75, 0x02,                         // 0: jne 4 [+2]777          0x0f, 0x0b,                         // 2: ud2778          0x48, 0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %rax779          0xff, 0x10,                         // 10: callq *(%rax)780      },781      {0xDEADBEEF, 0x0});782  GraphResult Result =783      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 10, 0x0});784  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,785            Analysis.validateCFIProtection(Result));786}787 788TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathExplicit2) {789  if (!SuccessfullyInitialised)790    GTEST_SKIP();791  Analysis.parseSectionContents(792      {793          0x75, 0x02,             // 0: jne 4 [+2]794          0x0f, 0x0b,             // 2: ud2795          0x48, 0x83, 0xc0, 0x00, // 4: add $0x0, %rax796          0xff, 0x10,             // 8: callq *(%rax)797      },798      {0xDEADBEEF, 0x0});799  GraphResult Result =800      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});801  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,802            Analysis.validateCFIProtection(Result));803}804 805TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberSinglePathImplicit) {806  if (!SuccessfullyInitialised)807    GTEST_SKIP();808  Analysis.parseSectionContents(809      {810          0x75, 0x02,                   // 0: jne 4 [+2]811          0x0f, 0x0b,                   // 2: ud2812          0x05, 0x00, 0x00, 0x00, 0x00, // 4: add $0x0, %eax813          0xff, 0x10,                   // 9: callq *(%rax)814      },815      {0xDEADBEEF, 0x0});816  GraphResult Result =817      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 9, 0x0});818  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,819            Analysis.validateCFIProtection(Result));820}821 822TEST_F(BasicX86FileAnalysisTest, CFIProtectionClobberDualPathImplicit) {823  if (!SuccessfullyInitialised)824    GTEST_SKIP();825  Analysis.parseSectionContents(826      {827          0x75, 0x04, // 0: jne 6 [+4]828          0x0f, 0x31, // 2: rdtsc (note: affects eax)829          0xff, 0x10, // 4: callq *(%rax)830          0x0f, 0x0b, // 6: ud2831          0x75, 0xf9, // 8: jne 2 [-7]832          0x0f, 0x0b, // 10: ud2833      },834      {0xDEADBEEF, 0x0});835  GraphResult Result =836      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 4, 0x0});837  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,838            Analysis.validateCFIProtection(Result));839}840 841TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicUnprotected) {842  if (!SuccessfullyInitialised)843    GTEST_SKIP();844  Analysis.parseSectionContents(845      {846          0x00, 0x01, 0x3f, 0xd6, // 0: blr x8847      },848      {0xDEADBEEF, 0x0});849  GraphResult Result =850      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF, 0x0});851  EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,852            Analysis.validateCFIProtection(Result));853}854 855TEST_F(BasicAArch64FileAnalysisTest, AArch64BasicProtected) {856  if (!SuccessfullyInitialised)857    GTEST_SKIP();858  Analysis.parseSectionContents(859      {860          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8861          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1862          0x00, 0x01, 0x3f, 0xd6, // 8: blr x8863      },864      {0xDEADBEEF, 0x0});865  GraphResult Result =866      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 8, 0x0});867  EXPECT_EQ(CFIProtectionStatus::PROTECTED,868            Analysis.validateCFIProtection(Result));869}870 871TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberBasic) {872  if (!SuccessfullyInitialised)873    GTEST_SKIP();874  Analysis.parseSectionContents(875      {876          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8877          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1878          0x08, 0x05, 0x00, 0x91, // 8: add x8, x8, #1879          0x00, 0x01, 0x3f, 0xd6, // 12: blr x8880      },881      {0xDEADBEEF, 0x0});882  GraphResult Result =883      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});884  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,885            Analysis.validateCFIProtection(Result));886}887 888TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberOneLoad) {889  if (!SuccessfullyInitialised)890    GTEST_SKIP();891  Analysis.parseSectionContents(892      {893          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8894          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1895          0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]896          0x20, 0x00, 0x1f, 0xd6, // 12: br x1897      },898      {0xDEADBEEF, 0x0});899  GraphResult Result =900      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});901  EXPECT_EQ(CFIProtectionStatus::PROTECTED,902            Analysis.validateCFIProtection(Result));903}904 905TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddGood) {906  if (!SuccessfullyInitialised)907    GTEST_SKIP();908  Analysis.parseSectionContents(909      {910          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8911          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1912          0x21, 0x04, 0x00, 0x91, // 8: add x1, x1, #1913          0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]914          0x20, 0x00, 0x1f, 0xd6, // 16: br x1915      },916      {0xDEADBEEF, 0x0});917  GraphResult Result =918      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});919  EXPECT_EQ(CFIProtectionStatus::PROTECTED,920            Analysis.validateCFIProtection(Result));921}922 923TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad) {924  if (!SuccessfullyInitialised)925    GTEST_SKIP();926  Analysis.parseSectionContents(927      {928          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8929          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1930          0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]931          0x21, 0x04, 0x00, 0x91, // 12: add x1, x1, #1932          0x20, 0x00, 0x1f, 0xd6, // 16: br x1933      },934      {0xDEADBEEF, 0x0});935  GraphResult Result =936      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});937  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,938            Analysis.validateCFIProtection(Result));939}940 941TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberLoadAddBad2) {942  if (!SuccessfullyInitialised)943    GTEST_SKIP();944  Analysis.parseSectionContents(945      {946          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8947          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1948          0x29, 0x04, 0x00, 0x91, // 16: add x9, x1, #1949          0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]950          0x20, 0x00, 0x1f, 0xd6, // 16: br x1951      },952      {0xDEADBEEF, 0x0});953  GraphResult Result =954      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});955  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,956            Analysis.validateCFIProtection(Result));957}958 959TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberTwoLoads) {960  if (!SuccessfullyInitialised)961    GTEST_SKIP();962  Analysis.parseSectionContents(963      {964          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8965          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1966          0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]967          0x21, 0x08, 0x40, 0xf9, // 12: ldr x1, [x1,#16]968          0x20, 0x00, 0x1f, 0xd6, // 16: br x1969      },970      {0xDEADBEEF, 0x0});971  GraphResult Result =972      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});973  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,974            Analysis.validateCFIProtection(Result));975}976 977TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedSecondLoad) {978  if (!SuccessfullyInitialised)979    GTEST_SKIP();980  Analysis.parseSectionContents(981      {982          0x49, 0x00, 0x00, 0x54, // 0: b.ls 8983          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x1984          0x21, 0x09, 0x40, 0xf9, // 8: ldr x1, [x9,#16]985          0x21, 0x09, 0x40, 0xf9, // 12: ldr x1, [x9,#16]986          0x20, 0x00, 0x1f, 0xd6, // 16: br x1987      },988      {0xDEADBEEF, 0x0});989  GraphResult Result =990      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});991  EXPECT_EQ(CFIProtectionStatus::PROTECTED,992            Analysis.validateCFIProtection(Result));993}994 995TEST_F(BasicAArch64FileAnalysisTest, AArch64ClobberUnrelatedLoads) {996  if (!SuccessfullyInitialised)997    GTEST_SKIP();998  Analysis.parseSectionContents(999      {1000          0x49, 0x00, 0x00, 0x54, // 0: b.ls 81001          0x20, 0x00, 0x20, 0xd4, // 4: brk #0x11002          0x22, 0x09, 0x40, 0xf9, // 8: ldr x2, [x9,#16]1003          0x22, 0x08, 0x40, 0xf9, // 12: ldr x2, [x1,#16]1004          0x20, 0x00, 0x1f, 0xd6, // 16: br x11005      },1006      {0xDEADBEEF, 0x0});1007  GraphResult Result =1008      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 16, 0x0});1009  EXPECT_EQ(CFIProtectionStatus::PROTECTED,1010            Analysis.validateCFIProtection(Result));1011}1012 1013TEST_F(BasicAArch64FileAnalysisTest, AArch64GoodAndBadPaths) {1014  if (!SuccessfullyInitialised)1015    GTEST_SKIP();1016  Analysis.parseSectionContents(1017      {1018          0x03, 0x00, 0x00, 0x14, // 0: b 121019          0x49, 0x00, 0x00, 0x54, // 4: b.ls 81020          0x20, 0x00, 0x20, 0xd4, // 8: brk #0x11021          0x20, 0x00, 0x1f, 0xd6, // 12: br x11022      },1023      {0xDEADBEEF, 0x0});1024  GraphResult Result =1025      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 12, 0x0});1026  EXPECT_EQ(CFIProtectionStatus::FAIL_ORPHANS,1027            Analysis.validateCFIProtection(Result));1028}1029 1030TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPaths) {1031  if (!SuccessfullyInitialised)1032    GTEST_SKIP();1033  Analysis.parseSectionContents(1034      {1035          0xc9, 0x00, 0x00, 0x54, // 0: b.ls 241036          0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]1037          0x03, 0x00, 0x00, 0x14, // 8: b 121038          0x69, 0x00, 0x00, 0x54, // 12: b.ls 121039          0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]1040          0x20, 0x00, 0x1f, 0xd6, // 20: br x11041          0x20, 0x00, 0x20, 0xd4, // 24: brk #0x11042      },1043      {0xDEADBEEF, 0x0});1044  GraphResult Result =1045      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 20, 0x0});1046  EXPECT_EQ(CFIProtectionStatus::PROTECTED,1047            Analysis.validateCFIProtection(Result));1048}1049 1050TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad1) {1051  if (!SuccessfullyInitialised)1052    GTEST_SKIP();1053  Analysis.parseSectionContents(1054      {1055          0xe9, 0x00, 0x00, 0x54, // 0: b.ls 281056          0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]1057          0x21, 0x08, 0x40, 0xf9, // 8: ldr x1, [x1,#16]1058          0x03, 0x00, 0x00, 0x14, // 12: b 121059          0x69, 0x00, 0x00, 0x54, // 16: b.ls 121060          0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]1061          0x20, 0x00, 0x1f, 0xd6, // 24: br x11062          0x20, 0x00, 0x20, 0xd4, // 28: brk #0x11063      },1064      {0xDEADBEEF, 0x0});1065  GraphResult Result =1066      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});1067  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,1068            Analysis.validateCFIProtection(Result));1069}1070 1071TEST_F(BasicAArch64FileAnalysisTest, AArch64TwoPathsBadLoad2) {1072  if (!SuccessfullyInitialised)1073    GTEST_SKIP();1074  Analysis.parseSectionContents(1075      {1076          0xe9, 0x00, 0x00, 0x54, // 0: b.ls 281077          0x21, 0x08, 0x40, 0xf9, // 4: ldr x1, [x1,#16]1078          0x03, 0x00, 0x00, 0x14, // 8: b 121079          0x89, 0x00, 0x00, 0x54, // 12: b.ls 161080          0x21, 0x08, 0x40, 0xf9, // 16: ldr x1, [x1,#16]1081          0x21, 0x08, 0x40, 0xf9, // 20: ldr x1, [x1,#16]1082          0x20, 0x00, 0x1f, 0xd6, // 24: br x11083          0x20, 0x00, 0x20, 0xd4, // 28: brk #0x11084      },1085      {0xDEADBEEF, 0x0});1086  GraphResult Result =1087      GraphBuilder::buildFlowGraph(Analysis, {0xDEADBEEF + 24, 0x0});1088  EXPECT_EQ(CFIProtectionStatus::FAIL_REGISTER_CLOBBERED,1089            Analysis.validateCFIProtection(Result));1090}1091 1092} // anonymous namespace1093} // end namespace cfi_verify1094} // end namespace llvm1095 1096int main(int argc, char **argv) {1097  ::testing::InitGoogleTest(&argc, argv);1098  llvm::cl::ParseCommandLineOptions(argc, argv);1099 1100  llvm::InitializeAllTargetInfos();1101  llvm::InitializeAllTargetMCs();1102  llvm::InitializeAllAsmParsers();1103  llvm::InitializeAllDisassemblers();1104 1105  return RUN_ALL_TESTS();1106}1107