// // LLVMSetDisasmOptions() sets the disassembler's options. It returns 1 if it // can set all the Options and 0 otherwise. // int LLVMSetDisasmOptions(LLVMDisasmContextRef DCR, uint64_t Options){ if (Options & LLVMDisassembler_Option_UseMarkup){ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; MCInstPrinter *IP = DC->getIP(); IP->setUseMarkup(1); Options &= ~LLVMDisassembler_Option_UseMarkup; } if (Options & LLVMDisassembler_Option_PrintImmHex){ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; MCInstPrinter *IP = DC->getIP(); IP->setPrintImmHex(1); Options &= ~LLVMDisassembler_Option_PrintImmHex; } if (Options & LLVMDisassembler_Option_AsmPrinterVariant){ LLVMDisasmContext *DC = (LLVMDisasmContext *)DCR; // Try to set up the new instruction printer. const MCAsmInfo *MAI = DC->getAsmInfo(); const MCInstrInfo *MII = DC->getInstrInfo(); const MCRegisterInfo *MRI = DC->getRegisterInfo(); const MCSubtargetInfo *STI = DC->getSubtargetInfo(); int AsmPrinterVariant = MAI->getAssemblerDialect(); AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0; MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter( AsmPrinterVariant, *MAI, *MII, *MRI, *STI); if (IP) { DC->setIP(IP); Options &= ~LLVMDisassembler_Option_AsmPrinterVariant; } } return (Options == 0); }
// // 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. ArrayRef<uint8_t> Data(Bytes, BytesSize); 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, Data, 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, *DC->getSubtargetInfo()); 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!"); }