start straightening out libedis's dependencies and make it fit

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
This commit is contained in:
Chris Lattner
2010-07-20 18:25:19 +00:00
parent c4fd9afaf9
commit 847da55716
16 changed files with 229 additions and 237 deletions

View File

@ -308,6 +308,7 @@ add_subdirectory(lib/Analysis)
add_subdirectory(lib/Analysis/IPA) add_subdirectory(lib/Analysis/IPA)
add_subdirectory(lib/MC) add_subdirectory(lib/MC)
add_subdirectory(lib/MC/MCParser) add_subdirectory(lib/MC/MCParser)
add_subdirectory(lib/MC/MCDisassembler)
add_subdirectory(test) add_subdirectory(test)
add_subdirectory(utils/FileCheck) add_subdirectory(utils/FileCheck)

View File

@ -51,41 +51,38 @@ typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
@typedef EDAssemblySyntax_t @typedef EDAssemblySyntax_t
An assembly syntax for use in tokenizing instructions. An assembly syntax for use in tokenizing instructions.
*/ */
typedef enum { enum {
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */ /*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
kEDAssemblySyntaxX86Intel = 0, kEDAssemblySyntaxX86Intel = 0,
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */ /*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
kEDAssemblySyntaxX86ATT = 1, kEDAssemblySyntaxX86ATT = 1,
kEDAssemblySyntaxARMUAL = 2 kEDAssemblySyntaxARMUAL = 2
} EDAssemblySyntax_t; };
typedef unsigned EDAssemblySyntax_t;
/*! /*!
@typedef EDDisassemblerRef @typedef EDDisassemblerRef
Encapsulates a disassembler for a single CPU architecture. Encapsulates a disassembler for a single CPU architecture.
*/ */
struct EDDisassembler; typedef void *EDDisassemblerRef;
typedef struct EDDisassembler *EDDisassemblerRef;
/*! /*!
@typedef EDInstRef @typedef EDInstRef
Encapsulates a single disassembled instruction in one assembly syntax. Encapsulates a single disassembled instruction in one assembly syntax.
*/ */
struct EDInst; typedef void *EDInstRef;
typedef struct EDInst *EDInstRef;
/*! /*!
@typedef EDTokenRef @typedef EDTokenRef
Encapsulates a token from the disassembly of an instruction. Encapsulates a token from the disassembly of an instruction.
*/ */
struct EDToken; typedef void *EDTokenRef;
typedef struct EDToken *EDTokenRef;
/*! /*!
@typedef EDOperandRef @typedef EDOperandRef
Encapsulates an operand of an instruction. Encapsulates an operand of an instruction.
*/ */
struct EDOperand; typedef void *EDOperandRef;
typedef struct EDOperand *EDOperandRef;
/*! /*!
@functiongroup Getting a disassembler @functiongroup Getting a disassembler

View File

@ -15,9 +15,6 @@
#include "EDDisassembler.h" #include "EDDisassembler.h"
#include "EDInst.h" #include "EDInst.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/EDInstInfo.h" #include "llvm/MC/EDInstInfo.h"
#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h" #include "llvm/MC/MCContext.h"
@ -38,7 +35,6 @@
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSelect.h" #include "llvm/Target/TargetSelect.h"
using namespace llvm; using namespace llvm;
bool EDDisassembler::sInitialized = false; bool EDDisassembler::sInitialized = false;
@ -79,22 +75,22 @@ static const char *tripleFromArch(Triple::ArchType arch) {
/// @arg arch - The target architecture /// @arg arch - The target architecture
/// @arg syntax - The assembly syntax in sd form /// @arg syntax - The assembly syntax in sd form
static int getLLVMSyntaxVariant(Triple::ArchType arch, static int getLLVMSyntaxVariant(Triple::ArchType arch,
EDAssemblySyntax_t syntax) { EDDisassembler::AssemblySyntax syntax) {
switch (syntax) { switch (syntax) {
default: default:
return -1; return -1;
// Mappings below from X86AsmPrinter.cpp // Mappings below from X86AsmPrinter.cpp
case kEDAssemblySyntaxX86ATT: case EDDisassembler::kEDAssemblySyntaxX86ATT:
if (arch == Triple::x86 || arch == Triple::x86_64) if (arch == Triple::x86 || arch == Triple::x86_64)
return 0; return 0;
else else
return -1; return -1;
case kEDAssemblySyntaxX86Intel: case EDDisassembler::kEDAssemblySyntaxX86Intel:
if (arch == Triple::x86 || arch == Triple::x86_64) if (arch == Triple::x86 || arch == Triple::x86_64)
return 1; return 1;
else else
return -1; return -1;
case kEDAssemblySyntaxARMUAL: case EDDisassembler::kEDAssemblySyntaxARMUAL:
if (arch == Triple::arm || arch == Triple::thumb) if (arch == Triple::arm || arch == Triple::thumb)
return 0; return 0;
else else
@ -118,7 +114,7 @@ void EDDisassembler::initialize() {
#undef BRINGUP_TARGET #undef BRINGUP_TARGET
EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch, EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
EDAssemblySyntax_t syntax) { AssemblySyntax syntax) {
CPUKey key; CPUKey key;
key.Arch = arch; key.Arch = arch;
key.Syntax = syntax; key.Syntax = syntax;
@ -143,10 +139,8 @@ EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
} }
EDDisassembler *EDDisassembler::getDisassembler(StringRef str, EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
EDAssemblySyntax_t syntax) { AssemblySyntax syntax) {
Triple triple(str); return getDisassembler(Triple(str).getArch(), syntax);
return getDisassembler(triple.getArch(), syntax);
} }
EDDisassembler::EDDisassembler(CPUKey &key) : EDDisassembler::EDDisassembler(CPUKey &key) :

View File

@ -1,4 +1,4 @@
//===-EDDisassembler.h - LLVM Enhanced Disassembler -------------*- C++ -*-===// //===-- EDDisassembler.h - LLVM Enhanced Disassembler -----------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,13 +13,11 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef EDDisassembler_ #ifndef LLVM_EDDISASSEMBLER_H
#define EDDisassembler_ #define LLVM_EDDISASSEMBLER_H
#include "EDInfo.inc" #include "EDInfo.inc"
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
@ -27,7 +25,6 @@
#include <map> #include <map>
#include <set> #include <set>
#include <string>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
@ -51,11 +48,24 @@ class TargetMachine;
class TargetRegisterInfo; class TargetRegisterInfo;
struct EDInstInfo; struct EDInstInfo;
} struct EDInst;
struct EDOperand;
struct EDToken;
typedef int (*EDByteReaderCallback)(uint8_t *byte, uint64_t address, void *arg);
/// EDDisassembler - Encapsulates a disassembler for a single architecture and /// EDDisassembler - Encapsulates a disassembler for a single architecture and
/// disassembly syntax. Also manages the static disassembler registry. /// disassembly syntax. Also manages the static disassembler registry.
struct EDDisassembler { struct EDDisassembler {
typedef enum {
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
kEDAssemblySyntaxX86Intel = 0,
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
kEDAssemblySyntaxX86ATT = 1,
kEDAssemblySyntaxARMUAL = 2
} AssemblySyntax;
//////////////////// ////////////////////
// Static members // // Static members //
//////////////////// ////////////////////
@ -67,7 +77,7 @@ struct EDDisassembler {
llvm::Triple::ArchType Arch; llvm::Triple::ArchType Arch;
/// The assembly syntax /// The assembly syntax
EDAssemblySyntax_t Syntax; AssemblySyntax Syntax;
/// operator== - Equality operator /// operator== - Equality operator
bool operator==(const CPUKey &key) const { bool operator==(const CPUKey &key) const {
@ -98,7 +108,7 @@ struct EDDisassembler {
/// @arg arch - The desired architecture /// @arg arch - The desired architecture
/// @arg syntax - The desired disassembly syntax /// @arg syntax - The desired disassembly syntax
static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch, static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch,
EDAssemblySyntax_t syntax); AssemblySyntax syntax);
/// getDisassembler - Returns the disassembler for a given combination of /// getDisassembler - Returns the disassembler for a given combination of
/// CPU type, CPU subtype, and assembly syntax, or NULL on failure /// CPU type, CPU subtype, and assembly syntax, or NULL on failure
@ -107,7 +117,7 @@ struct EDDisassembler {
/// "x86_64-apple-darwin" /// "x86_64-apple-darwin"
/// @arg syntax - The disassembly syntax for the required disassembler /// @arg syntax - The disassembly syntax for the required disassembler
static EDDisassembler *getDisassembler(llvm::StringRef str, static EDDisassembler *getDisassembler(llvm::StringRef str,
EDAssemblySyntax_t syntax); AssemblySyntax syntax);
/// initialize - Initializes the disassembler registry and the LLVM backend /// initialize - Initializes the disassembler registry and the LLVM backend
static void initialize(); static void initialize();
@ -128,7 +138,7 @@ struct EDDisassembler {
CPUKey Key; CPUKey Key;
/// The LLVM target corresponding to the disassembler /// The LLVM target corresponding to the disassembler
const llvm::Target *Tgt; const llvm::Target *Tgt;
/// The target machien instance. /// The target machine instance.
llvm::OwningPtr<llvm::TargetMachine> TargetMachine; llvm::OwningPtr<llvm::TargetMachine> TargetMachine;
/// The assembly information for the target architecture /// The assembly information for the target architecture
llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo; llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
@ -256,4 +266,6 @@ struct EDDisassembler {
int llvmSyntaxVariant() const; int llvmSyntaxVariant() const;
}; };
} // end namespace llvm
#endif #endif

View File

@ -13,8 +13,8 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "EDDisassembler.h"
#include "EDInst.h" #include "EDInst.h"
#include "EDDisassembler.h"
#include "EDOperand.h" #include "EDOperand.h"
#include "EDToken.h" #include "EDToken.h"

View File

@ -1,4 +1,4 @@
//===-EDInst.h - LLVM Enhanced Disassembler ---------------------*- C++ -*-===// //===-- EDInst.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,19 +13,23 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef EDInst_ #ifndef LLVM_EDINST_H
#define EDInst_ #define LLVM_EDINST_H
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include <string> #include <string>
#include <vector> #include <vector>
namespace llvm { namespace llvm {
class MCInst;
struct EDInstInfo; struct EDInstInfo;
} struct EDToken;
struct EDDisassembler;
struct EDOperand;
#ifdef __BLOCKS__
typedef int (^EDTokenVisitor_t)(EDToken *token);
#endif
/// CachedResult - Encapsulates the result of a function along with the validity /// CachedResult - Encapsulates the result of a function along with the validity
/// of that result, so that slow functions don't need to run twice /// of that result, so that slow functions don't need to run twice
@ -172,4 +176,6 @@ struct EDInst {
#endif #endif
}; };
} // end namespace llvm
#endif #endif

View File

@ -1,4 +1,4 @@
//===-EDOperand.cpp - LLVM Enhanced Disassembler --------------------------===// //===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,13 +13,11 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "EDOperand.h"
#include "EDDisassembler.h" #include "EDDisassembler.h"
#include "EDInst.h" #include "EDInst.h"
#include "EDOperand.h"
#include "llvm/MC/EDInstInfo.h" #include "llvm/MC/EDInstInfo.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
using namespace llvm; using namespace llvm;
EDOperand::EDOperand(const EDDisassembler &disassembler, EDOperand::EDOperand(const EDDisassembler &disassembler,
@ -263,7 +261,7 @@ int EDOperand::isMemory() {
#ifdef __BLOCKS__ #ifdef __BLOCKS__
struct RegisterReaderWrapper { struct RegisterReaderWrapper {
EDRegisterBlock_t regBlock; EDOperand::EDRegisterBlock_t regBlock;
}; };
int readerWrapperCallback(uint64_t *value, int readerWrapperCallback(uint64_t *value,

View File

@ -13,10 +13,19 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef EDOperand_ #ifndef LLVM_EDOPERAND_H
#define EDOperand_ #define LLVM_EDOPERAND_H
#include "llvm/Support/DataTypes.h"
namespace llvm {
struct EDDisassembler;
struct EDInst;
typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
void* arg);
#include "llvm-c/EnhancedDisassembly.h"
/// EDOperand - Encapsulates a single operand, which can be evaluated by the /// EDOperand - Encapsulates a single operand, which can be evaluated by the
/// client /// client
@ -69,10 +78,14 @@ struct EDOperand {
int isMemory(); int isMemory();
#ifdef __BLOCKS__ #ifdef __BLOCKS__
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
/// evaluate - Like evaluate for a callback, but uses a block instead /// evaluate - Like evaluate for a callback, but uses a block instead
int evaluate(uint64_t &result, int evaluate(uint64_t &result,
EDRegisterBlock_t regBlock); EDRegisterBlock_t regBlock);
#endif #endif
}; };
} // end namespace llvm
#endif #endif

View File

@ -1,4 +1,4 @@
//===-EDToken.cpp - LLVM Enhanced Disassembler ----------------------------===// //===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,13 +13,11 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "EDDisassembler.h"
#include "EDToken.h" #include "EDToken.h"
#include "EDDisassembler.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h" #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm; using namespace llvm;
EDToken::EDToken(StringRef str, EDToken::EDToken(StringRef str,

View File

@ -13,15 +13,17 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef EDToken_ #ifndef LLVM_EDTOKEN_H
#define EDToken_ #define LLVM_EDTOKEN_H
#include "llvm-c/EnhancedDisassembly.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
#include <string> #include <string>
#include <vector> #include <vector>
namespace llvm {
struct EDDisassembler;
/// EDToken - Encapsulates a single token, which can provide a string /// EDToken - Encapsulates a single token, which can provide a string
/// representation of itself or interpret itself in various ways, depending /// representation of itself or interpret itself in various ways, depending
/// on the token type. /// on the token type.
@ -132,4 +134,5 @@ struct EDToken {
int getString(const char*& buf); int getString(const char*& buf);
}; };
} // end namespace llvm
#endif #endif

View File

@ -10,7 +10,7 @@
LEVEL = ../.. LEVEL = ../..
LIBRARYNAME = LLVMMC LIBRARYNAME = LLVMMC
BUILD_ARCHIVE := 1 BUILD_ARCHIVE := 1
PARALLEL_DIRS := MCParser PARALLEL_DIRS := MCParser MCDisassembler
include $(LEVEL)/Makefile.common include $(LEVEL)/Makefile.common

View File

@ -15,14 +15,11 @@ OPTIONAL_PARALLEL_DIRS := clang
# NOTE: The tools are organized into five groups of four consisting of one # NOTE: The tools are organized into five groups of four consisting of one
# large and three small executables. This is done to minimize memory load # large and three small executables. This is done to minimize memory load
# in parallel builds. Please retain this ordering. # in parallel builds. Please retain this ordering.
DIRS := llvm-config
# libEnhancedDisassembly must be built ahead of llvm-mc PARALLEL_DIRS := opt llvm-as llvm-dis edis \
# because llvm-mc links against libEnhancedDisassembly
DIRS := llvm-config edis llvm-mc
PARALLEL_DIRS := opt llvm-as llvm-dis \
llc llvm-ranlib llvm-ar llvm-nm \ llc llvm-ranlib llvm-ar llvm-nm \
llvm-ld llvm-prof llvm-link \ llvm-ld llvm-prof llvm-link \
lli llvm-extract \ lli llvm-extract llvm-mc \
bugpoint llvm-bcanalyzer llvm-stub \ bugpoint llvm-bcanalyzer llvm-stub \
llvmc llvmc
@ -34,6 +31,7 @@ endif
include $(LEVEL)/Makefile.config include $(LEVEL)/Makefile.config
# These libraries build as dynamic libraries (.dylib /.so), they can only be # These libraries build as dynamic libraries (.dylib /.so), they can only be
# built if ENABLE_PIC is set. # built if ENABLE_PIC is set.
ifeq ($(ENABLE_PIC),1) ifeq ($(ENABLE_PIC),1)
@ -46,6 +44,14 @@ ifeq ($(ENABLE_PIC),1)
else else
PARALLEL_DIRS += lto PARALLEL_DIRS += lto
endif endif
# The edis library is only supported if ARM and/or X86 are enabled, and if
# LLVM is being built PIC on platforms that support dylibs.
ifneq ($(DISABLE_EDIS),1)
ifneq ($(filter $(TARGETS_TO_BUILD), X86 ARM),)
PARALLEL_DIRS := $(filter-out edis, $(PARALLEL_DIRS))
endif
endif
endif endif
endif endif

View File

@ -1,4 +1,4 @@
//===-EDMain.cpp - LLVM Enhanced Disassembly C API ------------------------===// //===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -11,33 +11,46 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "EDDisassembler.h" // FIXME: This code isn't layered right, the headers should be moved to
#include "EDInst.h" // include llvm/MC/MCDisassembler or something.
#include "EDOperand.h" #include "../../lib/MC/MCDisassembler/EDDisassembler.h"
#include "EDToken.h" #include "../../lib/MC/MCDisassembler/EDInst.h"
#include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
#include "llvm-c/EnhancedDisassembly.h" #include "llvm-c/EnhancedDisassembly.h"
using namespace llvm;
int EDGetDisassembler(EDDisassemblerRef *disassembler, int EDGetDisassembler(EDDisassemblerRef *disassembler,
const char *triple, const char *triple,
EDAssemblySyntax_t syntax) { EDAssemblySyntax_t syntax) {
EDDisassembler::initialize(); EDDisassembler::initialize();
EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, EDDisassembler::AssemblySyntax Syntax;
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;
}
if (ret) { EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple, Syntax);
if (!ret)
return -1;
*disassembler = ret; *disassembler = ret;
return 0; return 0;
} else {
return -1;
}
} }
int EDGetRegisterName(const char** regName, int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler, EDDisassemblerRef disassembler,
unsigned regID) { unsigned regID) {
const char* name = disassembler->nameWithRegisterID(regID); const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
if (!name) if (!name)
return -1; return -1;
*regName = name; *regName = name;
@ -46,24 +59,25 @@ int EDGetRegisterName(const char** regName,
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler, int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
unsigned regID) { unsigned regID) {
return disassembler->registerIsStackPointer(regID) ? 1 : 0; return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
} }
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler, int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
unsigned regID) { unsigned regID) {
return disassembler->registerIsProgramCounter(regID) ? 1 : 0; return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
} }
unsigned int EDCreateInsts(EDInstRef *insts, unsigned int EDCreateInsts(EDInstRef *insts,
unsigned int count, unsigned int count,
EDDisassemblerRef disassembler, EDDisassemblerRef disassembler,
EDByteReaderCallback byteReader, ::EDByteReaderCallback byteReader,
uint64_t address, uint64_t address,
void *arg) { void *arg) {
unsigned int index; unsigned int index;
for (index = 0; index < count; ++index) { for (index = 0; index < count; ++index) {
EDInst *inst = disassembler->createInst(byteReader, address, arg); EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
address, arg);
if (!inst) if (!inst)
return index; return index;
@ -76,163 +90,143 @@ unsigned int EDCreateInsts(EDInstRef *insts,
} }
void EDReleaseInst(EDInstRef inst) { void EDReleaseInst(EDInstRef inst) {
delete inst; delete ((EDInst*)inst);
} }
int EDInstByteSize(EDInstRef inst) { int EDInstByteSize(EDInstRef inst) {
return inst->byteSize(); return ((EDInst*)inst)->byteSize();
} }
int EDGetInstString(const char **buf, int EDGetInstString(const char **buf,
EDInstRef inst) { EDInstRef inst) {
return inst->getString(*buf); return ((EDInst*)inst)->getString(*buf);
} }
int EDInstID(unsigned *instID, EDInstRef inst) { int EDInstID(unsigned *instID, EDInstRef inst) {
*instID = inst->instID(); *instID = ((EDInst*)inst)->instID();
return 0; return 0;
} }
int EDInstIsBranch(EDInstRef inst) { int EDInstIsBranch(EDInstRef inst) {
return inst->isBranch(); return ((EDInst*)inst)->isBranch();
} }
int EDInstIsMove(EDInstRef inst) { int EDInstIsMove(EDInstRef inst) {
return inst->isMove(); return ((EDInst*)inst)->isMove();
} }
int EDBranchTargetID(EDInstRef inst) { int EDBranchTargetID(EDInstRef inst) {
return inst->branchTargetID(); return ((EDInst*)inst)->branchTargetID();
} }
int EDMoveSourceID(EDInstRef inst) { int EDMoveSourceID(EDInstRef inst) {
return inst->moveSourceID(); return ((EDInst*)inst)->moveSourceID();
} }
int EDMoveTargetID(EDInstRef inst) { int EDMoveTargetID(EDInstRef inst) {
return inst->moveTargetID(); return ((EDInst*)inst)->moveTargetID();
} }
int EDNumTokens(EDInstRef inst) { int EDNumTokens(EDInstRef inst) {
return inst->numTokens(); return ((EDInst*)inst)->numTokens();
} }
int EDGetToken(EDTokenRef *token, int EDGetToken(EDTokenRef *token,
EDInstRef inst, EDInstRef inst,
int index) { int index) {
return inst->getToken(*token, index); return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
} }
int EDGetTokenString(const char **buf, int EDGetTokenString(const char **buf,
EDTokenRef token) { EDTokenRef token) {
return token->getString(*buf); return ((EDToken*)token)->getString(*buf);
} }
int EDOperandIndexForToken(EDTokenRef token) { int EDOperandIndexForToken(EDTokenRef token) {
return token->operandID(); return ((EDToken*)token)->operandID();
} }
int EDTokenIsWhitespace(EDTokenRef token) { int EDTokenIsWhitespace(EDTokenRef token) {
if (token->type() == EDToken::kTokenWhitespace) return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
return 1;
else
return 0;
} }
int EDTokenIsPunctuation(EDTokenRef token) { int EDTokenIsPunctuation(EDTokenRef token) {
if (token->type() == EDToken::kTokenPunctuation) return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
return 1;
else
return 0;
} }
int EDTokenIsOpcode(EDTokenRef token) { int EDTokenIsOpcode(EDTokenRef token) {
if (token->type() == EDToken::kTokenOpcode) return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
return 1;
else
return 0;
} }
int EDTokenIsLiteral(EDTokenRef token) { int EDTokenIsLiteral(EDTokenRef token) {
if (token->type() == EDToken::kTokenLiteral) return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
return 1;
else
return 0;
} }
int EDTokenIsRegister(EDTokenRef token) { int EDTokenIsRegister(EDTokenRef token) {
if (token->type() == EDToken::kTokenRegister) return ((EDToken*)token)->type() == EDToken::kTokenRegister;
return 1;
else
return 0;
} }
int EDTokenIsNegativeLiteral(EDTokenRef token) { int EDTokenIsNegativeLiteral(EDTokenRef token) {
if (token->type() != EDToken::kTokenLiteral) if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
return -1; return -1;
return token->literalSign(); return ((EDToken*)token)->literalSign();
} }
int EDLiteralTokenAbsoluteValue(uint64_t *value, int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
EDTokenRef token) { if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
if (token->type() != EDToken::kTokenLiteral)
return -1; return -1;
return token->literalAbsoluteValue(*value); return ((EDToken*)token)->literalAbsoluteValue(*value);
} }
int EDRegisterTokenValue(unsigned *registerID, int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) { EDTokenRef token) {
if (token->type() != EDToken::kTokenRegister) if (((EDToken*)token)->type() != EDToken::kTokenRegister)
return -1; return -1;
return token->registerID(*registerID); return ((EDToken*)token)->registerID(*registerID);
} }
int EDNumOperands(EDInstRef inst) { int EDNumOperands(EDInstRef inst) {
return inst->numOperands(); return ((EDInst*)inst)->numOperands();
} }
int EDGetOperand(EDOperandRef *operand, int EDGetOperand(EDOperandRef *operand,
EDInstRef inst, EDInstRef inst,
int index) { int index) {
return inst->getOperand(*operand, index); return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
} }
int EDOperandIsRegister(EDOperandRef operand) { int EDOperandIsRegister(EDOperandRef operand) {
return operand->isRegister(); return ((EDOperand*)operand)->isRegister();
} }
int EDOperandIsImmediate(EDOperandRef operand) { int EDOperandIsImmediate(EDOperandRef operand) {
return operand->isImmediate(); return ((EDOperand*)operand)->isImmediate();
} }
int EDOperandIsMemory(EDOperandRef operand) { int EDOperandIsMemory(EDOperandRef operand) {
return operand->isMemory(); return ((EDOperand*)operand)->isMemory();
} }
int EDRegisterOperandValue(unsigned *value, int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
EDOperandRef operand) { if (!((EDOperand*)operand)->isRegister())
if (!operand->isRegister())
return -1; return -1;
*value = operand->regVal(); *value = ((EDOperand*)operand)->regVal();
return 0; return 0;
} }
int EDImmediateOperandValue(uint64_t *value, int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
EDOperandRef operand) { if (!((EDOperand*)operand)->isImmediate())
if (!operand->isImmediate())
return -1; return -1;
*value = operand->immediateVal(); *value = ((EDOperand*)operand)->immediateVal();
return 0; return 0;
} }
int EDEvaluateOperand(uint64_t *result, int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
EDOperandRef operand, ::EDRegisterReaderCallback regReader, void *arg) {
EDRegisterReaderCallback regReader, return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
void *arg) {
return operand->evaluate(*result, regReader, arg);
} }
#ifdef __BLOCKS__ #ifdef __BLOCKS__
@ -264,15 +258,13 @@ unsigned int EDBlockCreateInsts(EDInstRef *insts,
(void*)&wrapper); (void*)&wrapper);
} }
int EDBlockEvaluateOperand(uint64_t *result, int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
EDOperandRef operand,
EDRegisterBlock_t regBlock) { EDRegisterBlock_t regBlock) {
return operand->evaluate(*result, regBlock); return ((EDOperand*)operand)->evaluate(*result, regBlock);
} }
int EDBlockVisitTokens(EDInstRef inst, int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
EDTokenVisitor_t visitor) { return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
return inst->visitTokens(visitor);
} }
#else #else

View File

@ -1,5 +1,4 @@
set( LLVM_USED_LIBS EnhancedDisassembly) set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser MCDisassembler)
set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser)
add_llvm_tool(llvm-mc add_llvm_tool(llvm-mc
llvm-mc.cpp llvm-mc.cpp

View File

@ -13,21 +13,21 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "Disassembler.h" #include "Disassembler.h"
#include "../../lib/MC/MCDisassembler/EDDisassembler.h"
#include "llvm/ADT/OwningPtr.h" #include "../../lib/MC/MCDisassembler/EDInst.h"
#include "llvm/ADT/Triple.h" #include "../../lib/MC/MCDisassembler/EDOperand.h"
#include "../../lib/MC/MCDisassembler/EDToken.h"
#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h" #include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstPrinter.h"
#include "llvm/Target/TargetRegistry.h" #include "llvm/Target/TargetRegistry.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h" #include "llvm/Support/MemoryObject.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SourceMgr.h"
#include "llvm-c/EnhancedDisassembly.h"
using namespace llvm; using namespace llvm;
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy; typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
@ -179,21 +179,17 @@ static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) {
} }
static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) {
EDDisassemblerRef &disassembler = *((EDDisassemblerRef*)Arg); EDDisassembler &disassembler = *((EDDisassembler *)Arg);
const char *regName; if (const char *regName = disassembler.nameWithRegisterID(R))
if (!EDGetRegisterName(&regName,
disassembler,
R))
outs() << "[" << regName << "/" << R << "]"; outs() << "[" << regName << "/" << R << "]";
if (EDRegisterIsStackPointer(disassembler, R))
if (disassembler.registerIsStackPointer(R))
outs() << "(sp)"; outs() << "(sp)";
if (EDRegisterIsProgramCounter(disassembler, R)) if (disassembler.registerIsProgramCounter(R))
outs() << "(pc)"; outs() << "(pc)";
*V = 0; *V = 0;
return 0; return 0;
} }
@ -209,10 +205,8 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
return -1; return -1;
} }
EDDisassemblerRef disassembler;
Triple T(TS); Triple T(TS);
EDAssemblySyntax_t AS; EDDisassembler::AssemblySyntax AS;
switch (T.getArch()) { switch (T.getArch()) {
default: default:
@ -220,90 +214,82 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
return -1; return -1;
case Triple::arm: case Triple::arm:
case Triple::thumb: case Triple::thumb:
AS = kEDAssemblySyntaxARMUAL; AS = EDDisassembler::kEDAssemblySyntaxARMUAL;
break; break;
case Triple::x86: case Triple::x86:
case Triple::x86_64: case Triple::x86_64:
AS = kEDAssemblySyntaxX86ATT; AS = EDDisassembler::kEDAssemblySyntaxX86ATT;
break; break;
} }
if (EDGetDisassembler(&disassembler, EDDisassembler::initialize();
TS.c_str(), EDDisassembler *disassembler =
AS)) { EDDisassembler::getDisassembler(TS.c_str(), AS);
errs() << "error: couldn't get disassembler for " << TS.c_str() << "\n";
if (disassembler == 0) {
errs() << "error: couldn't get disassembler for " << TS << '\n';
return -1; return -1;
} }
EDInstRef inst; EDInst *inst =
disassembler->createInst(byteArrayReader, 0, &ByteArray);
if (EDCreateInsts(&inst, 1, disassembler, byteArrayReader, 0,&ByteArray) if (inst == 0) {
!= 1) {
errs() << "error: Didn't get an instruction\n"; errs() << "error: Didn't get an instruction\n";
return -1; return -1;
} }
int numTokens = EDNumTokens(inst); unsigned numTokens = inst->numTokens();
if ((int)numTokens < 0) {
if (numTokens < 0) { errs() << "error: couldn't count the instruction's tokens\n";
errs() << "error: Couldn't count the instruction's tokens\n";
return -1; return -1;
} }
int tokenIndex; for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) {
EDToken *token;
for (tokenIndex = 0; tokenIndex < numTokens; ++tokenIndex) { if (inst->getToken(token, tokenIndex)) {
EDTokenRef token;
if (EDGetToken(&token, inst, tokenIndex)) {
errs() << "error: Couldn't get token\n"; errs() << "error: Couldn't get token\n";
return -1; return -1;
} }
const char *buf; const char *buf;
if (token->getString(buf)) {
if (EDGetTokenString(&buf, token)) {
errs() << "error: Couldn't get string for token\n"; errs() << "error: Couldn't get string for token\n";
return -1; return -1;
} }
outs() << "["; outs() << '[';
int operandIndex = token->operandID();
int operandIndex = EDOperandIndexForToken(token);
if (operandIndex >= 0) if (operandIndex >= 0)
outs() << operandIndex << "-"; outs() << operandIndex << "-";
if (EDTokenIsWhitespace(token)) { switch (token->type()) {
outs() << "w"; default: outs() << "?"; break;
} else if (EDTokenIsPunctuation(token)) { case EDToken::kTokenWhitespace: outs() << "w"; break;
outs() << "p"; case EDToken::kTokenPunctuation: outs() << "p"; break;
} else if (EDTokenIsOpcode(token)) { case EDToken::kTokenOpcode: outs() << "o"; break;
outs() << "o"; case EDToken::kTokenLiteral: outs() << "l"; break;
} else if (EDTokenIsLiteral(token)) { case EDToken::kTokenRegister: outs() << "r"; break;
outs() << "l";
} else if (EDTokenIsRegister(token)) {
outs() << "r";
} else {
outs() << "?";
} }
outs() << ":" << buf; outs() << ":" << buf;
if (EDTokenIsLiteral(token)) { if (token->type() == EDToken::kTokenLiteral) {
outs() << "="; outs() << "=";
if (EDTokenIsNegativeLiteral(token)) if (token->literalSign())
outs() << "-"; outs() << "-";
uint64_t absoluteValue; uint64_t absoluteValue;
if (EDLiteralTokenAbsoluteValue(&absoluteValue, token)) { if (token->literalAbsoluteValue(absoluteValue)) {
errs() << "error: Couldn't get the value of a literal token\n"; errs() << "error: Couldn't get the value of a literal token\n";
return -1; return -1;
} }
outs() << absoluteValue; outs() << absoluteValue;
} else if (EDTokenIsRegister(token)) { } else if (token->type() == EDToken::kTokenRegister) {
outs() << "="; outs() << "=";
unsigned regID; unsigned regID;
if (EDRegisterTokenValue(&regID, token)) { if (token->registerID(regID)) {
errs() << "error: Couldn't get the ID of a register token\n"; errs() << "error: Couldn't get the ID of a register token\n";
return -1; return -1;
} }
@ -315,45 +301,34 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
outs() << " "; outs() << " ";
if (EDInstIsBranch(inst)) if (inst->isBranch())
outs() << "<br> "; outs() << "<br> ";
if (EDInstIsMove(inst)) if (inst->isMove())
outs() << "<mov> "; outs() << "<mov> ";
int numOperands = EDNumOperands(inst); unsigned numOperands = inst->numOperands();
if (numOperands < 0) { if ((int)numOperands < 0) {
errs() << "error: Couldn't count operands\n"; errs() << "error: Couldn't count operands\n";
return -1; return -1;
} }
int operandIndex; for (unsigned operandIndex = 0; operandIndex != numOperands; ++operandIndex) {
for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
outs() << operandIndex << ":"; outs() << operandIndex << ":";
EDOperandRef operand; EDOperand *operand;
if (inst->getOperand(operand, operandIndex)) {
if (EDGetOperand(&operand, errs() << "error: couldn't get operand\n";
inst,
operandIndex)) {
errs() << "error: Couldn't get operand\n";
return -1; return -1;
} }
uint64_t evaluatedResult; uint64_t evaluatedResult;
evaluatedResult = operand->evaluate(evaluatedResult, verboseEvaluator,
EDEvaluateOperand(&evaluatedResult, disassembler);
operand, outs() << "=" << evaluatedResult << " ";
verboseEvaluator,
&disassembler);
outs() << "=" << evaluatedResult;
outs() << " ";
} }
outs() << "\n"; outs() << '\n';
return 0; return 0;
} }

View File

@ -18,9 +18,7 @@ TOOL_NO_EXPORTS = 1
# early so we can set up LINK_COMPONENTS before including Makefile.rules # early so we can set up LINK_COMPONENTS before including Makefile.rules
include $(LEVEL)/Makefile.config include $(LEVEL)/Makefile.config
LINK_COMPONENTS := $(TARGETS_TO_BUILD) MCParser MC support LINK_COMPONENTS := $(TARGETS_TO_BUILD) MCDisassembler MCParser MC support
include $(LLVM_SRC_ROOT)/Makefile.rules include $(LLVM_SRC_ROOT)/Makefile.rules
# Using LIBS instead of USEDLIBS to force static linking
LIBS += $(LLVMLibDir)/libEnhancedDisassembly.a