Added the enhanced disassembly library's implementation and

fleshed out the .exports file.  I still have to fix several
details of operand parsing, but the basic functionality is
there and usable.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@94974 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Sean Callanan 2010-02-01 08:49:35 +00:00
parent ddba25ab70
commit ee5dfd42f1
10 changed files with 1865 additions and 2 deletions

445
tools/ed/EDDisassembler.cpp Normal file
View File

@ -0,0 +1,445 @@
//===-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 "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.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/MCStreamer.h"
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/AsmParser.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Target/TargetAsmLexer.h"
#include "llvm/Target/TargetAsmParser.h"
#include "llvm/Target/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSelect.h"
#include "EDDisassembler.h"
#include "EDInst.h"
#include "../../lib/Target/X86/X86GenEDInfo.inc"
using namespace llvm;
bool EDDisassembler::sInitialized = false;
EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
struct InfoMap {
Triple::ArchType Arch;
const char *String;
const InstInfo *Info;
};
static struct InfoMap infomap[] = {
{ Triple::x86, "i386-unknown-unknown", instInfoX86 },
{ Triple::x86_64, "x86_64-unknown-unknown", instInfoX86 },
{ Triple::InvalidArch, NULL, NULL }
};
/// infoFromArch - Returns the InfoMap corresponding to a given architecture,
/// or NULL if there is an error
///
/// @arg arch - The Triple::ArchType for the desired architecture
static const InfoMap *infoFromArch(Triple::ArchType arch) {
unsigned int infoIndex;
for (infoIndex = 0; infomap[infoIndex].String != NULL; ++infoIndex) {
if(arch == infomap[infoIndex].Arch)
return &infomap[infoIndex];
}
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,
EDAssemblySyntax_t syntax) {
switch (syntax) {
default:
return -1;
// Mappings below from X86AsmPrinter.cpp
case kEDAssemblySyntaxX86ATT:
if (arch == Triple::x86 || arch == Triple::x86_64)
return 0;
else
return -1;
case kEDAssemblySyntaxX86Intel:
if (arch == Triple::x86 || arch == Triple::x86_64)
return 1;
else
return -1;
}
}
#define BRINGUP_TARGET(tgt) \
LLVMInitialize##tgt##TargetInfo(); \
LLVMInitialize##tgt##Target(); \
LLVMInitialize##tgt##AsmPrinter(); \
LLVMInitialize##tgt##AsmParser(); \
LLVMInitialize##tgt##Disassembler();
void EDDisassembler::initialize() {
if (sInitialized)
return;
sInitialized = true;
BRINGUP_TARGET(X86)
}
#undef BRINGUP_TARGET
EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
EDAssemblySyntax_t syntax) {
CPUKey key;
key.Arch = arch;
key.Syntax = syntax;
EDDisassembler::DisassemblerMap_t::iterator i = sDisassemblers.find(key);
if (i != sDisassemblers.end()) {
return i->second;
}
else {
EDDisassembler* sdd = new EDDisassembler(key);
if(!sdd->valid()) {
delete sdd;
return NULL;
}
sDisassemblers[key] = sdd;
return sdd;
}
return NULL;
}
EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
EDAssemblySyntax_t syntax) {
Triple triple(str);
return getDisassembler(triple.getArch(), syntax);
}
namespace {
class EDAsmParser : public MCAsmParser {
AsmLexer Lexer;
MCContext Context;
OwningPtr<MCStreamer> Streamer;
public:
// Mandatory functions
EDAsmParser(const MCAsmInfo &MAI) : Lexer(MAI) {
Streamer.reset(createNullStreamer(Context));
}
virtual ~EDAsmParser() { }
MCAsmLexer &getLexer() { return Lexer; }
MCContext &getContext() { return Context; }
MCStreamer &getStreamer() { return *Streamer; }
void Warning(SMLoc L, const Twine &Msg) { }
bool Error(SMLoc L, const Twine &Msg) { return true; }
const AsmToken &Lex() { return Lexer.Lex(); }
bool ParseExpression(const MCExpr *&Res, SMLoc &EndLoc) {
AsmToken token = Lex();
if(token.isNot(AsmToken::Integer))
return true;
Res = MCConstantExpr::Create(token.getIntVal(), Context);
return false;
}
bool ParseParenExpression(const MCExpr *&Res, SMLoc &EndLoc) {
assert(0 && "I can't ParseParenExpression()s!");
}
bool ParseAbsoluteExpression(int64_t &Res) {
assert(0 && "I can't ParseAbsoluteExpression()s!");
}
/// setBuffer - loads a buffer into the parser
/// @arg buf - The buffer to read tokens from
void setBuffer(const MemoryBuffer &buf) { Lexer.setBuffer(&buf); }
/// parseInstName - When the lexer is positioned befor an instruction
/// name (with possible intervening whitespace), reads past the name,
/// returning 0 on success and -1 on failure
/// @arg name - A reference to a string that is filled in with the
/// instruction name
/// @arg loc - A reference to a location that is filled in with the
/// position of the instruction name
int parseInstName(StringRef &name, SMLoc &loc) {
AsmToken tok = Lexer.Lex();
if(tok.isNot(AsmToken::Identifier)) {
return -1;
}
name = tok.getString();
loc = tok.getLoc();
return 0;
}
};
}
EDDisassembler::EDDisassembler(CPUKey &key) :
Valid(false), ErrorString(), ErrorStream(ErrorString), Key(key) {
const InfoMap *infoMap = infoFromArch(key.Arch);
if (!infoMap)
return;
const char *triple = infoMap->String;
int syntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
if (syntaxVariant < 0)
return;
std::string tripleString(triple);
std::string errorString;
Tgt = TargetRegistry::lookupTarget(tripleString,
errorString);
if (!Tgt)
return;
std::string featureString;
OwningPtr<const TargetMachine>
targetMachine(Tgt->createTargetMachine(tripleString,
featureString));
const TargetRegisterInfo *registerInfo = targetMachine->getRegisterInfo();
if (!registerInfo)
return;
AsmInfo.reset(Tgt->createAsmInfo(tripleString));
if (!AsmInfo)
return;
Disassembler.reset(Tgt->createMCDisassembler());
if (!Disassembler)
return;
InstString.reset(new std::string);
InstStream.reset(new raw_string_ostream(*InstString));
InstPrinter.reset(Tgt->createMCInstPrinter(syntaxVariant,
*AsmInfo,
*InstStream));
if (!InstPrinter)
return;
GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
SpecificAsmLexer.reset(Tgt->createAsmLexer(*AsmInfo));
SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
InstInfos = infoMap->Info;
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;
if (!Disassembler->getInstruction(*inst,
byteSize,
memoryObject,
address,
ErrorStream)) {
delete inst;
return NULL;
}
else {
const InstInfo *thisInstInfo = &InstInfos[inst->getOpcode()];
EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
return sdInst;
}
}
void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
unsigned numRegisters = registerInfo.getNumRegs();
unsigned registerIndex;
for (registerIndex = 0; registerIndex < numRegisters; ++registerIndex) {
const char* registerName = registerInfo.get(registerIndex).Name;
RegVec.push_back(registerName);
RegRMap[registerName] = registerIndex;
}
if (Key.Arch == Triple::x86 ||
Key.Arch == 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"));
}
}
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->flush();
str = *InstString;
InstString->clear();
PrinterMutex.release();
return 0;
}
int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
SmallVectorImpl<AsmToken> &tokens,
const std::string &str) {
int ret = 0;
const char *cStr = str.c_str();
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
StringRef instName;
SMLoc instLoc;
SourceMgr sourceMgr;
sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over
MCContext context;
OwningPtr<MCStreamer> streamer
(createNullStreamer(context));
AsmParser genericParser(sourceMgr, context, *streamer, *AsmInfo);
OwningPtr<TargetAsmParser> specificParser
(Tgt->createAsmParser(genericParser));
AsmToken OpcodeToken = genericParser.Lex();
if(OpcodeToken.is(AsmToken::Identifier)) {
instName = OpcodeToken.getString();
instLoc = OpcodeToken.getLoc();
if (specificParser->ParseInstruction(instName, instLoc, operands))
ret = -1;
}
else {
ret = -1;
}
SmallVectorImpl<MCParsedAsmOperand*>::iterator oi;
for(oi = operands.begin(); oi != operands.end(); ++oi) {
printf("Operand start %p, end %p\n",
(*oi)->getStartLoc().getPointer(),
(*oi)->getEndLoc().getPointer());
}
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;
}

