// // 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); }
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; }
// // 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; } return (Options == 0); }
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; }
// // 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; }
// // 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 = static_cast<LLVMDisasmContext *>(DCR); MCInstPrinter *IP = DC->getIP(); IP->setUseMarkup(true); DC->addOptions(LLVMDisassembler_Option_UseMarkup); Options &= ~LLVMDisassembler_Option_UseMarkup; } if (Options & LLVMDisassembler_Option_PrintImmHex){ LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR); MCInstPrinter *IP = DC->getIP(); IP->setPrintImmHex(true); DC->addOptions(LLVMDisassembler_Option_PrintImmHex); Options &= ~LLVMDisassembler_Option_PrintImmHex; } if (Options & LLVMDisassembler_Option_AsmPrinterVariant){ LLVMDisasmContext *DC = static_cast<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(); int AsmPrinterVariant = MAI->getAssemblerDialect(); AsmPrinterVariant = AsmPrinterVariant == 0 ? 1 : 0; MCInstPrinter *IP = DC->getTarget()->createMCInstPrinter( Triple(DC->getTripleName()), AsmPrinterVariant, *MAI, *MII, *MRI); if (IP) { DC->setIP(IP); DC->addOptions(LLVMDisassembler_Option_AsmPrinterVariant); Options &= ~LLVMDisassembler_Option_AsmPrinterVariant; } } if (Options & LLVMDisassembler_Option_SetInstrComments) { LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR); MCInstPrinter *IP = DC->getIP(); IP->setCommentStream(DC->CommentStream); DC->addOptions(LLVMDisassembler_Option_SetInstrComments); Options &= ~LLVMDisassembler_Option_SetInstrComments; } if (Options & LLVMDisassembler_Option_PrintLatency) { LLVMDisasmContext *DC = static_cast<LLVMDisasmContext *>(DCR); DC->addOptions(LLVMDisassembler_Option_PrintLatency); Options &= ~LLVMDisassembler_Option_PrintLatency; } return (Options == 0); }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); setDwarfDebugProducer(); const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; // Now that GetTarget() has (potentially) replaced TripleName, it's safe to // construct the Triple object. Triple TheTriple(TripleName); ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = MemoryBuffer::getFileOrSTDIN(InputFilename); if (std::error_code EC = BufferPtr.getError()) { errs() << InputFilename << ": " << EC.message() << '\n'; return 1; } MemoryBuffer *Buffer = BufferPtr->get(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); MAI->setRelaxELFRelocations(RelaxELFRel); if (CompressDebugSections != DebugCompressionType::DCT_None) { if (!zlib::isAvailable()) { errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections"; return 1; } MAI->setCompressDebugSections(CompressDebugSections); } // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. MCObjectFileInfo MOFI; MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); // Default to 4 for dwarf version. unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4; if (DwarfVersion < 2 || DwarfVersion > 4) { errs() << ProgName << ": Dwarf version " << DwarfVersion << " is not supported." << '\n'; return 1; } Ctx.setDwarfVersion(DwarfVersion); if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty()) Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); else { // If no compilation dir is set, try to use the current directory. SmallString<128> CWD; if (!sys::fs::current_path(CWD)) Ctx.setCompilationDir(CWD); } if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::unique_ptr<tool_output_file> Out = GetOutputStream(); if (!Out) return 1; std::unique_ptr<buffer_ostream> BOS; raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCInstPrinter *IP = nullptr; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant, *MAI, *MCII, *MRI); // Set the display preference for hex vs. decimal immediates. IP->setPrintImmHex(PrintImmHex); // Set up the AsmStreamer. MCCodeEmitter *CE = nullptr; MCAsmBackend *MAB = nullptr; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS); Str.reset(TheTarget->createAsmStreamer( Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(TheTarget->createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); // Don't waste memory on names of temp labels. Ctx.setUseNamesOnTempLabels(false); if (!Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(Out->os()); OS = BOS.get(); } MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer( TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false)); if (NoExecStack) Str->InitSections(true); } int Res = 1; bool disassemble = false; switch (Action) { case AC_AsLex: Res = AsLexInput(SrcMgr, *MAI, Out->os()); break; case AC_Assemble: Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII, MCOptions); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, SrcMgr, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); return Res; }
void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter, raw_ostream &OS, const MCInst &Inst, const MCSubtargetInfo &STI) { InstPrinter.printInst(&Inst, OS, "", STI); }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); setDwarfDebugProducer(); const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; std::unique_ptr<MemoryBuffer> BufferPtr; if (std::error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { errs() << ProgName << ": " << ec.message() << '\n'; return 1; } MemoryBuffer *Buffer = BufferPtr.release(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); if (CompressDebugSections) { if (!zlib::isAvailable()) { errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections"; return 1; } MAI->setCompressDebugSections(true); } // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. std::unique_ptr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); if (DwarfVersion < 2 || DwarfVersion > 4) { errs() << ProgName << ": Dwarf version " << DwarfVersion << " is not supported." << '\n'; return 1; } Ctx.setDwarfVersion(DwarfVersion); if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty()) Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::unique_ptr<tool_output_file> Out(GetOutputStream()); if (!Out) return 1; formatted_raw_ostream FOS(Out->os()); std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCInstPrinter *IP = nullptr; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI); // Set the display preference for hex vs. decimal immediates. IP->setPrintImmHex(PrintImmHex); // Set up the AsmStreamer. MCCodeEmitter *CE = nullptr; MCAsmBackend *MAB = nullptr; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, FOS, CE, *STI, RelaxAll, NoExecStack)); } int Res = 1; bool disassemble = false; switch (Action) { case AC_AsLex: Res = AsLexInput(SrcMgr, *MAI, Out.get()); break; case AC_Assemble: Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, SrcMgr, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); return Res; }
int build_reg_table() { std::string buf; llvm::StringRef reg_name; int n; int tmp; MCInst *inst = new MCInst; LLVMSymbolLookupCallback SymbolLookUp = NULL; std::string TripleName = "x86_64-pc-linux-gnu"; // Get the target. std::string Error; //TargetRegistry::printRegisteredTargetsForVersion(); const llvm::Target *TheTarget = llvm::TargetRegistry::lookupTarget(TripleName, Error); if (!TheTarget) return 1; //outs() << TheTarget; const MCRegisterInfo *MRI = TheTarget->createMCRegInfo(TripleName); if (!MRI) return 2; // Get the assembler info needed to setup the MCContext. const MCAsmInfo *MAI = TheTarget->createMCAsmInfo(*MRI, TripleName); if (!MAI) return 3; const MCInstrInfo *MII = TheTarget->createMCInstrInfo(); if (!MII) return 4; tmp = MII->getNumOpcodes(); //outs() << format("Number of opcodes = 0x%x\n", tmp); // Package up features to be passed to target/subtarget std::string FeaturesStr; std::string CPU; const MCSubtargetInfo *STI = TheTarget->createMCSubtargetInfo(TripleName, CPU, FeaturesStr); if (!STI) return 5; // Set up the MCContext for creating symbols and MCExpr's. MCContext *Ctx = new MCContext(MAI, MRI, 0); if (!Ctx) return 6; // Set up disassembler. MCDisassembler *DisAsm = TheTarget->createMCDisassembler(*STI); if (!DisAsm) return 7; OwningPtr<MCRelocationInfo> RelInfo( TheTarget->createMCRelocationInfo(TripleName, *Ctx)); if (!RelInfo) return 8; LLVMOpInfoCallback GetOpInfo = NULL; void *DisInfo = NULL; OwningPtr<MCSymbolizer> Symbolizer( TheTarget->createMCSymbolizer(TripleName, 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 9; llvm::raw_string_ostream OS(buf); OS.SetUnbuffered(); for (n = 1; n < 233; n++) { buf.clear(); /* Clears the OS2 buffer */ IP->printRegName(OS, n); reg_name = OS.str(); llvm::outs() << llvm::format("Reg:0x%x:", n); llvm::outs() << reg_name << "\n"; } return 0; }