diff options
Diffstat (limited to 'contrib/llvm/tools/edis/EDMain.cpp')
-rw-r--r-- | contrib/llvm/tools/edis/EDMain.cpp | 292 |
1 files changed, 292 insertions, 0 deletions
diff --git a/contrib/llvm/tools/edis/EDMain.cpp b/contrib/llvm/tools/edis/EDMain.cpp new file mode 100644 index 0000000..b6ca32f --- /dev/null +++ b/contrib/llvm/tools/edis/EDMain.cpp @@ -0,0 +1,292 @@ +//===-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 |