248
tools/ed/EDDisassembler.h Normal file
View File

@ -0,0 +1,248 @@
//===-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 EDDisassembler_
#define EDDisassembler_
#include "EDInfo.inc"
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Mutex.h"
#include <map>
#include <set>
#include <string>
#include <vector>
namespace llvm {
class AsmLexer;
class AsmToken;
class MCContext;
class MCAsmInfo;
class MCAsmLexer;
class AsmParser;
class TargetAsmLexer;
class TargetAsmParser;
class MCDisassembler;
class MCInstPrinter;
class MCInst;
class MCParsedAsmOperand;
class MCStreamer;
template <typename T> class SmallVectorImpl;
class SourceMgr;
class Target;
class TargetRegisterInfo;
}
/// EDDisassembler - Encapsulates a disassembler for a single architecture and
/// disassembly syntax. Also manages the static disassembler registry.
struct EDDisassembler {
////////////////////
// Static members //
////////////////////
/// CPUKey - Encapsulates the descriptor of an architecture/disassembly-syntax
/// pair
struct CPUKey {
/// The architecture type
llvm::Triple::ArchType Arch;
/// The assembly syntax
EDAssemblySyntax_t Syntax;
/// operator== - Equality operator
bool operator==(const CPUKey &key) const {
return (Arch == key.Arch &&
Syntax == key.Syntax);
}
/// operator< - Less-than operator
bool operator<(const CPUKey &key) const {
if(Arch > key.Arch)
return false;
if(Syntax >= key.Syntax)
return false;
return true;
}
};
typedef std::map<CPUKey, EDDisassembler*> DisassemblerMap_t;
/// True if the disassembler registry has been initialized; false if not
static bool sInitialized;
/// 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,
EDAssemblySyntax_t 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,
EDAssemblySyntax_t syntax);
/// initialize - Initializes the disassembler registry and the LLVM backend
static void initialize();
////////////////////////
// Per-object members //
////////////////////////
/// True only if the object has been fully and successfully initialized
bool Valid;
/// The string that stores disassembler errors from the backend
std::string ErrorString;
/// The stream that wraps the ErrorString
llvm::raw_string_ostream ErrorStream;
/// The architecture/syntax pair for the current architecture
CPUKey Key;
/// 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 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 InstInfo *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::TargetAsmLexer> 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;
}
~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::TargetRegisterInfo &registerInfo);
/// 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;
};
#endif

