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, 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; }
// // LLVMDisasmInstruction() disassembles a single instruction using the // disassembler context specified in the parameter DC. The bytes of the // 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 // parameter OutStringSize. This function returns the number of bytes in the // instruction or zero if there was no valid instruction. If this function // returns zero the caller will have to pick how many bytes they want to step // over by printing a .byte, .long etc. to continue. // size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize){ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject. DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC); uint64_t Size; MCInst Inst; const MCDisassembler *DisAsm = DC->getDisAsm(); MCInstPrinter *IP = DC->getIP(); MCDisassembler::DecodeStatus S; SmallVector<char, 64> InsnStr; raw_svector_ostream Annotations(InsnStr); S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls(), Annotations); switch (S) { case MCDisassembler::Fail: case MCDisassembler::SoftFail: // FIXME: Do something different for soft failure modes? return 0; case MCDisassembler::Success: { Annotations.flush(); StringRef AnnotationsStr = Annotations.str(); SmallVector<char, 64> InsnStr; raw_svector_ostream OS(InsnStr); formatted_raw_ostream FormattedOS(OS); IP->printInst(&Inst, FormattedOS, AnnotationsStr); if (DC->getOptions() & LLVMDisassembler_Option_PrintLatency) emitLatency(DC, Inst); emitComments(DC, FormattedOS); 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. return Size; } } llvm_unreachable("Invalid DecodeStatus!"); }
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; }
// // LLVMDisasmInstruction() disassembles a single instruction using the // disassembler context specified in the parameter DC. The bytes of the // 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 // parameter OutStringSize. This function returns the number of bytes in the // instruction or zero if there was no valid instruction. If this function // returns zero the caller will have to pick how many bytes they want to step // over by printing a .byte, .long etc. to continue. // size_t LLVMDisasmInstruction(LLVMDisasmContextRef DCR, uint8_t *Bytes, uint64_t BytesSize, uint64_t PC, char *OutString, size_t OutStringSize){ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; // Wrap the pointer to the Bytes, BytesSize and PC in a MemoryObject. DisasmMemoryObject MemoryObject(Bytes, BytesSize, PC); uint64_t Size; MCInst Inst; const MCDisassembler *DisAsm = DC->getDisAsm(); MCInstPrinter *IP = DC->getIP(); MCDisassembler::DecodeStatus S; S = DisAsm->getInstruction(Inst, Size, MemoryObject, PC, /*REMOVE*/ nulls(), DC->CommentStream); switch (S) { case MCDisassembler::Fail: case MCDisassembler::SoftFail: // FIXME: Do something different for soft failure modes? return 0; case MCDisassembler::Success: { DC->CommentStream.flush(); StringRef Comments = DC->CommentsToEmit.str(); SmallVector<char, 64> InsnStr; raw_svector_ostream OS(InsnStr); IP->printInst(&Inst, OS, Comments); OS.flush(); // Tell the comment stream that the vector changed underneath it. DC->CommentsToEmit.clear(); DC->CommentStream.resync(); 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. return Size; } } llvm_unreachable("Invalid DecodeStatus!"); }
static bool PrintInsts(const MCDisassembler &DisAsm, MCInstPrinter &Printer, const ByteArrayTy &Bytes, SourceMgr &SM, raw_ostream &Out) { // 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: Printer.printInst(&Inst, Out, ""); Out << "\n"; break; } } return false; }
void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, const MCInst &Inst, const MCSubtargetInfo &STI) { InstPrinter.printInst(&Inst, OS, "", STI); }