diff options
Diffstat (limited to 'contrib/llvm/tools/edis')
-rw-r--r-- | contrib/llvm/tools/edis/CMakeLists.txt | 13 | ||||
-rw-r--r-- | contrib/llvm/tools/edis/EDMain.cpp | 284 | ||||
-rw-r--r-- | contrib/llvm/tools/edis/EnhancedDisassembly.exports | 36 | ||||
-rw-r--r-- | contrib/llvm/tools/edis/Makefile | 54 |
4 files changed, 387 insertions, 0 deletions
diff --git a/contrib/llvm/tools/edis/CMakeLists.txt b/contrib/llvm/tools/edis/CMakeLists.txt new file mode 100644 index 0000000..2019995 --- /dev/null +++ b/contrib/llvm/tools/edis/CMakeLists.txt @@ -0,0 +1,13 @@ +set(LLVM_NO_RTTI 1) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +add_llvm_library(EnhancedDisassembly + ../../include/llvm-c/EnhancedDisassembly.h + EDMain.cpp +) + +set_target_properties(EnhancedDisassembly + PROPERTIES + LINKER_LANGUAGE CXX) + diff --git a/contrib/llvm/tools/edis/EDMain.cpp b/contrib/llvm/tools/edis/EDMain.cpp new file mode 100644 index 0000000..16855b3 --- /dev/null +++ b/contrib/llvm/tools/edis/EDMain.cpp @@ -0,0 +1,284 @@ +//===-- 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 diff --git a/contrib/llvm/tools/edis/EnhancedDisassembly.exports b/contrib/llvm/tools/edis/EnhancedDisassembly.exports new file mode 100644 index 0000000..7050f7f --- /dev/null +++ b/contrib/llvm/tools/edis/EnhancedDisassembly.exports @@ -0,0 +1,36 @@ +EDGetDisassembler +EDGetRegisterName +EDRegisterIsStackPointer +EDRegisterIsProgramCounter +EDCreateInsts +EDReleaseInst +EDInstByteSize +EDGetInstString +EDInstIsBranch +EDInstIsMove +EDBranchTargetID +EDMoveSourceID +EDMoveTargetID +EDNumTokens +EDGetToken +EDGetTokenString +EDOperandIndexForToken +EDTokenIsWhitespace +EDTokenIsPunctuation +EDTokenIsOpcode +EDTokenIsLiteral +EDTokenIsRegister +EDTokenIsNegativeLiteral +EDLiteralTokenAbsoluteValue +EDRegisterTokenValue +EDNumOperands +EDGetOperand +EDOperandIsRegister +EDOperandIsImmediate +EDOperandIsMemory +EDRegisterOperandValue +EDImmediateOperandValue +EDEvaluateOperand +EDBlockCreateInsts +EDBlockEvaluateOperand +EDBlockVisitTokens diff --git a/contrib/llvm/tools/edis/Makefile b/contrib/llvm/tools/edis/Makefile new file mode 100644 index 0000000..92484bf --- /dev/null +++ b/contrib/llvm/tools/edis/Makefile @@ -0,0 +1,54 @@ +##===- tools/ed/Makefile -----------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +LIBRARYNAME = EnhancedDisassembly +LINK_LIBS_IN_SHARED = 1 +SHARED_LIBRARY = 1 + +EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/EnhancedDisassembly.exports + +# Include this here so we can get the configuration of the targets +# that have been configured for construction. We have to do this +# early so we can set up LINK_COMPONENTS before including Makefile.rules +include $(LEVEL)/Makefile.config + +LINK_COMPONENTS := mcdisassembler + +# If the X86 target is enabled, link in the asmprinter and disassembler. +ifneq ($(filter $(TARGETS_TO_BUILD), X86),) +LINK_COMPONENTS += x86asmprinter x86disassembler +endif + +# If the X86 target is enabled, link in the asmprinter and disassembler. +ifneq ($(filter $(TARGETS_TO_BUILD), ARM),) +LINK_COMPONENTS += armasmprinter armdisassembler +endif + +include $(LEVEL)/Makefile.common + +ifeq ($(HOST_OS),Darwin) + # extra options to override libtool defaults + LLVMLibsOptions := $(LLVMLibsOptions) \ + -Wl,-dead_strip + + ifdef EDIS_VERSION + LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version -Wl,$(EDIS_VERSION) \ + -Wl,-compatibility_version -Wl,1 + endif + + # Mac OS X 10.4 and earlier tools do not allow a second -install_name on command line + DARWIN_VERS := $(shell echo $(TARGET_TRIPLE) | sed 's/.*darwin\([0-9]*\).*/\1/') + ifneq ($(DARWIN_VERS),8) + LLVMLibsOptions := $(LLVMLibsOptions) \ + -Wl,-install_name \ + -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)" + endif +endif + |