1 //===- llvm/unittest/Object/Disassembler.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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm-c/Disassembler.h"
10 #include "llvm/Support/TargetSelect.h"
11 #include "gtest/gtest.h"
12 
13 using namespace llvm;
14 
symbolLookupCallback(void * DisInfo,uint64_t ReferenceValue,uint64_t * ReferenceType,uint64_t ReferencePC,const char ** ReferenceName)15 static const char *symbolLookupCallback(void *DisInfo, uint64_t ReferenceValue,
16                                         uint64_t *ReferenceType,
17                                         uint64_t ReferencePC,
18                                         const char **ReferenceName) {
19   *ReferenceType = LLVMDisassembler_ReferenceType_InOut_None;
20   return nullptr;
21 }
22 
TEST(Disassembler,X86Test)23 TEST(Disassembler, X86Test) {
24   llvm::InitializeAllTargetInfos();
25   llvm::InitializeAllTargetMCs();
26   llvm::InitializeAllDisassemblers();
27 
28   uint8_t Bytes[] = {0x90, 0x90, 0xeb, 0xfd};
29   uint8_t *BytesP = Bytes;
30   const char OutStringSize = 100;
31   char OutString[OutStringSize];
32   LLVMDisasmContextRef DCR = LLVMCreateDisasm("x86_64-pc-linux", nullptr, 0,
33                                               nullptr, symbolLookupCallback);
34   if (!DCR)
35     return;
36 
37   size_t InstSize;
38   unsigned NumBytes = sizeof(Bytes);
39   unsigned PC = 0;
40 
41   InstSize =
42       LLVMDisasmInstruction(DCR, BytesP, 0, PC, OutString, OutStringSize);
43   EXPECT_EQ(InstSize, 0U);
44 
45   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
46                                    OutStringSize);
47   EXPECT_EQ(InstSize, 1U);
48   EXPECT_EQ(StringRef(OutString), "\tnop");
49   PC += InstSize;
50   BytesP += InstSize;
51   NumBytes -= InstSize;
52 
53   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
54                                    OutStringSize);
55   EXPECT_EQ(InstSize, 1U);
56   EXPECT_EQ(StringRef(OutString), "\tnop");
57   PC += InstSize;
58   BytesP += InstSize;
59   NumBytes -= InstSize;
60 
61   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
62                                    OutStringSize);
63   EXPECT_EQ(InstSize, 2U);
64   EXPECT_EQ(StringRef(OutString), "\tjmp\t0x1");
65 
66   LLVMDisasmDispose(DCR);
67 }
68 
TEST(Disassembler,WebAssemblyTest)69 TEST(Disassembler, WebAssemblyTest) {
70   llvm::InitializeAllTargetInfos();
71   llvm::InitializeAllTargetMCs();
72   llvm::InitializeAllDisassemblers();
73 
74   uint8_t Bytes[] = {0x6a, 0x42, 0x7F, 0x35, 0x01, 0x10};
75   uint8_t *BytesP = Bytes;
76   const char OutStringSize = 100;
77   char OutString[OutStringSize];
78   LLVMDisasmContextRef DCR = LLVMCreateDisasm("wasm32-unknown-unknown", nullptr,
79                                               0, nullptr, symbolLookupCallback);
80   if (!DCR)
81     return;
82 
83   size_t InstSize;
84   unsigned NumBytes = sizeof(Bytes);
85   unsigned PC = 0;
86 
87   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
88                                    OutStringSize);
89   EXPECT_EQ(InstSize, 1U);
90   EXPECT_EQ(StringRef(OutString), "\ti32.add ");
91   PC += InstSize;
92   BytesP += InstSize;
93   NumBytes -= InstSize;
94 
95   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
96                                    OutStringSize);
97   EXPECT_EQ(InstSize, 2U);
98   EXPECT_EQ(StringRef(OutString), "\ti64.const\t-1");
99 
100   PC += InstSize;
101   BytesP += InstSize;
102   NumBytes -= InstSize;
103 
104   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
105                                    OutStringSize);
106   EXPECT_EQ(InstSize, 3U);
107   EXPECT_EQ(StringRef(OutString), "\ti64.load32_u\t16:p2align=1");
108 
109   LLVMDisasmDispose(DCR);
110 }
111