1//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
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// This file implements the enhanced disassembler's public C API.
11//
12//===----------------------------------------------------------------------===//
13
14#include "EDDisassembler.h"
15#include "EDInst.h"
16#include "EDOperand.h"
17#include "EDToken.h"
18#include "llvm-c/EnhancedDisassembly.h"
19using namespace llvm;
20
21int EDGetDisassembler(EDDisassemblerRef *disassembler,
22                      const char *triple,
23                      EDAssemblySyntax_t syntax) {
24  EDDisassembler::AssemblySyntax Syntax;
25  switch (syntax) {
26  default: llvm_unreachable("Unknown assembly syntax!");
27  case kEDAssemblySyntaxX86Intel:
28    Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
29    break;
30  case kEDAssemblySyntaxX86ATT:
31    Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
32    break;
33  case kEDAssemblySyntaxARMUAL:
34    Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
35    break;
36  }
37
38  EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
39
40  if (!ret)
41    return -1;
42  *disassembler = ret;
43  return 0;
44}
45
46int EDGetRegisterName(const char** regName,
47                      EDDisassemblerRef disassembler,
48                      unsigned regID) {
49  const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
50  if (!name)
51    return -1;
52  *regName = name;
53  return 0;
54}
55
56int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
57                             unsigned regID) {
58  return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
59}
60
61int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
62                               unsigned regID) {
63  return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
64}
65
66unsigned int EDCreateInsts(EDInstRef *insts,
67                           unsigned int count,
68                           EDDisassemblerRef disassembler,
69                           ::EDByteReaderCallback byteReader,
70                           uint64_t address,
71                           void *arg) {
72  unsigned int index;
73
74  for (index = 0; index < count; ++index) {
75    EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
76                                                               address, arg);
77
78    if (!inst)
79      return index;
80
81    insts[index] = inst;
82    address += inst->byteSize();
83  }
84
85  return count;
86}
87
88void EDReleaseInst(EDInstRef inst) {
89  delete ((EDInst*)inst);
90}
91
92int EDInstByteSize(EDInstRef inst) {
93  return ((EDInst*)inst)->byteSize();
94}
95
96int EDGetInstString(const char **buf,
97                    EDInstRef inst) {
98  return ((EDInst*)inst)->getString(*buf);
99}
100
101int EDInstID(unsigned *instID, EDInstRef inst) {
102  *instID = ((EDInst*)inst)->instID();
103  return 0;
104}
105
106int EDInstIsBranch(EDInstRef inst) {
107  return ((EDInst*)inst)->isBranch();
108}
109
110int EDInstIsMove(EDInstRef inst) {
111  return ((EDInst*)inst)->isMove();
112}
113
114int EDBranchTargetID(EDInstRef inst) {
115  return ((EDInst*)inst)->branchTargetID();
116}
117
118int EDMoveSourceID(EDInstRef inst) {
119  return ((EDInst*)inst)->moveSourceID();
120}
121
122int EDMoveTargetID(EDInstRef inst) {
123  return ((EDInst*)inst)->moveTargetID();
124}
125
126int EDNumTokens(EDInstRef inst) {
127  return ((EDInst*)inst)->numTokens();
128}
129
130int EDGetToken(EDTokenRef *token,
131               EDInstRef inst,
132               int index) {
133  return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
134}
135
136int EDGetTokenString(const char **buf,
137                     EDTokenRef token) {
138  return ((EDToken*)token)->getString(*buf);
139}
140
141int EDOperandIndexForToken(EDTokenRef token) {
142  return ((EDToken*)token)->operandID();
143}
144
145int EDTokenIsWhitespace(EDTokenRef token) {
146  return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
147}
148
149int EDTokenIsPunctuation(EDTokenRef token) {
150  return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
151}
152
153int EDTokenIsOpcode(EDTokenRef token) {
154  return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
155}
156
157int EDTokenIsLiteral(EDTokenRef token) {
158  return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
159}
160
161int EDTokenIsRegister(EDTokenRef token) {
162  return ((EDToken*)token)->type() == EDToken::kTokenRegister;
163}
164
165int EDTokenIsNegativeLiteral(EDTokenRef token) {
166  if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
167    return -1;
168
169  return ((EDToken*)token)->literalSign();
170}
171
172int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
173  if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
174    return -1;
175
176  return ((EDToken*)token)->literalAbsoluteValue(*value);
177}
178
179int EDRegisterTokenValue(unsigned *registerID,
180                         EDTokenRef token) {
181  if (((EDToken*)token)->type() != EDToken::kTokenRegister)
182    return -1;
183
184  return ((EDToken*)token)->registerID(*registerID);
185}
186
187int EDNumOperands(EDInstRef inst) {
188  return ((EDInst*)inst)->numOperands();
189}
190
191int EDGetOperand(EDOperandRef *operand,
192                 EDInstRef inst,
193                 int index) {
194  return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
195}
196
197int EDOperandIsRegister(EDOperandRef operand) {
198  return ((EDOperand*)operand)->isRegister();
199}
200
201int EDOperandIsImmediate(EDOperandRef operand) {
202  return ((EDOperand*)operand)->isImmediate();
203}
204
205int EDOperandIsMemory(EDOperandRef operand) {
206  return ((EDOperand*)operand)->isMemory();
207}
208
209int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
210  if (!((EDOperand*)operand)->isRegister())
211    return -1;
212  *value = ((EDOperand*)operand)->regVal();
213  return 0;
214}
215
216int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
217  if (!((EDOperand*)operand)->isImmediate())
218    return -1;
219  *value = ((EDOperand*)operand)->immediateVal();
220  return 0;
221}
222
223int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
224                      ::EDRegisterReaderCallback regReader, void *arg) {
225  return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
226}
227
228#ifdef __BLOCKS__
229
230struct ByteReaderWrapper {
231  EDByteBlock_t byteBlock;
232};
233
234static int readerWrapperCallback(uint8_t *byte,
235                          uint64_t address,
236                          void *arg) {
237  struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
238  return wrapper->byteBlock(byte, address);
239}
240
241unsigned int EDBlockCreateInsts(EDInstRef *insts,
242                                int count,
243                                EDDisassemblerRef disassembler,
244                                EDByteBlock_t byteBlock,
245                                uint64_t address) {
246  struct ByteReaderWrapper wrapper;
247  wrapper.byteBlock = byteBlock;
248
249  return EDCreateInsts(insts, count, disassembler, readerWrapperCallback,
250                       address, (void*)&wrapper);
251}
252
253int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
254                           EDRegisterBlock_t regBlock) {
255  return ((EDOperand*)operand)->evaluate(*result, regBlock);
256}
257
258int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
259  return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
260}
261
262#else
263
264extern "C" unsigned int EDBlockCreateInsts() {
265  return 0;
266}
267
268extern "C" int EDBlockEvaluateOperand() {
269  return -1;
270}
271
272extern "C" int EDBlockVisitTokens() {
273  return -1;
274}
275
276#endif
277