summaryrefslogtreecommitdiff
path: root/tools/edis
diff options
context:
space:
mode:
Diffstat (limited to 'tools/edis')
-rw-r--r--tools/edis/CMakeLists.txt25
-rw-r--r--tools/edis/EDDisassembler.cpp129
-rw-r--r--tools/edis/EDDisassembler.h20
-rw-r--r--tools/edis/EDInfo.td1
-rw-r--r--tools/edis/EDInst.cpp12
-rw-r--r--tools/edis/EDInst.h8
-rw-r--r--tools/edis/EDMain.cpp29
-rw-r--r--tools/edis/EDOperand.cpp238
-rw-r--r--tools/edis/EDToken.cpp18
-rw-r--r--tools/edis/EnhancedDisassembly.exports72
-rw-r--r--tools/edis/Makefile13
11 files changed, 375 insertions, 190 deletions
diff --git a/tools/edis/CMakeLists.txt b/tools/edis/CMakeLists.txt
new file mode 100644
index 0000000000000..f7a199d597b40
--- /dev/null
+++ b/tools/edis/CMakeLists.txt
@@ -0,0 +1,25 @@
+set(LLVM_NO_RTTI 1)
+
+add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/EDInfo.inc
+ COMMAND ${LLVM_TABLEGEN_EXE} -o ${CMAKE_CURRENT_BINARY_DIR}/EDInfo.inc
+ -gen-enhanced-disassembly-header ${CMAKE_CURRENT_SOURCE_DIR}/EDInfo.td
+ DEPENDS tblgen
+ COMMENT "Building enhanced disassembly semantic information header (EDInfo.inc)")
+set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/EDInfo.inc PROPERTIES GENERATED 1)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_llvm_library(EnhancedDisassembly
+ EDDisassembler.cpp
+ EDInst.cpp
+ EDMain.cpp
+ EDOperand.cpp
+ EDToken.cpp
+ ../../include/llvm-c/EnhancedDisassembly.h
+ ${CMAKE_CURRENT_BINARY_DIR}/EDInfo.inc
+)
+
+set_target_properties(EnhancedDisassembly
+ PROPERTIES
+ LINKER_LANGUAGE CXX)
+
diff --git a/tools/edis/EDDisassembler.cpp b/tools/edis/EDDisassembler.cpp
index 8729b4998fda3..00b5d8d33a005 100644
--- a/tools/edis/EDDisassembler.cpp
+++ b/tools/edis/EDDisassembler.cpp
@@ -13,8 +13,12 @@
//
//===----------------------------------------------------------------------===//
+#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"
#include "llvm/MC/MCDisassembler.h"
@@ -36,38 +40,34 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSelect.h"
-#include "EDDisassembler.h"
-#include "EDInst.h"
-
-#include "../../lib/Target/X86/X86GenEDInfo.inc"
-
using namespace llvm;
bool EDDisassembler::sInitialized = false;
EDDisassembler::DisassemblerMap_t EDDisassembler::sDisassemblers;
-struct InfoMap {
+struct TripleMap {
Triple::ArchType Arch;
const char *String;
- const InstInfo *Info;
};
-static struct InfoMap infomap[] = {
- { Triple::x86, "i386-unknown-unknown", instInfoX86 },
- { Triple::x86_64, "x86_64-unknown-unknown", instInfoX86 },
- { Triple::InvalidArch, NULL, NULL }
+static struct TripleMap triplemap[] = {
+ { Triple::x86, "i386-unknown-unknown" },
+ { Triple::x86_64, "x86_64-unknown-unknown" },
+ { Triple::arm, "arm-unknown-unknown" },
+ { Triple::thumb, "thumb-unknown-unknown" },
+ { Triple::InvalidArch, NULL, }
};
-/// infoFromArch - Returns the InfoMap corresponding to a given architecture,
+/// infoFromArch - Returns the TripleMap corresponding to a given architecture,
/// or NULL if there is an error
///
/// @arg arch - The Triple::ArchType for the desired architecture
-static const InfoMap *infoFromArch(Triple::ArchType arch) {
+static const char *tripleFromArch(Triple::ArchType arch) {
unsigned int infoIndex;
- for (infoIndex = 0; infomap[infoIndex].String != NULL; ++infoIndex) {
- if(arch == infomap[infoIndex].Arch)
- return &infomap[infoIndex];
+ for (infoIndex = 0; triplemap[infoIndex].String != NULL; ++infoIndex) {
+ if (arch == triplemap[infoIndex].Arch)
+ return triplemap[infoIndex].String;
}
return NULL;
@@ -95,23 +95,25 @@ static int getLLVMSyntaxVariant(Triple::ArchType arch,
return 1;
else
return -1;
+ case kEDAssemblySyntaxARMUAL:
+ if (arch == Triple::arm || arch == Triple::thumb)
+ return 0;
+ else
+ return -1;
}
}
-#define BRINGUP_TARGET(tgt) \
- LLVMInitialize##tgt##TargetInfo(); \
- LLVMInitialize##tgt##Target(); \
- LLVMInitialize##tgt##AsmPrinter(); \
- LLVMInitialize##tgt##AsmParser(); \
- LLVMInitialize##tgt##Disassembler();
-
void EDDisassembler::initialize() {
if (sInitialized)
return;
sInitialized = true;
- BRINGUP_TARGET(X86)
+ InitializeAllTargetInfos();
+ InitializeAllTargets();
+ InitializeAllAsmPrinters();
+ InitializeAllAsmParsers();
+ InitializeAllDisassemblers();
}
#undef BRINGUP_TARGET
@@ -126,10 +128,9 @@ EDDisassembler *EDDisassembler::getDisassembler(Triple::ArchType arch,
if (i != sDisassemblers.end()) {
return i->second;
- }
- else {
+ } else {
EDDisassembler* sdd = new EDDisassembler(key);
- if(!sdd->valid()) {
+ if (!sdd->valid()) {
delete sdd;
return NULL;
}
@@ -150,17 +151,18 @@ EDDisassembler *EDDisassembler::getDisassembler(StringRef str,
}
EDDisassembler::EDDisassembler(CPUKey &key) :
- Valid(false), ErrorString(), ErrorStream(ErrorString), Key(key) {
- const InfoMap *infoMap = infoFromArch(key.Arch);
-
- if (!infoMap)
+ Valid(false),
+ HasSemantics(false),
+ ErrorStream(nulls()),
+ Key(key) {
+ const char *triple = tripleFromArch(key.Arch);
+
+ if (!triple)
return;
- const char *triple = infoMap->String;
-
- int syntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
+ LLVMSyntaxVariant = getLLVMSyntaxVariant(key.Arch, key.Syntax);
- if (syntaxVariant < 0)
+ if (LLVMSyntaxVariant < 0)
return;
std::string tripleString(triple);
@@ -182,6 +184,8 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
if (!registerInfo)
return;
+
+ initMaps(*registerInfo);
AsmInfo.reset(Tgt->createAsmInfo(tripleString));
@@ -192,10 +196,12 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
if (!Disassembler)
return;
+
+ InstInfos = Disassembler->getEDInfo();
InstString.reset(new std::string);
InstStream.reset(new raw_string_ostream(*InstString));
- InstPrinter.reset(Tgt->createMCInstPrinter(syntaxVariant, *AsmInfo));
+ InstPrinter.reset(Tgt->createMCInstPrinter(LLVMSyntaxVariant, *AsmInfo));
if (!InstPrinter)
return;
@@ -203,8 +209,6 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
GenericAsmLexer.reset(new AsmLexer(*AsmInfo));
SpecificAsmLexer.reset(Tgt->createAsmLexer(*AsmInfo));
SpecificAsmLexer->InstallLexer(*GenericAsmLexer);
-
- InstInfos = infoMap->Info;
initMaps(*targetMachine->getRegisterInfo());
@@ -212,7 +216,7 @@ EDDisassembler::EDDisassembler(CPUKey &key) :
}
EDDisassembler::~EDDisassembler() {
- if(!valid())
+ if (!valid())
return;
}
@@ -230,10 +234,10 @@ namespace {
uint64_t getBase() const { return 0x0; }
uint64_t getExtent() const { return (uint64_t)-1; }
int readByte(uint64_t address, uint8_t *ptr) const {
- if(!Callback)
+ if (!Callback)
return -1;
- if(Callback(ptr, address, Arg))
+ if (Callback(ptr, address, Arg))
return -1;
return 0;
@@ -256,9 +260,10 @@ EDInst *EDDisassembler::createInst(EDByteReaderCallback byteReader,
ErrorStream)) {
delete inst;
return NULL;
- }
- else {
- const InstInfo *thisInstInfo = &InstInfos[inst->getOpcode()];
+ } else {
+ const llvm::EDInstInfo *thisInstInfo;
+
+ thisInstInfo = &InstInfos[inst->getOpcode()];
EDInst* sdInst = new EDInst(inst, byteSize, *this, thisInstInfo);
return sdInst;
@@ -276,8 +281,11 @@ void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
RegRMap[registerName] = registerIndex;
}
- if (Key.Arch == Triple::x86 ||
- Key.Arch == Triple::x86_64) {
+ switch (Key.Arch) {
+ default:
+ break;
+ case Triple::x86:
+ case Triple::x86_64:
stackPointers.insert(registerIDWithName("SP"));
stackPointers.insert(registerIDWithName("ESP"));
stackPointers.insert(registerIDWithName("RSP"));
@@ -285,6 +293,13 @@ void EDDisassembler::initMaps(const TargetRegisterInfo &registerInfo) {
programCounters.insert(registerIDWithName("IP"));
programCounters.insert(registerIDWithName("EIP"));
programCounters.insert(registerIDWithName("RIP"));
+ break;
+ case Triple::arm:
+ case Triple::thumb:
+ stackPointers.insert(registerIDWithName("SP"));
+
+ programCounters.insert(registerIDWithName("PC"));
+ break;
}
}
@@ -329,6 +344,16 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
const std::string &str) {
int ret = 0;
+ switch (Key.Arch) {
+ default:
+ return -1;
+ case Triple::x86:
+ case Triple::x86_64:
+ case Triple::arm:
+ case Triple::thumb:
+ break;
+ }
+
const char *cStr = str.c_str();
MemoryBuffer *buf = MemoryBuffer::getMemBuffer(cStr, cStr + strlen(cStr));
@@ -343,14 +368,16 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands,
OwningPtr<TargetAsmParser> TargetParser(Tgt->createAsmParser(genericParser));
AsmToken OpcodeToken = genericParser.Lex();
-
- if(OpcodeToken.is(AsmToken::Identifier)) {
+ AsmToken NextToken = genericParser.Lex(); // consume next token, because specificParser expects us to
+
+ if (OpcodeToken.is(AsmToken::Identifier)) {
instName = OpcodeToken.getString();
instLoc = OpcodeToken.getLoc();
- if (TargetParser->ParseInstruction(instName, instLoc, operands))
+
+ if (NextToken.isNot(AsmToken::Eof) &&
+ TargetParser->ParseInstruction(instName, instLoc, operands))
ret = -1;
- }
- else {
+ } else {
ret = -1;
}
diff --git a/tools/edis/EDDisassembler.h b/tools/edis/EDDisassembler.h
index 6be9152facb68..74a260e82532b 100644
--- a/tools/edis/EDDisassembler.h
+++ b/tools/edis/EDDisassembler.h
@@ -48,6 +48,8 @@ template <typename T> class SmallVectorImpl;
class SourceMgr;
class Target;
class TargetRegisterInfo;
+
+struct EDInstInfo;
}
/// EDDisassembler - Encapsulates a disassembler for a single architecture and
@@ -113,13 +115,13 @@ struct EDDisassembler {
// Per-object members //
////////////////////////
- /// True only if the object has been fully and successfully initialized
+ /// True only if the object has been successfully initialized
bool Valid;
+ /// True if the disassembler can provide semantic information
+ bool HasSemantics;
- /// The string that stores disassembler errors from the backend
- std::string ErrorString;
- /// The stream that wraps the ErrorString
- llvm::raw_string_ostream ErrorStream;
+ /// The stream to write errors to
+ llvm::raw_ostream &ErrorStream;
/// The architecture/syntax pair for the current architecture
CPUKey Key;
@@ -143,7 +145,7 @@ struct EDDisassembler {
llvm::sys::Mutex PrinterMutex;
/// The array of instruction information provided by the TableGen backend for
/// the target architecture
- const InstInfo *InstInfos;
+ const llvm::EDInstInfo *InstInfos;
/// The target-specific lexer for use in tokenizing strings, in
/// target-independent and target-specific portions
llvm::OwningPtr<llvm::AsmLexer> GenericAsmLexer;
@@ -180,6 +182,12 @@ struct EDDisassembler {
return Valid;
}
+ /// hasSemantics - reports whether the disassembler can provide operands and
+ /// tokens.
+ bool hasSemantics() {
+ return HasSemantics;
+ }
+
~EDDisassembler();
/// createInst - creates and returns an instruction given a callback and
diff --git a/tools/edis/EDInfo.td b/tools/edis/EDInfo.td
new file mode 100644
index 0000000000000..bd9ec079d80d4
--- /dev/null
+++ b/tools/edis/EDInfo.td
@@ -0,0 +1 @@
+// Intentionally empty.
diff --git a/tools/edis/EDInst.cpp b/tools/edis/EDInst.cpp
index 9ed27002ad579..af3a54abbcf0b 100644
--- a/tools/edis/EDInst.cpp
+++ b/tools/edis/EDInst.cpp
@@ -18,6 +18,7 @@
#include "EDOperand.h"
#include "EDToken.h"
+#include "llvm/MC/EDInstInfo.h"
#include "llvm/MC/MCInst.h"
using namespace llvm;
@@ -25,7 +26,7 @@ using namespace llvm;
EDInst::EDInst(llvm::MCInst *inst,
uint64_t byteSize,
EDDisassembler &disassembler,
- const InstInfo *info) :
+ const llvm::EDInstInfo *info) :
Disassembler(disassembler),
Inst(inst),
ThisInstInfo(info),
@@ -33,6 +34,7 @@ EDInst::EDInst(llvm::MCInst *inst,
BranchTarget(-1),
MoveSource(-1),
MoveTarget(-1) {
+ OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
}
EDInst::~EDInst() {
@@ -60,8 +62,6 @@ int EDInst::stringify() {
if (Disassembler.printInst(String, *Inst))
return StringifyResult.setResult(-1);
-
- OperandOrder = ThisInstInfo->operandOrders[Disassembler.llvmSyntaxVariant()];
return StringifyResult.setResult(0);
}
@@ -81,21 +81,21 @@ unsigned EDInst::instID() {
bool EDInst::isBranch() {
if (ThisInstInfo)
- return ThisInstInfo->instructionFlags & kInstructionFlagBranch;
+ return ThisInstInfo->instructionType == kInstructionTypeBranch;
else
return false;
}
bool EDInst::isMove() {
if (ThisInstInfo)
- return ThisInstInfo->instructionFlags & kInstructionFlagMove;
+ return ThisInstInfo->instructionType == kInstructionTypeMove;
else
return false;
}
int EDInst::parseOperands() {
if (ParseResult.valid())
- return ParseResult.result();
+ return ParseResult.result();
if (!ThisInstInfo)
return ParseResult.setResult(-1);
diff --git a/tools/edis/EDInst.h b/tools/edis/EDInst.h
index db03a7852eef7..c8a747ff99f9b 100644
--- a/tools/edis/EDInst.h
+++ b/tools/edis/EDInst.h
@@ -23,6 +23,10 @@
#include <string>
#include <vector>
+namespace llvm {
+ struct EDInstInfo;
+}
+
/// CachedResult - Encapsulates the result of a function along with the validity
/// of that result, so that slow functions don't need to run twice
struct CachedResult {
@@ -54,7 +58,7 @@ struct EDInst {
/// The containing MCInst
llvm::MCInst *Inst;
/// The instruction information provided by TableGen for this instruction
- const InstInfo *ThisInstInfo;
+ const llvm::EDInstInfo *ThisInstInfo;
/// The number of bytes for the machine code representation of the instruction
uint64_t ByteSize;
@@ -95,7 +99,7 @@ struct EDInst {
EDInst(llvm::MCInst *inst,
uint64_t byteSize,
EDDisassembler &disassembler,
- const InstInfo *instInfo);
+ const llvm::EDInstInfo *instInfo);
~EDInst();
/// byteSize - returns the number of bytes consumed by the machine code
diff --git a/tools/edis/EDMain.cpp b/tools/edis/EDMain.cpp
index 3585657ca62da..b6ca32f2db869 100644
--- a/tools/edis/EDMain.cpp
+++ b/tools/edis/EDMain.cpp
@@ -29,8 +29,7 @@ int EDGetDisassembler(EDDisassemblerRef *disassembler,
if (ret) {
*disassembler = ret;
return 0;
- }
- else {
+ } else {
return -1;
}
}
@@ -39,7 +38,7 @@ int EDGetRegisterName(const char** regName,
EDDisassemblerRef disassembler,
unsigned regID) {
const char* name = disassembler->nameWithRegisterID(regID);
- if(!name)
+ if (!name)
return -1;
*regName = name;
return 0;
@@ -63,10 +62,10 @@ unsigned int EDCreateInsts(EDInstRef *insts,
void *arg) {
unsigned int index;
- for (index = 0; index < count; index++) {
+ for (index = 0; index < count; ++index) {
EDInst *inst = disassembler->createInst(byteReader, address, arg);
- if(!inst)
+ if (!inst)
return index;
insts[index] = inst;
@@ -134,42 +133,42 @@ int EDOperandIndexForToken(EDTokenRef token) {
}
int EDTokenIsWhitespace(EDTokenRef token) {
- if(token->type() == EDToken::kTokenWhitespace)
+ if (token->type() == EDToken::kTokenWhitespace)
return 1;
else
return 0;
}
int EDTokenIsPunctuation(EDTokenRef token) {
- if(token->type() == EDToken::kTokenPunctuation)
+ if (token->type() == EDToken::kTokenPunctuation)
return 1;
else
return 0;
}
int EDTokenIsOpcode(EDTokenRef token) {
- if(token->type() == EDToken::kTokenOpcode)
+ if (token->type() == EDToken::kTokenOpcode)
return 1;
else
return 0;
}
int EDTokenIsLiteral(EDTokenRef token) {
- if(token->type() == EDToken::kTokenLiteral)
+ if (token->type() == EDToken::kTokenLiteral)
return 1;
else
return 0;
}
int EDTokenIsRegister(EDTokenRef token) {
- if(token->type() == EDToken::kTokenRegister)
+ if (token->type() == EDToken::kTokenRegister)
return 1;
else
return 0;
}
int EDTokenIsNegativeLiteral(EDTokenRef token) {
- if(token->type() != EDToken::kTokenLiteral)
+ if (token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalSign();
@@ -177,7 +176,7 @@ int EDTokenIsNegativeLiteral(EDTokenRef token) {
int EDLiteralTokenAbsoluteValue(uint64_t *value,
EDTokenRef token) {
- if(token->type() != EDToken::kTokenLiteral)
+ if (token->type() != EDToken::kTokenLiteral)
return -1;
return token->literalAbsoluteValue(*value);
@@ -185,7 +184,7 @@ int EDLiteralTokenAbsoluteValue(uint64_t *value,
int EDRegisterTokenValue(unsigned *registerID,
EDTokenRef token) {
- if(token->type() != EDToken::kTokenRegister)
+ if (token->type() != EDToken::kTokenRegister)
return -1;
return token->registerID(*registerID);
@@ -215,7 +214,7 @@ int EDOperandIsMemory(EDOperandRef operand) {
int EDRegisterOperandValue(unsigned *value,
EDOperandRef operand) {
- if(!operand->isRegister())
+ if (!operand->isRegister())
return -1;
*value = operand->regVal();
return 0;
@@ -223,7 +222,7 @@ int EDRegisterOperandValue(unsigned *value,
int EDImmediateOperandValue(uint64_t *value,
EDOperandRef operand) {
- if(!operand->isImmediate())
+ if (!operand->isImmediate())
return -1;
*value = operand->immediateVal();
return 0;
diff --git a/tools/edis/EDOperand.cpp b/tools/edis/EDOperand.cpp
index da6797e035d82..d63c1c6bfbf93 100644
--- a/tools/edis/EDOperand.cpp
+++ b/tools/edis/EDOperand.cpp
@@ -17,6 +17,7 @@
#include "EDInst.h"
#include "EDOperand.h"
+#include "llvm/MC/EDInstInfo.h"
#include "llvm/MC/MCInst.h"
using namespace llvm;
@@ -31,26 +32,77 @@ EDOperand::EDOperand(const EDDisassembler &disassembler,
MCOpIndex(mcOpIndex) {
unsigned int numMCOperands = 0;
- if(Disassembler.Key.Arch == Triple::x86 ||
- Disassembler.Key.Arch == Triple::x86_64) {
- uint8_t operandFlags = inst.ThisInstInfo->operandFlags[opIndex];
+ if (Disassembler.Key.Arch == Triple::x86 ||
+ Disassembler.Key.Arch == Triple::x86_64) {
+ uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
- if (operandFlags & kOperandFlagImmediate) {
+ switch (operandType) {
+ default:
+ break;
+ case kOperandTypeImmediate:
numMCOperands = 1;
- }
- else if (operandFlags & kOperandFlagRegister) {
+ break;
+ case kOperandTypeRegister:
numMCOperands = 1;
+ break;
+ case kOperandTypeX86Memory:
+ numMCOperands = 5;
+ break;
+ case kOperandTypeX86EffectiveAddress:
+ numMCOperands = 4;
+ break;
+ case kOperandTypeX86PCRelative:
+ numMCOperands = 1;
+ break;
}
- else if (operandFlags & kOperandFlagMemory) {
- if (operandFlags & kOperandFlagPCRelative) {
- numMCOperands = 1;
- }
- else {
- numMCOperands = 5;
- }
- }
- else if (operandFlags & kOperandFlagEffectiveAddress) {
+ }
+ else if (Disassembler.Key.Arch == Triple::arm ||
+ Disassembler.Key.Arch == Triple::thumb) {
+ uint8_t operandType = inst.ThisInstInfo->operandTypes[opIndex];
+
+ switch (operandType) {
+ default:
+ case kOperandTypeARMRegisterList:
+ break;
+ case kOperandTypeImmediate:
+ case kOperandTypeRegister:
+ case kOperandTypeARMBranchTarget:
+ case kOperandTypeARMSoImm:
+ case kOperandTypeThumb2SoImm:
+ case kOperandTypeARMSoImm2Part:
+ case kOperandTypeARMPredicate:
+ case kOperandTypeThumbITMask:
+ case kOperandTypeThumb2AddrModeImm8Offset:
+ case kOperandTypeARMTBAddrMode:
+ case kOperandTypeThumb2AddrModeImm8s4Offset:
+ numMCOperands = 1;
+ break;
+ case kOperandTypeThumb2SoReg:
+ case kOperandTypeARMAddrMode2Offset:
+ case kOperandTypeARMAddrMode3Offset:
+ case kOperandTypeARMAddrMode4:
+ case kOperandTypeARMAddrMode5:
+ case kOperandTypeARMAddrModePC:
+ case kOperandTypeThumb2AddrModeImm8:
+ case kOperandTypeThumb2AddrModeImm12:
+ case kOperandTypeThumb2AddrModeImm8s4:
+ case kOperandTypeThumbAddrModeRR:
+ case kOperandTypeThumbAddrModeSP:
+ numMCOperands = 2;
+ break;
+ case kOperandTypeARMSoReg:
+ case kOperandTypeARMAddrMode2:
+ case kOperandTypeARMAddrMode3:
+ case kOperandTypeThumb2AddrModeSoReg:
+ case kOperandTypeThumbAddrModeS1:
+ case kOperandTypeThumbAddrModeS2:
+ case kOperandTypeThumbAddrModeS4:
+ case kOperandTypeARMAddrMode6Offset:
+ numMCOperands = 3;
+ break;
+ case kOperandTypeARMAddrMode6:
numMCOperands = 4;
+ break;
}
}
@@ -63,70 +115,103 @@ EDOperand::~EDOperand() {
int EDOperand::evaluate(uint64_t &result,
EDRegisterReaderCallback callback,
void *arg) {
- if (Disassembler.Key.Arch == Triple::x86 ||
- Disassembler.Key.Arch == Triple::x86_64) {
- uint8_t operandFlags = Inst.ThisInstInfo->operandFlags[OpIndex];
-
- if (operandFlags & kOperandFlagImmediate) {
+ uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
+
+ switch (Disassembler.Key.Arch) {
+ default:
+ return -1;
+ case Triple::x86:
+ case Triple::x86_64:
+ switch (operandType) {
+ default:
+ return -1;
+ case kOperandTypeImmediate:
result = Inst.Inst->getOperand(MCOpIndex).getImm();
return 0;
- }
- if (operandFlags & kOperandFlagRegister) {
+ case kOperandTypeRegister:
+ {
unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
return callback(&result, reg, arg);
}
- if (operandFlags & kOperandFlagMemory ||
- operandFlags & kOperandFlagEffectiveAddress){
- if(operandFlags & kOperandFlagPCRelative) {
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+ case kOperandTypeX86PCRelative:
+ {
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
- uint64_t ripVal;
+ uint64_t ripVal;
- // TODO fix how we do this
+ // TODO fix how we do this
- if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
- return -1;
+ if (callback(&ripVal, Disassembler.registerIDWithName("RIP"), arg))
+ return -1;
- result = ripVal + displacement;
- return 0;
- }
- else {
- unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
- uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
- unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
- int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
- //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
+ result = ripVal + displacement;
+ return 0;
+ }
+ case kOperandTypeX86Memory:
+ case kOperandTypeX86EffectiveAddress:
+ {
+ unsigned baseReg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ uint64_t scaleAmount = Inst.Inst->getOperand(MCOpIndex+1).getImm();
+ unsigned indexReg = Inst.Inst->getOperand(MCOpIndex+2).getReg();
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex+3).getImm();
+ //unsigned segmentReg = Inst.Inst->getOperand(MCOpIndex+4).getReg();
- uint64_t addr = 0;
+ uint64_t addr = 0;
- if(baseReg) {
- uint64_t baseVal;
- if (callback(&baseVal, baseReg, arg))
- return -1;
- addr += baseVal;
- }
-
- if(indexReg) {
- uint64_t indexVal;
- if (callback(&indexVal, indexReg, arg))
- return -1;
- addr += (scaleAmount * indexVal);
- }
-
- addr += displacement;
+ if (baseReg) {
+ uint64_t baseVal;
+ if (callback(&baseVal, baseReg, arg))
+ return -1;
+ addr += baseVal;
+ }
- result = addr;
- return 0;
+ if (indexReg) {
+ uint64_t indexVal;
+ if (callback(&indexVal, indexReg, arg))
+ return -1;
+ addr += (scaleAmount * indexVal);
}
+
+ addr += displacement;
+
+ result = addr;
+ return 0;
+ }
+ }
+ break;
+ case Triple::arm:
+ case Triple::thumb:
+ switch (operandType) {
+ default:
+ return -1;
+ case kOperandTypeImmediate:
+ result = Inst.Inst->getOperand(MCOpIndex).getImm();
+ return 0;
+ case kOperandTypeRegister:
+ {
+ unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg();
+ return callback(&result, reg, arg);
+ }
+ case kOperandTypeARMBranchTarget:
+ {
+ int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm();
+
+ uint64_t pcVal;
+
+ if (callback(&pcVal, Disassembler.registerIDWithName("PC"), arg))
+ return -1;
+
+ result = pcVal + displacement;
+ return 0;
+ }
}
- return -1;
}
return -1;
}
int EDOperand::isRegister() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagRegister);
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeRegister);
}
unsigned EDOperand::regVal() {
@@ -134,7 +219,7 @@ unsigned EDOperand::regVal() {
}
int EDOperand::isImmediate() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagImmediate);
+ return(Inst.ThisInstInfo->operandFlags[OpIndex] == kOperandTypeImmediate);
}
uint64_t EDOperand::immediateVal() {
@@ -142,7 +227,38 @@ uint64_t EDOperand::immediateVal() {
}
int EDOperand::isMemory() {
- return(Inst.ThisInstInfo->operandFlags[OpIndex] & kOperandFlagMemory);
+ uint8_t operandType = Inst.ThisInstInfo->operandTypes[OpIndex];
+
+ switch (operandType) {
+ default:
+ return 0;
+ case kOperandTypeX86Memory:
+ case kOperandTypeX86PCRelative:
+ case kOperandTypeX86EffectiveAddress:
+ case kOperandTypeARMSoReg:
+ case kOperandTypeARMSoImm:
+ case kOperandTypeARMAddrMode2:
+ case kOperandTypeARMAddrMode2Offset:
+ case kOperandTypeARMAddrMode3:
+ case kOperandTypeARMAddrMode3Offset:
+ case kOperandTypeARMAddrMode4:
+ case kOperandTypeARMAddrMode5:
+ case kOperandTypeARMAddrMode6:
+ case kOperandTypeARMAddrModePC:
+ case kOperandTypeARMBranchTarget:
+ case kOperandTypeThumbAddrModeS1:
+ case kOperandTypeThumbAddrModeS2:
+ case kOperandTypeThumbAddrModeS4:
+ case kOperandTypeThumbAddrModeRR:
+ case kOperandTypeThumbAddrModeSP:
+ case kOperandTypeThumb2SoImm:
+ case kOperandTypeThumb2AddrModeImm8:
+ case kOperandTypeThumb2AddrModeImm8Offset:
+ case kOperandTypeThumb2AddrModeImm12:
+ case kOperandTypeThumb2AddrModeSoReg:
+ case kOperandTypeThumb2AddrModeImm8s4:
+ return 1;
+ }
}
#ifdef __BLOCKS__
diff --git a/tools/edis/EDToken.cpp b/tools/edis/EDToken.cpp
index cd79152e35946..3bcb0a14b8c42 100644
--- a/tools/edis/EDToken.cpp
+++ b/tools/edis/EDToken.cpp
@@ -68,20 +68,20 @@ int EDToken::operandID() const {
}
int EDToken::literalSign() const {
- if(Type != kTokenLiteral)
+ if (Type != kTokenLiteral)
return -1;
return (LiteralSign ? 1 : 0);
}
int EDToken::literalAbsoluteValue(uint64_t &value) const {
- if(Type != kTokenLiteral)
+ if (Type != kTokenLiteral)
return -1;
value = LiteralAbsoluteValue;
return 0;
}
int EDToken::registerID(unsigned &registerID) const {
- if(Type != kTokenRegister)
+ if (Type != kTokenRegister)
return -1;
registerID = RegisterID;
return 0;
@@ -94,7 +94,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
SmallVector<MCParsedAsmOperand*, 5> parsedOperands;
SmallVector<AsmToken, 10> asmTokens;
- if(disassembler.parseInst(parsedOperands, asmTokens, str))
+ if (disassembler.parseInst(parsedOperands, asmTokens, str))
return -1;
SmallVectorImpl<MCParsedAsmOperand*>::iterator operandIterator;
@@ -115,7 +115,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
const char *tokenPointer = tokenLoc.getPointer();
- if(tokenPointer > wsPointer) {
+ if (tokenPointer > wsPointer) {
unsigned long wsLength = tokenPointer - wsPointer;
EDToken *whitespaceToken = new EDToken(StringRef(wsPointer, wsLength),
@@ -164,7 +164,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
int64_t intVal = tokenIterator->getIntVal();
- if(intVal < 0)
+ if (intVal < 0)
token->makeLiteral(true, -intVal);
else
token->makeLiteral(false, intVal);
@@ -182,14 +182,14 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
}
}
- if(operandIterator != parsedOperands.end() &&
+ if (operandIterator != parsedOperands.end() &&
tokenLoc.getPointer() >=
(*operandIterator)->getStartLoc().getPointer()) {
/// operandIndex == 0 means the operand is the instruction (which the
/// AsmParser treats as an operand but edis does not). We therefore skip
/// operandIndex == 0 and subtract 1 from all other operand indices.
- if(operandIndex > 0)
+ if (operandIndex > 0)
token->setOperandID(operandOrder[operandIndex - 1]);
}
@@ -200,7 +200,7 @@ int EDToken::tokenize(std::vector<EDToken*> &tokens,
}
int EDToken::getString(const char*& buf) {
- if(PermStr.length() == 0) {
+ if (PermStr.length() == 0) {
PermStr = Str.str();
}
buf = PermStr.c_str();
diff --git a/tools/edis/EnhancedDisassembly.exports b/tools/edis/EnhancedDisassembly.exports
index d3f87435cc3d4..7050f7f329481 100644
--- a/tools/edis/EnhancedDisassembly.exports
+++ b/tools/edis/EnhancedDisassembly.exports
@@ -1,36 +1,36 @@
-_EDGetDisassembler
-_EDGetRegisterName
-_EDRegisterIsStackPointer
-_EDRegisterIsProgramCounter
-_EDCreateInsts
-_EDReleaseInst
-_EDInstByteSize
-_EDGetInstString
-_EDInstIsBranch
-_EDInstIsMove
-_EDBranchTargetID
-_EDMoveSourceID
-_EDMoveTargetID
-_EDNumTokens
-_EDGetToken
-_EDGetTokenString
-_EDOperandIndexForToken
-_EDTokenIsWhitespace
-_EDTokenIsPunctuation
-_EDTokenIsOpcode
-_EDTokenIsLiteral
-_EDTokenIsRegister
-_EDTokenIsNegativeLiteral
-_EDLiteralTokenAbsoluteValue
-_EDRegisterTokenValue
-_EDNumOperands
-_EDGetOperand
-_EDOperandIsRegister
-_EDOperandIsImmediate
-_EDOperandIsMemory
-_EDRegisterOperandValue
-_EDImmediateOperandValue
-_EDEvaluateOperand
-_EDBlockCreateInsts
-_EDBlockEvaluateOperand
-_EDBlockVisitTokens
+EDGetDisassembler
+EDGetRegisterName
+EDRegisterIsStackPointer
+EDRegisterIsProgramCounter
+EDCreateInsts
+EDReleaseInst
+EDInstByteSize
+EDGetInstString
+EDInstIsBranch
+EDInstIsMove
+EDBranchTargetID
+EDMoveSourceID
+EDMoveTargetID
+EDNumTokens
+EDGetToken
+EDGetTokenString
+EDOperandIndexForToken
+EDTokenIsWhitespace
+EDTokenIsPunctuation
+EDTokenIsOpcode
+EDTokenIsLiteral
+EDTokenIsRegister
+EDTokenIsNegativeLiteral
+EDLiteralTokenAbsoluteValue
+EDRegisterTokenValue
+EDNumOperands
+EDGetOperand
+EDOperandIsRegister
+EDOperandIsImmediate
+EDOperandIsMemory
+EDRegisterOperandValue
+EDImmediateOperandValue
+EDEvaluateOperand
+EDBlockCreateInsts
+EDBlockEvaluateOperand
+EDBlockVisitTokens
diff --git a/tools/edis/Makefile b/tools/edis/Makefile
index 7f7b097e2ce37..9151f627bb0cc 100644
--- a/tools/edis/Makefile
+++ b/tools/edis/Makefile
@@ -12,13 +12,19 @@ LIBRARYNAME = EnhancedDisassembly
BUILT_SOURCES = EDInfo.inc
+EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/EnhancedDisassembly.exports
+
# Include this here so we can get the configuration of the targets
# that have been configured for construction. We have to do this
# early so we can set up LINK_COMPONENTS before including Makefile.rules
include $(LEVEL)/Makefile.config
-LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
+ifeq ($(ENABLE_PIC),1)
+ ifneq ($(TARGET_OS), $(filter $(TARGET_OS), Cygwin MingW))
+ LINK_LIBS_IN_SHARED = 1
+ SHARED_LIBRARY = 1
+ endif
+endif
LINK_COMPONENTS := $(TARGETS_TO_BUILD) x86asmprinter x86disassembler
@@ -28,11 +34,10 @@ ifeq ($(HOST_OS),Darwin)
# extra options to override libtool defaults
LLVMLibsOptions := $(LLVMLibsOptions) \
-avoid-version \
- -Wl,-exported_symbols_list -Wl,$(PROJ_SRC_DIR)/EnhancedDisassembly.exports \
-Wl,-dead_strip
ifdef EDIS_VERSION
- LLVMLibsOptions := -Wl,-current_version -Wl,$(EDIS_VERSION) \
+ LLVMLibsOptions := $(LLVMLibsOptions) -Wl,-current_version -Wl,$(EDIS_VERSION) \
-Wl,-compatibility_version -Wl,1
endif