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