//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file implements the enhanced disassembler's public C API. // //===----------------------------------------------------------------------===// // FIXME: This code isn't layered right, the headers should be moved to // include llvm/MC/MCDisassembler or something. #include "../../lib/MC/MCDisassembler/EDDisassembler.h" #include "../../lib/MC/MCDisassembler/EDInst.h" #include "../../lib/MC/MCDisassembler/EDOperand.h" #include "../../lib/MC/MCDisassembler/EDToken.h" #include "llvm-c/EnhancedDisassembly.h" using namespace llvm; int EDGetDisassembler(EDDisassemblerRef *disassembler, const char *triple, EDAssemblySyntax_t syntax) { EDDisassembler::initialize(); EDDisassembler::AssemblySyntax Syntax; switch (syntax) { default: assert(0 && "Unknown assembly syntax!"); case kEDAssemblySyntaxX86Intel: Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel; break; case kEDAssemblySyntaxX86ATT: Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT; break; case kEDAssemblySyntaxARMUAL: Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL; break; } EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax); if (!ret) return -1; *disassembler = ret; return 0; } int EDGetRegisterName(const char** regName, EDDisassemblerRef disassembler, unsigned regID) { const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID); if (!name) return -1; *regName = name; return 0; } int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, unsigned regID) { return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0; } int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, unsigned regID) { return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0; } unsigned int EDCreateInsts(EDInstRef *insts, unsigned int count, EDDisassemblerRef disassembler, ::EDByteReaderCallback byteReader, uint64_t address, void *arg) { unsigned int index; for (index = 0; index < count; ++index) { EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader, address, arg); if (!inst) return index; insts[index] = inst; address += inst->byteSize(); } return count; } void EDReleaseInst(EDInstRef inst) { delete ((EDInst*)inst); } int EDInstByteSize(EDInstRef inst) { return ((EDInst*)inst)->byteSize(); } int EDGetInstString(const char **buf, EDInstRef inst) { return ((EDInst*)inst)->getString(*buf); } int EDInstID(unsigned *instID, EDInstRef inst) { *instID = ((EDInst*)inst)->instID(); return 0; } int EDInstIsBranch(EDInstRef inst) { return ((EDInst*)inst)->isBranch(); } int EDInstIsMove(EDInstRef inst) { return ((EDInst*)inst)->isMove(); } int EDBranchTargetID(EDInstRef inst) { return ((EDInst*)inst)->branchTargetID(); } int EDMoveSourceID(EDInstRef inst) { return ((EDInst*)inst)->moveSourceID(); } int EDMoveTargetID(EDInstRef inst) { return ((EDInst*)inst)->moveTargetID(); } int EDNumTokens(EDInstRef inst) { return ((EDInst*)inst)->numTokens(); } int EDGetToken(EDTokenRef *token, EDInstRef inst, int index) { return ((EDInst*)inst)->getToken(*(EDToken**)token, index); } int EDGetTokenString(const char **buf, EDTokenRef token) { return ((EDToken*)token)->getString(*buf); } int EDOperandIndexForToken(EDTokenRef token) { return ((EDToken*)token)->operandID(); } int EDTokenIsWhitespace(EDTokenRef token) { return ((EDToken*)token)->type() == EDToken::kTokenWhitespace; } int EDTokenIsPunctuation(EDTokenRef token) { return ((EDToken*)token)->type() == EDToken::kTokenPunctuation; } int EDTokenIsOpcode(EDTokenRef token) { return ((EDToken*)token)->type() == EDToken::kTokenOpcode; } int EDTokenIsLiteral(EDTokenRef token) { return ((EDToken*)token)->type() == EDToken::kTokenLiteral; } int EDTokenIsRegister(EDTokenRef token) { return ((EDToken*)token)->type() == EDToken::kTokenRegister; } int EDTokenIsNegativeLiteral(EDTokenRef token) { if (((EDToken*)token)->type() != EDToken::kTokenLiteral) return -1; return ((EDToken*)token)->literalSign(); } int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) { if (((EDToken*)token)->type() != EDToken::kTokenLiteral) return -1; return ((EDToken*)token)->literalAbsoluteValue(*value); } int EDRegisterTokenValue(unsigned *registerID, EDTokenRef token) { if (((EDToken*)token)->type() != EDToken::kTokenRegister) return -1; return ((EDToken*)token)->registerID(*registerID); } int EDNumOperands(EDInstRef inst) { return ((EDInst*)inst)->numOperands(); } int EDGetOperand(EDOperandRef *operand, EDInstRef inst, int index) { return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index); } int EDOperandIsRegister(EDOperandRef operand) { return ((EDOperand*)operand)->isRegister(); } int EDOperandIsImmediate(EDOperandRef operand) { return ((EDOperand*)operand)->isImmediate(); } int EDOperandIsMemory(EDOperandRef operand) { return ((EDOperand*)operand)->isMemory(); } int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) { if (!((EDOperand*)operand)->isRegister()) return -1; *value = ((EDOperand*)operand)->regVal(); return 0; } int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) { if (!((EDOperand*)operand)->isImmediate()) return -1; *value = ((EDOperand*)operand)->immediateVal(); return 0; } int EDEvaluateOperand(uint64_t *result, EDOperandRef operand, ::EDRegisterReaderCallback regReader, void *arg) { return ((EDOperand*)operand)->evaluate(*result, regReader, arg); } #ifdef __BLOCKS__ struct ByteReaderWrapper { EDByteBlock_t byteBlock; }; static int readerWrapperCallback(uint8_t *byte, uint64_t address, void *arg) { struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg; return wrapper->byteBlock(byte, address); } unsigned int EDBlockCreateInsts(EDInstRef *insts, int count, EDDisassemblerRef disassembler, EDByteBlock_t byteBlock, uint64_t address) { struct ByteReaderWrapper wrapper; wrapper.byteBlock = byteBlock; return EDCreateInsts(insts, count, disassembler, readerWrapperCallback, address, (void*)&wrapper); } int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand, EDRegisterBlock_t regBlock) { return ((EDOperand*)operand)->evaluate(*result, regBlock); } int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) { return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor); } #else extern "C" unsigned int EDBlockCreateInsts() { return 0; } extern "C" int EDBlockEvaluateOperand() { return -1; } extern "C" int EDBlockVisitTokens() { return -1; } #endif