diff options
Diffstat (limited to 'lib/MC/MCDisassembler')
-rw-r--r-- | lib/MC/MCDisassembler/Disassembler.cpp | 50 | ||||
-rw-r--r-- | lib/MC/MCDisassembler/Disassembler.h | 8 | ||||
-rw-r--r-- | lib/MC/MCDisassembler/EDDisassembler.cpp | 10 | ||||
-rw-r--r-- | lib/MC/MCDisassembler/EDOperand.cpp | 9 |
4 files changed, 45 insertions, 32 deletions
diff --git a/lib/MC/MCDisassembler/Disassembler.cpp b/lib/MC/MCDisassembler/Disassembler.cpp index 4707198..6e636f0 100644 --- a/lib/MC/MCDisassembler/Disassembler.cpp +++ b/lib/MC/MCDisassembler/Disassembler.cpp @@ -6,11 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// + #include "Disassembler.h" -#include <stdio.h> #include "llvm-c/Disassembler.h" -#include <string> #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDisassembler.h" #include "llvm/MC/MCInst.h" @@ -27,17 +26,12 @@ class Target; } // namespace llvm using namespace llvm; -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// // LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic // disassembly is supported by passing a block of information in the DisInfo -// parameter and specifing the TagType and call back functions as described in +// parameter and specifying the TagType and callback functions as described in // the header llvm-c/Disassembler.h . The pointer to the block and the -// functions can all be passed as NULL. If successfull this returns a -// disassembler context if not it returns NULL. +// functions can all be passed as NULL. If successful, this returns a +// disassembler context. If not, it returns NULL. // LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, @@ -77,8 +71,9 @@ LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, assert(Ctx && "Unable to create MCContext!"); // Set up disassembler. - const MCDisassembler *DisAsm = TheTarget->createMCDisassembler(); + MCDisassembler *DisAsm = TheTarget->createMCDisassembler(); assert(DisAsm && "Unable to create disassembler!"); + DisAsm->setupForSymbolicDisassembly(GetOpInfo, DisInfo, Ctx); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); @@ -107,7 +102,6 @@ namespace { // The memory object created by LLVMDisasmInstruction(). // class DisasmMemoryObject : public MemoryObject { -private: uint8_t *Bytes; uint64_t Size; uint64_t BasePC; @@ -125,12 +119,12 @@ public: return 0; } }; -} // namespace +} // end anonymous namespace // -// LLVMDisasmInstruction() disassmbles a single instruction using the +// LLVMDisasmInstruction() disassembles a single instruction using the // disassembler context specified in the parameter DC. The bytes of the -// instuction are specified in the parameter Bytes, and contains at least +// instruction are specified in the parameter Bytes, and contains at least // BytesSize number of bytes. The instruction is at the address specified by // the PC parameter. If a valid instruction can be disassembled its string is // returned indirectly in OutString which whos size is specified in the @@ -153,21 +147,15 @@ size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, if (!DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls())) return 0; - std::string InsnStr; - raw_string_ostream OS(InsnStr); - raw_ostream &Out = OS; - IP->printInst(&Inst, Out); - - std::string p; - p = OS.str(); -#ifdef LLVM_ON_WIN32 - sprintf(OutString, "%s", p.c_str()); -#else - snprintf(OutString, OutStringSize, "%s", p.c_str()); -#endif - return Size; -} + SmallVector<char, 64> InsnStr; + raw_svector_ostream OS(InsnStr); + IP->printInst(&Inst, OS); + OS.flush(); + + assert(OutStringSize != 0 && "Output buffer cannot be zero size"); + size_t OutputSize = std::min(OutStringSize-1, InsnStr.size()); + std::memcpy(OutString, InsnStr.data(), OutputSize); + OutString[OutputSize] = '\0'; // Terminate string. -#ifdef __cplusplus + return Size; } -#endif // __cplusplus diff --git a/lib/MC/MCDisassembler/Disassembler.h b/lib/MC/MCDisassembler/Disassembler.h index f844951..f0ec42a 100644 --- a/lib/MC/MCDisassembler/Disassembler.h +++ b/lib/MC/MCDisassembler/Disassembler.h @@ -13,6 +13,10 @@ // syntax. // //===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_DISASSEMBLER_H +#define LLVM_MC_DISASSEMBLER_H + #include "llvm-c/Disassembler.h" #include <string> #include "llvm/ADT/OwningPtr.h" @@ -69,7 +73,7 @@ private: public: LLVMDisasmContext(std::string tripleName, void *disInfo, int tagType, - LLVMOpInfoCallback getOpInfo, + LLVMOpInfoCallback getOpInfo, LLVMSymbolLookupCallback symbolLookUp, const Target *theTarget, const MCAsmInfo *mAI, llvm::TargetMachine *tM, const TargetAsmInfo *tai, @@ -88,3 +92,5 @@ public: }; } // namespace llvm + +#endif diff --git a/lib/MC/MCDisassembler/EDDisassembler.cpp b/lib/MC/MCDisassembler/EDDisassembler.cpp index e36b3a4..91c5284 100644 --- a/lib/MC/MCDisassembler/EDDisassembler.cpp +++ b/lib/MC/MCDisassembler/EDDisassembler.cpp @@ -334,6 +334,15 @@ int EDDisassembler::printInst(std::string &str, MCInst &inst) { return 0; } +static void diag_handler(const SMDiagnostic &diag, + void *context) +{ + if (context) { + EDDisassembler *disassembler = static_cast<EDDisassembler*>(context); + diag.Print("", disassembler->ErrorStream); + } +} + int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, SmallVectorImpl<AsmToken> &tokens, const std::string &str) { @@ -356,6 +365,7 @@ int EDDisassembler::parseInst(SmallVectorImpl<MCParsedAsmOperand*> &operands, SMLoc instLoc; SourceMgr sourceMgr; + sourceMgr.setDiagHandler(diag_handler, static_cast<void*>(this)); sourceMgr.AddNewSourceBuffer(buf, SMLoc()); // ownership of buf handed over MCContext context(*AsmInfo, NULL); OwningPtr<MCStreamer> streamer(createNullStreamer(context)); diff --git a/lib/MC/MCDisassembler/EDOperand.cpp b/lib/MC/MCDisassembler/EDOperand.cpp index 04b21cb..492bb08 100644 --- a/lib/MC/MCDisassembler/EDOperand.cpp +++ b/lib/MC/MCDisassembler/EDOperand.cpp @@ -198,15 +198,24 @@ int EDOperand::evaluate(uint64_t &result, default: return -1; case kOperandTypeImmediate: + if (!Inst.Inst->getOperand(MCOpIndex).isImm()) + return -1; + result = Inst.Inst->getOperand(MCOpIndex).getImm(); return 0; case kOperandTypeRegister: { + if (!Inst.Inst->getOperand(MCOpIndex).isReg()) + return -1; + unsigned reg = Inst.Inst->getOperand(MCOpIndex).getReg(); return callback(&result, reg, arg); } case kOperandTypeARMBranchTarget: { + if (!Inst.Inst->getOperand(MCOpIndex).isImm()) + return -1; + int64_t displacement = Inst.Inst->getOperand(MCOpIndex).getImm(); uint64_t pcVal; |