diff options
Diffstat (limited to 'tools/edis')
-rw-r--r-- | tools/edis/CMakeLists.txt | 25 | ||||
-rw-r--r-- | tools/edis/EDDisassembler.cpp | 129 | ||||
-rw-r--r-- | tools/edis/EDDisassembler.h | 20 | ||||
-rw-r--r-- | tools/edis/EDInfo.td | 1 | ||||
-rw-r--r-- | tools/edis/EDInst.cpp | 12 | ||||
-rw-r--r-- | tools/edis/EDInst.h | 8 | ||||
-rw-r--r-- | tools/edis/EDMain.cpp | 29 | ||||
-rw-r--r-- | tools/edis/EDOperand.cpp | 238 | ||||
-rw-r--r-- | tools/edis/EDToken.cpp | 18 | ||||
-rw-r--r-- | tools/edis/EnhancedDisassembly.exports | 72 | ||||
-rw-r--r-- | tools/edis/Makefile | 13 |
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 ®isterInfo) { 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 ®isterInfo) { 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 ®isterID) 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 |