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, 250 count, 251 disassembler, 252 readerWrapperCallback, 253 address, 254 (void*)&wrapper); 255} 256 257int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand, 258 EDRegisterBlock_t regBlock) { 259 return ((EDOperand*)operand)->evaluate(*result, regBlock); 260} 261 262int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) { 263 return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor); 264} 265 266#else 267 268extern "C" unsigned int EDBlockCreateInsts() { 269 return 0; 270} 271 272extern "C" int EDBlockEvaluateOperand() { 273 return -1; 274} 275 276extern "C" int EDBlockVisitTokens() { 277 return -1; 278} 279 280#endif 281