205
tools/ed/EDInst.cpp Normal file
View File

@ -0,0 +1,205 @@
//===-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 "EDDisassembler.h"
#include "EDInst.h"
#include "EDOperand.h"
#include "EDToken.h"
#include "llvm/MC/MCInst.h"
using namespace llvm;
EDInst::EDInst(llvm::MCInst *inst,
uint64_t byteSize,
EDDisassembler &disassembler,
const InstInfo *info) :
Disassembler(disassembler),
Inst(inst),
ThisInstInfo(info),
ByteSize(byteSize),
BranchTarget(-1),
MoveSource(-1),
MoveTarget(-1) {
}
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);
OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
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->instructionFlags & kInstructionFlagBranch;
else
return false;
}
bool EDInst::isMove() {
if (ThisInstInfo)
return ThisInstInfo->instructionFlags & kInstructionFlagMove;
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 (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

171
tools/ed/EDInst.h Normal file
View File

@ -0,0 +1,171 @@
//===-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 EDInst_
#define EDInst_
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/SmallVector.h"
#include <string>
#include <vector>
/// 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 InstInfo *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 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 InstInfo *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
};
#endif

View File

@ -11,10 +11,241 @@
//
//===----------------------------------------------------------------------===//
#include <llvm-c/EnhancedDisassembly.h>
#include "EDDisassembler.h"
#include "EDInst.h"
#include "EDOperand.h"
#include "EDToken.h"
#include "llvm-c/EnhancedDisassembly.h"
int EDGetDisassembler(EDDisassemblerRef *disassembler,
const char *triple,
EDAssemblySyntax_t syntax) {
return -1;
EDDisassembler::initialize();
EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple,
syntax);
if (ret) {
*disassembler = ret;
return 0;
}
else {
return -1;
}
}
int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler,
unsigned regID) {
const char* name = disassembler->nameWithRegisterID(regID);
if(!name)
return -1;
*regName = name;
return 0;
}
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
unsigned regID) {
return disassembler->registerIsStackPointer(regID) ? 1 : 0;
}
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
unsigned regID) {
return disassembler->registerIsProgramCounter(regID) ? 1 : 0;
}
unsigned int EDCreateInsts(EDInstRef *insts,
unsigned int count,
EDDisassemblerRef disassembler,
EDByteReaderCallback byteReader,
uint64_t address,
void *arg) {
unsigned int index;
for (index = 0; index < count; index++) {
EDInst *inst = disassembler->createInst(byteReader, address, arg);
if(!inst)
return index;
insts[index] = inst;
address += inst->byteSize();
}
return count;
}
void EDReleaseInst(EDInstRef inst) {
delete inst;
}
int EDInstByteSize(EDInstRef inst) {
return inst->byteSize();
}
int EDGetInstString(const char **buf,
EDInstRef inst) {
return inst->getString(*buf);
}
int EDInstID(unsigned *instID, EDInstRef inst) {
*instID = inst->instID();
return 0;
}
int EDInstIsBranch(EDInstRef inst) {
return inst->isBranch();
}
int EDInstIsMove(EDInstRef inst) {
return inst->isMove();
}
int EDBranchTargetID(EDInstRef inst) {
return inst->branchTargetID();
}
int EDMoveSourceID(EDInstRef inst) {
return inst->moveSourceID();
}
int EDMoveTargetID(EDInstRef inst) {
return inst->moveTargetID();
}
int EDNumTokens(EDInstRef inst) {
return inst->numTokens();
}
int EDGetToken(EDTokenRef *token,
EDInstRef inst,
int index) {
return inst->getToken(*token, index);
}
int EDGetTokenString(const char **buf,
EDTokenRef token) {
return token->getString(*buf);
}
int EDOperandIndexForToken(EDTokenRef token) {
return token->operandID();
}
int EDTokenIsWhitespace(EDTokenRef token) {
if(token->type() == EDToken::kTokenWhitespace)
return 1;
else
return 0;
}
int EDTokenIsPunctuation(EDTokenRef token) {
if(token->type() == EDToken::kTokenPunctuation)
return 1;
else
return 0;
}
int EDTokenIsOpcode(EDTokenRef token) {
if(token->type() == EDToken::kTokenOpcode)
return 1;
else
return 0;
}
int EDTokenIsLiteral(EDTokenRef token) {
if(token->type() == EDToken::kTokenLiteral)
return 1;
else
return 0;
}
int EDTokenIsRegister(EDTokenRef token) {
if(token->type() == EDToken::kTokenRegister)
return 1;
else
return 0;
}
int EDTokenIsNegativeLiteral(EDTokenRef token) {
if(token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalSign();
}
int EDLiteralTokenAbsoluteValue(uint64_t *value,
EDTokenRef token) {
if(token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalAbsoluteValue(*value);
}
int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) {
if(token->type() != EDToken::kTokenRegister)
return -1;
return token->registerID(*registerID);
}
int EDNumOperands(EDInstRef inst) {
return inst->numOperands();
}
int EDGetOperand(EDOperandRef *operand,
EDInstRef inst,
int index) {
return inst->getOperand(*operand, index);
}
int EDEvaluateOperand(uint64_t *result,
EDOperandRef operand,
EDRegisterReaderCallback regReader,
void *arg) {
return operand->evaluate(*result, regReader, arg);
}
#ifdef __BLOCKS__
struct ByteReaderWrapper {
EDByteBlock_t byteBlock;
};
static int readerWrapperCallback(uint8_t *byte,
uint64_t address,
void *arg) {
struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
return wrapper->byteBlock(byte, address);
}
unsigned int EDBlockCreateInsts(EDInstRef *insts,
int count,
EDDisassemblerRef disassembler,
EDByteBlock_t byteBlock,
uint64_t address) {
struct ByteReaderWrapper wrapper;
wrapper.byteBlock = byteBlock;
return EDCreateInsts(insts,
count,
disassembler,
readerWrapperCallback,
address,
(void*)&wrapper);
}
int EDBlockEvaluateOperand(uint64_t *result,
EDOperandRef operand,
EDRegisterBlock_t regBlock) {
return operand->evaluate(*result, regBlock);
}
int EDBlockVisitTokens(EDInstRef inst,
EDTokenVisitor_t visitor) {
return inst->visitTokens(visitor);
}
#endif

148
tools/ed/EDOperand.cpp Normal file
View File

@ -0,0 +1,148 @@
//===-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 "EDDisassembler.h"
#include "EDInst.h"
#include "EDOperand.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;
if(Disassembler.Key.Arch == Triple::x86 ||
Disassembler.Key.Arch == Triple::x86_64) {
uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
if (operandFlags & kOperandFlagImmediate) {
numMCOperands = 1;
}
else if (operandFlags & kOperandFlagRegister) {
numMCOperands = 1;
}
else if (operandFlags & kOperandFlagMemory) {
if (operandFlags & kOperandFlagPCRelative) {
numMCOperands = 1;
}
else {
numMCOperands = 5;
}
}
else if (operandFlags & kOperandFlagEffectiveAddress) {
numMCOperands = 4;
}
}
mcOpIndex += numMCOperands;
}
EDOperand::~EDOperand() {
}
int EDOperand::evaluate(uint64_t &result,
EDRegisterReaderCallback callback,
void *arg) {
if (Disassembler.Key.Arch == Triple::x86 ||
Disassembler.Key.Arch == Triple::x86_64) {
uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
if (operandFlags & kOperandFlagImmediate) {
result = Inst.Inst->getOperand(MCOpIndex).getImm();
return 0;
}
if (operandFlags & kOperandFlagRegister) {
unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
return callback(&result, reg, arg);
}
if (operandFlags & kOperandFlagMemory ||
operandFlags & kOperandFlagEffectiveAddress){
if(operandFlags & kOperandFlagPCRelative) {
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;
}
else {
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();
//unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
uint64_t addr = 0;
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;
}
}
return -1;
}
return -1;
}
#ifdef __BLOCKS__
struct RegisterReaderWrapper {
EDRegisterBlock_t regBlock;
};
int readerWrapperCallback(uint64_t *value,
unsigned regID,
void *arg) {
struct RegisterReaderWrapper *wrapper = (struct RegisterReaderWrapper *)arg;
return wrapper->regBlock(value, regID);
}
int EDOperand::evaluate(uint64_t &result,
EDRegisterBlock_t regBlock) {
struct RegisterReaderWrapper wrapper;
wrapper.regBlock = regBlock;
return evaluate(result,
readerWrapperCallback,
(void*)&wrapper);
}
#endif

