mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
Remove edis - the enhanced disassembler. Fixes PR14654.
llvm-svn: 170578
This commit is contained in:
parent
b0b73c2c50
commit
7a967134bc
@ -1869,11 +1869,6 @@ $(ObjDir)/%GenDisassemblerTables.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
|
||||
$(Echo) "Building $(<F) disassembly tables with tblgen"
|
||||
$(Verb) $(LLVMTableGen) -gen-disassembler -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenEDInfo.inc.tmp): \
|
||||
$(ObjDir)/%GenEDInfo.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
|
||||
$(Echo) "Building $(<F) enhanced disassembly information with tblgen"
|
||||
$(Verb) $(LLVMTableGen) -gen-enhanced-disassembly-info -o $(call SYSPATH, $@) $<
|
||||
|
||||
$(TARGET:%=$(ObjDir)/%GenFastISel.inc.tmp): \
|
||||
$(ObjDir)/%GenFastISel.inc.tmp : %.td $(ObjDir)/.dir $(LLVM_TBLGEN)
|
||||
$(Echo) "Building $(<F) \"fast\" instruction selector implementation with tblgen"
|
||||
|
@ -1,530 +0,0 @@
|
||||
/*===-- llvm-c/EnhancedDisassembly.h - Disassembler C Interface ---*- C -*-===*\
|
||||
|* *|
|
||||
|* The LLVM Compiler Infrastructure *|
|
||||
|* *|
|
||||
|* This file is distributed under the University of Illinois Open Source *|
|
||||
|* License. See LICENSE.TXT for details. *|
|
||||
|* *|
|
||||
|*===----------------------------------------------------------------------===*|
|
||||
|* *|
|
||||
|* This header declares the C interface to EnhancedDisassembly.so, which *|
|
||||
|* implements a disassembler with the ability to extract operand values and *|
|
||||
|* individual tokens from assembly instructions. *|
|
||||
|* *|
|
||||
|* The header declares additional interfaces if the host compiler supports *|
|
||||
|* the blocks API. *|
|
||||
|* *|
|
||||
\*===----------------------------------------------------------------------===*/
|
||||
|
||||
#ifndef LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
#define LLVM_C_ENHANCEDDISASSEMBLY_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup LLVMCEnhancedDisassembly Enhanced Disassembly
|
||||
* @ingroup LLVMC
|
||||
* @deprecated
|
||||
*
|
||||
* This module contains an interface to the Enhanced Disassembly (edis)
|
||||
* library. The edis library is deprecated and will likely disappear in
|
||||
* the near future. You should use the @ref LLVMCDisassembler interface
|
||||
* instead.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*!
|
||||
@typedef EDByteReaderCallback
|
||||
Interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterReaderCallback
|
||||
Interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
void* arg);
|
||||
|
||||
/*!
|
||||
@typedef EDAssemblySyntax_t
|
||||
An assembly syntax for use in tokenizing instructions.
|
||||
*/
|
||||
enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1,
|
||||
kEDAssemblySyntaxARMUAL = 2
|
||||
};
|
||||
typedef unsigned EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
@typedef EDDisassemblerRef
|
||||
Encapsulates a disassembler for a single CPU architecture.
|
||||
*/
|
||||
typedef void *EDDisassemblerRef;
|
||||
|
||||
/*!
|
||||
@typedef EDInstRef
|
||||
Encapsulates a single disassembled instruction in one assembly syntax.
|
||||
*/
|
||||
typedef void *EDInstRef;
|
||||
|
||||
/*!
|
||||
@typedef EDTokenRef
|
||||
Encapsulates a token from the disassembly of an instruction.
|
||||
*/
|
||||
typedef void *EDTokenRef;
|
||||
|
||||
/*!
|
||||
@typedef EDOperandRef
|
||||
Encapsulates an operand of an instruction.
|
||||
*/
|
||||
typedef void *EDOperandRef;
|
||||
|
||||
/*!
|
||||
@functiongroup Getting a disassembler
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetDisassembler
|
||||
Gets the disassembler for a given target.
|
||||
@param disassembler A pointer whose target will be filled in with the
|
||||
disassembler.
|
||||
@param triple Identifies the target. Example: "x86_64-apple-darwin10"
|
||||
@param syntax The assembly syntax to use when decoding instructions.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetDisassembler(EDDisassemblerRef *disassembler,
|
||||
const char *triple,
|
||||
EDAssemblySyntax_t syntax);
|
||||
|
||||
/*!
|
||||
@functiongroup Generic architectural queries
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDGetRegisterName
|
||||
Gets the human-readable name for a given register.
|
||||
@param regName A pointer whose target will be pointed at the name of the
|
||||
register. The name does not need to be deallocated and will be
|
||||
@param disassembler The disassembler to query for the name.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetRegisterName(const char** regName,
|
||||
EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsStackPointer
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@function EDRegisterIsProgramCounter
|
||||
Determines if a register is one of the platform's stack-pointer registers.
|
||||
@param disassembler The disassembler to query.
|
||||
@param regID The register identifier, as returned by EDRegisterTokenValue.
|
||||
@result 1 if true; 0 otherwise.
|
||||
*/
|
||||
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
|
||||
unsigned regID);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying instructions
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDCreateInst
|
||||
Gets a set of contiguous instructions from a disassembler.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteReader The function to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@param arg An anonymous argument to be passed to byteReader.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDCreateInsts(EDInstRef *insts,
|
||||
unsigned int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg);
|
||||
|
||||
/*!
|
||||
@function EDReleaseInst
|
||||
Frees the memory for an instruction. The instruction can no longer be accessed
|
||||
after this call.
|
||||
@param inst The instruction to be freed.
|
||||
*/
|
||||
void EDReleaseInst(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstByteSize
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of bytes in the instruction's machine-code representation.
|
||||
*/
|
||||
int EDInstByteSize(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetInstString
|
||||
Gets the disassembled text equivalent of the instruction.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the instruction is released.)
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetInstString(const char **buf,
|
||||
EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstID
|
||||
@param instID A pointer whose target will be filled in with the LLVM identifier
|
||||
for the instruction.
|
||||
@param inst The instruction to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDInstID(unsigned *instID, EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsBranch
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a branch instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsBranch(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDInstIsMove
|
||||
@param inst The instruction to be queried.
|
||||
@result 1 if the instruction is a move instruction; 0 if it is some other
|
||||
type of instruction; -1 if there was an error.
|
||||
*/
|
||||
int EDInstIsMove(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDBranchTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the branch target operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDBranchTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveSourceID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveSourceID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDMoveTargetID
|
||||
@param inst The instruction to be queried.
|
||||
@result The ID of the move source operand, suitable for use with
|
||||
EDCopyOperand. -1 if no such operand exists.
|
||||
*/
|
||||
int EDMoveTargetID(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying tokens
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumTokens
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of tokens in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumTokens(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetToken
|
||||
Retrieves a token from an instruction. The token is valid until the
|
||||
instruction is released.
|
||||
@param token A pointer to be filled in with the token.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the token in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetToken(EDTokenRef *token,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDGetTokenString
|
||||
Gets the disassembled text for a token.
|
||||
@param buf A pointer whose target will be filled in with a pointer to the
|
||||
string. (The string becomes invalid when the token is released.)
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetTokenString(const char **buf,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDOperandIndexForToken
|
||||
Returns the index of the operand to which a token belongs.
|
||||
@param token The token to be queried.
|
||||
@result The operand index on success; -1 otherwise
|
||||
*/
|
||||
int EDOperandIndexForToken(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsWhitespace
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is whitespace; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsWhitespace(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsPunctuation
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is punctuation; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsPunctuation(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsOpcode
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is opcode; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsOpcode(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a numeric literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsRegister
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token identifies a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsRegister(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDTokenIsNegativeLiteral
|
||||
@param token The token to be queried.
|
||||
@result 1 if the token is a negative signed literal; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDTokenIsNegativeLiteral(EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDLiteralTokenAbsoluteValue
|
||||
@param value A pointer whose target will be filled in with the absolute value
|
||||
of the literal.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDLiteralTokenAbsoluteValue(uint64_t *value,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@function EDRegisterTokenValue
|
||||
@param registerID A pointer whose target will be filled in with the LLVM
|
||||
register identifier for the token.
|
||||
@param token The token to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterTokenValue(unsigned *registerID,
|
||||
EDTokenRef token);
|
||||
|
||||
/*!
|
||||
@functiongroup Creating and querying operands
|
||||
*/
|
||||
|
||||
/*!
|
||||
@function EDNumOperands
|
||||
@param inst The instruction to be queried.
|
||||
@result The number of operands in the instruction, or -1 on error.
|
||||
*/
|
||||
int EDNumOperands(EDInstRef inst);
|
||||
|
||||
/*!
|
||||
@function EDGetOperand
|
||||
Retrieves an operand from an instruction. The operand is valid until the
|
||||
instruction is released.
|
||||
@param operand A pointer to be filled in with the operand.
|
||||
@param inst The instruction to be queried.
|
||||
@param index The index of the operand in the instruction.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDGetOperand(EDOperandRef *operand,
|
||||
EDInstRef inst,
|
||||
int index);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsRegister
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand names a register; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsRegister(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsImmediate
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies an immediate value; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsImmediate(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDOperandIsMemory
|
||||
@param operand The operand to be queried.
|
||||
@result 1 if the operand specifies a location in memory; 0 if not; -1 on error.
|
||||
*/
|
||||
int EDOperandIsMemory(EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDRegisterOperandValue
|
||||
@param value A pointer whose target will be filled in with the LLVM register ID
|
||||
of the register named by the operand.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDRegisterOperandValue(unsigned *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDImmediateOperandValue
|
||||
@param value A pointer whose target will be filled in with the value of the
|
||||
immediate.
|
||||
@param operand The operand to be queried.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
int EDImmediateOperandValue(uint64_t *value,
|
||||
EDOperandRef operand);
|
||||
|
||||
/*!
|
||||
@function EDEvaluateOperand
|
||||
Evaluates an operand using a client-supplied register state accessor. Register
|
||||
operands are evaluated by reading the value of the register; immediate operands
|
||||
are evaluated by reporting the immediate value; memory operands are evaluated
|
||||
by computing the target address (with only those relocations applied that were
|
||||
already applied to the original bytes).
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regReader The function to use when reading registers from the register
|
||||
state.
|
||||
@param arg An anonymous argument for client use.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterReaderCallback regReader,
|
||||
void *arg);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
|
||||
/*!
|
||||
@typedef EDByteBlock_t
|
||||
Block-based interface to memory from which instructions may be read.
|
||||
@param byte A pointer whose target should be filled in with the data returned.
|
||||
@param address The address of the byte to be read.
|
||||
@result 0 on success; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDByteBlock_t)(uint8_t *byte, uint64_t address);
|
||||
|
||||
/*!
|
||||
@typedef EDRegisterBlock_t
|
||||
Block-based interface to registers from which registers may be read.
|
||||
@param value A pointer whose target should be filled in with the value of the
|
||||
register.
|
||||
@param regID The LLVM register identifier for the register to read.
|
||||
@result 0 if the register could be read; -1 otherwise.
|
||||
*/
|
||||
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
|
||||
|
||||
/*!
|
||||
@typedef EDTokenVisitor_t
|
||||
Block-based handler for individual tokens.
|
||||
@param token The current token being read.
|
||||
@result 0 to continue; 1 to stop normally; -1 on error.
|
||||
*/
|
||||
typedef int (^EDTokenVisitor_t)(EDTokenRef token);
|
||||
|
||||
/*! @functiongroup Block-based interfaces */
|
||||
|
||||
/*!
|
||||
@function EDBlockCreateInsts
|
||||
Gets a set of contiguous instructions from a disassembler, using a block to
|
||||
read memory.
|
||||
@param insts A pointer to an array that will be filled in with the
|
||||
instructions. Must have at least count entries. Entries not filled in will
|
||||
be set to NULL.
|
||||
@param count The maximum number of instructions to fill in.
|
||||
@param disassembler The disassembler to use when decoding the instructions.
|
||||
@param byteBlock The block to use when reading the instruction's machine
|
||||
code.
|
||||
@param address The address of the first byte of the instruction.
|
||||
@result The number of instructions read on success; 0 otherwise.
|
||||
*/
|
||||
unsigned int EDBlockCreateInsts(EDInstRef *insts,
|
||||
int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteBlock_t byteBlock,
|
||||
uint64_t address);
|
||||
|
||||
/*!
|
||||
@function EDBlockEvaluateOperand
|
||||
Evaluates an operand using a block to read registers.
|
||||
@param result A pointer whose target is to be filled with the result of
|
||||
evaluating the operand.
|
||||
@param operand The operand to be evaluated.
|
||||
@param regBlock The block to use when reading registers from the register
|
||||
state.
|
||||
@result 0 if the operand could be evaluated; -1 otherwise.
|
||||
*/
|
||||
int EDBlockEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterBlock_t regBlock);
|
||||
|
||||
/*!
|
||||
@function EDBlockVisitTokens
|
||||
Visits every token with a visitor.
|
||||
@param inst The instruction with the tokens to be visited.
|
||||
@param visitor The visitor.
|
||||
@result 0 if the visit ended normally; -1 if the visitor encountered an error
|
||||
or there was some other error.
|
||||
*/
|
||||
int EDBlockVisitTokens(EDInstRef inst,
|
||||
EDTokenVisitor_t visitor);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -20,8 +20,6 @@ class MemoryObject;
|
||||
class raw_ostream;
|
||||
class MCContext;
|
||||
|
||||
struct EDInstInfo;
|
||||
|
||||
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
|
||||
/// and provides an array of assembly instructions.
|
||||
class MCDisassembler {
|
||||
@ -84,14 +82,6 @@ public:
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const = 0;
|
||||
|
||||
/// getEDInfo - Returns the enhanced instruction information corresponding to
|
||||
/// the disassembler.
|
||||
///
|
||||
/// @return - An array of instruction information, with one entry for
|
||||
/// each MCInst opcode this disassembler returns.
|
||||
/// NULL if there is no info for this target.
|
||||
virtual const EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
|
||||
|
||||
private:
|
||||
//
|
||||
// Hooks for symbolic disassembly via the public 'C' interface.
|
||||
|
@ -1,8 +1,3 @@
|
||||
add_llvm_library(LLVMMCDisassembler
|
||||
Disassembler.cpp
|
||||
EDDisassembler.cpp
|
||||
EDInst.cpp
|
||||
EDMain.cpp
|
||||
EDOperand.cpp
|
||||
EDToken.cpp
|
||||
)
|
||||
|
@ -1,400 +0,0 @@
|
||||
//===-EDDisassembler.cpp - LLVM Enhanced Disassembler ---------------------===//
|
||||
//
|
||||
// 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 Disassembly library's disassembler class.
|
||||
// The disassembler is responsible for vending individual instructions according
|
||||
// to a given architecture and disassembly syntax.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCParser/AsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCTargetAsmLexer.h"
|
||||
#include "llvm/MC/MCTargetAsmParser.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MemoryObject.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
|
||||
|
||||
struct TripleMap {
|
||||
Triple::ArchType Arch;
|
||||
const char *String;
|
||||
};
|
||||
|
||||
static const struct TripleMap triplemap[] = {
|
||||
{ Triple::x86, "i386-unknown-unknown" },
|
||||
{ Triple::x86_64, "x86_64-unknown-unknown" },
|
||||
{ Triple::arm, "arm-unknown-unknown" },
|
||||
{ Triple::thumb, "thumb-unknown-unknown" }
|
||||
};
|
||||
|
||||
/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
|
||||
/// or NULL if there is an error
|
||||
///
|
||||
/// @arg arch - The Triple::ArchType for the desired architecture
|
||||
static const char *tripleFromArch(Triple::ArchType arch) {
|
||||
unsigned int infoIndex;
|
||||
|
||||
for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) {
|
||||
if (arch == triplemap[infoIndex].Arch)
|
||||
return triplemap[infoIndex].String;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// getLLVMSyntaxVariant - gets the constant to use to get an assembly printer
|
||||
/// for the desired assembly syntax, suitable for passing to
|
||||
/// Target::createMCInstPrinter()
|
||||
///
|
||||
/// @arg arch - The target architecture
|
||||
/// @arg syntax - The assembly syntax in sd form
|
||||
static int getLLVMSyntaxVariant(Triple::ArchType arch,
|
||||
EDDisassembler::AssemblySyntax syntax) {
|
||||
switch (syntax) {
|
||||
// Mappings below from X86AsmPrinter.cpp
|
||||
case EDDisassembler::kEDAssemblySyntaxX86ATT:
|
||||
if (arch == Triple::x86 || arch == Triple::x86_64)
|
||||
return 0;
|
||||
break;
|
||||
case EDDisassembler::kEDAssemblySyntaxX86Intel:
|
||||
if (arch == Triple::x86 || arch == Triple::x86_64)
|
||||
return 1;
|
||||
break;
|
||||
case EDDisassembler::kEDAssemblySyntaxARMUAL:
|
||||
if (arch == Triple::arm || arch == Triple::thumb)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
|
||||
AssemblySyntax syntax) {
|
||||
const char *triple = tripleFromArch(arch);
|
||||
return getDisassembler(StringRef(triple), syntax);
|
||||
}
|
||||
|
||||
EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
|
||||
AssemblySyntax syntax) {
|
||||
CPUKey key;
|
||||
key.Triple = str.str();
|
||||
key.Syntax = syntax;
|
||||
|
||||
EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
|
||||
|
||||
if (i != sDisassemblers.end()) {
|
||||
return i->second;
|
||||
}
|
||||
|
||||
EDDisassembler *sdd = new EDDisassembler(key);
|
||||
if (!sdd->valid()) {
|
||||
delete sdd;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sDisassemblers[key] = sdd;
|
||||
|
||||
return sdd;
|
||||
}
|
||||
|
||||
EDDisassembler::EDDisassembler(CPUKey &key) :
|
||||
Valid(false),
|
||||
HasSemantics(false),
|
||||
ErrorStream(nulls()),
|
||||
Key(key),
|
||||
TgtTriple(key.Triple.c_str()) {
|
||||
|
||||
LLVMSyntaxVariant = getLLVMSyntaxVariant(TgtTriple.getArch(), key.Syntax);
|
||||
|
||||
if (LLVMSyntaxVariant < 0)
|
||||
return;
|
||||
|
||||
std::string tripleString(key.Triple);
|
||||
std::string errorString;
|
||||
|
||||
Tgt = TargetRegistry::lookupTarget(key.Triple,
|
||||
errorString);
|
||||
|
||||
if (!Tgt)
|
||||
return;
|
||||
|
||||
MRI.reset(Tgt->createMCRegInfo(tripleString));
|
||||
|
||||
if (!MRI)
|
||||
return;
|
||||
|
||||
initMaps(*MRI);
|
||||
|
||||
AsmInfo.reset(Tgt->createMCAsmInfo(tripleString));
|
||||
|
||||
if (!AsmInfo)
|
||||
return;
|
||||
|
||||
STI.reset(Tgt->createMCSubtargetInfo(tripleString, "", ""));
|
||||
|
||||
if (!STI)
|
||||
return;
|
||||
|
||||
Disassembler.reset(Tgt->createMCDisassembler(*STI));
|
||||
|
||||
if (!Disassembler)
|
||||
return;
|
||||
|
||||
InstInfos = Disassembler->getEDInfo();
|
||||
|
||||
MII.reset(Tgt->createMCInstrInfo());
|
||||
|
||||
if (!MII)
|
||||
return;
|
||||
|
||||
InstString.reset(new std::string);
|
||||
InstStream.reset(new raw_string_ostream(*InstString));
|
||||
InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo,
|
||||
*MII, *MRI, *STI));
|
||||
|
||||
if (!InstPrinter)
|
||||
return;
|
||||
|
||||
GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
|
||||
SpecificAsmLexer.reset(Tgt->createMCAsmLexer(*MRI, *AsmInfo));
|
||||
SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
|
||||
|
||||
initMaps(*MRI);
|
||||
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
EDDisassembler::~EDDisassembler() {
|
||||
if (!valid())
|
||||
return;
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// EDMemoryObject - a subclass of MemoryObject that allows use of a callback
|
||||
/// as provided by the sd interface. See MemoryObject.
|
||||
class EDMemoryObject : public llvm::MemoryObject {
|
||||
private:
|
||||
EDByteReaderCallback Callback;
|
||||
void *Arg;
|
||||
public:
|
||||
EDMemoryObject(EDByteReaderCallback callback,
|
||||
void *arg) : Callback(callback), Arg(arg) { }
|
||||
~EDMemoryObject() { }
|
||||
uint64_t getBase() const { return 0x0; }
|
||||
uint64_t getExtent() const { return (uint64_t)-1; }
|
||||
int readByte(uint64_t address, uint8_t *ptr) const {
|
||||
if (!Callback)
|
||||
return -1;
|
||||
|
||||
if (Callback(ptr, address, Arg))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg) {
|
||||
EDMemoryObject memoryObject(byteReader, arg);
|
||||
|
||||
MCInst* inst = new MCInst;
|
||||
uint64_t byteSize;
|
||||
|
||||
MCDisassembler::DecodeStatus S;
|
||||
S = Disassembler->getInstruction(*inst, byteSize, memoryObject, address,
|
||||
ErrorStream, nulls());
|
||||
switch (S) {
|
||||
case MCDisassembler::Fail:
|
||||
case MCDisassembler::SoftFail:
|
||||
// FIXME: Do something different on soft failure mode?
|
||||
delete inst;
|
||||
return NULL;
|
||||
|
||||
case MCDisassembler::Success: {
|
||||
const llvm::EDInstInfo *thisInstInfo = NULL;
|
||||
|
||||
if (InstInfos) {
|
||||
thisInstInfo = &InstInfos[inst->getOpcode()];
|
||||
}
|
||||
|
||||
EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
|
||||
return sdInst;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void EDDisassembler::initMaps(const MCRegisterInfo ®isterInfo) {
|
||||
unsigned numRegisters = registerInfo.getNumRegs();
|
||||
unsigned registerIndex;
|
||||
|
||||
for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
|
||||
const char* registerName = registerInfo.getName(registerIndex);
|
||||
|
||||
RegVec.push_back(registerName);
|
||||
RegRMap[registerName] = registerIndex;
|
||||
}
|
||||
|
||||
switch (TgtTriple.getArch()) {
|
||||
default:
|
||||
break;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
stackPointers.insert(registerIDWithName("SP"));
|
||||
stackPointers.insert(registerIDWithName("ESP"));
|
||||
stackPointers.insert(registerIDWithName("RSP"));
|
||||
|
||||
programCounters.insert(registerIDWithName("IP"));
|
||||
programCounters.insert(registerIDWithName("EIP"));
|
||||
programCounters.insert(registerIDWithName("RIP"));
|
||||
break;
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
stackPointers.insert(registerIDWithName("SP"));
|
||||
|
||||
programCounters.insert(registerIDWithName("PC"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *EDDisassembler::nameWithRegisterID(unsigned registerID) const {
|
||||
if (registerID >= RegVec.size())
|
||||
return NULL;
|
||||
else
|
||||
return RegVec[registerID].c_str();
|
||||
}
|
||||
|
||||
unsigned EDDisassembler::registerIDWithName(const char *name) const {
|
||||
regrmap_t::const_iterator iter = RegRMap.find(std::string(name));
|
||||
if (iter == RegRMap.end())
|
||||
return 0;
|
||||
else
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
bool EDDisassembler::registerIsStackPointer(unsigned registerID) {
|
||||
return (stackPointers.find(registerID) != stackPointers.end());
|
||||
}
|
||||
|
||||
bool EDDisassembler::registerIsProgramCounter(unsigned registerID) {
|
||||
return (programCounters.find(registerID) != programCounters.end());
|
||||
}
|
||||
|
||||
int EDDisassembler::printInst(std::string &str, MCInst &inst) {
|
||||
PrinterMutex.acquire();
|
||||
|
||||
InstPrinter->printInst(&inst, *InstStream, "");
|
||||
InstStream->flush();
|
||||
str = *InstString;
|
||||
InstString->clear();
|
||||
|
||||
PrinterMutex.release();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void diag_handler(const SMDiagnostic &diag, void *context) {
|
||||
if (context)
|
||||
diag.print("", static_cast<EDDisassembler*>(context)->ErrorStream);
|
||||
}
|
||||
|
||||
int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
|
||||
SmallVectorImpl<AsmToken> &tokens,
|
||||
const std::string &str) {
|
||||
int ret = 0;
|
||||
|
||||
switch (TgtTriple.getArch()) {
|
||||
default:
|
||||
return -1;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
break;
|
||||
}
|
||||
|
||||
const char *cStr = str.c_str();
|
||||
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
|
||||
|
||||
StringRef instName;
|
||||
SMLoc instLoc;
|
||||
|
||||
SourceMgr sourceMgr;
|
||||
sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this));
|
||||
sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
|
||||
MCContext context(*AsmInfo, *MRI, NULL);
|
||||
OwningPtr<MCStreamer> streamer(createNullStreamer(context));
|
||||
OwningPtr<MCAsmParser> genericParser(createMCAsmParser(sourceMgr,
|
||||
context, *streamer,
|
||||
*AsmInfo));
|
||||
|
||||
OwningPtr<MCSubtargetInfo> STI(Tgt->createMCSubtargetInfo(Key.Triple.c_str(), "", ""));
|
||||
OwningPtr<MCTargetAsmParser>
|
||||
TargetParser(Tgt->createMCAsmParser(*STI, *genericParser));
|
||||
|
||||
AsmToken OpcodeToken = genericParser->Lex();
|
||||
AsmToken NextToken = genericParser->Lex(); // consume next token, because specificParser expects us to
|
||||
|
||||
if (OpcodeToken.is(AsmToken::Identifier)) {
|
||||
instName = OpcodeToken.getString();
|
||||
instLoc = OpcodeToken.getLoc();
|
||||
|
||||
ParseInstructionInfo Info;
|
||||
if (NextToken.isNot(AsmToken::Eof) &&
|
||||
TargetParser->ParseInstruction(Info, instName, instLoc, operands))
|
||||
ret = -1;
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
ParserMutex.acquire();
|
||||
|
||||
if (!ret) {
|
||||
GenericAsmLexer->setBuffer(buf);
|
||||
|
||||
while (SpecificAsmLexer->Lex(),
|
||||
SpecificAsmLexer->isNot(AsmToken::Eof) &&
|
||||
SpecificAsmLexer->isNot(AsmToken::EndOfStatement)) {
|
||||
if (SpecificAsmLexer->is(AsmToken::Error)) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
tokens.push_back(SpecificAsmLexer->getTok());
|
||||
}
|
||||
}
|
||||
|
||||
ParserMutex.release();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int EDDisassembler::llvmSyntaxVariant() const {
|
||||
return LLVMSyntaxVariant;
|
||||
}
|
@ -1,269 +0,0 @@
|
||||
//===-- EDDisassembler.h - LLVM Enhanced Disassembler -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the interface for the Enhanced Disassembly library's
|
||||
// disassembler class. The disassembler is responsible for vending individual
|
||||
// instructions according to a given architecture and disassembly syntax.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EDDISASSEMBLER_H
|
||||
#define LLVM_EDDISASSEMBLER_H
|
||||
|
||||
#include "EDInfo.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/Mutex.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class AsmLexer;
|
||||
class AsmParser;
|
||||
class AsmToken;
|
||||
class MCContext;
|
||||
class MCAsmInfo;
|
||||
class MCAsmLexer;
|
||||
class MCDisassembler;
|
||||
class MCInst;
|
||||
class MCInstPrinter;
|
||||
class MCInstrInfo;
|
||||
class MCParsedAsmOperand;
|
||||
class MCRegisterInfo;
|
||||
class MCStreamer;
|
||||
class MCSubtargetInfo;
|
||||
class MCTargetAsmLexer;
|
||||
class MCTargetAsmParser;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
class SourceMgr;
|
||||
class Target;
|
||||
|
||||
struct EDInstInfo;
|
||||
struct EDInst;
|
||||
struct EDOperand;
|
||||
struct EDToken;
|
||||
|
||||
typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
|
||||
|
||||
/// EDDisassembler - Encapsulates a disassembler for a single architecture and
|
||||
/// disassembly syntax. Also manages the static disassembler registry.
|
||||
struct EDDisassembler {
|
||||
typedef enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1,
|
||||
kEDAssemblySyntaxARMUAL = 2
|
||||
} AssemblySyntax;
|
||||
|
||||
|
||||
////////////////////
|
||||
// Static members //
|
||||
////////////////////
|
||||
|
||||
/// CPUKey - Encapsulates the descriptor of an architecture/disassembly-syntax
|
||||
/// pair
|
||||
struct CPUKey {
|
||||
/// The architecture type
|
||||
std::string Triple;
|
||||
|
||||
/// The assembly syntax
|
||||
AssemblySyntax Syntax;
|
||||
|
||||
/// operator== - Equality operator
|
||||
bool operator==(const CPUKey &key) const {
|
||||
return (Triple == key.Triple &&
|
||||
Syntax == key.Syntax);
|
||||
}
|
||||
|
||||
/// operator< - Less-than operator
|
||||
bool operator<(const CPUKey &key) const {
|
||||
return ((Triple < key.Triple) ||
|
||||
((Triple == key.Triple) && Syntax < (key.Syntax)));
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::map<CPUKey, EDDisassembler*> DisassemblerMap_t;
|
||||
|
||||
/// A map from disassembler specifications to disassemblers. Populated
|
||||
/// lazily.
|
||||
static DisassemblerMap_t sDisassemblers;
|
||||
|
||||
/// getDisassembler - Returns the specified disassemble, or NULL on failure
|
||||
///
|
||||
/// @arg arch - The desired architecture
|
||||
/// @arg syntax - The desired disassembly syntax
|
||||
static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch,
|
||||
AssemblySyntax syntax);
|
||||
|
||||
/// getDisassembler - Returns the disassembler for a given combination of
|
||||
/// CPU type, CPU subtype, and assembly syntax, or NULL on failure
|
||||
///
|
||||
/// @arg str - The string representation of the architecture triple, e.g.,
|
||||
/// "x86_64-apple-darwin"
|
||||
/// @arg syntax - The disassembly syntax for the required disassembler
|
||||
static EDDisassembler *getDisassembler(llvm::StringRef str,
|
||||
AssemblySyntax syntax);
|
||||
|
||||
////////////////////////
|
||||
// Per-object members //
|
||||
////////////////////////
|
||||
|
||||
/// True only if the object has been successfully initialized
|
||||
bool Valid;
|
||||
/// True if the disassembler can provide semantic information
|
||||
bool HasSemantics;
|
||||
|
||||
/// The stream to write errors to
|
||||
llvm::raw_ostream &ErrorStream;
|
||||
|
||||
/// The triple/syntax pair for the current architecture
|
||||
CPUKey Key;
|
||||
/// The Triple fur the current architecture
|
||||
Triple TgtTriple;
|
||||
/// The LLVM target corresponding to the disassembler
|
||||
const llvm::Target *Tgt;
|
||||
/// The assembly information for the target architecture
|
||||
llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
|
||||
/// The subtarget information for the target architecture
|
||||
llvm::OwningPtr<const llvm::MCSubtargetInfo> STI;
|
||||
// The instruction information for the target architecture.
|
||||
llvm::OwningPtr<const llvm::MCInstrInfo> MII;
|
||||
// The register information for the target architecture.
|
||||
llvm::OwningPtr<const llvm::MCRegisterInfo> MRI;
|
||||
/// The disassembler for the target architecture
|
||||
llvm::OwningPtr<const llvm::MCDisassembler> Disassembler;
|
||||
/// The output string for the instruction printer; must be guarded with
|
||||
/// PrinterMutex
|
||||
llvm::OwningPtr<std::string> InstString;
|
||||
/// The output stream for the disassembler; must be guarded with
|
||||
/// PrinterMutex
|
||||
llvm::OwningPtr<llvm::raw_string_ostream> InstStream;
|
||||
/// The instruction printer for the target architecture; must be guarded with
|
||||
/// PrinterMutex when printing
|
||||
llvm::OwningPtr<llvm::MCInstPrinter> InstPrinter;
|
||||
/// The mutex that guards the instruction printer's printing functions, which
|
||||
/// use a shared stream
|
||||
llvm::sys::Mutex PrinterMutex;
|
||||
/// The array of instruction information provided by the TableGen backend for
|
||||
/// the target architecture
|
||||
const llvm::EDInstInfo *InstInfos;
|
||||
/// The target-specific lexer for use in tokenizing strings, in
|
||||
/// target-independent and target-specific portions
|
||||
llvm::OwningPtr<llvm::AsmLexer> GenericAsmLexer;
|
||||
llvm::OwningPtr<llvm::MCTargetAsmLexer> SpecificAsmLexer;
|
||||
/// The guard for the above
|
||||
llvm::sys::Mutex ParserMutex;
|
||||
/// The LLVM number used for the target disassembly syntax variant
|
||||
int LLVMSyntaxVariant;
|
||||
|
||||
typedef std::vector<std::string> regvec_t;
|
||||
typedef std::map<std::string, unsigned> regrmap_t;
|
||||
|
||||
/// A vector of registers for quick mapping from LLVM register IDs to names
|
||||
regvec_t RegVec;
|
||||
/// A map of registers for quick mapping from register names to LLVM IDs
|
||||
regrmap_t RegRMap;
|
||||
|
||||
/// A set of register IDs for aliases of the stack pointer for the current
|
||||
/// architecture
|
||||
std::set<unsigned> stackPointers;
|
||||
/// A set of register IDs for aliases of the program counter for the current
|
||||
/// architecture
|
||||
std::set<unsigned> programCounters;
|
||||
|
||||
/// Constructor - initializes a disassembler with all the necessary objects,
|
||||
/// which come pre-allocated from the registry accessor function
|
||||
///
|
||||
/// @arg key - the architecture and disassembly syntax for the
|
||||
/// disassembler
|
||||
EDDisassembler(CPUKey& key);
|
||||
|
||||
/// valid - reports whether there was a failure in the constructor.
|
||||
bool valid() {
|
||||
return Valid;
|
||||
}
|
||||
|
||||
/// hasSemantics - reports whether the disassembler can provide operands and
|
||||
/// tokens.
|
||||
bool hasSemantics() {
|
||||
return HasSemantics;
|
||||
}
|
||||
|
||||
~EDDisassembler();
|
||||
|
||||
/// createInst - creates and returns an instruction given a callback and
|
||||
/// memory address, or NULL on failure
|
||||
///
|
||||
/// @arg byteReader - A callback function that provides machine code bytes
|
||||
/// @arg address - The address of the first byte of the instruction,
|
||||
/// suitable for passing to byteReader
|
||||
/// @arg arg - An opaque argument for byteReader
|
||||
EDInst *createInst(EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg);
|
||||
|
||||
/// initMaps - initializes regVec and regRMap using the provided register
|
||||
/// info
|
||||
///
|
||||
/// @arg registerInfo - the register information to use as a source
|
||||
void initMaps(const llvm::MCRegisterInfo ®isterInfo);
|
||||
/// nameWithRegisterID - Returns the name (owned by the EDDisassembler) of a
|
||||
/// register for a given register ID, or NULL on failure
|
||||
///
|
||||
/// @arg registerID - the ID of the register to be queried
|
||||
const char *nameWithRegisterID(unsigned registerID) const;
|
||||
/// registerIDWithName - Returns the ID of a register for a given register
|
||||
/// name, or (unsigned)-1 on failure
|
||||
///
|
||||
/// @arg name - The name of the register
|
||||
unsigned registerIDWithName(const char *name) const;
|
||||
|
||||
/// registerIsStackPointer - reports whether a register ID is an alias for the
|
||||
/// stack pointer register
|
||||
///
|
||||
/// @arg registerID - The LLVM register ID
|
||||
bool registerIsStackPointer(unsigned registerID);
|
||||
/// registerIsStackPointer - reports whether a register ID is an alias for the
|
||||
/// stack pointer register
|
||||
///
|
||||
/// @arg registerID - The LLVM register ID
|
||||
bool registerIsProgramCounter(unsigned registerID);
|
||||
|
||||
/// printInst - prints an MCInst to a string, returning 0 on success, or -1
|
||||
/// otherwise
|
||||
///
|
||||
/// @arg str - A reference to a string which is filled in with the string
|
||||
/// representation of the instruction
|
||||
/// @arg inst - A reference to the MCInst to be printed
|
||||
int printInst(std::string& str,
|
||||
llvm::MCInst& inst);
|
||||
|
||||
/// parseInst - extracts operands and tokens from a string for use in
|
||||
/// tokenizing the string. Returns 0 on success, or -1 otherwise.
|
||||
///
|
||||
/// @arg operands - A reference to a vector that will be filled in with the
|
||||
/// parsed operands
|
||||
/// @arg tokens - A reference to a vector that will be filled in with the
|
||||
/// tokens
|
||||
/// @arg str - The string representation of the instruction
|
||||
int parseInst(llvm::SmallVectorImpl<llvm::MCParsedAsmOperand*> &operands,
|
||||
llvm::SmallVectorImpl<llvm::AsmToken> &tokens,
|
||||
const std::string &str);
|
||||
|
||||
/// llvmSyntaxVariant - returns the LLVM syntax variant for this disassembler
|
||||
int llvmSyntaxVariant() const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,84 +0,0 @@
|
||||
//===-- EDInfo.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EDINFO_H
|
||||
#define LLVM_EDINFO_H
|
||||
|
||||
enum {
|
||||
EDIS_MAX_OPERANDS = 13,
|
||||
EDIS_MAX_SYNTAXES = 2
|
||||
};
|
||||
|
||||
enum OperandTypes {
|
||||
kOperandTypeNone,
|
||||
kOperandTypeImmediate,
|
||||
kOperandTypeRegister,
|
||||
kOperandTypeX86Memory,
|
||||
kOperandTypeX86EffectiveAddress,
|
||||
kOperandTypeX86PCRelative,
|
||||
kOperandTypeARMBranchTarget,
|
||||
kOperandTypeARMSoReg,
|
||||
kOperandTypeARMSoImm,
|
||||
kOperandTypeARMRotImm,
|
||||
kOperandTypeARMSoImm2Part,
|
||||
kOperandTypeARMPredicate,
|
||||
kOperandTypeAddrModeImm12,
|
||||
kOperandTypeLdStSOReg,
|
||||
kOperandTypeARMAddrMode2,
|
||||
kOperandTypeARMAddrMode2Offset,
|
||||
kOperandTypeARMAddrMode3,
|
||||
kOperandTypeARMAddrMode3Offset,
|
||||
kOperandTypeARMAddrMode4,
|
||||
kOperandTypeARMAddrMode5,
|
||||
kOperandTypeARMAddrMode6,
|
||||
kOperandTypeARMAddrMode6Offset,
|
||||
kOperandTypeARMAddrMode7,
|
||||
kOperandTypeARMAddrModePC,
|
||||
kOperandTypeARMRegisterList,
|
||||
kOperandTypeARMDPRRegisterList,
|
||||
kOperandTypeARMSPRRegisterList,
|
||||
kOperandTypeARMTBAddrMode,
|
||||
kOperandTypeThumbITMask,
|
||||
kOperandTypeThumbAddrModeRegS1,
|
||||
kOperandTypeThumbAddrModeRegS2,
|
||||
kOperandTypeThumbAddrModeRegS4,
|
||||
kOperandTypeThumbAddrModeImmS1,
|
||||
kOperandTypeThumbAddrModeImmS2,
|
||||
kOperandTypeThumbAddrModeImmS4,
|
||||
kOperandTypeThumbAddrModeRR,
|
||||
kOperandTypeThumbAddrModeSP,
|
||||
kOperandTypeThumbAddrModePC,
|
||||
kOperandTypeThumb2AddrModeReg,
|
||||
kOperandTypeThumb2SoReg,
|
||||
kOperandTypeThumb2SoImm,
|
||||
kOperandTypeThumb2AddrModeImm8,
|
||||
kOperandTypeThumb2AddrModeImm8Offset,
|
||||
kOperandTypeThumb2AddrModeImm12,
|
||||
kOperandTypeThumb2AddrModeSoReg,
|
||||
kOperandTypeThumb2AddrModeImm8s4,
|
||||
kOperandTypeThumb2AddrModeImm8s4Offset
|
||||
};
|
||||
|
||||
enum OperandFlags {
|
||||
kOperandFlagSource = 0x1,
|
||||
kOperandFlagTarget = 0x2
|
||||
};
|
||||
|
||||
enum InstructionTypes {
|
||||
kInstructionTypeNone,
|
||||
kInstructionTypeMove,
|
||||
kInstructionTypeBranch,
|
||||
kInstructionTypePush,
|
||||
kInstructionTypePop,
|
||||
kInstructionTypeCall,
|
||||
kInstructionTypeReturn
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -1,211 +0,0 @@
|
||||
//===-EDInst.cpp - LLVM Enhanced Disassembler -----------------------------===//
|
||||
//
|
||||
// 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 Disassembly library's instruction class.
|
||||
// The instruction is responsible for vending the string representation,
|
||||
// individual tokens, and operands for a single instruction.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDInst.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDOperand.h"
|
||||
#include "EDToken.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
EDInst::EDInst(llvm::MCInst *inst,
|
||||
uint64_t byteSize,
|
||||
EDDisassembler &disassembler,
|
||||
const llvm::EDInstInfo *info) :
|
||||
Disassembler(disassembler),
|
||||
Inst(inst),
|
||||
ThisInstInfo(info),
|
||||
ByteSize(byteSize),
|
||||
BranchTarget(-1),
|
||||
MoveSource(-1),
|
||||
MoveTarget(-1) {
|
||||
OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
|
||||
}
|
||||
|
||||
EDInst::~EDInst() {
|
||||
unsigned int index;
|
||||
unsigned int numOperands = Operands.size();
|
||||
|
||||
for (index = 0; index < numOperands; ++index)
|
||||
delete Operands[index];
|
||||
|
||||
unsigned int numTokens = Tokens.size();
|
||||
|
||||
for (index = 0; index < numTokens; ++index)
|
||||
delete Tokens[index];
|
||||
|
||||
delete Inst;
|
||||
}
|
||||
|
||||
uint64_t EDInst::byteSize() {
|
||||
return ByteSize;
|
||||
}
|
||||
|
||||
int EDInst::stringify() {
|
||||
if (StringifyResult.valid())
|
||||
return StringifyResult.result();
|
||||
|
||||
if (Disassembler.printInst(String, *Inst))
|
||||
return StringifyResult.setResult(-1);
|
||||
|
||||
String.push_back('\n');
|
||||
|
||||
return StringifyResult.setResult(0);
|
||||
}
|
||||
|
||||
int EDInst::getString(const char*& str) {
|
||||
if (stringify())
|
||||
return -1;
|
||||
|
||||
str = String.c_str();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned EDInst::instID() {
|
||||
return Inst->getOpcode();
|
||||
}
|
||||
|
||||
bool EDInst::isBranch() {
|
||||
if (ThisInstInfo)
|
||||
return
|
||||
ThisInstInfo->instructionType == kInstructionTypeBranch ||
|
||||
ThisInstInfo->instructionType == kInstructionTypeCall;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EDInst::isMove() {
|
||||
if (ThisInstInfo)
|
||||
return ThisInstInfo->instructionType == kInstructionTypeMove;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
int EDInst::parseOperands() {
|
||||
if (ParseResult.valid())
|
||||
return ParseResult.result();
|
||||
|
||||
if (!ThisInstInfo)
|
||||
return ParseResult.setResult(-1);
|
||||
|
||||
unsigned int opIndex;
|
||||
unsigned int mcOpIndex = 0;
|
||||
|
||||
for (opIndex = 0; opIndex < ThisInstInfo->numOperands; ++opIndex) {
|
||||
if (isBranch() &&
|
||||
(ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)) {
|
||||
BranchTarget = opIndex;
|
||||
}
|
||||
else if (isMove()) {
|
||||
if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagSource)
|
||||
MoveSource = opIndex;
|
||||
else if (ThisInstInfo->operandFlags[opIndex] & kOperandFlagTarget)
|
||||
MoveTarget = opIndex;
|
||||
}
|
||||
|
||||
EDOperand *operand = new EDOperand(Disassembler, *this, opIndex, mcOpIndex);
|
||||
|
||||
Operands.push_back(operand);
|
||||
}
|
||||
|
||||
return ParseResult.setResult(0);
|
||||
}
|
||||
|
||||
int EDInst::branchTargetID() {
|
||||
if (parseOperands())
|
||||
return -1;
|
||||
return BranchTarget;
|
||||
}
|
||||
|
||||
int EDInst::moveSourceID() {
|
||||
if (parseOperands())
|
||||
return -1;
|
||||
return MoveSource;
|
||||
}
|
||||
|
||||
int EDInst::moveTargetID() {
|
||||
if (parseOperands())
|
||||
return -1;
|
||||
return MoveTarget;
|
||||
}
|
||||
|
||||
int EDInst::numOperands() {
|
||||
if (parseOperands())
|
||||
return -1;
|
||||
return Operands.size();
|
||||
}
|
||||
|
||||
int EDInst::getOperand(EDOperand *&operand, unsigned int index) {
|
||||
if (parseOperands())
|
||||
return -1;
|
||||
|
||||
if (index >= Operands.size())
|
||||
return -1;
|
||||
|
||||
operand = Operands[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDInst::tokenize() {
|
||||
if (TokenizeResult.valid())
|
||||
return TokenizeResult.result();
|
||||
|
||||
if (ThisInstInfo == NULL)
|
||||
return TokenizeResult.setResult(-1);
|
||||
|
||||
if (stringify())
|
||||
return TokenizeResult.setResult(-1);
|
||||
|
||||
return TokenizeResult.setResult(EDToken::tokenize(Tokens,
|
||||
String,
|
||||
OperandOrder,
|
||||
Disassembler));
|
||||
|
||||
}
|
||||
|
||||
int EDInst::numTokens() {
|
||||
if (tokenize())
|
||||
return -1;
|
||||
return Tokens.size();
|
||||
}
|
||||
|
||||
int EDInst::getToken(EDToken *&token, unsigned int index) {
|
||||
if (tokenize())
|
||||
return -1;
|
||||
token = Tokens[index];
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
int EDInst::visitTokens(EDTokenVisitor_t visitor) {
|
||||
if (tokenize())
|
||||
return -1;
|
||||
|
||||
tokvec_t::iterator iter;
|
||||
|
||||
for (iter = Tokens.begin(); iter != Tokens.end(); ++iter) {
|
||||
int ret = visitor(*iter);
|
||||
if (ret == 1)
|
||||
return 0;
|
||||
if (ret != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
@ -1,182 +0,0 @@
|
||||
//===-- EDInst.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the interface for the Enhanced Disassembly library's
|
||||
// instruction class. The instruction is responsible for vending the string
|
||||
// representation, individual tokens and operands for a single instruction.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EDINST_H
|
||||
#define LLVM_EDINST_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class MCInst;
|
||||
struct EDInstInfo;
|
||||
struct EDToken;
|
||||
struct EDDisassembler;
|
||||
struct EDOperand;
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
typedef int (^EDTokenVisitor_t)(EDToken *token);
|
||||
#endif
|
||||
|
||||
/// CachedResult - Encapsulates the result of a function along with the validity
|
||||
/// of that result, so that slow functions don't need to run twice
|
||||
struct CachedResult {
|
||||
/// True if the result has been obtained by executing the function
|
||||
bool Valid;
|
||||
/// The result last obtained from the function
|
||||
int Result;
|
||||
|
||||
/// Constructor - Initializes an invalid result
|
||||
CachedResult() : Valid(false) { }
|
||||
/// valid - Returns true if the result has been obtained by executing the
|
||||
/// function and false otherwise
|
||||
bool valid() { return Valid; }
|
||||
/// result - Returns the result of the function or an undefined value if
|
||||
/// valid() is false
|
||||
int result() { return Result; }
|
||||
/// setResult - Sets the result of the function and declares it valid
|
||||
/// returning the result (so that setResult() can be called from inside a
|
||||
/// return statement)
|
||||
/// @arg result - The result of the function
|
||||
int setResult(int result) { Result = result; Valid = true; return result; }
|
||||
};
|
||||
|
||||
/// EDInst - Encapsulates a single instruction, which can be queried for its
|
||||
/// string representation, as well as its operands and tokens
|
||||
struct EDInst {
|
||||
/// The parent disassembler
|
||||
EDDisassembler &Disassembler;
|
||||
/// The containing MCInst
|
||||
llvm::MCInst *Inst;
|
||||
/// The instruction information provided by TableGen for this instruction
|
||||
const llvm::EDInstInfo *ThisInstInfo;
|
||||
/// The number of bytes for the machine code representation of the instruction
|
||||
uint64_t ByteSize;
|
||||
|
||||
/// The result of the stringify() function
|
||||
CachedResult StringifyResult;
|
||||
/// The string representation of the instruction
|
||||
std::string String;
|
||||
/// The order in which operands from the InstInfo's operand information appear
|
||||
/// in String
|
||||
const signed char* OperandOrder;
|
||||
|
||||
/// The result of the parseOperands() function
|
||||
CachedResult ParseResult;
|
||||
typedef llvm::SmallVector<EDOperand*, 5> opvec_t;
|
||||
/// The instruction's operands
|
||||
opvec_t Operands;
|
||||
/// The operand corresponding to the target, if the instruction is a branch
|
||||
int BranchTarget;
|
||||
/// The operand corresponding to the source, if the instruction is a move
|
||||
int MoveSource;
|
||||
/// The operand corresponding to the target, if the instruction is a move
|
||||
int MoveTarget;
|
||||
|
||||
/// The result of the tokenize() function
|
||||
CachedResult TokenizeResult;
|
||||
typedef std::vector<EDToken*> tokvec_t;
|
||||
/// The instruction's tokens
|
||||
tokvec_t Tokens;
|
||||
|
||||
/// Constructor - initializes an instruction given the output of the LLVM
|
||||
/// C++ disassembler
|
||||
///
|
||||
/// @arg inst - The MCInst, which will now be owned by this object
|
||||
/// @arg byteSize - The size of the consumed instruction, in bytes
|
||||
/// @arg disassembler - The parent disassembler
|
||||
/// @arg instInfo - The instruction information produced by the table
|
||||
/// generator for this instruction
|
||||
EDInst(llvm::MCInst *inst,
|
||||
uint64_t byteSize,
|
||||
EDDisassembler &disassembler,
|
||||
const llvm::EDInstInfo *instInfo);
|
||||
~EDInst();
|
||||
|
||||
/// byteSize - returns the number of bytes consumed by the machine code
|
||||
/// representation of the instruction
|
||||
uint64_t byteSize();
|
||||
/// instID - returns the LLVM instruction ID of the instruction
|
||||
unsigned instID();
|
||||
|
||||
/// stringify - populates the String and AsmString members of the instruction,
|
||||
/// returning 0 on success or -1 otherwise
|
||||
int stringify();
|
||||
/// getString - retrieves a pointer to the string representation of the
|
||||
/// instructinon, returning 0 on success or -1 otherwise
|
||||
///
|
||||
/// @arg str - A reference to a pointer that, on success, is set to point to
|
||||
/// the string representation of the instruction; this string is still owned
|
||||
/// by the instruction and will be deleted when it is
|
||||
int getString(const char *&str);
|
||||
|
||||
/// isBranch - Returns true if the instruction is a branch
|
||||
bool isBranch();
|
||||
/// isMove - Returns true if the instruction is a move
|
||||
bool isMove();
|
||||
|
||||
/// parseOperands - populates the Operands member of the instruction,
|
||||
/// returning 0 on success or -1 otherwise
|
||||
int parseOperands();
|
||||
/// branchTargetID - returns the ID (suitable for use with getOperand()) of
|
||||
/// the target operand if the instruction is a branch, or -1 otherwise
|
||||
int branchTargetID();
|
||||
/// moveSourceID - returns the ID of the source operand if the instruction
|
||||
/// is a move, or -1 otherwise
|
||||
int moveSourceID();
|
||||
/// moveTargetID - returns the ID of the target operand if the instruction
|
||||
/// is a move, or -1 otherwise
|
||||
int moveTargetID();
|
||||
|
||||
/// numOperands - returns the number of operands available to retrieve, or -1
|
||||
/// on error
|
||||
int numOperands();
|
||||
/// getOperand - retrieves an operand from the instruction's operand list by
|
||||
/// index, returning 0 on success or -1 on error
|
||||
///
|
||||
/// @arg operand - A reference whose target is pointed at the operand on
|
||||
/// success, although the operand is still owned by the EDInst
|
||||
/// @arg index - The index of the operand in the instruction
|
||||
int getOperand(EDOperand *&operand, unsigned int index);
|
||||
|
||||
/// tokenize - populates the Tokens member of the instruction, returning 0 on
|
||||
/// success or -1 otherwise
|
||||
int tokenize();
|
||||
/// numTokens - returns the number of tokens in the instruction, or -1 on
|
||||
/// error
|
||||
int numTokens();
|
||||
/// getToken - retrieves a token from the instruction's token list by index,
|
||||
/// returning 0 on success or -1 on error
|
||||
///
|
||||
/// @arg token - A reference whose target is pointed at the token on success,
|
||||
/// although the token is still owned by the EDInst
|
||||
/// @arg index - The index of the token in the instrcutino
|
||||
int getToken(EDToken *&token, unsigned int index);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/// visitTokens - Visits each token in turn and applies a block to it,
|
||||
/// returning 0 if all blocks are visited and/or the block signals
|
||||
/// termination by returning 1; returns -1 on error
|
||||
///
|
||||
/// @arg visitor - The visitor block to apply to all tokens.
|
||||
int visitTokens(EDTokenVisitor_t visitor);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,276 +0,0 @@
|
||||
//===-- 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"
|
||||
using namespace llvm;
|
||||
|
||||
int EDGetDisassembler(EDDisassemblerRef *disassembler,
|
||||
const char *triple,
|
||||
EDAssemblySyntax_t syntax) {
|
||||
EDDisassembler::AssemblySyntax Syntax;
|
||||
switch (syntax) {
|
||||
default: llvm_unreachable("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
|
@ -1,315 +0,0 @@
|
||||
//===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
|
||||
//
|
||||
// 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 Disassembly library's operand class. The
|
||||
// operand is responsible for allowing evaluation given a particular register
|
||||
// context.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDOperand.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
using namespace llvm;
|
||||
|
||||
EDOperand::EDOperand(const EDDisassembler &disassembler,
|
||||
const EDInst &inst,
|
||||
unsigned int opIndex,
|
||||
unsigned int &mcOpIndex) :
|
||||
Disassembler(disassembler),
|
||||
Inst(inst),
|
||||
OpIndex(opIndex),
|
||||
MCOpIndex(mcOpIndex) {
|
||||
unsigned int numMCOperands = 0;
|
||||
|
||||
Triple::ArchType arch = Disassembler.TgtTriple.getArch();
|
||||
|
||||
if (arch == Triple::x86 ||
|
||||
arch == Triple::x86_64) {
|
||||
uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
|
||||
|
||||
switch (operandType) {
|
||||
default:
|
||||
break;
|
||||
case kOperandTypeImmediate:
|
||||
numMCOperands = 1;
|
||||
break;
|
||||
case kOperandTypeRegister:
|
||||
numMCOperands = 1;
|
||||
break;
|
||||
case kOperandTypeX86Memory:
|
||||
numMCOperands = 5;
|
||||
break;
|
||||
case kOperandTypeX86EffectiveAddress:
|
||||
numMCOperands = 4;
|
||||
break;
|
||||
case kOperandTypeX86PCRelative:
|
||||
numMCOperands = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (arch == Triple::arm ||
|
||||
arch == Triple::thumb) {
|
||||
uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
|
||||
|
||||
switch (operandType) {
|
||||
default:
|
||||
case kOperandTypeARMRegisterList:
|
||||
case kOperandTypeARMDPRRegisterList:
|
||||
case kOperandTypeARMSPRRegisterList:
|
||||
break;
|
||||
case kOperandTypeImmediate:
|
||||
case kOperandTypeRegister:
|
||||
case kOperandTypeARMBranchTarget:
|
||||
case kOperandTypeARMSoImm:
|
||||
case kOperandTypeARMRotImm:
|
||||
case kOperandTypeThumb2SoImm:
|
||||
case kOperandTypeARMSoImm2Part:
|
||||
case kOperandTypeARMPredicate:
|
||||
case kOperandTypeThumbITMask:
|
||||
case kOperandTypeThumb2AddrModeImm8Offset:
|
||||
case kOperandTypeARMTBAddrMode:
|
||||
case kOperandTypeThumb2AddrModeImm8s4Offset:
|
||||
case kOperandTypeARMAddrMode7:
|
||||
case kOperandTypeThumb2AddrModeReg:
|
||||
numMCOperands = 1;
|
||||
break;
|
||||
case kOperandTypeThumb2SoReg:
|
||||
case kOperandTypeAddrModeImm12:
|
||||
case kOperandTypeARMAddrMode2Offset:
|
||||
case kOperandTypeARMAddrMode3Offset:
|
||||
case kOperandTypeARMAddrMode4:
|
||||
case kOperandTypeARMAddrMode5:
|
||||
case kOperandTypeARMAddrModePC:
|
||||
case kOperandTypeThumb2AddrModeImm8:
|
||||
case kOperandTypeThumb2AddrModeImm12:
|
||||
case kOperandTypeThumb2AddrModeImm8s4:
|
||||
case kOperandTypeThumbAddrModeImmS1:
|
||||
case kOperandTypeThumbAddrModeImmS2:
|
||||
case kOperandTypeThumbAddrModeImmS4:
|
||||
case kOperandTypeThumbAddrModeRR:
|
||||
case kOperandTypeThumbAddrModeSP:
|
||||
case kOperandTypeThumbAddrModePC:
|
||||
numMCOperands = 2;
|
||||
break;
|
||||
case kOperandTypeARMSoReg:
|
||||
case kOperandTypeLdStSOReg:
|
||||
case kOperandTypeARMAddrMode2:
|
||||
case kOperandTypeARMAddrMode3:
|
||||
case kOperandTypeThumb2AddrModeSoReg:
|
||||
case kOperandTypeThumbAddrModeRegS1:
|
||||
case kOperandTypeThumbAddrModeRegS2:
|
||||
case kOperandTypeThumbAddrModeRegS4:
|
||||
case kOperandTypeARMAddrMode6Offset:
|
||||
numMCOperands = 3;
|
||||
break;
|
||||
case kOperandTypeARMAddrMode6:
|
||||
numMCOperands = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mcOpIndex += numMCOperands;
|
||||
}
|
||||
|
||||
EDOperand::~EDOperand() {
|
||||
}
|
||||
|
||||
int EDOperand::evaluate(uint64_t &result,
|
||||
EDRegisterReaderCallback callback,
|
||||
void *arg) {
|
||||
uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
|
||||
|
||||
Triple::ArchType arch = Disassembler.TgtTriple.getArch();
|
||||
|
||||
switch (arch) {
|
||||
default:
|
||||
return -1;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
switch (operandType) {
|
||||
default:
|
||||
return -1;
|
||||
case kOperandTypeImmediate:
|
||||
result = Inst.Inst->getOperand(MCOpIndex).getImm();
|
||||
return 0;
|
||||
case kOperandTypeRegister:
|
||||
{
|
||||
unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
|
||||
return callback(&result, reg, arg);
|
||||
}
|
||||
case kOperandTypeX86PCRelative:
|
||||
{
|
||||
int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
|
||||
|
||||
uint64_t ripVal;
|
||||
|
||||
// TODO fix how we do this
|
||||
|
||||
if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
|
||||
return -1;
|
||||
|
||||
result = ripVal + displacement;
|
||||
return 0;
|
||||
}
|
||||
case kOperandTypeX86Memory:
|
||||
case kOperandTypeX86EffectiveAddress:
|
||||
{
|
||||
unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
|
||||
uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
|
||||
unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
|
||||
int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
|
||||
|
||||
uint64_t addr = 0;
|
||||
|
||||
unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
|
||||
|
||||
if (segmentReg != 0 && arch == Triple::x86_64) {
|
||||
unsigned fsID = Disassembler.registerIDWithName("FS");
|
||||
unsigned gsID = Disassembler.registerIDWithName("GS");
|
||||
|
||||
if (segmentReg == fsID ||
|
||||
segmentReg == gsID) {
|
||||
uint64_t segmentBase;
|
||||
if (!callback(&segmentBase, segmentReg, arg))
|
||||
addr += segmentBase;
|
||||
}
|
||||
}
|
||||
|
||||
if (baseReg) {
|
||||
uint64_t baseVal;
|
||||
if (callback(&baseVal, baseReg, arg))
|
||||
return -1;
|
||||
addr += baseVal;
|
||||
}
|
||||
|
||||
if (indexReg) {
|
||||
uint64_t indexVal;
|
||||
if (callback(&indexVal, indexReg, arg))
|
||||
return -1;
|
||||
addr += (scaleAmount * indexVal);
|
||||
}
|
||||
|
||||
addr += displacement;
|
||||
|
||||
result = addr;
|
||||
return 0;
|
||||
}
|
||||
} // switch (operandType)
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
switch (operandType) {
|
||||
default:
|
||||
return -1;
|
||||
case kOperandTypeImmediate:
|
||||
if (!Inst.Inst->getOperand(MCOpIndex).isImm())
|
||||
return -1;
|
||||
|
||||
result = Inst.Inst->getOperand(MCOpIndex).getImm();
|
||||
return 0;
|
||||
case kOperandTypeRegister:
|
||||
{
|
||||
if (!Inst.Inst->getOperand(MCOpIndex).isReg())
|
||||
return -1;
|
||||
|
||||
unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
|
||||
return callback(&result, reg, arg);
|
||||
}
|
||||
case kOperandTypeARMBranchTarget:
|
||||
{
|
||||
if (!Inst.Inst->getOperand(MCOpIndex).isImm())
|
||||
return -1;
|
||||
|
||||
int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
|
||||
|
||||
uint64_t pcVal;
|
||||
|
||||
if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
|
||||
return -1;
|
||||
|
||||
result = pcVal + displacement;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int EDOperand::isRegister() {
|
||||
return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
|
||||
}
|
||||
|
||||
unsigned EDOperand::regVal() {
|
||||
return Inst.Inst->getOperand(MCOpIndex).getReg();
|
||||
}
|
||||
|
||||
int EDOperand::isImmediate() {
|
||||
return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
|
||||
}
|
||||
|
||||
uint64_t EDOperand::immediateVal() {
|
||||
return Inst.Inst->getOperand(MCOpIndex).getImm();
|
||||
}
|
||||
|
||||
int EDOperand::isMemory() {
|
||||
uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
|
||||
|
||||
switch (operandType) {
|
||||
default:
|
||||
return 0;
|
||||
case kOperandTypeX86Memory:
|
||||
case kOperandTypeX86PCRelative:
|
||||
case kOperandTypeX86EffectiveAddress:
|
||||
case kOperandTypeARMSoReg:
|
||||
case kOperandTypeARMSoImm:
|
||||
case kOperandTypeARMAddrMode2:
|
||||
case kOperandTypeARMAddrMode2Offset:
|
||||
case kOperandTypeARMAddrMode3:
|
||||
case kOperandTypeARMAddrMode3Offset:
|
||||
case kOperandTypeARMAddrMode4:
|
||||
case kOperandTypeARMAddrMode5:
|
||||
case kOperandTypeARMAddrMode6:
|
||||
case kOperandTypeARMAddrMode7:
|
||||
case kOperandTypeARMAddrModePC:
|
||||
case kOperandTypeARMBranchTarget:
|
||||
case kOperandTypeThumbAddrModeRegS1:
|
||||
case kOperandTypeThumbAddrModeRegS2:
|
||||
case kOperandTypeThumbAddrModeRegS4:
|
||||
case kOperandTypeThumbAddrModeRR:
|
||||
case kOperandTypeThumbAddrModeSP:
|
||||
case kOperandTypeThumb2SoImm:
|
||||
case kOperandTypeThumb2AddrModeImm8:
|
||||
case kOperandTypeThumb2AddrModeImm8Offset:
|
||||
case kOperandTypeThumb2AddrModeImm12:
|
||||
case kOperandTypeThumb2AddrModeSoReg:
|
||||
case kOperandTypeThumb2AddrModeImm8s4:
|
||||
case kOperandTypeThumb2AddrModeReg:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
namespace {
|
||||
struct RegisterReaderWrapper {
|
||||
EDOperand::EDRegisterBlock_t regBlock;
|
||||
};
|
||||
}
|
||||
|
||||
static int readerWrapperCallback(uint64_t *value, unsigned regID, void *arg) {
|
||||
RegisterReaderWrapper *wrapper = (RegisterReaderWrapper *)arg;
|
||||
return wrapper->regBlock(value, regID);
|
||||
}
|
||||
|
||||
int EDOperand::evaluate(uint64_t &result, EDRegisterBlock_t regBlock) {
|
||||
RegisterReaderWrapper wrapper;
|
||||
wrapper.regBlock = regBlock;
|
||||
return evaluate(result, readerWrapperCallback, (void*)&wrapper);
|
||||
}
|
||||
#endif
|
@ -1,91 +0,0 @@
|
||||
//===-EDOperand.h - LLVM Enhanced Disassembler ------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the interface for the Enhanced Disassembly library's
|
||||
// operand class. The operand is responsible for allowing evaluation given a
|
||||
// particular register context.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EDOPERAND_H
|
||||
#define LLVM_EDOPERAND_H
|
||||
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct EDDisassembler;
|
||||
struct EDInst;
|
||||
|
||||
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
void* arg);
|
||||
|
||||
|
||||
/// EDOperand - Encapsulates a single operand, which can be evaluated by the
|
||||
/// client
|
||||
struct EDOperand {
|
||||
/// The parent disassembler
|
||||
const EDDisassembler &Disassembler;
|
||||
/// The parent instruction
|
||||
const EDInst &Inst;
|
||||
|
||||
/// The index of the operand in the EDInst
|
||||
unsigned int OpIndex;
|
||||
/// The index of the first component of the operand in the MCInst
|
||||
unsigned int MCOpIndex;
|
||||
|
||||
/// Constructor - Initializes an EDOperand
|
||||
///
|
||||
/// @arg disassembler - The disassembler responsible for the operand
|
||||
/// @arg inst - The instruction containing this operand
|
||||
/// @arg opIndex - The index of the operand in inst
|
||||
/// @arg mcOpIndex - The index of the operand in the original MCInst
|
||||
EDOperand(const EDDisassembler &disassembler,
|
||||
const EDInst &inst,
|
||||
unsigned int opIndex,
|
||||
unsigned int &mcOpIndex);
|
||||
~EDOperand();
|
||||
|
||||
/// evaluate - Returns the numeric value of an operand to the extent possible,
|
||||
/// returning 0 on success or -1 if there was some problem (such as a
|
||||
/// register not being readable)
|
||||
///
|
||||
/// @arg result - A reference whose target is filled in with the value of
|
||||
/// the operand (the address if it is a memory operand)
|
||||
/// @arg callback - A function to call to obtain register values
|
||||
/// @arg arg - An opaque argument to pass to callback
|
||||
int evaluate(uint64_t &result,
|
||||
EDRegisterReaderCallback callback,
|
||||
void *arg);
|
||||
|
||||
/// isRegister - Returns 1 if the operand is a register or 0 otherwise
|
||||
int isRegister();
|
||||
/// regVal - Returns the register value.
|
||||
unsigned regVal();
|
||||
|
||||
/// isImmediate - Returns 1 if the operand is an immediate or 0 otherwise
|
||||
int isImmediate();
|
||||
/// immediateVal - Returns the immediate value.
|
||||
uint64_t immediateVal();
|
||||
|
||||
/// isMemory - Returns 1 if the operand is a memory location or 0 otherwise
|
||||
int isMemory();
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
|
||||
|
||||
/// evaluate - Like evaluate for a callback, but uses a block instead
|
||||
int evaluate(uint64_t &result,
|
||||
EDRegisterBlock_t regBlock);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,214 +0,0 @@
|
||||
//===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
|
||||
//
|
||||
// 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 library's token class. The
|
||||
// token is responsible for vending information about the token, such as its
|
||||
// type and logical value.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDToken.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
using namespace llvm;
|
||||
|
||||
EDToken::EDToken(StringRef str,
|
||||
enum tokenType type,
|
||||
uint64_t localType,
|
||||
EDDisassembler &disassembler) :
|
||||
Disassembler(disassembler),
|
||||
Str(str),
|
||||
Type(type),
|
||||
LocalType(localType),
|
||||
OperandID(-1) {
|
||||
}
|
||||
|
||||
EDToken::~EDToken() {
|
||||
}
|
||||
|
||||
void EDToken::makeLiteral(bool sign, uint64_t absoluteValue) {
|
||||
Type = kTokenLiteral;
|
||||
LiteralSign = sign;
|
||||
LiteralAbsoluteValue = absoluteValue;
|
||||
}
|
||||
|
||||
void EDToken::makeRegister(unsigned registerID) {
|
||||
Type = kTokenRegister;
|
||||
RegisterID = registerID;
|
||||
}
|
||||
|
||||
void EDToken::setOperandID(int operandID) {
|
||||
OperandID = operandID;
|
||||
}
|
||||
|
||||
enum EDToken::tokenType EDToken::type() const {
|
||||
return Type;
|
||||
}
|
||||
|
||||
uint64_t EDToken::localType() const {
|
||||
return LocalType;
|
||||
}
|
||||
|
||||
StringRef EDToken::string() const {
|
||||
return Str;
|
||||
}
|
||||
|
||||
int EDToken::operandID() const {
|
||||
return OperandID;
|
||||
}
|
||||
|
||||
int EDToken::literalSign() const {
|
||||
if (Type != kTokenLiteral)
|
||||
return -1;
|
||||
return (LiteralSign ? 1 : 0);
|
||||
}
|
||||
|
||||
int EDToken::literalAbsoluteValue(uint64_t &value) const {
|
||||
if (Type != kTokenLiteral)
|
||||
return -1;
|
||||
value = LiteralAbsoluteValue;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::registerID(unsigned ®isterID) const {
|
||||
if (Type != kTokenRegister)
|
||||
return -1;
|
||||
registerID = RegisterID;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::tokenize(std::vector<EDToken*> &tokens,
|
||||
std::string &str,
|
||||
const signed char *operandOrder,
|
||||
EDDisassembler &disassembler) {
|
||||
SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
|
||||
SmallVector<AsmToken, 10> asmTokens;
|
||||
|
||||
if (disassembler.parseInst(parsedOperands, asmTokens, str))
|
||||
{
|
||||
for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
|
||||
delete parsedOperands[i];
|
||||
return -1;
|
||||
}
|
||||
|
||||
SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
|
||||
unsigned int operandIndex;
|
||||
SmallVectorImpl<AsmToken>::iterator tokenIterator;
|
||||
|
||||
operandIterator = parsedOperands.begin();
|
||||
operandIndex = 0;
|
||||
|
||||
bool readOpcode = false;
|
||||
|
||||
const char *wsPointer = asmTokens.begin()->getLoc().getPointer();
|
||||
|
||||
for (tokenIterator = asmTokens.begin();
|
||||
tokenIterator != asmTokens.end();
|
||||
++tokenIterator) {
|
||||
SMLoc tokenLoc = tokenIterator->getLoc();
|
||||
|
||||
const char *tokenPointer = tokenLoc.getPointer();
|
||||
|
||||
if (tokenPointer > wsPointer) {
|
||||
unsigned long wsLength = tokenPointer - wsPointer;
|
||||
|
||||
EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
|
||||
EDToken::kTokenWhitespace,
|
||||
0,
|
||||
disassembler);
|
||||
|
||||
tokens.push_back(whitespaceToken);
|
||||
}
|
||||
|
||||
wsPointer = tokenPointer + tokenIterator->getString().size();
|
||||
|
||||
while (operandIterator != parsedOperands.end() &&
|
||||
tokenLoc.getPointer() >
|
||||
(*operandIterator)->getEndLoc().getPointer()) {
|
||||
++operandIterator;
|
||||
++operandIndex;
|
||||
}
|
||||
|
||||
EDToken *token;
|
||||
|
||||
switch (tokenIterator->getKind()) {
|
||||
case AsmToken::Identifier:
|
||||
if (!readOpcode) {
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenOpcode,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
readOpcode = true;
|
||||
break;
|
||||
}
|
||||
// any identifier that isn't an opcode is mere punctuation; so we fall
|
||||
// through
|
||||
default:
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenPunctuation,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
break;
|
||||
case AsmToken::Integer:
|
||||
{
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenLiteral,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
|
||||
int64_t intVal = tokenIterator->getIntVal();
|
||||
|
||||
if (intVal < 0)
|
||||
token->makeLiteral(true, -intVal);
|
||||
else
|
||||
token->makeLiteral(false, intVal);
|
||||
break;
|
||||
}
|
||||
case AsmToken::Register:
|
||||
{
|
||||
token = new EDToken(tokenIterator->getString(),
|
||||
EDToken::kTokenLiteral,
|
||||
(uint64_t)tokenIterator->getKind(),
|
||||
disassembler);
|
||||
|
||||
token->makeRegister((unsigned)tokenIterator->getRegVal());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (operandIterator != parsedOperands.end() &&
|
||||
tokenLoc.getPointer() >=
|
||||
(*operandIterator)->getStartLoc().getPointer()) {
|
||||
/// operandIndex == 0 means the operand is the instruction (which the
|
||||
/// AsmParser treats as an operand but edis does not). We therefore skip
|
||||
/// operandIndex == 0 and subtract 1 from all other operand indices.
|
||||
|
||||
if (operandIndex > 0)
|
||||
token->setOperandID(operandOrder[operandIndex - 1]);
|
||||
}
|
||||
|
||||
tokens.push_back(token);
|
||||
}
|
||||
|
||||
// Free any parsed operands.
|
||||
for (unsigned i = 0, e = parsedOperands.size(); i != e; ++i)
|
||||
delete parsedOperands[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDToken::getString(const char*& buf) {
|
||||
if (PermStr.length() == 0) {
|
||||
PermStr = Str.str();
|
||||
}
|
||||
buf = PermStr.c_str();
|
||||
return 0;
|
||||
}
|
@ -1,139 +0,0 @@
|
||||
//===-EDToken.h - LLVM Enhanced Disassembler --------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the interface for the Enhanced Disassembly library's token
|
||||
// class. The token is responsible for vending information about the token,
|
||||
// such as its type and logical value.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EDTOKEN_H
|
||||
#define LLVM_EDTOKEN_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct EDDisassembler;
|
||||
|
||||
/// EDToken - Encapsulates a single token, which can provide a string
|
||||
/// representation of itself or interpret itself in various ways, depending
|
||||
/// on the token type.
|
||||
struct EDToken {
|
||||
enum tokenType {
|
||||
kTokenWhitespace,
|
||||
kTokenOpcode,
|
||||
kTokenLiteral,
|
||||
kTokenRegister,
|
||||
kTokenPunctuation
|
||||
};
|
||||
|
||||
/// The parent disassembler
|
||||
EDDisassembler &Disassembler;
|
||||
|
||||
/// The token's string representation
|
||||
llvm::StringRef Str;
|
||||
/// The token's string representation, but in a form suitable for export
|
||||
std::string PermStr;
|
||||
/// The type of the token, as exposed through the external API
|
||||
enum tokenType Type;
|
||||
/// The type of the token, as recorded by the syntax-specific tokenizer
|
||||
uint64_t LocalType;
|
||||
/// The operand corresponding to the token, or (unsigned int)-1 if not
|
||||
/// part of an operand.
|
||||
int OperandID;
|
||||
|
||||
/// The sign if the token is a literal (1 if negative, 0 otherwise)
|
||||
bool LiteralSign;
|
||||
/// The absolute value if the token is a literal
|
||||
uint64_t LiteralAbsoluteValue;
|
||||
/// The LLVM register ID if the token is a register name
|
||||
unsigned RegisterID;
|
||||
|
||||
/// Constructor - Initializes an EDToken with the information common to all
|
||||
/// tokens
|
||||
///
|
||||
/// @arg str - The string corresponding to the token
|
||||
/// @arg type - The token's type as exposed through the public API
|
||||
/// @arg localType - The token's type as recorded by the tokenizer
|
||||
/// @arg disassembler - The disassembler responsible for the token
|
||||
EDToken(llvm::StringRef str,
|
||||
enum tokenType type,
|
||||
uint64_t localType,
|
||||
EDDisassembler &disassembler);
|
||||
|
||||
/// makeLiteral - Adds the information specific to a literal
|
||||
/// @arg sign - The sign of the literal (1 if negative, 0
|
||||
/// otherwise)
|
||||
///
|
||||
/// @arg absoluteValue - The absolute value of the literal
|
||||
void makeLiteral(bool sign, uint64_t absoluteValue);
|
||||
/// makeRegister - Adds the information specific to a register
|
||||
///
|
||||
/// @arg registerID - The LLVM register ID
|
||||
void makeRegister(unsigned registerID);
|
||||
|
||||
/// setOperandID - Links the token to a numbered operand
|
||||
///
|
||||
/// @arg operandID - The operand ID to link to
|
||||
void setOperandID(int operandID);
|
||||
|
||||
~EDToken();
|
||||
|
||||
/// type - Returns the public type of the token
|
||||
enum tokenType type() const;
|
||||
/// localType - Returns the tokenizer-specific type of the token
|
||||
uint64_t localType() const;
|
||||
/// string - Returns the string representation of the token
|
||||
llvm::StringRef string() const;
|
||||
/// operandID - Returns the operand ID of the token
|
||||
int operandID() const;
|
||||
|
||||
/// literalSign - Returns the sign of the token
|
||||
/// (1 if negative, 0 if positive or unsigned, -1 if it is not a literal)
|
||||
int literalSign() const;
|
||||
/// literalAbsoluteValue - Retrieves the absolute value of the token, and
|
||||
/// returns -1 if the token is not a literal
|
||||
/// @arg value - A reference to a value that is filled in with the absolute
|
||||
/// value, if it is valid
|
||||
int literalAbsoluteValue(uint64_t &value) const;
|
||||
/// registerID - Retrieves the register ID of the token, and returns -1 if the
|
||||
/// token is not a register
|
||||
///
|
||||
/// @arg registerID - A reference to a value that is filled in with the
|
||||
/// register ID, if it is valid
|
||||
int registerID(unsigned ®isterID) const;
|
||||
|
||||
/// tokenize - Tokenizes a string using the platform- and syntax-specific
|
||||
/// tokenizer, and returns 0 on success (-1 on failure)
|
||||
///
|
||||
/// @arg tokens - A vector that will be filled in with pointers to
|
||||
/// allocated tokens
|
||||
/// @arg str - The string, as outputted by the AsmPrinter
|
||||
/// @arg operandOrder - The order of the operands from the operandFlags array
|
||||
/// as they appear in str
|
||||
/// @arg disassembler - The disassembler for the desired target and
|
||||
// assembly syntax
|
||||
static int tokenize(std::vector<EDToken*> &tokens,
|
||||
std::string &str,
|
||||
const signed char *operandOrder,
|
||||
EDDisassembler &disassembler);
|
||||
|
||||
/// getString - Directs a character pointer to the string, returning 0 on
|
||||
/// success (-1 on failure)
|
||||
/// @arg buf - A reference to a pointer that is set to point to the string.
|
||||
/// The string is still owned by the token.
|
||||
int getString(const char*& buf);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
#endif
|
@ -11,7 +11,6 @@ tablegen(LLVM ARMGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM ARMGenFastISel.inc -gen-fast-isel)
|
||||
tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM ARMGenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM ARMGenEDInfo.inc -gen-enhanced-disassembly-info)
|
||||
tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler)
|
||||
add_public_tablegen_target(ARMCommonTableGen)
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "MCTargetDesc/ARMAddressingModes.h"
|
||||
#include "MCTargetDesc/ARMBaseInfo.h"
|
||||
#include "MCTargetDesc/ARMMCExpr.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCFixedLenDisassembler.h"
|
||||
@ -105,10 +104,6 @@ public:
|
||||
uint64_t address,
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const;
|
||||
|
||||
/// getEDInfo - See MCDisassembler.
|
||||
const EDInstInfo *getEDInfo() const;
|
||||
private:
|
||||
};
|
||||
|
||||
/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
|
||||
@ -131,8 +126,6 @@ public:
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const;
|
||||
|
||||
/// getEDInfo - See MCDisassembler.
|
||||
const EDInstInfo *getEDInfo() const;
|
||||
private:
|
||||
mutable ITStatus ITBlock;
|
||||
DecodeStatus AddThumbPredicate(MCInst&) const;
|
||||
@ -385,7 +378,6 @@ static DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
|
||||
static DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
|
||||
uint64_t Address, const void *Decoder);
|
||||
#include "ARMGenDisassemblerTables.inc"
|
||||
#include "ARMGenEDInfo.inc"
|
||||
|
||||
static MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) {
|
||||
return new ARMDisassembler(STI);
|
||||
@ -395,14 +387,6 @@ static MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtarge
|
||||
return new ThumbDisassembler(STI);
|
||||
}
|
||||
|
||||
const EDInstInfo *ARMDisassembler::getEDInfo() const {
|
||||
return instInfoARM;
|
||||
}
|
||||
|
||||
const EDInstInfo *ThumbDisassembler::getEDInfo() const {
|
||||
return instInfoARM;
|
||||
}
|
||||
|
||||
DecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
|
||||
const MemoryObject &Region,
|
||||
uint64_t Address,
|
||||
|
@ -16,7 +16,7 @@ BUILT_SOURCES = ARMGenRegisterInfo.inc ARMGenInstrInfo.inc \
|
||||
ARMGenAsmWriter.inc ARMGenAsmMatcher.inc \
|
||||
ARMGenDAGISel.inc ARMGenSubtargetInfo.inc \
|
||||
ARMGenCodeEmitter.inc ARMGenCallingConv.inc \
|
||||
ARMGenEDInfo.inc ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
|
||||
ARMGenFastISel.inc ARMGenMCCodeEmitter.inc \
|
||||
ARMGenMCPseudoLowering.inc ARMGenDisassemblerTables.inc
|
||||
|
||||
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
|
||||
|
@ -9,7 +9,6 @@ tablegen(LLVM MBlazeGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM MBlazeGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM MBlazeGenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM MBlazeGenIntrinsics.inc -gen-tgt-intrinsic)
|
||||
tablegen(LLVM MBlazeGenEDInfo.inc -gen-enhanced-disassembly-info)
|
||||
add_public_tablegen_target(MBlazeCommonTableGen)
|
||||
|
||||
add_llvm_target(MBlazeCodeGen
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
#include "MBlazeDisassembler.h"
|
||||
#include "MBlaze.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
@ -25,7 +24,6 @@
|
||||
|
||||
// #include "MBlazeGenDecoderTables.inc"
|
||||
// #include "MBlazeGenRegisterNames.inc"
|
||||
#include "MBlazeGenEDInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
extern const MCInstrDesc MBlazeInsts[];
|
||||
@ -491,10 +489,6 @@ static unsigned getOPCODE(uint32_t insn) {
|
||||
}
|
||||
}
|
||||
|
||||
const EDInstInfo *MBlazeDisassembler::getEDInfo() const {
|
||||
return instInfoMBlaze;
|
||||
}
|
||||
|
||||
//
|
||||
// Public interface for the disassembler
|
||||
//
|
||||
|
@ -23,8 +23,6 @@ class MCInst;
|
||||
class MemoryObject;
|
||||
class raw_ostream;
|
||||
|
||||
struct EDInstInfo;
|
||||
|
||||
/// MBlazeDisassembler - Disassembler for all MBlaze platforms.
|
||||
class MBlazeDisassembler : public MCDisassembler {
|
||||
public:
|
||||
@ -44,9 +42,6 @@ public:
|
||||
uint64_t address,
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const;
|
||||
|
||||
/// getEDInfo - See MCDisassembler.
|
||||
const EDInstInfo *getEDInfo() const;
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -15,8 +15,7 @@ BUILT_SOURCES = MBlazeGenRegisterInfo.inc MBlazeGenInstrInfo.inc \
|
||||
MBlazeGenAsmWriter.inc \
|
||||
MBlazeGenDAGISel.inc MBlazeGenAsmMatcher.inc \
|
||||
MBlazeGenCodeEmitter.inc MBlazeGenCallingConv.inc \
|
||||
MBlazeGenSubtargetInfo.inc MBlazeGenIntrinsics.inc \
|
||||
MBlazeGenEDInfo.inc
|
||||
MBlazeGenSubtargetInfo.inc MBlazeGenIntrinsics.inc
|
||||
|
||||
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc
|
||||
|
||||
|
@ -9,7 +9,6 @@ tablegen(LLVM MipsGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM MipsGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM MipsGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM MipsGenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM MipsGenEDInfo.inc -gen-enhanced-disassembly-info)
|
||||
tablegen(LLVM MipsGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM MipsGenMCPseudoLowering.inc -gen-pseudo-lowering)
|
||||
add_public_tablegen_target(MipsCommonTableGen)
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "Mips.h"
|
||||
#include "MipsRegisterInfo.h"
|
||||
#include "MipsSubtarget.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCFixedLenDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
@ -23,9 +22,6 @@
|
||||
#include "llvm/Support/MemoryObject.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
// Not a normal header, this must come last.
|
||||
#include "MipsGenEDInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
typedef MCDisassembler::DecodeStatus DecodeStatus;
|
||||
@ -43,9 +39,6 @@ public:
|
||||
|
||||
virtual ~MipsDisassemblerBase() {}
|
||||
|
||||
/// getEDInfo - See MCDisassembler.
|
||||
const EDInstInfo *getEDInfo() const;
|
||||
|
||||
const MCRegisterInfo *getRegInfo() const { return RegInfo; }
|
||||
|
||||
private:
|
||||
@ -93,10 +86,6 @@ public:
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
const EDInstInfo *MipsDisassemblerBase::getEDInfo() const {
|
||||
return instInfoMips;
|
||||
}
|
||||
|
||||
// Forward declare these because the autogenerated code will reference them.
|
||||
// Definitions are further down.
|
||||
static DecodeStatus DecodeCPU64RegsRegisterClass(MCInst &Inst,
|
||||
|
@ -16,7 +16,7 @@ BUILT_SOURCES = MipsGenRegisterInfo.inc MipsGenInstrInfo.inc \
|
||||
MipsGenAsmWriter.inc MipsGenCodeEmitter.inc \
|
||||
MipsGenDAGISel.inc MipsGenCallingConv.inc \
|
||||
MipsGenSubtargetInfo.inc MipsGenMCCodeEmitter.inc \
|
||||
MipsGenEDInfo.inc MipsGenDisassemblerTables.inc \
|
||||
MipsGenDisassemblerTables.inc \
|
||||
MipsGenMCPseudoLowering.inc MipsGenAsmMatcher.inc
|
||||
|
||||
DIRS = InstPrinter Disassembler AsmParser TargetInfo MCTargetDesc
|
||||
|
@ -10,7 +10,6 @@ tablegen(LLVM X86GenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM X86GenFastISel.inc -gen-fast-isel)
|
||||
tablegen(LLVM X86GenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM X86GenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM X86GenEDInfo.inc -gen-enhanced-disassembly-info)
|
||||
add_public_tablegen_target(X86CommonTableGen)
|
||||
|
||||
set(sources
|
||||
|
@ -16,7 +16,6 @@
|
||||
|
||||
#include "X86Disassembler.h"
|
||||
#include "X86DisassemblerDecoder.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
@ -32,7 +31,6 @@
|
||||
#include "X86GenRegisterInfo.inc"
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "X86GenInstrInfo.inc"
|
||||
#include "X86GenEDInfo.inc"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::X86Disassembler;
|
||||
@ -83,10 +81,6 @@ X86GenericDisassembler::~X86GenericDisassembler() {
|
||||
delete MII;
|
||||
}
|
||||
|
||||
const EDInstInfo *X86GenericDisassembler::getEDInfo() const {
|
||||
return instInfoX86;
|
||||
}
|
||||
|
||||
/// regionReader - a callback function that wraps the readByte method from
|
||||
/// MemoryObject.
|
||||
///
|
||||
|
@ -95,8 +95,6 @@ class MCSubtargetInfo;
|
||||
class MemoryObject;
|
||||
class raw_ostream;
|
||||
|
||||
struct EDInstInfo;
|
||||
|
||||
namespace X86Disassembler {
|
||||
|
||||
/// X86GenericDisassembler - Generic disassembler for all X86 platforms.
|
||||
@ -122,8 +120,6 @@ public:
|
||||
raw_ostream &vStream,
|
||||
raw_ostream &cStream) const;
|
||||
|
||||
/// getEDInfo - See MCDisassembler.
|
||||
const EDInstInfo *getEDInfo() const;
|
||||
private:
|
||||
DisassemblerMode fMode;
|
||||
};
|
||||
|
@ -16,8 +16,7 @@ BUILT_SOURCES = X86GenRegisterInfo.inc X86GenInstrInfo.inc \
|
||||
X86GenAsmWriter.inc X86GenAsmMatcher.inc \
|
||||
X86GenAsmWriter1.inc X86GenDAGISel.inc \
|
||||
X86GenDisassemblerTables.inc X86GenFastISel.inc \
|
||||
X86GenCallingConv.inc X86GenSubtargetInfo.inc \
|
||||
X86GenEDInfo.inc
|
||||
X86GenCallingConv.inc X86GenSubtargetInfo.inc
|
||||
|
||||
DIRS = InstPrinter AsmParser Disassembler TargetInfo MCTargetDesc Utils
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
# RUN: llvm-mc --edis %s -triple=x86_64-apple-darwin9 2>&1 | FileCheck %s
|
||||
|
||||
# CHECK: [o:jne][w: ][0-p:-][0-l:10=10] <br> 0:[RIP/{{[0-9]+}}](pc)=18446744073709551606
|
||||
0x0f 0x85 0xf6 0xff 0xff 0xff
|
||||
# CHECK: [o:movq][w: ][1-r:%gs=r{{[0-9]+}}][1-p::][1-l:8=8][p:,][w: ][0-r:%rcx=r{{[0-9]+}}] <mov> 0:[RCX/{{[0-9]+}}]=0 1:[GS/{{[0-9]+}}]=8
|
||||
0x65 0x48 0x8b 0x0c 0x25 0x08 0x00 0x00 0x00
|
||||
# CHECK: [o:xorps][w: ][2-r:%xmm1=r{{[0-9]+}}][p:,][w: ][0-r:%xmm2=r{{[0-9]+}}] 0:[XMM2/{{[0-9]+}}]=0 1:[XMM2/{{[0-9]+}}]=0 2:[XMM1/{{[0-9]+}}]=0
|
||||
0x0f 0x57 0xd1
|
||||
# CHECK: [o:andps][w: ][2-r:%xmm1=r{{[0-9]+}}][p:,][w: ][0-r:%xmm2=r{{[0-9]+}}] 0:[XMM2/{{[0-9]+}}]=0 1:[XMM2/{{[0-9]+}}]=0 2:[XMM1/{{[0-9]+}}]=0
|
||||
0x0f 0x54 0xd1
|
@ -13,10 +13,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Disassembler.h"
|
||||
#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/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
@ -169,175 +165,3 @@ int Disassembler::disassemble(const Target &T,
|
||||
|
||||
return ErrorOccurred;
|
||||
}
|
||||
|
||||
static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) {
|
||||
ByteArrayTy &ByteArray = *((ByteArrayTy*)Arg);
|
||||
|
||||
if (A >= ByteArray.size())
|
||||
return -1;
|
||||
|
||||
*B = ByteArray[A].first;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) {
|
||||
EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0];
|
||||
raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1];
|
||||
|
||||
if (const char *regName = disassembler.nameWithRegisterID(R))
|
||||
Out << "[" << regName << "/" << R << "]";
|
||||
|
||||
if (disassembler.registerIsStackPointer(R))
|
||||
Out << "(sp)";
|
||||
if (disassembler.registerIsProgramCounter(R))
|
||||
Out << "(pc)";
|
||||
|
||||
*V = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Disassembler::disassembleEnhanced(const std::string &TS,
|
||||
MemoryBuffer &Buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out) {
|
||||
ByteArrayTy ByteArray;
|
||||
StringRef Str = Buffer.getBuffer();
|
||||
|
||||
if (ByteArrayFromString(ByteArray, Str, SM)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Triple T(TS);
|
||||
EDDisassembler::AssemblySyntax AS;
|
||||
|
||||
switch (T.getArch()) {
|
||||
default:
|
||||
errs() << "error: no default assembly syntax for " << TS.c_str() << "\n";
|
||||
return -1;
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
AS = EDDisassembler::kEDAssemblySyntaxARMUAL;
|
||||
break;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
AS = EDDisassembler::kEDAssemblySyntaxX86ATT;
|
||||
break;
|
||||
}
|
||||
|
||||
OwningPtr<EDDisassembler>
|
||||
disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS));
|
||||
|
||||
if (disassembler == 0) {
|
||||
errs() << "error: couldn't get disassembler for " << TS << '\n';
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (ByteArray.size()) {
|
||||
OwningPtr<EDInst>
|
||||
inst(disassembler->createInst(byteArrayReader, 0, &ByteArray));
|
||||
|
||||
if (inst == 0) {
|
||||
errs() << "error: Didn't get an instruction\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
ByteArray.erase (ByteArray.begin(), ByteArray.begin() + inst->byteSize());
|
||||
|
||||
unsigned numTokens = inst->numTokens();
|
||||
if ((int)numTokens < 0) {
|
||||
errs() << "error: couldn't count the instruction's tokens\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) {
|
||||
EDToken *token;
|
||||
|
||||
if (inst->getToken(token, tokenIndex)) {
|
||||
errs() << "error: Couldn't get token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *buf;
|
||||
if (token->getString(buf)) {
|
||||
errs() << "error: Couldn't get string for token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
Out << '[';
|
||||
int operandIndex = token->operandID();
|
||||
|
||||
if (operandIndex >= 0)
|
||||
Out << operandIndex << "-";
|
||||
|
||||
switch (token->type()) {
|
||||
case EDToken::kTokenWhitespace: Out << "w"; break;
|
||||
case EDToken::kTokenPunctuation: Out << "p"; break;
|
||||
case EDToken::kTokenOpcode: Out << "o"; break;
|
||||
case EDToken::kTokenLiteral: Out << "l"; break;
|
||||
case EDToken::kTokenRegister: Out << "r"; break;
|
||||
}
|
||||
|
||||
Out << ":" << buf;
|
||||
|
||||
if (token->type() == EDToken::kTokenLiteral) {
|
||||
Out << "=";
|
||||
if (token->literalSign())
|
||||
Out << "-";
|
||||
uint64_t absoluteValue;
|
||||
if (token->literalAbsoluteValue(absoluteValue)) {
|
||||
errs() << "error: Couldn't get the value of a literal token\n";
|
||||
return -1;
|
||||
}
|
||||
Out << absoluteValue;
|
||||
} else if (token->type() == EDToken::kTokenRegister) {
|
||||
Out << "=";
|
||||
unsigned regID;
|
||||
if (token->registerID(regID)) {
|
||||
errs() << "error: Couldn't get the ID of a register token\n";
|
||||
return -1;
|
||||
}
|
||||
Out << "r" << regID;
|
||||
}
|
||||
|
||||
Out << "]";
|
||||
}
|
||||
|
||||
Out << " ";
|
||||
|
||||
if (inst->isBranch())
|
||||
Out << "<br> ";
|
||||
if (inst->isMove())
|
||||
Out << "<mov> ";
|
||||
|
||||
unsigned numOperands = inst->numOperands();
|
||||
|
||||
if ((int)numOperands < 0) {
|
||||
errs() << "error: Couldn't count operands\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (unsigned operandIndex = 0; operandIndex != numOperands;
|
||||
++operandIndex) {
|
||||
Out << operandIndex << ":";
|
||||
|
||||
EDOperand *operand;
|
||||
if (inst->getOperand(operand, operandIndex)) {
|
||||
errs() << "error: couldn't get operand\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t evaluatedResult;
|
||||
void *Arg[] = { disassembler.get(), &Out };
|
||||
if (operand->evaluate(evaluatedResult, verboseEvaluator, Arg)) {
|
||||
errs() << "error: Couldn't evaluate an operand\n";
|
||||
return -1;
|
||||
}
|
||||
Out << "=" << evaluatedResult << " ";
|
||||
}
|
||||
|
||||
Out << '\n';
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -35,11 +35,6 @@ public:
|
||||
MemoryBuffer &Buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out);
|
||||
|
||||
static int disassembleEnhanced(const std::string &tripleString,
|
||||
MemoryBuffer &buffer,
|
||||
SourceMgr &SM,
|
||||
raw_ostream &Out);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -169,7 +169,6 @@ enum ActionType {
|
||||
AC_AsLex,
|
||||
AC_Assemble,
|
||||
AC_Disassemble,
|
||||
AC_EDisassemble,
|
||||
AC_MDisassemble,
|
||||
AC_HDisassemble
|
||||
};
|
||||
@ -183,8 +182,6 @@ Action(cl::desc("Action to perform:"),
|
||||
"Assemble a .s file (default)"),
|
||||
clEnumValN(AC_Disassemble, "disassemble",
|
||||
"Disassemble strings of hex bytes"),
|
||||
clEnumValN(AC_EDisassemble, "edis",
|
||||
"Enhanced disassembly of strings of hex bytes"),
|
||||
clEnumValN(AC_MDisassemble, "mdis",
|
||||
"Marked up disassembly of strings of hex bytes"),
|
||||
clEnumValN(AC_HDisassemble, "hdis",
|
||||
@ -472,9 +469,6 @@ int main(int argc, char **argv) {
|
||||
case AC_Disassemble:
|
||||
disassemble = true;
|
||||
break;
|
||||
case AC_EDisassemble:
|
||||
Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os());
|
||||
break;
|
||||
}
|
||||
if (disassemble)
|
||||
Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
|
||||
|
@ -19,7 +19,6 @@ add_tablegen(llvm-tblgen LLVM
|
||||
DAGISelMatcher.cpp
|
||||
DFAPacketizerEmitter.cpp
|
||||
DisassemblerEmitter.cpp
|
||||
EDEmitter.cpp
|
||||
FastISelEmitter.cpp
|
||||
FixedLenDecoderEmitter.cpp
|
||||
InstrInfoEmitter.cpp
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,7 +38,6 @@ enum ActionType {
|
||||
GenSubtarget,
|
||||
GenIntrinsic,
|
||||
GenTgtIntrinsic,
|
||||
GenEDInfo,
|
||||
PrintEnums,
|
||||
PrintSets,
|
||||
GenOptParserDefs
|
||||
@ -77,8 +76,6 @@ namespace {
|
||||
"Generate intrinsic information"),
|
||||
clEnumValN(GenTgtIntrinsic, "gen-tgt-intrinsic",
|
||||
"Generate target intrinsic information"),
|
||||
clEnumValN(GenEDInfo, "gen-enhanced-disassembly-info",
|
||||
"Generate enhanced disassembly info"),
|
||||
clEnumValN(PrintEnums, "print-enums",
|
||||
"Print enum values for a class"),
|
||||
clEnumValN(PrintSets, "print-sets",
|
||||
@ -138,9 +135,6 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
||||
case GenTgtIntrinsic:
|
||||
EmitIntrinsics(Records, OS, true);
|
||||
break;
|
||||
case GenEDInfo:
|
||||
EmitEnhancedDisassemblerInfo(Records, OS);
|
||||
break;
|
||||
case GenOptParserDefs:
|
||||
EmitOptParser(Records, OS);
|
||||
break;
|
||||
|
@ -68,7 +68,6 @@ void EmitCodeEmitter(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitDAGISel(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitDFAPacketizer(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitDisassembler(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitEnhancedDisassemblerInfo(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitFastISel(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitInstrInfo(RecordKeeper &RK, raw_ostream &OS);
|
||||
void EmitPseudoLowering(RecordKeeper &RK, raw_ostream &OS);
|
||||
|
Loading…
x
Reference in New Issue
Block a user