diff --git a/include/llvm/MC/MCDisassembler.h b/include/llvm/MC/MCDisassembler.h new file mode 100644 index 00000000000..96ceb58adbb --- /dev/null +++ b/include/llvm/MC/MCDisassembler.h @@ -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 ®ion, + uint64_t address, + raw_ostream &vStream) const = 0; +}; + +} // namespace llvm + +#endif diff --git a/include/llvm/Support/MemoryObject.h b/include/llvm/Support/MemoryObject.h index fd0e966bc9c..dec0f134b30 100644 --- a/include/llvm/Support/MemoryObject.h +++ b/include/llvm/Support/MemoryObject.h @@ -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; }; } diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h index 0ee2422c668..bb09b5413ff 100644 --- a/include/llvm/Target/TargetRegistry.h +++ b/include/llvm/Target/TargetRegistry.h @@ -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. diff --git a/lib/MC/MCDisassembler.cpp b/lib/MC/MCDisassembler.cpp new file mode 100644 index 00000000000..29af019ec55 --- /dev/null +++ b/lib/MC/MCDisassembler.cpp @@ -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() { +} \ No newline at end of file diff --git a/lib/Support/MemoryObject.cpp b/lib/Support/MemoryObject.cpp new file mode 100644 index 00000000000..08e5fb75b3a --- /dev/null +++ b/lib/Support/MemoryObject.cpp @@ -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; + } + +}