65
tools/ed/EDOperand.h Normal file
View File

@ -0,0 +1,65 @@
//===-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 EDOperand_
#define EDOperand_
#include "llvm-c/EnhancedDisassembly.h"
/// 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);
#ifdef __BLOCKS__
/// evaluate - Like evaluate for a callback, but uses a block instead
int evaluate(uint64_t &result,
EDRegisterBlock_t regBlock);
#endif
};
#endif

185
tools/ed/EDToken.cpp Normal file
View File

@ -0,0 +1,185 @@
//===-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 "EDDisassembler.h"
#include "EDToken.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 &registerID) const {
if(Type != kTokenRegister)
return -1;
registerID = RegisterID;
return 0;
}
int EDToken::tokenize(std::vector<EDToken*> &tokens,
std::string &str,
const char *operandOrder,
EDDisassembler &disassembler) {
SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
SmallVector<AsmToken, 10> asmTokens;
disassembler.parseInst(parsedOperands, asmTokens, str);
SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
unsigned int operandIndex;
SmallVectorImpl<AsmToken>::iterator tokenIterator;
operandIterator = parsedOperands.begin();
operandIndex = 0;
bool readOpcode = false;
for (tokenIterator = asmTokens.begin();
tokenIterator != asmTokens.end();
++tokenIterator) {
SMLoc tokenLoc = tokenIterator->getLoc();
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()) {
token->setOperandID(operandOrder[operandIndex]);
}
tokens.push_back(token);
}
return 0;
}
int EDToken::getString(const char*& buf) {
if(PermStr.length() == 0) {
PermStr = Str.str();
}
buf = PermStr.c_str();
return 0;
}

135
tools/ed/EDToken.h Normal file
View File

@ -0,0 +1,135 @@
//===-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 EDToken_
#define EDToken_
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/StringRef.h"
#include <string>
#include <vector>
/// 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 &registerID) 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 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);
};
#endif

View File

@ -1 +1,31 @@
_EDGetDisassembler
_EDGetRegisterName
_EDRegisterIsStackPointer
_EDRegisterIsProgramCounter
_EDCreateInsts
_EDReleaseInst
_EDInstByteSize
_EDGetInstString
_EDInstIsBranch
_EDInstIsMove
_EDBranchTargetID
_EDMoveSourceID
_EDMoveTargetID
_EDNumTokens
_EDGetToken
_EDGetTokenString
_EDOperandIndexForToken
_EDTokenIsWhitespace
_EDTokenIsPunctuation
_EDTokenIsOpcode
_EDTokenIsLiteral
_EDTokenIsRegister
_EDTokenIsNegativeLiteral
_EDLiteralTokenAbsoluteValue
_EDRegisterTokenValue
_EDNumOperands
_EDGetOperand
_EDEvaluateOperand
_EDBlockCreateInsts
_EDBlockEvaluateOperand
_EDBlockVisitTokens