mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
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. llvm-svn: 108869
This commit is contained in:
parent
1b0b3bc7e0
commit
1ac58ea0f3
@ -308,6 +308,7 @@ add_subdirectory(lib/Analysis)
|
||||
add_subdirectory(lib/Analysis/IPA)
|
||||
add_subdirectory(lib/MC)
|
||||
add_subdirectory(lib/MC/MCParser)
|
||||
add_subdirectory(lib/MC/MCDisassembler)
|
||||
add_subdirectory(test)
|
||||
|
||||
add_subdirectory(utils/FileCheck)
|
||||
|
@ -51,41 +51,38 @@ typedef int (*EDRegisterReaderCallback)(uint64_t *value, unsigned regID,
|
||||
@typedef EDAssemblySyntax_t
|
||||
An assembly syntax for use in tokenizing instructions.
|
||||
*/
|
||||
typedef enum {
|
||||
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
|
||||
} EDAssemblySyntax_t;
|
||||
};
|
||||
typedef unsigned EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
@typedef EDDisassemblerRef
|
||||
Encapsulates a disassembler for a single CPU architecture.
|
||||
*/
|
||||
struct EDDisassembler;
|
||||
typedef struct EDDisassembler *EDDisassemblerRef;
|
||||
typedef void *EDDisassemblerRef;
|
||||
|
||||
/*!
|
||||
@typedef EDInstRef
|
||||
Encapsulates a single disassembled instruction in one assembly syntax.
|
||||
*/
|
||||
struct EDInst;
|
||||
typedef struct EDInst *EDInstRef;
|
||||
typedef void *EDInstRef;
|
||||
|
||||
/*!
|
||||
@typedef EDTokenRef
|
||||
Encapsulates a token from the disassembly of an instruction.
|
||||
*/
|
||||
struct EDToken;
|
||||
typedef struct EDToken *EDTokenRef;
|
||||
typedef void *EDTokenRef;
|
||||
|
||||
/*!
|
||||
@typedef EDOperandRef
|
||||
Encapsulates an operand of an instruction.
|
||||
*/
|
||||
struct EDOperand;
|
||||
typedef struct EDOperand *EDOperandRef;
|
||||
typedef void *EDOperandRef;
|
||||
|
||||
/*!
|
||||
@functiongroup Getting a disassembler
|
||||
|
@ -15,9 +15,6 @@
|
||||
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
@ -38,7 +35,6 @@
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSelect.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool EDDisassembler::sInitialized = false;
|
||||
@ -79,22 +75,22 @@ static const char *tripleFromArch(Triple::ArchType arch) {
|
||||
/// @arg arch - The target architecture
|
||||
/// @arg syntax - The assembly syntax in sd form
|
||||
static int getLLVMSyntaxVariant(Triple::ArchType arch,
|
||||
EDAssemblySyntax_t syntax) {
|
||||
EDDisassembler::AssemblySyntax syntax) {
|
||||
switch (syntax) {
|
||||
default:
|
||||
return -1;
|
||||
// Mappings below from X86AsmPrinter.cpp
|
||||
case kEDAssemblySyntaxX86ATT:
|
||||
case EDDisassembler::kEDAssemblySyntaxX86ATT:
|
||||
if (arch == Triple::x86 || arch == Triple::x86_64)
|
||||
return 0;
|
||||
else
|
||||
return -1;
|
||||
case kEDAssemblySyntaxX86Intel:
|
||||
case EDDisassembler::kEDAssemblySyntaxX86Intel:
|
||||
if (arch == Triple::x86 || arch == Triple::x86_64)
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
case kEDAssemblySyntaxARMUAL:
|
||||
case EDDisassembler::kEDAssemblySyntaxARMUAL:
|
||||
if (arch == Triple::arm || arch == Triple::thumb)
|
||||
return 0;
|
||||
else
|
||||
@ -118,7 +114,7 @@ void EDDisassembler::initialize() {
|
||||
#undef BRINGUP_TARGET
|
||||
|
||||
EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
|
||||
EDAssemblySyntax_t syntax) {
|
||||
AssemblySyntax syntax) {
|
||||
CPUKey key;
|
||||
key.Arch = arch;
|
||||
key.Syntax = syntax;
|
||||
@ -143,10 +139,8 @@ EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
|
||||
}
|
||||
|
||||
EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
|
||||
EDAssemblySyntax_t syntax) {
|
||||
Triple triple(str);
|
||||
|
||||
return getDisassembler(triple.getArch(), syntax);
|
||||
AssemblySyntax syntax) {
|
||||
return getDisassembler(Triple(str).getArch(), syntax);
|
||||
}
|
||||
|
||||
EDDisassembler::EDDisassembler(CPUKey &key) :
|
@ -1,4 +1,4 @@
|
||||
//===-EDDisassembler.h - LLVM Enhanced Disassembler -------------*- C++ -*-===//
|
||||
//===-- EDDisassembler.h - LLVM Enhanced Disassembler -----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -13,13 +13,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef EDDisassembler_
|
||||
#define EDDisassembler_
|
||||
#ifndef LLVM_EDDISASSEMBLER_H
|
||||
#define LLVM_EDDISASSEMBLER_H
|
||||
|
||||
#include "EDInfo.inc"
|
||||
|
||||
#include "llvm-c/EnhancedDisassembly.h"
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
@ -27,7 +25,6 @@
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
@ -51,11 +48,24 @@ class TargetMachine;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
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
|
||||
/// disassembly syntax. Also manages the static disassembler registry.
|
||||
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 //
|
||||
////////////////////
|
||||
@ -67,7 +77,7 @@ struct EDDisassembler {
|
||||
llvm::Triple::ArchType Arch;
|
||||
|
||||
/// The assembly syntax
|
||||
EDAssemblySyntax_t Syntax;
|
||||
AssemblySyntax Syntax;
|
||||
|
||||
/// operator== - Equality operator
|
||||
bool operator==(const CPUKey &key) const {
|
||||
@ -98,7 +108,7 @@ struct EDDisassembler {
|
||||
/// @arg arch - The desired architecture
|
||||
/// @arg syntax - The desired disassembly syntax
|
||||
static EDDisassembler *getDisassembler(llvm::Triple::ArchType arch,
|
||||
EDAssemblySyntax_t syntax);
|
||||
AssemblySyntax syntax);
|
||||
|
||||
/// getDisassembler - Returns the disassembler for a given combination of
|
||||
/// CPU type, CPU subtype, and assembly syntax, or NULL on failure
|
||||
@ -107,7 +117,7 @@ struct EDDisassembler {
|
||||
/// "x86_64-apple-darwin"
|
||||
/// @arg syntax - The disassembly syntax for the required disassembler
|
||||
static EDDisassembler *getDisassembler(llvm::StringRef str,
|
||||
EDAssemblySyntax_t syntax);
|
||||
AssemblySyntax syntax);
|
||||
|
||||
/// initialize - Initializes the disassembler registry and the LLVM backend
|
||||
static void initialize();
|
||||
@ -128,7 +138,7 @@ struct EDDisassembler {
|
||||
CPUKey Key;
|
||||
/// The LLVM target corresponding to the disassembler
|
||||
const llvm::Target *Tgt;
|
||||
/// The target machien instance.
|
||||
/// The target machine instance.
|
||||
llvm::OwningPtr<llvm::TargetMachine> TargetMachine;
|
||||
/// The assembly information for the target architecture
|
||||
llvm::OwningPtr<const llvm::MCAsmInfo> AsmInfo;
|
||||
@ -256,4 +266,6 @@ struct EDDisassembler {
|
||||
int llvmSyntaxVariant() const;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -13,8 +13,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDOperand.h"
|
||||
#include "EDToken.h"
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-EDInst.h - LLVM Enhanced Disassembler ---------------------*- C++ -*-===//
|
||||
//===-- EDInst.h - LLVM Enhanced Disassembler -------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -13,19 +13,23 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef EDInst_
|
||||
#define EDInst_
|
||||
|
||||
#include "llvm-c/EnhancedDisassembly.h"
|
||||
#ifndef LLVM_EDINST_H
|
||||
#define LLVM_EDINST_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class MCInst;
|
||||
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
|
||||
/// of that result, so that slow functions don't need to run twice
|
||||
@ -172,4 +176,6 @@ struct EDInst {
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
//===-EDOperand.cpp - LLVM Enhanced Disassembler --------------------------===//
|
||||
//===-- EDOperand.cpp - LLVM Enhanced Disassembler ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -13,13 +13,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDOperand.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
#include "EDOperand.h"
|
||||
|
||||
#include "llvm/MC/EDInstInfo.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
EDOperand::EDOperand(const EDDisassembler &disassembler,
|
||||
@ -263,7 +261,7 @@ int EDOperand::isMemory() {
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
struct RegisterReaderWrapper {
|
||||
EDRegisterBlock_t regBlock;
|
||||
EDOperand::EDRegisterBlock_t regBlock;
|
||||
};
|
||||
|
||||
int readerWrapperCallback(uint64_t *value,
|
@ -13,10 +13,19 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef EDOperand_
|
||||
#define EDOperand_
|
||||
#ifndef LLVM_EDOPERAND_H
|
||||
#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
|
||||
/// client
|
||||
@ -69,10 +78,14 @@ struct EDOperand {
|
||||
int isMemory();
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
typedef int (^EDRegisterBlock_t)(uint64_t *value, unsigned regID);
|
||||
|
||||
/// evaluate - Like evaluate for a callback, but uses a block instead
|
||||
int evaluate(uint64_t &result,
|
||||
EDRegisterBlock_t regBlock);
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,4 +1,4 @@
|
||||
//===-EDToken.cpp - LLVM Enhanced Disassembler ----------------------------===//
|
||||
//===-- EDToken.cpp - LLVM Enhanced Disassembler --------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -13,13 +13,11 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDToken.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "EDDisassembler.h"
|
||||
#include "llvm/MC/MCParser/MCAsmLexer.h"
|
||||
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
using namespace llvm;
|
||||
|
||||
EDToken::EDToken(StringRef str,
|
@ -13,15 +13,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef EDToken_
|
||||
#define EDToken_
|
||||
#ifndef LLVM_EDTOKEN_H
|
||||
#define LLVM_EDTOKEN_H
|
||||
|
||||
#include "llvm-c/EnhancedDisassembly.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
struct EDDisassembler;
|
||||
|
||||
/// EDToken - Encapsulates a single token, which can provide a string
|
||||
/// representation of itself or interpret itself in various ways, depending
|
||||
/// on the token type.
|
||||
@ -132,4 +134,5 @@ struct EDToken {
|
||||
int getString(const char*& buf);
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
#endif
|
@ -10,7 +10,7 @@
|
||||
LEVEL = ../..
|
||||
LIBRARYNAME = LLVMMC
|
||||
BUILD_ARCHIVE := 1
|
||||
PARALLEL_DIRS := MCParser
|
||||
PARALLEL_DIRS := MCParser MCDisassembler
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
|
@ -15,14 +15,11 @@ OPTIONAL_PARALLEL_DIRS := clang
|
||||
# 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
|
||||
# in parallel builds. Please retain this ordering.
|
||||
|
||||
# libEnhancedDisassembly must be built ahead of llvm-mc
|
||||
# because llvm-mc links against libEnhancedDisassembly
|
||||
DIRS := llvm-config edis llvm-mc
|
||||
PARALLEL_DIRS := opt llvm-as llvm-dis \
|
||||
DIRS := llvm-config
|
||||
PARALLEL_DIRS := opt llvm-as llvm-dis edis \
|
||||
llc llvm-ranlib llvm-ar llvm-nm \
|
||||
llvm-ld llvm-prof llvm-link \
|
||||
lli llvm-extract \
|
||||
lli llvm-extract llvm-mc \
|
||||
bugpoint llvm-bcanalyzer llvm-stub \
|
||||
llvmc
|
||||
|
||||
@ -34,6 +31,7 @@ endif
|
||||
|
||||
include $(LEVEL)/Makefile.config
|
||||
|
||||
|
||||
# These libraries build as dynamic libraries (.dylib /.so), they can only be
|
||||
# built if ENABLE_PIC is set.
|
||||
ifeq ($(ENABLE_PIC),1)
|
||||
@ -46,6 +44,14 @@ ifeq ($(ENABLE_PIC),1)
|
||||
else
|
||||
PARALLEL_DIRS += lto
|
||||
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
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-EDMain.cpp - LLVM Enhanced Disassembly C API ------------------------===//
|
||||
//===-- EDMain.cpp - LLVM Enhanced Disassembly C API ----------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,33 +11,46 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "EDDisassembler.h"
|
||||
#include "EDInst.h"
|
||||
#include "EDOperand.h"
|
||||
#include "EDToken.h"
|
||||
|
||||
// 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();
|
||||
|
||||
EDDisassemblerRef ret = EDDisassembler::getDisassembler(triple,
|
||||
syntax);
|
||||
|
||||
if (ret) {
|
||||
*disassembler = ret;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
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 = disassembler->nameWithRegisterID(regID);
|
||||
const char *name = ((EDDisassembler*)disassembler)->nameWithRegisterID(regID);
|
||||
if (!name)
|
||||
return -1;
|
||||
*regName = name;
|
||||
@ -46,24 +59,25 @@ int EDGetRegisterName(const char** regName,
|
||||
|
||||
int EDRegisterIsStackPointer(EDDisassemblerRef disassembler,
|
||||
unsigned regID) {
|
||||
return disassembler->registerIsStackPointer(regID) ? 1 : 0;
|
||||
return ((EDDisassembler*)disassembler)->registerIsStackPointer(regID) ? 1 : 0;
|
||||
}
|
||||
|
||||
int EDRegisterIsProgramCounter(EDDisassemblerRef disassembler,
|
||||
unsigned regID) {
|
||||
return disassembler->registerIsProgramCounter(regID) ? 1 : 0;
|
||||
return ((EDDisassembler*)disassembler)->registerIsProgramCounter(regID) ? 1:0;
|
||||
}
|
||||
|
||||
unsigned int EDCreateInsts(EDInstRef *insts,
|
||||
unsigned int count,
|
||||
EDDisassemblerRef disassembler,
|
||||
EDByteReaderCallback byteReader,
|
||||
::EDByteReaderCallback byteReader,
|
||||
uint64_t address,
|
||||
void *arg) {
|
||||
unsigned int index;
|
||||
|
||||
for (index = 0; index < count; ++index) {
|
||||
EDInst *inst = disassembler->createInst(byteReader, address, arg);
|
||||
EDInst *inst = ((EDDisassembler*)disassembler)->createInst(byteReader,
|
||||
address, arg);
|
||||
|
||||
if (!inst)
|
||||
return index;
|
||||
@ -76,163 +90,143 @@ unsigned int EDCreateInsts(EDInstRef *insts,
|
||||
}
|
||||
|
||||
void EDReleaseInst(EDInstRef inst) {
|
||||
delete inst;
|
||||
delete ((EDInst*)inst);
|
||||
}
|
||||
|
||||
int EDInstByteSize(EDInstRef inst) {
|
||||
return inst->byteSize();
|
||||
return ((EDInst*)inst)->byteSize();
|
||||
}
|
||||
|
||||
int EDGetInstString(const char **buf,
|
||||
EDInstRef inst) {
|
||||
return inst->getString(*buf);
|
||||
return ((EDInst*)inst)->getString(*buf);
|
||||
}
|
||||
|
||||
int EDInstID(unsigned *instID, EDInstRef inst) {
|
||||
*instID = inst->instID();
|
||||
*instID = ((EDInst*)inst)->instID();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDInstIsBranch(EDInstRef inst) {
|
||||
return inst->isBranch();
|
||||
return ((EDInst*)inst)->isBranch();
|
||||
}
|
||||
|
||||
int EDInstIsMove(EDInstRef inst) {
|
||||
return inst->isMove();
|
||||
return ((EDInst*)inst)->isMove();
|
||||
}
|
||||
|
||||
int EDBranchTargetID(EDInstRef inst) {
|
||||
return inst->branchTargetID();
|
||||
return ((EDInst*)inst)->branchTargetID();
|
||||
}
|
||||
|
||||
int EDMoveSourceID(EDInstRef inst) {
|
||||
return inst->moveSourceID();
|
||||
return ((EDInst*)inst)->moveSourceID();
|
||||
}
|
||||
|
||||
int EDMoveTargetID(EDInstRef inst) {
|
||||
return inst->moveTargetID();
|
||||
return ((EDInst*)inst)->moveTargetID();
|
||||
}
|
||||
|
||||
int EDNumTokens(EDInstRef inst) {
|
||||
return inst->numTokens();
|
||||
return ((EDInst*)inst)->numTokens();
|
||||
}
|
||||
|
||||
int EDGetToken(EDTokenRef *token,
|
||||
EDInstRef inst,
|
||||
int index) {
|
||||
return inst->getToken(*token, index);
|
||||
return ((EDInst*)inst)->getToken(*(EDToken**)token, index);
|
||||
}
|
||||
|
||||
int EDGetTokenString(const char **buf,
|
||||
EDTokenRef token) {
|
||||
return token->getString(*buf);
|
||||
return ((EDToken*)token)->getString(*buf);
|
||||
}
|
||||
|
||||
int EDOperandIndexForToken(EDTokenRef token) {
|
||||
return token->operandID();
|
||||
return ((EDToken*)token)->operandID();
|
||||
}
|
||||
|
||||
int EDTokenIsWhitespace(EDTokenRef token) {
|
||||
if (token->type() == EDToken::kTokenWhitespace)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((EDToken*)token)->type() == EDToken::kTokenWhitespace;
|
||||
}
|
||||
|
||||
int EDTokenIsPunctuation(EDTokenRef token) {
|
||||
if (token->type() == EDToken::kTokenPunctuation)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((EDToken*)token)->type() == EDToken::kTokenPunctuation;
|
||||
}
|
||||
|
||||
int EDTokenIsOpcode(EDTokenRef token) {
|
||||
if (token->type() == EDToken::kTokenOpcode)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((EDToken*)token)->type() == EDToken::kTokenOpcode;
|
||||
}
|
||||
|
||||
int EDTokenIsLiteral(EDTokenRef token) {
|
||||
if (token->type() == EDToken::kTokenLiteral)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((EDToken*)token)->type() == EDToken::kTokenLiteral;
|
||||
}
|
||||
|
||||
int EDTokenIsRegister(EDTokenRef token) {
|
||||
if (token->type() == EDToken::kTokenRegister)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
return ((EDToken*)token)->type() == EDToken::kTokenRegister;
|
||||
}
|
||||
|
||||
int EDTokenIsNegativeLiteral(EDTokenRef token) {
|
||||
if (token->type() != EDToken::kTokenLiteral)
|
||||
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
|
||||
return -1;
|
||||
|
||||
return token->literalSign();
|
||||
return ((EDToken*)token)->literalSign();
|
||||
}
|
||||
|
||||
int EDLiteralTokenAbsoluteValue(uint64_t *value,
|
||||
EDTokenRef token) {
|
||||
if (token->type() != EDToken::kTokenLiteral)
|
||||
int EDLiteralTokenAbsoluteValue(uint64_t *value, EDTokenRef token) {
|
||||
if (((EDToken*)token)->type() != EDToken::kTokenLiteral)
|
||||
return -1;
|
||||
|
||||
return token->literalAbsoluteValue(*value);
|
||||
return ((EDToken*)token)->literalAbsoluteValue(*value);
|
||||
}
|
||||
|
||||
int EDRegisterTokenValue(unsigned *registerID,
|
||||
EDTokenRef token) {
|
||||
if (token->type() != EDToken::kTokenRegister)
|
||||
if (((EDToken*)token)->type() != EDToken::kTokenRegister)
|
||||
return -1;
|
||||
|
||||
return token->registerID(*registerID);
|
||||
return ((EDToken*)token)->registerID(*registerID);
|
||||
}
|
||||
|
||||
int EDNumOperands(EDInstRef inst) {
|
||||
return inst->numOperands();
|
||||
return ((EDInst*)inst)->numOperands();
|
||||
}
|
||||
|
||||
int EDGetOperand(EDOperandRef *operand,
|
||||
EDInstRef inst,
|
||||
int index) {
|
||||
return inst->getOperand(*operand, index);
|
||||
return ((EDInst*)inst)->getOperand(*(EDOperand**)operand, index);
|
||||
}
|
||||
|
||||
int EDOperandIsRegister(EDOperandRef operand) {
|
||||
return operand->isRegister();
|
||||
return ((EDOperand*)operand)->isRegister();
|
||||
}
|
||||
|
||||
int EDOperandIsImmediate(EDOperandRef operand) {
|
||||
return operand->isImmediate();
|
||||
return ((EDOperand*)operand)->isImmediate();
|
||||
}
|
||||
|
||||
int EDOperandIsMemory(EDOperandRef operand) {
|
||||
return operand->isMemory();
|
||||
return ((EDOperand*)operand)->isMemory();
|
||||
}
|
||||
|
||||
int EDRegisterOperandValue(unsigned *value,
|
||||
EDOperandRef operand) {
|
||||
if (!operand->isRegister())
|
||||
int EDRegisterOperandValue(unsigned *value, EDOperandRef operand) {
|
||||
if (!((EDOperand*)operand)->isRegister())
|
||||
return -1;
|
||||
*value = operand->regVal();
|
||||
*value = ((EDOperand*)operand)->regVal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDImmediateOperandValue(uint64_t *value,
|
||||
EDOperandRef operand) {
|
||||
if (!operand->isImmediate())
|
||||
int EDImmediateOperandValue(uint64_t *value, EDOperandRef operand) {
|
||||
if (!((EDOperand*)operand)->isImmediate())
|
||||
return -1;
|
||||
*value = operand->immediateVal();
|
||||
*value = ((EDOperand*)operand)->immediateVal();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EDEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
EDRegisterReaderCallback regReader,
|
||||
void *arg) {
|
||||
return operand->evaluate(*result, regReader, arg);
|
||||
int EDEvaluateOperand(uint64_t *result, EDOperandRef operand,
|
||||
::EDRegisterReaderCallback regReader, void *arg) {
|
||||
return ((EDOperand*)operand)->evaluate(*result, regReader, arg);
|
||||
}
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
@ -264,15 +258,13 @@ unsigned int EDBlockCreateInsts(EDInstRef *insts,
|
||||
(void*)&wrapper);
|
||||
}
|
||||
|
||||
int EDBlockEvaluateOperand(uint64_t *result,
|
||||
EDOperandRef operand,
|
||||
int EDBlockEvaluateOperand(uint64_t *result, EDOperandRef operand,
|
||||
EDRegisterBlock_t regBlock) {
|
||||
return operand->evaluate(*result, regBlock);
|
||||
return ((EDOperand*)operand)->evaluate(*result, regBlock);
|
||||
}
|
||||
|
||||
int EDBlockVisitTokens(EDInstRef inst,
|
||||
EDTokenVisitor_t visitor) {
|
||||
return inst->visitTokens(visitor);
|
||||
int EDBlockVisitTokens(EDInstRef inst, ::EDTokenVisitor_t visitor) {
|
||||
return ((EDInst*)inst)->visitTokens((llvm::EDTokenVisitor_t)visitor);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -1,5 +1,4 @@
|
||||
set( LLVM_USED_LIBS EnhancedDisassembly)
|
||||
set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser)
|
||||
set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC MCParser MCDisassembler)
|
||||
|
||||
add_llvm_tool(llvm-mc
|
||||
llvm-mc.cpp
|
||||
|
@ -13,21 +13,21 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Disassembler.h"
|
||||
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#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/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/Target/TargetRegistry.h"
|
||||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/MemoryObject.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
|
||||
#include "llvm-c/EnhancedDisassembly.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
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) {
|
||||
EDDisassemblerRef &disassembler = *((EDDisassemblerRef*)Arg);
|
||||
EDDisassembler &disassembler = *((EDDisassembler *)Arg);
|
||||
|
||||
const char *regName;
|
||||
|
||||
if (!EDGetRegisterName(®Name,
|
||||
disassembler,
|
||||
R))
|
||||
if (const char *regName = disassembler.nameWithRegisterID(R))
|
||||
outs() << "[" << regName << "/" << R << "]";
|
||||
if (EDRegisterIsStackPointer(disassembler, R))
|
||||
|
||||
if (disassembler.registerIsStackPointer(R))
|
||||
outs() << "(sp)";
|
||||
if (EDRegisterIsProgramCounter(disassembler, R))
|
||||
if (disassembler.registerIsProgramCounter(R))
|
||||
outs() << "(pc)";
|
||||
|
||||
*V = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -209,10 +205,8 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
|
||||
return -1;
|
||||
}
|
||||
|
||||
EDDisassemblerRef disassembler;
|
||||
|
||||
Triple T(TS);
|
||||
EDAssemblySyntax_t AS;
|
||||
EDDisassembler::AssemblySyntax AS;
|
||||
|
||||
switch (T.getArch()) {
|
||||
default:
|
||||
@ -220,90 +214,82 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
|
||||
return -1;
|
||||
case Triple::arm:
|
||||
case Triple::thumb:
|
||||
AS = kEDAssemblySyntaxARMUAL;
|
||||
AS = EDDisassembler::kEDAssemblySyntaxARMUAL;
|
||||
break;
|
||||
case Triple::x86:
|
||||
case Triple::x86_64:
|
||||
AS = kEDAssemblySyntaxX86ATT;
|
||||
AS = EDDisassembler::kEDAssemblySyntaxX86ATT;
|
||||
break;
|
||||
}
|
||||
|
||||
if (EDGetDisassembler(&disassembler,
|
||||
TS.c_str(),
|
||||
AS)) {
|
||||
errs() << "error: couldn't get disassembler for " << TS.c_str() << "\n";
|
||||
EDDisassembler::initialize();
|
||||
EDDisassembler *disassembler =
|
||||
EDDisassembler::getDisassembler(TS.c_str(), AS);
|
||||
|
||||
if (disassembler == 0) {
|
||||
errs() << "error: couldn't get disassembler for " << TS << '\n';
|
||||
return -1;
|
||||
}
|
||||
|
||||
EDInstRef inst;
|
||||
|
||||
if (EDCreateInsts(&inst, 1, disassembler, byteArrayReader, 0,&ByteArray)
|
||||
!= 1) {
|
||||
EDInst *inst =
|
||||
disassembler->createInst(byteArrayReader, 0, &ByteArray);
|
||||
|
||||
if (inst == 0) {
|
||||
errs() << "error: Didn't get an instruction\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int numTokens = EDNumTokens(inst);
|
||||
|
||||
if (numTokens < 0) {
|
||||
errs() << "error: Couldn't count the instruction's tokens\n";
|
||||
unsigned numTokens = inst->numTokens();
|
||||
if ((int)numTokens < 0) {
|
||||
errs() << "error: couldn't count the instruction's tokens\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tokenIndex;
|
||||
|
||||
for (tokenIndex = 0; tokenIndex < numTokens; ++tokenIndex) {
|
||||
EDTokenRef token;
|
||||
for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) {
|
||||
EDToken *token;
|
||||
|
||||
if (EDGetToken(&token, inst, tokenIndex)) {
|
||||
if (inst->getToken(token, tokenIndex)) {
|
||||
errs() << "error: Couldn't get token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *buf;
|
||||
|
||||
if (EDGetTokenString(&buf, token)) {
|
||||
if (token->getString(buf)) {
|
||||
errs() << "error: Couldn't get string for token\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
outs() << "[";
|
||||
|
||||
int operandIndex = EDOperandIndexForToken(token);
|
||||
outs() << '[';
|
||||
int operandIndex = token->operandID();
|
||||
|
||||
if (operandIndex >= 0)
|
||||
outs() << operandIndex << "-";
|
||||
|
||||
if (EDTokenIsWhitespace(token)) {
|
||||
outs() << "w";
|
||||
} else if (EDTokenIsPunctuation(token)) {
|
||||
outs() << "p";
|
||||
} else if (EDTokenIsOpcode(token)) {
|
||||
outs() << "o";
|
||||
} else if (EDTokenIsLiteral(token)) {
|
||||
outs() << "l";
|
||||
} else if (EDTokenIsRegister(token)) {
|
||||
outs() << "r";
|
||||
} else {
|
||||
outs() << "?";
|
||||
switch (token->type()) {
|
||||
default: outs() << "?"; break;
|
||||
case EDToken::kTokenWhitespace: outs() << "w"; break;
|
||||
case EDToken::kTokenPunctuation: outs() << "p"; break;
|
||||
case EDToken::kTokenOpcode: outs() << "o"; break;
|
||||
case EDToken::kTokenLiteral: outs() << "l"; break;
|
||||
case EDToken::kTokenRegister: outs() << "r"; break;
|
||||
}
|
||||
|
||||
outs() << ":" << buf;
|
||||
|
||||
if (EDTokenIsLiteral(token)) {
|
||||
if (token->type() == EDToken::kTokenLiteral) {
|
||||
outs() << "=";
|
||||
if (EDTokenIsNegativeLiteral(token))
|
||||
if (token->literalSign())
|
||||
outs() << "-";
|
||||
uint64_t absoluteValue;
|
||||
if (EDLiteralTokenAbsoluteValue(&absoluteValue, token)) {
|
||||
if (token->literalAbsoluteValue(absoluteValue)) {
|
||||
errs() << "error: Couldn't get the value of a literal token\n";
|
||||
return -1;
|
||||
}
|
||||
outs() << absoluteValue;
|
||||
} else if (EDTokenIsRegister(token)) {
|
||||
} else if (token->type() == EDToken::kTokenRegister) {
|
||||
outs() << "=";
|
||||
unsigned regID;
|
||||
if (EDRegisterTokenValue(®ID, token)) {
|
||||
if (token->registerID(regID)) {
|
||||
errs() << "error: Couldn't get the ID of a register token\n";
|
||||
return -1;
|
||||
}
|
||||
@ -315,45 +301,34 @@ int Disassembler::disassembleEnhanced(const std::string &TS,
|
||||
|
||||
outs() << " ";
|
||||
|
||||
if (EDInstIsBranch(inst))
|
||||
if (inst->isBranch())
|
||||
outs() << "<br> ";
|
||||
if (EDInstIsMove(inst))
|
||||
if (inst->isMove())
|
||||
outs() << "<mov> ";
|
||||
|
||||
int numOperands = EDNumOperands(inst);
|
||||
unsigned numOperands = inst->numOperands();
|
||||
|
||||
if (numOperands < 0) {
|
||||
if ((int)numOperands < 0) {
|
||||
errs() << "error: Couldn't count operands\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
int operandIndex;
|
||||
|
||||
for (operandIndex = 0; operandIndex < numOperands; ++operandIndex) {
|
||||
for (unsigned operandIndex = 0; operandIndex != numOperands; ++operandIndex) {
|
||||
outs() << operandIndex << ":";
|
||||
|
||||
EDOperandRef operand;
|
||||
|
||||
if (EDGetOperand(&operand,
|
||||
inst,
|
||||
operandIndex)) {
|
||||
errs() << "error: Couldn't get operand\n";
|
||||
EDOperand *operand;
|
||||
if (inst->getOperand(operand, operandIndex)) {
|
||||
errs() << "error: couldn't get operand\n";
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t evaluatedResult;
|
||||
|
||||
EDEvaluateOperand(&evaluatedResult,
|
||||
operand,
|
||||
verboseEvaluator,
|
||||
&disassembler);
|
||||
|
||||
outs() << "=" << evaluatedResult;
|
||||
|
||||
outs() << " ";
|
||||
evaluatedResult = operand->evaluate(evaluatedResult, verboseEvaluator,
|
||||
disassembler);
|
||||
outs() << "=" << evaluatedResult << " ";
|
||||
}
|
||||
|
||||
outs() << "\n";
|
||||
outs() << '\n';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,9 +18,7 @@ TOOL_NO_EXPORTS = 1
|
||||
# early so we can set up LINK_COMPONENTS before including Makefile.rules
|
||||
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
|
||||
|
||||
# Using LIBS instead of USEDLIBS to force static linking
|
||||
LIBS += $(LLVMLibDir)/libEnhancedDisassembly.a
|
||||
|
Loading…
x
Reference in New Issue
Block a user