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