| //===-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. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #include "EDDisassembler.h" |
| #include "EDInst.h" |
| #include "EDOperand.h" |
| #include "EDToken.h" |
| |
| #include "llvm-c/EnhancedDisassembly.h" |
| |
| int EDGetDisassembler(EDDisassemblerRef *disassembler, |
| const char *triple, |
| EDAssemblySyntax_t syntax) { |
| EDDisassembler::initialize(); |
| |
| EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, |
| syntax); |
| |
| if (ret) { |
| *disassembler = ret; |
| return 0; |
| } else { |
| return -1; |
| } |
| } |
| |
| int EDGetRegisterName(const char** regName, |
| EDDisassemblerRef disassembler, |
| unsigned regID) { |
| const char* name = disassembler->nameWithRegisterID(regID); |
| if (!name) |
| return -1; |
| *regName = name; |
| return 0; |
| } |
| |
| int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, |
| unsigned regID) { |
| return disassembler->registerIsStackPointer(regID) ? 1 : 0; |
| } |
| |
| int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, |
| unsigned regID) { |
| return 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 = disassembler->createInst(byteReader, address, arg); |
| |
| if (!inst) |
| return index; |
| |
| insts[index] = inst; |
| address += inst->byteSize(); |
| } |
| |
| return count; |
| } |
| |
| void EDReleaseInst(EDInstRef inst) { |
| delete inst; |
| } |
| |
| int EDInstByteSize(EDInstRef inst) { |
| return inst->byteSize(); |
| } |
| |
| int EDGetInstString(const char **buf, |
| EDInstRef inst) { |
| return inst->getString(*buf); |
| } |
| |
| int EDInstID(unsigned *instID, EDInstRef inst) { |
| *instID = inst->instID(); |
| return 0; |
| } |
| |
| int EDInstIsBranch(EDInstRef inst) { |
| return inst->isBranch(); |
| } |
| |
| int EDInstIsMove(EDInstRef inst) { |
| return inst->isMove(); |
| } |
| |
| int EDBranchTargetID(EDInstRef inst) { |
| return inst->branchTargetID(); |
| } |
| |
| int EDMoveSourceID(EDInstRef inst) { |
| return inst->moveSourceID(); |
| } |
| |
| int EDMoveTargetID(EDInstRef inst) { |
| return inst->moveTargetID(); |
| } |
| |
| int EDNumTokens(EDInstRef inst) { |
| return inst->numTokens(); |
| } |
| |
| int EDGetToken(EDTokenRef *token, |
| EDInstRef inst, |
| int index) { |
| return inst->getToken(*token, index); |
| } |
| |
| int EDGetTokenString(const char **buf, |
| EDTokenRef token) { |
| return token->getString(*buf); |
| } |
| |
| int EDOperandIndexForToken(EDTokenRef token) { |
| return token->operandID(); |
| } |
| |
| int EDTokenIsWhitespace(EDTokenRef token) { |
| if (token->type() == EDToken::kTokenWhitespace) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int EDTokenIsPunctuation(EDTokenRef token) { |
| if (token->type() == EDToken::kTokenPunctuation) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int EDTokenIsOpcode(EDTokenRef token) { |
| if (token->type() == EDToken::kTokenOpcode) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int EDTokenIsLiteral(EDTokenRef token) { |
| if (token->type() == EDToken::kTokenLiteral) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int EDTokenIsRegister(EDTokenRef token) { |
| if (token->type() == EDToken::kTokenRegister) |
| return 1; |
| else |
| return 0; |
| } |
| |
| int EDTokenIsNegativeLiteral(EDTokenRef token) { |
| if (token->type() != EDToken::kTokenLiteral) |
| return -1; |
| |
| return token->literalSign(); |
| } |
| |
| int EDLiteralTokenAbsoluteValue(uint64_t *value, |
| EDTokenRef token) { |
| if (token->type() != EDToken::kTokenLiteral) |
| return -1; |
| |
| return token->literalAbsoluteValue(*value); |
| } |
| |
| int EDRegisterTokenValue(unsigned *registerID, |
| EDTokenRef token) { |
| if (token->type() != EDToken::kTokenRegister) |
| return -1; |
| |
| return token->registerID(*registerID); |
| } |
| |
| int EDNumOperands(EDInstRef inst) { |
| return inst->numOperands(); |
| } |
| |
| int EDGetOperand(EDOperandRef *operand, |
| EDInstRef inst, |
| int index) { |
| return inst->getOperand(*operand, index); |
| } |
| |
| int EDOperandIsRegister(EDOperandRef operand) { |
| return operand->isRegister(); |
| } |
| |
| int EDOperandIsImmediate(EDOperandRef operand) { |
| return operand->isImmediate(); |
| } |
| |
| int EDOperandIsMemory(EDOperandRef operand) { |
| return operand->isMemory(); |
| } |
| |
| int EDRegisterOperandValue(unsigned *value, |
| EDOperandRef operand) { |
| if (!operand->isRegister()) |
| return -1; |
| *value = operand->regVal(); |
| return 0; |
| } |
| |
| int EDImmediateOperandValue(uint64_t *value, |
| EDOperandRef operand) { |
| if (!operand->isImmediate()) |
| return -1; |
| *value = operand->immediateVal(); |
| return 0; |
| } |
| |
| int EDEvaluateOperand(uint64_t *result, |
| EDOperandRef operand, |
| EDRegisterReaderCallback regReader, |
| void *arg) { |
| return 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 operand->evaluate(*result, regBlock); |
| } |
| |
| int EDBlockVisitTokens(EDInstRef inst, |
| EDTokenVisitor_t visitor) { |
| return inst->visitTokens(visitor); |
| } |
| |
| #else |
| |
| extern "C" unsigned int EDBlockCreateInsts() { |
| return 0; |
| } |
| |
| extern "C" int EDBlockEvaluateOperand() { |
| return -1; |
| } |
| |
| extern "C" int EDBlockVisitTokens() { |
| return -1; |
| } |
| |
| #endif |