1 //===-- TextX86GetControlFlowKind.cpp ------------------------------------------===//
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Support/TargetSelect.h"
11 #include "gtest/gtest.h"
13 #include "lldb/Core/Address.h"
14 #include "lldb/Core/Disassembler.h"
15 #include "lldb/Target/ExecutionContext.h"
16 #include "lldb/Utility/ArchSpec.h"
18 #include "Plugins/Disassembler/LLVMC/DisassemblerLLVMC.h"
21 using namespace lldb_private
;
23 class TestGetControlFlowKindx86
: public testing::Test
{
25 static void SetUpTestCase();
26 static void TearDownTestCase();
31 void TestGetControlFlowKindx86::SetUpTestCase() {
32 llvm::InitializeAllTargets();
33 llvm::InitializeAllAsmPrinters();
34 llvm::InitializeAllTargetMCs();
35 llvm::InitializeAllDisassemblers();
36 DisassemblerLLVMC::Initialize();
39 void TestGetControlFlowKindx86::TearDownTestCase() {
40 DisassemblerLLVMC::Terminate();
43 TEST_F(TestGetControlFlowKindx86
, TestX86_64Instruction
) {
44 ArchSpec
arch("x86_64-*-linux");
46 const unsigned num_of_instructions
= 29;
48 0x55, // other -- pushq %rbp
49 0x48, 0x89, 0xe5, // other -- movq %rsp, %rbp
51 0xe8, 0xfc, 0xfe, 0xff, 0xff, // call -- callq 0x4004c0
52 0x41, 0xff, 0x14, 0xdc, // call -- callq *(%r12,%rbx,8)
53 0xff, 0x50, 0x18, // call -- callq *0x18(%rax)
54 0xe8, 0x48, 0x0d, 0x00, 0x00, // call -- callq 0x94fe0
56 0xc3, // return -- retq
58 0xeb, 0xd3, // jump -- jmp 0x92dab
59 0xe9, 0x22, 0xff, 0xff, 0xff, // jump -- jmp 0x933ae
60 0xff, 0xe0, // jump -- jmpq *%rax
61 0xf2, 0xff, 0x25, 0x75, 0xe7, 0x39, 0x00, // jump -- repne jmpq *0x39e775
63 0x73, 0xc2, // cond jump -- jae 0x9515c
64 0x74, 0x1f, // cond jump -- je 0x400626
65 0x75, 0xea, // cond jump -- jne 0x400610
66 0x76, 0x10, // cond jump -- jbe 0x94d10
67 0x77, 0x58, // cond jump -- ja 0x1208c8
68 0x7e, 0x67, // cond jump -- jle 0x92180
69 0x78, 0x0b, // cond jump -- js 0x92dc3
70 0x0f, 0x82, 0x17, 0x01, 0x00, 0x00, // cond jump -- jb 0x9c7b0
71 0x0f, 0x83, 0xa7, 0x00, 0x00, 0x00, // cond jump -- jae 0x895c8
72 0x0f, 0x84, 0x8c, 0x00, 0x00, 0x00, // cond jump -- je 0x941f0
73 0x0f, 0x85, 0x51, 0xff, 0xff, 0xff, // cond jump -- jne 0x8952c
74 0x0f, 0x86, 0xa3, 0x02, 0x00, 0x00, // cond jump -- jbe 0x9ae10
75 0x0f, 0x87, 0xff, 0x00, 0x00, 0x00, // cond jump -- ja 0x9ab60
76 0x0f, 0x8e, 0x7e, 0x00, 0x00, 0x00, // cond jump -- jle 0x92dd8
77 0x0f, 0x86, 0xdf, 0x00, 0x00, 0x00, // cond jump -- jbe 0x921b0
79 0x0f, 0x05, // far call -- syscall
81 0x0f, 0x07, // far return -- sysret
82 0xcf, // far return -- interrupt ret
85 InstructionControlFlowKind result
[] = {
86 eInstructionControlFlowKindOther
,
87 eInstructionControlFlowKindOther
,
89 eInstructionControlFlowKindCall
,
90 eInstructionControlFlowKindCall
,
91 eInstructionControlFlowKindCall
,
92 eInstructionControlFlowKindCall
,
94 eInstructionControlFlowKindReturn
,
96 eInstructionControlFlowKindJump
,
97 eInstructionControlFlowKindJump
,
98 eInstructionControlFlowKindJump
,
99 eInstructionControlFlowKindJump
,
101 eInstructionControlFlowKindCondJump
,
102 eInstructionControlFlowKindCondJump
,
103 eInstructionControlFlowKindCondJump
,
104 eInstructionControlFlowKindCondJump
,
105 eInstructionControlFlowKindCondJump
,
106 eInstructionControlFlowKindCondJump
,
107 eInstructionControlFlowKindCondJump
,
108 eInstructionControlFlowKindCondJump
,
109 eInstructionControlFlowKindCondJump
,
110 eInstructionControlFlowKindCondJump
,
111 eInstructionControlFlowKindCondJump
,
112 eInstructionControlFlowKindCondJump
,
113 eInstructionControlFlowKindCondJump
,
114 eInstructionControlFlowKindCondJump
,
115 eInstructionControlFlowKindCondJump
,
117 eInstructionControlFlowKindFarCall
,
119 eInstructionControlFlowKindFarReturn
,
120 eInstructionControlFlowKindFarReturn
,
123 DisassemblerSP disass_sp
;
124 Address
start_addr(0x100);
126 Disassembler::DisassembleBytes(arch
, nullptr, nullptr, start_addr
, &data
,
127 sizeof (data
), num_of_instructions
, false);
129 // If we failed to get a disassembler, we can assume it is because
130 // the llvm we linked against was not built with the i386 target,
131 // and we should skip these tests without marking anything as failing.
134 const InstructionList
inst_list(disass_sp
->GetInstructionList());
135 EXPECT_EQ(num_of_instructions
, inst_list
.GetSize());
137 for (size_t i
= 0; i
< num_of_instructions
; ++i
) {
138 InstructionSP inst_sp
;
139 inst_sp
= inst_list
.GetInstructionAtIndex(i
);
140 ExecutionContext
exe_ctx (nullptr, nullptr, nullptr);
141 InstructionControlFlowKind kind
= inst_sp
->GetControlFlowKind(&exe_ctx
);
142 EXPECT_EQ(kind
, result
[i
]);