Added an abstract superclass, MCDisassembler, for

all disassemblers.

Modified the MemoryObject to support 64-bit address
spaces, regardless of the LLVM process's address
width.

Modified the Target class to allow extraction of a
MCDisassembler.

llvm-svn: 81392
This commit is contained in:
Sean Callanan 2009-09-09 22:49:13 +00:00
parent 626d5a2539
commit 7b789f8cba
5 changed files with 148 additions and 25 deletions

View File

@ -0,0 +1,50 @@
//===-- llvm/MC/MCDisassembler.h - Disassembler interface -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef MCDISASSEMBLER_H
#define MCDISASSEMBLER_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
class MCInst;
class MemoryObject;
class raw_ostream;
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
/// and provides an array of assembly instructions.
class MCDisassembler {
public:
/// Constructor - Performs initial setup for the disassembler.
MCDisassembler();
virtual ~MCDisassembler();
/// getInstruction - Returns the disassembly of a single instruction.
///
/// @param instr - An MCInst to populate with the contents of the
/// instruction.
/// @param size - A value to populate with the size of the instruction, or
/// the number of bytes consumed while attempting to decode
/// an invalid instruction.
/// @param region - The memory object to use as a source for machine code.
/// @param address - The address, in the memory space of region, of the first
/// byte of the instruction.
/// @param vStream - The stream to print warnings and diagnostic messages on.
/// @return - True if the instruction is valid; false otherwise.
virtual bool getInstruction(MCInst& instr,
uint64_t& size,
const MemoryObject &region,
uint64_t address,
raw_ostream &vStream) const = 0;
};
} // namespace llvm
#endif

View File

@ -17,23 +17,24 @@ namespace llvm {
/// MemoryObject - Abstract base class for contiguous addressable memory.
/// Necessary for cases in which the memory is in another process, in a
/// file, or on a remote machine.
/// All size and offset parameters are uint64_ts, to allow 32-bit processes
/// access to 64-bit address spaces.
class MemoryObject {
public:
/// Destructor - Override as necessary.
virtual ~MemoryObject() {
}
virtual ~MemoryObject();
/// getBase - Returns the lowest valid address in the region.
///
/// @result - The lowest valid address.
virtual uintptr_t getBase() const = 0;
virtual uint64_t getBase() const = 0;
/// getExtent - Returns the size of the region in bytes. (The region is
/// contiguous, so the highest valid address of the region
/// is getBase() + getExtent() - 1).
///
/// @result - The size of the region.
virtual uintptr_t getExtent() const = 0;
virtual uint64_t getExtent() const = 0;
/// readByte - Tries to read a single byte from the region.
///
@ -41,9 +42,9 @@ public:
/// @param ptr - A pointer to a byte to be filled in. Must be non-NULL.
/// @result - 0 if successful; -1 if not. Failure may be due to a
/// bounds violation or an implementation-specific error.
virtual int readByte(uintptr_t address, uint8_t* ptr) const = 0;
virtual int readByte(uint64_t address, uint8_t* ptr) const = 0;
/// readByte - Tries to read a contiguous range of bytes from the
/// readBytes - Tries to read a contiguous range of bytes from the
/// region, up to the end of the region.
/// You should override this function if there is a quicker
/// way than going back and forth with individual bytes.
@ -53,25 +54,14 @@ public:
/// @param size - The maximum number of bytes to copy.
/// @param buf - A pointer to a buffer to be filled in. Must be non-NULL
/// and large enough to hold size bytes.
/// @result - The number of bytes copied if successful; (uintptr_t)-1
/// if not.
/// Failure may be due to a bounds violation or an
/// implementation-specific error.
virtual uintptr_t readBytes(uintptr_t address,
uintptr_t size,
uint8_t* buf) const {
uintptr_t current = address;
uintptr_t limit = getBase() + getExtent();
while(current - address < size && current < limit) {
if(readByte(current, &buf[(current - address)]))
return (uintptr_t)-1;
current++;
}
return current - address;
}
/// @param copied - A pointer to a nunber that is filled in with the number
/// of bytes actually read. May be NULL.
/// @result - 0 if successful; -1 if not. Failure may be due to a
/// bounds violation or an implementation-specific error.
virtual int readBytes(uint64_t address,
uint64_t size,
uint8_t* buf,
uint64_t* copied) const;
};
}

