// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic // disassembly is supported by passing a block of information in the DisInfo // 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 successful, this returns a // disassembler context. If not, it returns NULL. // LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { // Initialize targets and assembly printers/parsers. // FIXME: Clients are responsible for initializing the targets. And this // would be done by calling routines in "llvm-c/Target.h" which are static // line functions. But the current use of LLVMCreateDisasm() is to dynamically // load libLTO with dlopen() and then lookup the symbols using dlsym(). // And since these initialize routines are static that does not work which // is why the call to them in this 'C' library API was added back. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Get the target. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); assert(TheTarget && "Unable to create target!"); // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName); assert(MAI && "Unable to create target asm info!"); const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); assert(MRI && "Unable to create target register info!"); // Package up features to be passed to target/subtarget std::string FeaturesStr; std::string CPU; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, FeaturesStr); assert(STI && "Unable to create subtarget info!"); // Set up the MCContext for creating symbols and MCExpr's. MCContext *Ctx = new MCContext(*MAI, *MRI, 0); assert(Ctx && "Unable to create MCContext!"); // Set up disassembler. MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); assert(DisAsm && "Unable to create disassembler!"); DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, Ctx); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *STI); assert(IP && "Unable to create instruction printer!"); LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, Ctx, DisAsm, IP); assert(DC && "Allocation failure!"); return DC; }
void llvmutil_disassemblefunction(void * data, size_t numBytes, size_t numInst) { InitializeNativeTargetDisassembler(); std::string Error; #if LLVM_VERSION >= 33 std::string TripleName = llvm::sys::getProcessTriple(); #else std::string TripleName = llvm::sys::getDefaultTargetTriple(); #endif std::string CPU = llvm::sys::getHostCPUName(); const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); assert(TheTarget && "Unable to create target!"); const MCAsmInfo *MAI = TheTarget->createMCAsmInfo( #if LLVM_VERSION >= 34 *TheTarget->createMCRegInfo(TripleName), #endif TripleName); assert(MAI && "Unable to create target asm info!"); const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); assert(MII && "Unable to create target instruction info!"); const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); assert(MRI && "Unable to create target register info!"); std::string FeaturesStr; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, FeaturesStr); assert(STI && "Unable to create subtarget info!"); #if LLVM_VERSION >= 35 MCContext Ctx(MAI,MRI, NULL); MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI,Ctx); #else MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); #endif assert(DisAsm && "Unable to create disassembler!"); int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI); assert(IP && "Unable to create instruction printer!"); SimpleMemoryObject SMO; uint64_t addr = (uint64_t)data; uint64_t Size; fflush(stdout); raw_fd_ostream Out(fileno(stdout), false); for(size_t i = 0, b = 0; b < numBytes || i < numInst; i++, b += Size) { MCInst Inst; MCDisassembler::DecodeStatus S = DisAsm->getInstruction(Inst, Size, SMO,addr + b, nulls(), Out); if(MCDisassembler::Fail == S || MCDisassembler::SoftFail == S) break; Out << (void*) ((uintptr_t)data + b) << "(+" << b << ")" << ":\t"; IP->printInst(&Inst,Out,""); Out << "\n"; } Out.flush(); delete MAI; delete MRI; delete STI; delete MII; delete DisAsm; delete IP; }
// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic // disassembly is supported by passing a block of information in the DisInfo // 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 successful, this returns a // disassembler context. If not, it returns NULL. // LLVMDisasmContextRef LLVMCreateDisasm(const char *TripleName, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Get the target. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); assert(TheTarget && "Unable to create target!"); // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName); assert(MAI && "Unable to create target asm info!"); const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); assert(MRI && "Unable to create target register info!"); // Package up features to be passed to target/subtarget std::string FeaturesStr; std::string CPU; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, FeaturesStr); assert(STI && "Unable to create subtarget info!"); // Set up the MCContext for creating symbols and MCExpr's. MCContext *Ctx = new MCContext(*MAI, *MRI, 0); assert(Ctx && "Unable to create MCContext!"); // Set up disassembler. MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); assert(DisAsm && "Unable to create disassembler!"); DisAsm->setupForSymbolicDisassembly(GetOpInfo, DisInfo, Ctx); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *STI); assert(IP && "Unable to create instruction printer!"); LLVMDisasmContext *DC = new LLVMDisasmContext(TripleName, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, Ctx, DisAsm, IP); assert(DC && "Allocation failure!"); return DC; }
static bool PrintInsts(const MCDisassembler &DisAsm, MCInstPrinter &Printer, const ByteArrayTy &Bytes, SourceMgr &SM) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); // Disassemble it to strings. uint64_t Size; uint64_t Index; for (Index = 0; Index < Bytes.size(); Index += Size) { MCInst Inst; if (DisAsm.getInstruction(Inst, Size, memoryObject, Index, /*REMOVE*/ nulls())) { Printer.printInst(&Inst, outs()); outs() << "\n"; } else { SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), "invalid instruction encoding", "warning"); if (Size == 0) Size = 1; // skip illegible bytes } } return false; }
void llvmutil_disassemblefunction(void * data, size_t numBytes) { InitializeNativeTargetDisassembler(); std::string Error; std::string TripleName = llvm::sys::getDefaultTargetTriple(); const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error); assert(TheTarget && "Unable to create target!"); const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(TripleName); assert(MAI && "Unable to create target asm info!"); const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); assert(MII && "Unable to create target instruction info!"); const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); assert(MRI && "Unable to create target register info!"); std::string FeaturesStr; std::string CPU; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, FeaturesStr); assert(STI && "Unable to create subtarget info!"); MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); assert(DisAsm && "Unable to create disassembler!"); int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI); assert(IP && "Unable to create instruction printer!"); printf("assembly for function at address %p\n",data); SimpleMemoryObject SMO; SMO.Bytes = (uint8_t*)data; SMO.Size = numBytes; uint64_t Size; fflush(stdout); raw_fd_ostream Out(fileno(stdout), false); for(int i = 0; i < numBytes; i += Size) { MCInst Inst; MCDisassembler::DecodeStatus S = DisAsm->getInstruction(Inst, Size, SMO, 0, nulls(), Out); if(MCDisassembler::Fail == S || MCDisassembler::SoftFail == S) break; Out << i << ":\t"; IP->printInst(&Inst,Out,""); Out << "\n"; SMO.Size -= Size; SMO.Bytes += Size; } Out.flush(); delete MAI; delete MRI; delete STI; delete MII; delete DisAsm; delete IP; }
static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, SourceMgr &SM, raw_ostream &Out, MCStreamer &Streamer, bool InAtomicBlock, const MCSubtargetInfo &STI) { ArrayRef<uint8_t> Data(Bytes.first.data(), Bytes.first.size()); // Disassemble it to strings. uint64_t Size; uint64_t Index; for (Index = 0; Index < Bytes.first.size(); Index += Size) { MCInst Inst; MCDisassembler::DecodeStatus S; S = DisAsm.getInstruction(Inst, Size, Data.slice(Index), Index, /*REMOVE*/ nulls(), nulls()); switch (S) { case MCDisassembler::Fail: SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]), SourceMgr::DK_Warning, "invalid instruction encoding"); // Don't try to resynchronise the stream in a block if (InAtomicBlock) return true; if (Size == 0) Size = 1; // skip illegible bytes break; case MCDisassembler::SoftFail: SM.PrintMessage(SMLoc::getFromPointer(Bytes.second[Index]), SourceMgr::DK_Warning, "potentially undefined instruction encoding"); LLVM_FALLTHROUGH; case MCDisassembler::Success: Streamer.EmitInstruction(Inst, STI); break; } } return false; }
static bool PrintInsts(const MCDisassembler &DisAsm, const ByteArrayTy &Bytes, SourceMgr &SM, raw_ostream &Out, MCStreamer &Streamer) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); // Disassemble it to strings. uint64_t Size; uint64_t Index; for (Index = 0; Index < Bytes.size(); Index += Size) { MCInst Inst; MCDisassembler::DecodeStatus S; S = DisAsm.getInstruction(Inst, Size, memoryObject, Index, /*REMOVE*/ nulls(), nulls()); switch (S) { case MCDisassembler::Fail: SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), SourceMgr::DK_Warning, "invalid instruction encoding"); if (Size == 0) Size = 1; // skip illegible bytes break; case MCDisassembler::SoftFail: SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), SourceMgr::DK_Warning, "potentially undefined instruction encoding"); // Fall through case MCDisassembler::Success: Streamer.EmitInstruction(Inst); break; } } return false; }
// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic // disassembly is supported by passing a block of information in the DisInfo // 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 successful, this returns a // disassembler context. If not, it returns NULL. // LLVMDisasmContextRef LLVMCreateDisasmCPU(const char *Triple, const char *CPU, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp){ // Get the target. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(Triple, Error); if (!TheTarget) return 0; const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(Triple); if (!MRI) return 0; // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, Triple); if (!MAI) return 0; const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); if (!MII) return 0; // Package up features to be passed to target/subtarget std::string FeaturesStr; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(Triple, CPU, FeaturesStr); if (!STI) return 0; // Set up the MCContext for creating symbols and MCExpr's. MCContext *Ctx = new MCContext(MAI, MRI, 0); if (!Ctx) return 0; // Set up disassembler. MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); if (!DisAsm) return 0; OwningPtr<MCRelocationInfo> RelInfo( TheTarget->createMCRelocationInfo(Triple, *Ctx)); if (!RelInfo) return 0; OwningPtr<MCSymbolizer> Symbolizer( TheTarget->createMCSymbolizer(Triple, GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo.take())); DisAsm->setSymbolizer(Symbolizer); DisAsm->setupForSymbolicDisassembly(GetOpInfo, SymbolLookUp, DisInfo, Ctx, RelInfo); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI); if (!IP) return 0; LLVMDisasmContext *DC = new LLVMDisasmContext(Triple, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP); if (!DC) return 0; return DC; }
// LLVMCreateDisasm() creates a disassembler for the TripleName. Symbolic // disassembly is supported by passing a block of information in the DisInfo // 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 successful, this returns a // disassembler context. If not, it returns NULL. // LLVMDisasmContextRef LLVMCreateDisasmCPUFeatures(const char *TT, const char *CPU, const char *Features, void *DisInfo, int TagType, LLVMOpInfoCallback GetOpInfo, LLVMSymbolLookupCallback SymbolLookUp) { // Get the target. std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(TT, Error); if (!TheTarget) return nullptr; const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TT); if (!MRI) return nullptr; // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, TT); if (!MAI) return nullptr; const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); if (!MII) return nullptr; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TT, CPU, Features); if (!STI) return nullptr; // Set up the MCContext for creating symbols and MCExpr's. MCContext *Ctx = new MCContext(MAI, MRI, nullptr); if (!Ctx) return nullptr; // Set up disassembler. MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI, *Ctx); if (!DisAsm) return nullptr; std::unique_ptr<MCRelocationInfo> RelInfo( TheTarget->createMCRelocationInfo(TT, *Ctx)); if (!RelInfo) return nullptr; std::unique_ptr<MCSymbolizer> Symbolizer(TheTarget->createMCSymbolizer( TT, GetOpInfo, SymbolLookUp, DisInfo, Ctx, std::move(RelInfo))); DisAsm->setSymbolizer(std::move(Symbolizer)); // Set up the instruction printer. int AsmPrinterVariant = MAI->getAssemblerDialect(); MCInstPrinter *IP = TheTarget->createMCInstPrinter( Triple(TT), AsmPrinterVariant, *MAI, *MII, *MRI); if (!IP) return nullptr; LLVMDisasmContext *DC = new LLVMDisasmContext(TT, DisInfo, TagType, GetOpInfo, SymbolLookUp, TheTarget, MAI, MRI, STI, MII, Ctx, DisAsm, IP); if (!DC) return nullptr; DC->setCPU(CPU); return DC; }