1194612Sed//===-- llvm-mc.cpp - Machine Code Hacking Driver -------------------------===// 2194612Sed// 3194612Sed// The LLVM Compiler Infrastructure 4194612Sed// 5194612Sed// This file is distributed under the University of Illinois Open Source 6194612Sed// License. See LICENSE.TXT for details. 7194612Sed// 8194612Sed//===----------------------------------------------------------------------===// 9194612Sed// 10194612Sed// This utility is a simple driver that allows command line hacking on machine 11194612Sed// code. 12194612Sed// 13194612Sed//===----------------------------------------------------------------------===// 14194612Sed 15252723Sdim#include "Disassembler.h" 16252723Sdim#include "llvm/ADT/OwningPtr.h" 17226584Sdim#include "llvm/MC/MCAsmBackend.h" 18235633Sdim#include "llvm/MC/MCAsmInfo.h" 19195098Sed#include "llvm/MC/MCContext.h" 20198090Srdivacky#include "llvm/MC/MCInstPrinter.h" 21224133Sdim#include "llvm/MC/MCInstrInfo.h" 22226584Sdim#include "llvm/MC/MCObjectFileInfo.h" 23252723Sdim#include "llvm/MC/MCParser/AsmLexer.h" 24226584Sdim#include "llvm/MC/MCRegisterInfo.h" 25198090Srdivacky#include "llvm/MC/MCSectionMachO.h" 26195098Sed#include "llvm/MC/MCStreamer.h" 27224133Sdim#include "llvm/MC/MCSubtargetInfo.h" 28226584Sdim#include "llvm/MC/MCTargetAsmParser.h" 29194612Sed#include "llvm/Support/CommandLine.h" 30212793Sdim#include "llvm/Support/FileUtilities.h" 31198090Srdivacky#include "llvm/Support/FormattedStream.h" 32252723Sdim#include "llvm/Support/Host.h" 33194612Sed#include "llvm/Support/ManagedStatic.h" 34194612Sed#include "llvm/Support/MemoryBuffer.h" 35194612Sed#include "llvm/Support/PrettyStackTrace.h" 36252723Sdim#include "llvm/Support/Signals.h" 37194612Sed#include "llvm/Support/SourceMgr.h" 38226584Sdim#include "llvm/Support/TargetRegistry.h" 39226584Sdim#include "llvm/Support/TargetSelect.h" 40252723Sdim#include "llvm/Support/ToolOutputFile.h" 41194612Sedusing namespace llvm; 42194612Sed 43194612Sedstatic cl::opt<std::string> 44194612SedInputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 45194612Sed 46194612Sedstatic cl::opt<std::string> 47194612SedOutputFilename("o", cl::desc("Output filename"), 48194612Sed cl::value_desc("filename")); 49194612Sed 50198090Srdivackystatic cl::opt<bool> 51198090SrdivackyShowEncoding("show-encoding", cl::desc("Show instruction encodings")); 52198090Srdivacky 53203954Srdivackystatic cl::opt<bool> 54203954SrdivackyShowInst("show-inst", cl::desc("Show internal instruction representation")); 55203954Srdivacky 56212793Sdimstatic cl::opt<bool> 57212793SdimShowInstOperands("show-inst-operands", 58212793Sdim cl::desc("Show instructions operands as parsed")); 59212793Sdim 60198090Srdivackystatic cl::opt<unsigned> 61198090SrdivackyOutputAsmVariant("output-asm-variant", 62198090Srdivacky cl::desc("Syntax variant to use for output printing")); 63198090Srdivacky 64206083Srdivackystatic cl::opt<bool> 65206083SrdivackyRelaxAll("mc-relax-all", cl::desc("Relax all fixups")); 66206083Srdivacky 67208599Srdivackystatic cl::opt<bool> 68252723SdimDisableCFI("disable-cfi", cl::desc("Do not use .cfi_* directives")); 69252723Sdim 70252723Sdimstatic cl::opt<bool> 71218885SdimNoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack")); 72218885Sdim 73198090Srdivackyenum OutputFileType { 74206083Srdivacky OFT_Null, 75198090Srdivacky OFT_AssemblyFile, 76198090Srdivacky OFT_ObjectFile 77198090Srdivacky}; 78198090Srdivackystatic cl::opt<OutputFileType> 79198090SrdivackyFileType("filetype", cl::init(OFT_AssemblyFile), 80198090Srdivacky cl::desc("Choose an output file type:"), 81198090Srdivacky cl::values( 82198090Srdivacky clEnumValN(OFT_AssemblyFile, "asm", 83198090Srdivacky "Emit an assembly ('.s') file"), 84206083Srdivacky clEnumValN(OFT_Null, "null", 85206083Srdivacky "Don't emit anything (for timing purposes)"), 86198090Srdivacky clEnumValN(OFT_ObjectFile, "obj", 87198090Srdivacky "Emit a native object ('.o') file"), 88198090Srdivacky clEnumValEnd)); 89198090Srdivacky 90194612Sedstatic cl::list<std::string> 91194612SedIncludeDirs("I", cl::desc("Directory of include files"), 92194612Sed cl::value_desc("directory"), cl::Prefix); 93194612Sed 94198090Srdivackystatic cl::opt<std::string> 95205218SrdivackyArchName("arch", cl::desc("Target arch to assemble for, " 96224133Sdim "see -version for available targets")); 97205218Srdivacky 98205218Srdivackystatic cl::opt<std::string> 99198892SrdivackyTripleName("triple", cl::desc("Target triple to assemble for, " 100205218Srdivacky "see -version for available targets")); 101198090Srdivacky 102218885Sdimstatic cl::opt<std::string> 103218885SdimMCPU("mcpu", 104218885Sdim cl::desc("Target a specific cpu type (-mcpu=help for details)"), 105218885Sdim cl::value_desc("cpu-name"), 106218885Sdim cl::init("")); 107218885Sdim 108226584Sdimstatic cl::list<std::string> 109226584SdimMAttrs("mattr", 110226584Sdim cl::CommaSeparated, 111226584Sdim cl::desc("Target specific attributes (-mattr=help for details)"), 112226584Sdim cl::value_desc("a1,+a2,-a3,...")); 113226584Sdim 114226584Sdimstatic cl::opt<Reloc::Model> 115226584SdimRelocModel("relocation-model", 116226584Sdim cl::desc("Choose relocation model"), 117226584Sdim cl::init(Reloc::Default), 118226584Sdim cl::values( 119226584Sdim clEnumValN(Reloc::Default, "default", 120226584Sdim "Target default relocation model"), 121226584Sdim clEnumValN(Reloc::Static, "static", 122226584Sdim "Non-relocatable code"), 123226584Sdim clEnumValN(Reloc::PIC_, "pic", 124226584Sdim "Fully relocatable, position independent code"), 125226584Sdim clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", 126226584Sdim "Relocatable external references, non-relocatable code"), 127226584Sdim clEnumValEnd)); 128226584Sdim 129226584Sdimstatic cl::opt<llvm::CodeModel::Model> 130226584SdimCMModel("code-model", 131226584Sdim cl::desc("Choose code model"), 132226584Sdim cl::init(CodeModel::Default), 133226584Sdim cl::values(clEnumValN(CodeModel::Default, "default", 134226584Sdim "Target default code model"), 135226584Sdim clEnumValN(CodeModel::Small, "small", 136226584Sdim "Small code model"), 137226584Sdim clEnumValN(CodeModel::Kernel, "kernel", 138226584Sdim "Kernel code model"), 139226584Sdim clEnumValN(CodeModel::Medium, "medium", 140226584Sdim "Medium code model"), 141226584Sdim clEnumValN(CodeModel::Large, "large", 142226584Sdim "Large code model"), 143226584Sdim clEnumValEnd)); 144226584Sdim 145205218Srdivackystatic cl::opt<bool> 146224133SdimNoInitialTextSection("n", cl::desc("Don't assume assembly file starts " 147224133Sdim "in the text section")); 148205218Srdivacky 149221337Sdimstatic cl::opt<bool> 150224133SdimSaveTempLabels("L", cl::desc("Don't discard temporary labels")); 151221337Sdim 152235633Sdimstatic cl::opt<bool> 153235633SdimGenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly " 154235633Sdim "source files")); 155235633Sdim 156252723Sdimstatic cl::opt<std::string> 157252723SdimDebugCompilationDir("fdebug-compilation-dir", 158252723Sdim cl::desc("Specifies the debug info's compilation dir")); 159252723Sdim 160252723Sdimstatic cl::opt<std::string> 161252723SdimMainFileName("main-file-name", 162252723Sdim cl::desc("Specifies the name we should consider the input file")); 163252723Sdim 164194612Sedenum ActionType { 165194612Sed AC_AsLex, 166201360Srdivacky AC_Assemble, 167207618Srdivacky AC_Disassemble, 168252723Sdim AC_MDisassemble, 169252723Sdim AC_HDisassemble 170194612Sed}; 171194612Sed 172194612Sedstatic cl::opt<ActionType> 173194612SedAction(cl::desc("Action to perform:"), 174194612Sed cl::init(AC_Assemble), 175194612Sed cl::values(clEnumValN(AC_AsLex, "as-lex", 176194612Sed "Lex tokens from a .s file"), 177194612Sed clEnumValN(AC_Assemble, "assemble", 178194612Sed "Assemble a .s file (default)"), 179201360Srdivacky clEnumValN(AC_Disassemble, "disassemble", 180201360Srdivacky "Disassemble strings of hex bytes"), 181245431Sdim clEnumValN(AC_MDisassemble, "mdis", 182245431Sdim "Marked up disassembly of strings of hex bytes"), 183252723Sdim clEnumValN(AC_HDisassemble, "hdis", 184252723Sdim "Disassemble strings of hex bytes printing " 185252723Sdim "immediates as hex"), 186194612Sed clEnumValEnd)); 187194612Sed 188198090Srdivackystatic const Target *GetTarget(const char *ProgName) { 189205218Srdivacky // Figure out the target triple. 190205218Srdivacky if (TripleName.empty()) 191235633Sdim TripleName = sys::getDefaultTargetTriple(); 192226584Sdim Triple TheTriple(Triple::normalize(TripleName)); 193226584Sdim 194245431Sdim // Get the target specific parser. 195245431Sdim std::string Error; 196245431Sdim const Target *TheTarget = TargetRegistry::lookupTarget(ArchName, TheTriple, 197245431Sdim Error); 198245431Sdim if (!TheTarget) { 199245431Sdim errs() << ProgName << ": " << Error; 200245431Sdim return 0; 201205218Srdivacky } 202205218Srdivacky 203245431Sdim // Update the triple name and return the found target. 204226584Sdim TripleName = TheTriple.getTriple(); 205226584Sdim return TheTarget; 206198090Srdivacky} 207198090Srdivacky 208212793Sdimstatic tool_output_file *GetOutputStream() { 209212793Sdim if (OutputFilename == "") 210212793Sdim OutputFilename = "-"; 211212793Sdim 212212793Sdim std::string Err; 213263509Sdim tool_output_file *Out = 214263509Sdim new tool_output_file(OutputFilename.c_str(), Err, sys::fs::F_Binary); 215212793Sdim if (!Err.empty()) { 216212793Sdim errs() << Err << '\n'; 217212793Sdim delete Out; 218212793Sdim return 0; 219212793Sdim } 220212793Sdim 221212793Sdim return Out; 222212793Sdim} 223212793Sdim 224235633Sdimstatic std::string DwarfDebugFlags; 225235633Sdimstatic void setDwarfDebugFlags(int argc, char **argv) { 226235633Sdim if (!getenv("RC_DEBUG_OPTIONS")) 227235633Sdim return; 228235633Sdim for (int i = 0; i < argc; i++) { 229235633Sdim DwarfDebugFlags += argv[i]; 230235633Sdim if (i + 1 < argc) 231235633Sdim DwarfDebugFlags += " "; 232194612Sed } 233235633Sdim} 234194612Sed 235252723Sdimstatic std::string DwarfDebugProducer; 236252723Sdimstatic void setDwarfDebugProducer(void) { 237252723Sdim if(!getenv("DEBUG_PRODUCER")) 238252723Sdim return; 239252723Sdim DwarfDebugProducer += getenv("DEBUG_PRODUCER"); 240252723Sdim} 241252723Sdim 242235633Sdimstatic int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) { 243223013Sdim 244235633Sdim AsmLexer Lexer(MAI); 245212793Sdim Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); 246212793Sdim 247194612Sed bool Error = false; 248198090Srdivacky while (Lexer.Lex().isNot(AsmToken::Eof)) { 249218885Sdim AsmToken Tok = Lexer.getTok(); 250218885Sdim 251218885Sdim switch (Tok.getKind()) { 252194612Sed default: 253235633Sdim SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning, 254235633Sdim "unknown token"); 255194612Sed Error = true; 256194612Sed break; 257198090Srdivacky case AsmToken::Error: 258194612Sed Error = true; // error already printed. 259194612Sed break; 260198090Srdivacky case AsmToken::Identifier: 261218885Sdim Out->os() << "identifier: " << Lexer.getTok().getString(); 262194612Sed break; 263218885Sdim case AsmToken::Integer: 264218885Sdim Out->os() << "int: " << Lexer.getTok().getString(); 265218885Sdim break; 266218885Sdim case AsmToken::Real: 267218885Sdim Out->os() << "real: " << Lexer.getTok().getString(); 268218885Sdim break; 269198090Srdivacky case AsmToken::String: 270218885Sdim Out->os() << "string: " << Lexer.getTok().getString(); 271194612Sed break; 272195340Sed 273218885Sdim case AsmToken::Amp: Out->os() << "Amp"; break; 274218885Sdim case AsmToken::AmpAmp: Out->os() << "AmpAmp"; break; 275218885Sdim case AsmToken::At: Out->os() << "At"; break; 276218885Sdim case AsmToken::Caret: Out->os() << "Caret"; break; 277218885Sdim case AsmToken::Colon: Out->os() << "Colon"; break; 278218885Sdim case AsmToken::Comma: Out->os() << "Comma"; break; 279218885Sdim case AsmToken::Dollar: Out->os() << "Dollar"; break; 280218885Sdim case AsmToken::Dot: Out->os() << "Dot"; break; 281218885Sdim case AsmToken::EndOfStatement: Out->os() << "EndOfStatement"; break; 282218885Sdim case AsmToken::Eof: Out->os() << "Eof"; break; 283218885Sdim case AsmToken::Equal: Out->os() << "Equal"; break; 284218885Sdim case AsmToken::EqualEqual: Out->os() << "EqualEqual"; break; 285218885Sdim case AsmToken::Exclaim: Out->os() << "Exclaim"; break; 286218885Sdim case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual"; break; 287218885Sdim case AsmToken::Greater: Out->os() << "Greater"; break; 288218885Sdim case AsmToken::GreaterEqual: Out->os() << "GreaterEqual"; break; 289218885Sdim case AsmToken::GreaterGreater: Out->os() << "GreaterGreater"; break; 290218885Sdim case AsmToken::Hash: Out->os() << "Hash"; break; 291218885Sdim case AsmToken::LBrac: Out->os() << "LBrac"; break; 292218885Sdim case AsmToken::LCurly: Out->os() << "LCurly"; break; 293218885Sdim case AsmToken::LParen: Out->os() << "LParen"; break; 294218885Sdim case AsmToken::Less: Out->os() << "Less"; break; 295218885Sdim case AsmToken::LessEqual: Out->os() << "LessEqual"; break; 296218885Sdim case AsmToken::LessGreater: Out->os() << "LessGreater"; break; 297218885Sdim case AsmToken::LessLess: Out->os() << "LessLess"; break; 298218885Sdim case AsmToken::Minus: Out->os() << "Minus"; break; 299218885Sdim case AsmToken::Percent: Out->os() << "Percent"; break; 300218885Sdim case AsmToken::Pipe: Out->os() << "Pipe"; break; 301218885Sdim case AsmToken::PipePipe: Out->os() << "PipePipe"; break; 302218885Sdim case AsmToken::Plus: Out->os() << "Plus"; break; 303218885Sdim case AsmToken::RBrac: Out->os() << "RBrac"; break; 304218885Sdim case AsmToken::RCurly: Out->os() << "RCurly"; break; 305218885Sdim case AsmToken::RParen: Out->os() << "RParen"; break; 306218885Sdim case AsmToken::Slash: Out->os() << "Slash"; break; 307218885Sdim case AsmToken::Star: Out->os() << "Star"; break; 308218885Sdim case AsmToken::Tilde: Out->os() << "Tilde"; break; 309194612Sed } 310218885Sdim 311218885Sdim // Print the token string. 312218885Sdim Out->os() << " (\""; 313218885Sdim Out->os().write_escaped(Tok.getString()); 314218885Sdim Out->os() << "\")\n"; 315194612Sed } 316212793Sdim 317194612Sed return Error; 318194612Sed} 319194612Sed 320235633Sdimstatic int AssembleInput(const char *ProgName, const Target *TheTarget, 321235633Sdim SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str, 322263509Sdim MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII) { 323235633Sdim OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, 324235633Sdim Str, MAI)); 325263509Sdim OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(STI, *Parser, MCII)); 326235633Sdim if (!TAP) { 327235633Sdim errs() << ProgName 328235633Sdim << ": error: this target does not support assembly parsing.\n"; 329235633Sdim return 1; 330235633Sdim } 331235633Sdim 332235633Sdim Parser->setShowParsedOperands(ShowInstOperands); 333235633Sdim Parser->setTargetParser(*TAP.get()); 334235633Sdim 335235633Sdim int Res = Parser->Run(NoInitialTextSection); 336235633Sdim 337235633Sdim return Res; 338235633Sdim} 339235633Sdim 340235633Sdimint main(int argc, char **argv) { 341235633Sdim // Print a stack trace if we signal out. 342235633Sdim sys::PrintStackTraceOnErrorSignal(); 343235633Sdim PrettyStackTraceProgram X(argc, argv); 344235633Sdim llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 345235633Sdim 346235633Sdim // Initialize targets and assembly printers/parsers. 347235633Sdim llvm::InitializeAllTargetInfos(); 348235633Sdim llvm::InitializeAllTargetMCs(); 349235633Sdim llvm::InitializeAllAsmParsers(); 350235633Sdim llvm::InitializeAllDisassemblers(); 351235633Sdim 352235633Sdim // Register the target printer for --version. 353235633Sdim cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); 354235633Sdim 355235633Sdim cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); 356235633Sdim TripleName = Triple::normalize(TripleName); 357235633Sdim setDwarfDebugFlags(argc, argv); 358235633Sdim 359252723Sdim setDwarfDebugProducer(); 360252723Sdim 361235633Sdim const char *ProgName = argv[0]; 362198090Srdivacky const Target *TheTarget = GetTarget(ProgName); 363198090Srdivacky if (!TheTarget) 364198090Srdivacky return 1; 365198090Srdivacky 366218885Sdim OwningPtr<MemoryBuffer> BufferPtr; 367218885Sdim if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) { 368218885Sdim errs() << ProgName << ": " << ec.message() << '\n'; 369194612Sed return 1; 370194612Sed } 371218885Sdim MemoryBuffer *Buffer = BufferPtr.take(); 372223013Sdim 373194612Sed SourceMgr SrcMgr; 374223013Sdim 375198090Srdivacky // Tell SrcMgr about this buffer, which is what the parser will pick up. 376194612Sed SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 377223013Sdim 378194612Sed // Record the location of the include directories so that the lexer can find 379194612Sed // it later. 380194612Sed SrcMgr.setIncludeDirs(IncludeDirs); 381223013Sdim 382226584Sdim llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); 383226584Sdim assert(MRI && "Unable to create target register info!"); 384195098Sed 385263509Sdim llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); 386263509Sdim assert(MAI && "Unable to create target asm info!"); 387263509Sdim 388226584Sdim // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and 389226584Sdim // MCObjectFileInfo needs a MCContext reference in order to initialize itself. 390226584Sdim OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo()); 391263509Sdim MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &SrcMgr); 392226584Sdim MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx); 393198090Srdivacky 394221337Sdim if (SaveTempLabels) 395221337Sdim Ctx.setAllowTemporaryLabels(false); 396218885Sdim 397235633Sdim Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); 398252723Sdim if (!DwarfDebugFlags.empty()) 399235633Sdim Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); 400252723Sdim if (!DwarfDebugProducer.empty()) 401252723Sdim Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); 402252723Sdim if (!DebugCompilationDir.empty()) 403252723Sdim Ctx.setCompilationDir(DebugCompilationDir); 404252723Sdim if (!MainFileName.empty()) 405252723Sdim Ctx.setMainFileName(MainFileName); 406235633Sdim 407226584Sdim // Package up features to be passed to target/subtarget 408226584Sdim std::string FeaturesStr; 409226584Sdim if (MAttrs.size()) { 410226584Sdim SubtargetFeatures Features; 411226584Sdim for (unsigned i = 0; i != MAttrs.size(); ++i) 412226584Sdim Features.AddFeature(MAttrs[i]); 413226584Sdim FeaturesStr = Features.getString(); 414226584Sdim } 415226584Sdim 416212793Sdim OwningPtr<tool_output_file> Out(GetOutputStream()); 417212793Sdim if (!Out) 418212793Sdim return 1; 419212793Sdim 420212793Sdim formatted_raw_ostream FOS(Out->os()); 421198090Srdivacky OwningPtr<MCStreamer> Str; 422198090Srdivacky 423224133Sdim OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); 424224133Sdim OwningPtr<MCSubtargetInfo> 425224133Sdim STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); 426224133Sdim 427252723Sdim MCInstPrinter *IP = NULL; 428198090Srdivacky if (FileType == OFT_AssemblyFile) { 429245431Sdim IP = 430235633Sdim TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI); 431212793Sdim MCCodeEmitter *CE = 0; 432226584Sdim MCAsmBackend *MAB = 0; 433218885Sdim if (ShowEncoding) { 434245431Sdim CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); 435263509Sdim MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); 436218885Sdim } 437252723Sdim bool UseCFI = !DisableCFI; 438218885Sdim Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true, 439221337Sdim /*useLoc*/ true, 440252723Sdim UseCFI, 441235633Sdim /*useDwarfDirectory*/ true, 442235633Sdim IP, CE, MAB, ShowInst)); 443235633Sdim 444206083Srdivacky } else if (FileType == OFT_Null) { 445206083Srdivacky Str.reset(createNullStreamer(Ctx)); 446198090Srdivacky } else { 447198090Srdivacky assert(FileType == OFT_ObjectFile && "Invalid file type!"); 448245431Sdim MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); 449263509Sdim MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); 450226584Sdim Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, 451226584Sdim FOS, CE, RelaxAll, 452226584Sdim NoExecStack)); 453198090Srdivacky } 454198090Srdivacky 455235633Sdim int Res = 1; 456252723Sdim bool disassemble = false; 457194612Sed switch (Action) { 458194612Sed case AC_AsLex: 459235633Sdim Res = AsLexInput(SrcMgr, *MAI, Out.get()); 460235633Sdim break; 461194612Sed case AC_Assemble: 462263509Sdim Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII); 463235633Sdim break; 464245431Sdim case AC_MDisassemble: 465252723Sdim assert(IP && "Expected assembly output"); 466245431Sdim IP->setUseMarkup(1); 467252723Sdim disassemble = true; 468252723Sdim break; 469252723Sdim case AC_HDisassemble: 470252723Sdim assert(IP && "Expected assembly output"); 471252723Sdim IP->setPrintImmHex(1); 472252723Sdim disassemble = true; 473252723Sdim break; 474201360Srdivacky case AC_Disassemble: 475252723Sdim disassemble = true; 476252723Sdim break; 477252723Sdim } 478252723Sdim if (disassemble) 479235633Sdim Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, 480235633Sdim *Buffer, SrcMgr, Out->os()); 481223013Sdim 482235633Sdim // Keep output if no errors. 483235633Sdim if (Res == 0) Out->keep(); 484235633Sdim return Res; 485194612Sed} 486