mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-11-04 05:17:07 +00:00 
			
		
		
		
	better in the llvm world. Among other things, this changes: 1. The guts of libedis are now moved into lib/MC/MCDisassembler 2. llvm-mc now depends on lib/MC/MCDisassembler, not tools/edis, so edis and mc don't have to be built in series. 3. lib/MC/MCDisassembler no longer depends on the C api, the C API depends on it. 4. Various code cleanup changes. There is still a lot to be done to make edis fit with the llvm design, but this is an incremental step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108869 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			285 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
		
			7.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
//===-- 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
 |