View File

@ -29,6 +29,7 @@ namespace llvm {
class MCCodeEmitter;
class Module;
class MCAsmInfo;
class MCDisassembler;
class TargetAsmParser;
class TargetMachine;
class formatted_raw_ostream;
@ -58,6 +59,7 @@ namespace llvm {
bool VerboseAsm);
typedef TargetAsmParser *(*AsmParserCtorTy)(const Target &T,
MCAsmParser &P);
typedef const MCDisassembler *(*MCDisassemblerCtorTy)(const Target &T);
typedef MCCodeEmitter *(*CodeEmitterCtorTy)(const Target &T,
TargetMachine &TM);
@ -92,6 +94,10 @@ namespace llvm {
/// AsmParserCtorFn - Construction function for this target's AsmParser,
/// if registered.
AsmParserCtorTy AsmParserCtorFn;
/// MCDisassemblerCtorFn - Construction function for this target's
/// MCDisassembler, if registered.
MCDisassemblerCtorTy MCDisassemblerCtorFn;
/// CodeEmitterCtorFn - Construction function for this target's CodeEmitter,
/// if registered.
@ -125,6 +131,9 @@ namespace llvm {
/// hasAsmParser - Check if this target supports .s parsing.
bool hasAsmParser() const { return AsmParserCtorFn != 0; }
/// hasMCDisassembler - Check if this target has a disassembler.
bool hasMCDisassembler() const { return MCDisassemblerCtorFn != 0; }
/// hasCodeEmitter - Check if this target supports instruction encoding.
bool hasCodeEmitter() const { return CodeEmitterCtorFn != 0; }
@ -177,6 +186,12 @@ namespace llvm {
return 0;
return AsmParserCtorFn(*this, Parser);
}
const MCDisassembler *createMCDisassembler() const {
if (!MCDisassemblerCtorFn)
return 0;
return MCDisassemblerCtorFn(*this);
}
/// createCodeEmitter - Create a target specific code emitter.
MCCodeEmitter *createCodeEmitter(TargetMachine &TM) const {
@ -333,6 +348,21 @@ namespace llvm {
if (!T.AsmParserCtorFn)
T.AsmParserCtorFn = Fn;
}
/// RegisterMCDisassembler - Register a MCDisassembler implementation for
/// the given target.
///
/// Clients are responsible for ensuring that registration doesn't occur
/// while another thread is attempting to access the registry. Typically
/// this is done by initializing all targets at program startup.
///
/// @param T - The target being registered.
/// @param Fn - A function to construct an MCDisassembler for the target.
static void RegisterMCDisassembler(Target &T,
Target::MCDisassemblerCtorTy Fn) {
if (!T.MCDisassemblerCtorFn)
T.MCDisassemblerCtorFn = Fn;
}
/// RegisterCodeEmitter - Register a MCCodeEmitter implementation for the
/// given target.

16
lib/MC/MCDisassembler.cpp Normal file
View File

@ -0,0 +1,16 @@
//===-- lib/MC/MCDisassembler.cpp - Disassembler interface ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCDisassembler.h"
llvm::MCDisassembler::MCDisassembler() {
}
llvm::MCDisassembler::~MCDisassembler() {
}

View File

@ -0,0 +1,37 @@
//===- MemoryObject.cpp - Abstract memory interface -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/MemoryObject.h"
namespace llvm {
MemoryObject::~MemoryObject() {
}
int MemoryObject::readBytes(uint64_t address,
uint64_t size,
uint8_t* buf,
uint64_t* copied) const {
uint64_t current = address;
uint64_t limit = getBase() + getExtent();
while (current - address < size && current < limit) {
if (readByte(current, &buf[(current - address)]))
return -1;
current++;
}
if (copied)
*copied = current - address;
return 0;
}
}