//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the enhanced disassembler's public C API.
//
//===----------------------------------------------------------------------===//
// FIXME: This code isn't layered right, the headers should be moved to
// include llvm/MC/MCDisassembler or something.
#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
#include "../../lib/MC/MCDisassembler/EDInst.h"
#include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
#include "llvm-c/EnhancedDisassembly.h"
using namespace llvm;
int EDGetDisassembler(EDDisassemblerRef *disassembler,
const char *triple,
EDAssemblySyntax_t syntax) {
EDDisassembler::initialize();
EDDisassembler::AssemblySyntax Syntax;
switch (syntax) {
default: assert(0 && "Unknown assembly syntax!");
case kEDAssemblySyntaxX86Intel:
Syntax = EDDisassembler::kEDAssemblySyntaxX86Intel;
break;
case kEDAssemblySyntaxX86ATT:
Syntax = EDDisassembler::kEDAssemblySyntaxX86ATT;
break;
case kEDAssemblySyntaxARMUAL:
Syntax = EDDisassembler::kEDAssemblySyntaxARMUAL;
break;
}
EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
if (!ret)
return -1;
*disassembler = ret;
return 0;
}
int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler,
unsigned regID) {
const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
if (!name)
return -1;
*regName = name;
return 0;
}
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
unsigned regID) {
return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
}
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
unsigned regID) {
return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
}
unsigned int EDCreateInsts(EDInstRef *insts,
unsigned int count,
EDDisassemblerRef disassembler,
::EDByteReaderCallback byteReader,
uint64_t address,
void *arg) {
unsigned int index;
for (index = 0; index < count; ++index) {
EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
address, arg);
if (!inst)
return index;
insts[index] = inst;
address += inst->byteSize();
}
return count;
}
void EDReleaseInst(EDInstRef inst) {
delete ((EDInst*)inst);
}
int EDInstByteSize(EDInstRef inst) {
return ((EDInst*)inst)->byteSize();
}
int EDGetInstString(const char **buf,
EDInstRef inst) {
return ((EDInst*)inst)->getString(*buf);
}
int EDInstID(unsigned *instID, EDInstRef inst) {
*instID = ((EDInst*)inst)->instID();
return 0;
}
int EDInstIsBranch(EDInstRef inst) {
return ((EDInst*)inst)->isBranch();
}
int EDInstIsMove(EDInstRef inst) {
return ((EDInst*)inst)->isMove();
}
int EDBranchTargetID(EDInstRef inst) {
return ((EDInst*)inst)->branchTargetID();
}
int EDMoveSourceID(EDInstRef inst) {
return ((EDInst*)inst)->moveSourceID();
}
int EDMoveTargetID(EDInstRef inst) {
return ((EDInst*)inst)->moveTargetID();
}
int EDNumTokens(EDInstRef inst) {
return ((EDInst*)inst)->numTokens();
}
int EDGetToken(EDTokenRef *token,
EDInstRef inst,
int index) {
return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
}
int EDGetTokenString(const char **buf,
EDTokenRef token) {
return ((EDToken*)token)->getString(*buf);
}
int EDOperandIndexForToken(EDTokenRef token) {
return ((EDToken*)token)->operandID();
}
int EDTokenIsWhitespace(EDTokenRef token) {
return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
}
int EDTokenIsPunctuation(EDTokenRef token) {
return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
}
int EDTokenIsOpcode(EDTokenRef token) {
return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
}
int EDTokenIsLiteral(EDTokenRef token) {
return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
}
int EDTokenIsRegister(EDTokenRef token) {
return ((EDToken*)token)->type() == EDToken::kTokenRegister;
}
int EDTokenIsNegativeLiteral(EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
return -1;
return ((EDToken*)token)->literalSign();
}
int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
return -1;
return ((EDToken*)token)->literalAbsoluteValue(*value);
}
int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) {
if (((EDToken*)token)->type() != EDToken::kTokenRegister)
return -1;
return ((EDToken*)token)->registerID(*registerID);
}
int EDNumOperands(EDInstRef inst) {
return ((EDInst*)inst)->numOperands();
}
int EDGetOperand(EDOperandRef *operand,
EDInstRef inst,
int index) {
return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
}
int EDOperandIsRegister(EDOperandRef operand) {
return ((EDOperand*)operand)->isRegister();
}
int EDOperandIsImmediate(EDOperandRef operand) {
return ((EDOperand*)operand)->isImmediate();
}
int EDOperandIsMemory(EDOperandRef operand) {
return ((EDOperand*)operand)->isMemory();
}
int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
if (!((EDOperand*)operand)->isRegister())
return -1;
*value = ((EDOperand*)operand)->regVal();
return 0;
}
int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
if (!((EDOperand*)operand)->isImmediate())
return -1;
*value = ((EDOperand*)operand)->immediateVal();
return 0;
}
int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
::EDRegisterReaderCallback regReader, void *arg) {
return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
}
#ifdef __BLOCKS__
struct ByteReaderWrapper {
EDByteBlock_t byteBlock;
};
static int readerWrapperCallback(uint8_t *byte,
uint64_t address,
void *arg) {
struct ByteReaderWrapper *wrapper = (struct ByteReaderWrapper *)arg;
return wrapper->byteBlock(byte, address);
}
unsigned int EDBlockCreateInsts(EDInstRef *insts,
int count,
EDDisassemblerRef disassembler,
EDByteBlock_t byteBlock,
uint64_t address) {
struct ByteReaderWrapper wrapper;
wrapper.byteBlock = byteBlock;
return EDCreateInsts(insts,
count,
disassembler,
readerWrapperCallback,
address,
(void*)&wrapper);
}
int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
EDRegisterBlock_t regBlock) {
return ((EDOperand*)operand)->evaluate(*result, regBlock);
}
int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
}
#else
extern "C" unsigned int EDBlockCreateInsts() {
return 0;
}
extern "C" int EDBlockEvaluateOperand() {
return -1;
}
extern "C" int EDBlockVisitTokens() {
return -1;
}
#endif