xref: /llvm-project/lldb/unittests/Disassembler/x86/TestGetControlFlowKindx86.cpp (revision f109517d153609d4a8a3a3d3d3cc06da1b629364)
189c9fee4SDavid Spickett //===-- TestX86GetControlFlowKind.cpp -------------------------------------===//
2ad7bcda9SWalter Erquinigo 
3ad7bcda9SWalter Erquinigo //
4ad7bcda9SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5ad7bcda9SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
6ad7bcda9SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7ad7bcda9SWalter Erquinigo //
8ad7bcda9SWalter Erquinigo //===----------------------------------------------------------------------===//
9ad7bcda9SWalter Erquinigo 
10ad7bcda9SWalter Erquinigo #include "llvm/Support/TargetSelect.h"
11ad7bcda9SWalter Erquinigo #include "gtest/gtest.h"
12ad7bcda9SWalter Erquinigo 
13ad7bcda9SWalter Erquinigo #include "lldb/Core/Address.h"
14ad7bcda9SWalter Erquinigo #include "lldb/Core/Disassembler.h"
15ad7bcda9SWalter Erquinigo #include "lldb/Target/ExecutionContext.h"
16ad7bcda9SWalter Erquinigo #include "lldb/Utility/ArchSpec.h"
17ad7bcda9SWalter Erquinigo 
18ad7bcda9SWalter Erquinigo #include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h"
19ad7bcda9SWalter Erquinigo 
20ad7bcda9SWalter Erquinigo using namespace lldb;
21ad7bcda9SWalter Erquinigo using namespace lldb_private;
22ad7bcda9SWalter Erquinigo 
23dfa8a15dSVenkata Ramanaiah Nalamothu namespace {
24ad7bcda9SWalter Erquinigo class TestGetControlFlowKindx86 : public testing::Test {
25ad7bcda9SWalter Erquinigo public:
26ad7bcda9SWalter Erquinigo   static void SetUpTestCase();
27ad7bcda9SWalter Erquinigo   static void TearDownTestCase();
28ad7bcda9SWalter Erquinigo 
29ad7bcda9SWalter Erquinigo protected:
30ad7bcda9SWalter Erquinigo };
31ad7bcda9SWalter Erquinigo 
32ad7bcda9SWalter Erquinigo void TestGetControlFlowKindx86::SetUpTestCase() {
33ad7bcda9SWalter Erquinigo   llvm::InitializeAllTargets();
34ad7bcda9SWalter Erquinigo   llvm::InitializeAllAsmPrinters();
35ad7bcda9SWalter Erquinigo   llvm::InitializeAllTargetMCs();
36ad7bcda9SWalter Erquinigo   llvm::InitializeAllDisassemblers();
37ad7bcda9SWalter Erquinigo   DisassemblerLLVMC::Initialize();
38ad7bcda9SWalter Erquinigo }
39ad7bcda9SWalter Erquinigo 
40ad7bcda9SWalter Erquinigo void TestGetControlFlowKindx86::TearDownTestCase() {
41ad7bcda9SWalter Erquinigo   DisassemblerLLVMC::Terminate();
42ad7bcda9SWalter Erquinigo }
43dfa8a15dSVenkata Ramanaiah Nalamothu } // namespace
44ad7bcda9SWalter Erquinigo 
45ad7bcda9SWalter Erquinigo TEST_F(TestGetControlFlowKindx86, TestX86_64Instruction) {
46ad7bcda9SWalter Erquinigo   ArchSpec arch("x86_64-*-linux");
47ad7bcda9SWalter Erquinigo 
48ad7bcda9SWalter Erquinigo   const unsigned num_of_instructions = 29;
49ad7bcda9SWalter Erquinigo   uint8_t data[] = {
50ad7bcda9SWalter Erquinigo       0x55,                               // other -- pushq %rbp
51ad7bcda9SWalter Erquinigo       0x48, 0x89, 0xe5,                   // other -- movq %rsp, %rbp
52ad7bcda9SWalter Erquinigo 
53ad7bcda9SWalter Erquinigo       0xe8, 0xfc, 0xfe, 0xff, 0xff,       // call -- callq 0x4004c0
54ad7bcda9SWalter Erquinigo       0x41, 0xff, 0x14, 0xdc,             // call -- callq *(%r12,%rbx,8)
55ad7bcda9SWalter Erquinigo       0xff, 0x50, 0x18,                   // call -- callq *0x18(%rax)
56ad7bcda9SWalter Erquinigo       0xe8, 0x48, 0x0d, 0x00, 0x00,       // call -- callq 0x94fe0
57ad7bcda9SWalter Erquinigo 
58ad7bcda9SWalter Erquinigo       0xc3,                               // return -- retq
59ad7bcda9SWalter Erquinigo 
60ad7bcda9SWalter Erquinigo       0xeb, 0xd3,                         // jump -- jmp 0x92dab
61ad7bcda9SWalter Erquinigo       0xe9, 0x22, 0xff, 0xff, 0xff,       // jump -- jmp 0x933ae
62ad7bcda9SWalter Erquinigo       0xff, 0xe0,                         // jump -- jmpq *%rax
63ad7bcda9SWalter Erquinigo       0xf2, 0xff, 0x25, 0x75, 0xe7, 0x39, 0x00, // jump -- repne jmpq *0x39e775
64ad7bcda9SWalter Erquinigo 
65ad7bcda9SWalter Erquinigo       0x73, 0xc2,                         // cond jump -- jae 0x9515c
66ad7bcda9SWalter Erquinigo       0x74, 0x1f,                         // cond jump -- je 0x400626
67ad7bcda9SWalter Erquinigo       0x75, 0xea,                         // cond jump -- jne 0x400610
68ad7bcda9SWalter Erquinigo       0x76, 0x10,                         // cond jump -- jbe 0x94d10
69ad7bcda9SWalter Erquinigo       0x77, 0x58,                         // cond jump -- ja 0x1208c8
70ad7bcda9SWalter Erquinigo       0x7e, 0x67,                         // cond jump -- jle 0x92180
71ad7bcda9SWalter Erquinigo       0x78, 0x0b,                         // cond jump -- js 0x92dc3
72ad7bcda9SWalter Erquinigo       0x0f, 0x82, 0x17, 0x01, 0x00, 0x00, // cond jump -- jb 0x9c7b0
73ad7bcda9SWalter Erquinigo       0x0f, 0x83, 0xa7, 0x00, 0x00, 0x00, // cond jump -- jae 0x895c8
74ad7bcda9SWalter Erquinigo       0x0f, 0x84, 0x8c, 0x00, 0x00, 0x00, // cond jump -- je 0x941f0
75ad7bcda9SWalter Erquinigo       0x0f, 0x85, 0x51, 0xff, 0xff, 0xff, // cond jump -- jne 0x8952c
76ad7bcda9SWalter Erquinigo       0x0f, 0x86, 0xa3, 0x02, 0x00, 0x00, // cond jump -- jbe 0x9ae10
77ad7bcda9SWalter Erquinigo       0x0f, 0x87, 0xff, 0x00, 0x00, 0x00, // cond jump -- ja 0x9ab60
78ad7bcda9SWalter Erquinigo       0x0f, 0x8e, 0x7e, 0x00, 0x00, 0x00, // cond jump -- jle 0x92dd8
79ad7bcda9SWalter Erquinigo       0x0f, 0x86, 0xdf, 0x00, 0x00, 0x00, // cond jump -- jbe 0x921b0
80ad7bcda9SWalter Erquinigo 
81ad7bcda9SWalter Erquinigo       0x0f, 0x05,                         // far call -- syscall
82ad7bcda9SWalter Erquinigo 
83ad7bcda9SWalter Erquinigo       0x0f, 0x07,                         // far return -- sysret
84ad7bcda9SWalter Erquinigo       0xcf,                               // far return -- interrupt ret
85ad7bcda9SWalter Erquinigo   };
86ad7bcda9SWalter Erquinigo 
87ad7bcda9SWalter Erquinigo   InstructionControlFlowKind result[] = {
88ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindOther,
89ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindOther,
90ad7bcda9SWalter Erquinigo 
91ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCall,
92ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCall,
93ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCall,
94ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCall,
95ad7bcda9SWalter Erquinigo 
96ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindReturn,
97ad7bcda9SWalter Erquinigo 
98ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindJump,
99ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindJump,
100ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindJump,
101ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindJump,
102ad7bcda9SWalter Erquinigo 
103ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
104ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
105ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
106ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
107ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
108ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
109ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
110ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
111ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
112ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
113ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
114ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
115ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
116ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
117ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindCondJump,
118ad7bcda9SWalter Erquinigo 
119ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindFarCall,
120ad7bcda9SWalter Erquinigo 
121ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindFarReturn,
122ad7bcda9SWalter Erquinigo       eInstructionControlFlowKindFarReturn,
123ad7bcda9SWalter Erquinigo   };
124ad7bcda9SWalter Erquinigo 
125ad7bcda9SWalter Erquinigo   DisassemblerSP disass_sp;
126ad7bcda9SWalter Erquinigo   Address start_addr(0x100);
127*f109517dSJonas Devlieghere   disass_sp = Disassembler::DisassembleBytes(
128*f109517dSJonas Devlieghere       arch, nullptr, nullptr, nullptr, nullptr, start_addr, &data, sizeof(data),
129*f109517dSJonas Devlieghere       num_of_instructions, false);
130ad7bcda9SWalter Erquinigo 
131ad7bcda9SWalter Erquinigo   // If we failed to get a disassembler, we can assume it is because
132ad7bcda9SWalter Erquinigo   // the llvm we linked against was not built with the i386 target,
133ad7bcda9SWalter Erquinigo   // and we should skip these tests without marking anything as failing.
134254a3127SVenkata Ramanaiah Nalamothu   if (!disass_sp)
135254a3127SVenkata Ramanaiah Nalamothu     return;
136ad7bcda9SWalter Erquinigo 
137ad7bcda9SWalter Erquinigo   const InstructionList inst_list(disass_sp->GetInstructionList());
138ad7bcda9SWalter Erquinigo   EXPECT_EQ(num_of_instructions, inst_list.GetSize());
139ad7bcda9SWalter Erquinigo 
140ad7bcda9SWalter Erquinigo   for (size_t i = 0; i < num_of_instructions; ++i) {
141ad7bcda9SWalter Erquinigo     InstructionSP inst_sp;
142ad7bcda9SWalter Erquinigo     inst_sp = inst_list.GetInstructionAtIndex(i);
1430538e543SWalter Erquinigo     ExecutionContext exe_ctx(nullptr, nullptr, nullptr);
1440538e543SWalter Erquinigo     InstructionControlFlowKind kind = inst_sp->GetControlFlowKind(&exe_ctx);
145ad7bcda9SWalter Erquinigo     EXPECT_EQ(kind, result[i]);
146254a3127SVenkata Ramanaiah Nalamothu 
147254a3127SVenkata Ramanaiah Nalamothu     // Also, test the DisassemblerLLVMC::MCDisasmInstance methods.
14808201cb4SDavid Spickett     if (kind == eInstructionControlFlowKindReturn) {
149254a3127SVenkata Ramanaiah Nalamothu       EXPECT_FALSE(inst_sp->IsCall());
15008201cb4SDavid Spickett     }
15108201cb4SDavid Spickett 
15208201cb4SDavid Spickett     if (kind == eInstructionControlFlowKindCall) {
153254a3127SVenkata Ramanaiah Nalamothu       EXPECT_TRUE(inst_sp->IsCall());
15408201cb4SDavid Spickett     }
15508201cb4SDavid Spickett 
156254a3127SVenkata Ramanaiah Nalamothu     if (kind == eInstructionControlFlowKindCall ||
157254a3127SVenkata Ramanaiah Nalamothu         kind == eInstructionControlFlowKindJump ||
158254a3127SVenkata Ramanaiah Nalamothu         kind == eInstructionControlFlowKindCondJump ||
15908201cb4SDavid Spickett         kind == eInstructionControlFlowKindReturn) {
160254a3127SVenkata Ramanaiah Nalamothu       EXPECT_TRUE(inst_sp->DoesBranch());
161ad7bcda9SWalter Erquinigo     }
162ad7bcda9SWalter Erquinigo   }
16308201cb4SDavid Spickett }
164