llvm-mc.cpp revision 165e8344d833147268810bbec18276dafe0122b9
1bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner//===-- llvm-mc.cpp - Machine Code Hacking Driver -------------------------===// 2f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// 3f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// The LLVM Compiler Infrastructure 4f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// 5f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// This file is distributed under the University of Illinois Open Source 6f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// License. See LICENSE.TXT for details. 7f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// 8f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//===----------------------------------------------------------------------===// 9f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// 10bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner// This utility is a simple driver that allows command line hacking on machine 11bb4688a9cf385ccada90ebeb04b3ba5827bf213dChris Lattner// code. 12f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner// 13f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner//===----------------------------------------------------------------------===// 14f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 15cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/MC/MCContext.h" 16cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/MC/MCStreamer.h" 17cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner#include "llvm/ADT/OwningPtr.h" 18f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/CommandLine.h" 19f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/ManagedStatic.h" 20f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/MemoryBuffer.h" 21f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/PrettyStackTrace.h" 22b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner#include "llvm/Support/SourceMgr.h" 23f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/Support/raw_ostream.h" 24f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner#include "llvm/System/Signals.h" 2527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner#include "AsmParser.h" 26f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerusing namespace llvm; 27f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 28f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string> 29f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerInputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-")); 30f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 31f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattnerstatic cl::opt<std::string> 32f9f065e45500823cdeb25bde2154d871ab6e9125Chris LattnerOutputFilename("o", cl::desc("Output filename"), 33f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner cl::value_desc("filename")); 34f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 35b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::list<std::string> 36b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerIncludeDirs("I", cl::desc("Directory of include files"), 37b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner cl::value_desc("directory"), cl::Prefix); 38f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 39b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerenum ActionType { 4027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner AC_AsLex, 41b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner AC_Assemble 42b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner}; 43f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 44b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerstatic cl::opt<ActionType> 45b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris LattnerAction(cl::desc("Action to perform:"), 4627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner cl::init(AC_Assemble), 4727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner cl::values(clEnumValN(AC_AsLex, "as-lex", 4827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner "Lex tokens from a .s file"), 4927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner clEnumValN(AC_Assemble, "assemble", 50b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner "Assemble a .s file (default)"), 51b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner clEnumValEnd)); 52f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 5327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AsLexInput(const char *ProgName) { 54b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner std::string ErrorMessage; 55b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, 56b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner &ErrorMessage); 57f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner if (Buffer == 0) { 58b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner errs() << ProgName << ": "; 59f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner if (ErrorMessage.size()) 60f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner errs() << ErrorMessage << "\n"; 61f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner else 62f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner errs() << "input file didn't read correctly.\n"; 63f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner return 1; 64f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner } 65b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 66b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner SourceMgr SrcMgr; 67b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 68b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner // Tell SrcMgr about this buffer, which is what TGParser will pick up. 69b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 70b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 71b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner // Record the location of the include directories so that the lexer can find 72b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner // it later. 73b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner SrcMgr.setIncludeDirs(IncludeDirs); 74a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner 75a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner AsmLexer Lexer(SrcMgr); 76f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 7727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner bool Error = false; 7827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 79a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner asmtok::TokKind Tok = Lexer.Lex(); 80a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner while (Tok != asmtok::Eof) { 81a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner switch (Tok) { 8227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner default: 833fb7683bec8c8edb24e80c95f3b0668c6ecc0ae6Daniel Dunbar Lexer.PrintMessage(Lexer.getLoc(), "unknown token", "warning"); 8427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner Error = true; 8527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner break; 864651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Error: 8727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner Error = true; // error already printed. 884651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner break; 89a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner case asmtok::Identifier: 90a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner outs() << "identifier: " << Lexer.getCurStrVal() << '\n'; 91a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner break; 924651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Register: 934651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner outs() << "register: " << Lexer.getCurStrVal() << '\n'; 944651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner break; 9510a907d70fb54c40eecabb889e81c79b44092221Chris Lattner case asmtok::String: 9610a907d70fb54c40eecabb889e81c79b44092221Chris Lattner outs() << "string: " << Lexer.getCurStrVal() << '\n'; 9710a907d70fb54c40eecabb889e81c79b44092221Chris Lattner break; 98a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner case asmtok::IntVal: 99a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner outs() << "int: " << Lexer.getCurIntVal() << '\n'; 100a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner break; 101165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar 102165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Amp: outs() << "Amp\n"; break; 103165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::AmpAmp: outs() << "AmpAmp\n"; break; 104165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Caret: outs() << "Caret\n"; break; 10587380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::Colon: outs() << "Colon\n"; break; 10687380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::Comma: outs() << "Comma\n"; break; 10787380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::Dollar: outs() << "Dollar\n"; break; 108165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break; 109165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Eof: outs() << "Eof\n"; break; 11087380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::Equal: outs() << "Equal\n"; break; 11187380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::EqualEqual: outs() << "EqualEqual\n"; break; 112165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Exclaim: outs() << "Exclaim\n"; break; 113165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::ExclaimEqual: outs() << "ExclaimEqual\n"; break; 114165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Greater: outs() << "Greater\n"; break; 115165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::GreaterEqual: outs() << "GreaterEqual\n"; break; 116165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::GreaterGreater: outs() << "GreaterGreater\n"; break; 117165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::LParen: outs() << "LParen\n"; break; 118165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Less: outs() << "Less\n"; break; 119165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::LessEqual: outs() << "LessEqual\n"; break; 120165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::LessGreater: outs() << "LessGreater\n"; break; 121165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::LessLess: outs() << "LessLess\n"; break; 122165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Minus: outs() << "Minus\n"; break; 123165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Percent: outs() << "Percent\n"; break; 12487380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::Pipe: outs() << "Pipe\n"; break; 12587380cb0e0d6157b8845d59a50bc2ba94a38ebd1Chris Lattner case asmtok::PipePipe: outs() << "PipePipe\n"; break; 126165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Plus: outs() << "Plus\n"; break; 127165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::RParen: outs() << "RParen\n"; break; 128165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Slash: outs() << "Slash\n"; break; 129165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Star: outs() << "Star\n"; break; 130165e8344d833147268810bbec18276dafe0122b9Daniel Dunbar case asmtok::Tilde: outs() << "Tilde\n"; break; 131a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner } 132a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner 133a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner Tok = Lexer.Lex(); 134a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner } 135f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 13627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return Error; 137b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner} 138b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 13927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AssembleInput(const char *ProgName) { 14027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner std::string ErrorMessage; 14127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, 14227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner &ErrorMessage); 14327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner if (Buffer == 0) { 14427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << ProgName << ": "; 14527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner if (ErrorMessage.size()) 14627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << ErrorMessage << "\n"; 14727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner else 14827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << "input file didn't read correctly.\n"; 14927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return 1; 15027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner } 15127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 15227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SourceMgr SrcMgr; 15327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 15427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // Tell SrcMgr about this buffer, which is what TGParser will pick up. 15527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 15627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 15727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // Record the location of the include directories so that the lexer can find 15827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // it later. 15927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SrcMgr.setIncludeDirs(IncludeDirs); 16027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 161cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner MCContext Ctx; 162cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner OwningPtr<MCStreamer> Str(createAsmStreamer(Ctx, outs())); 163a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar 164a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar // FIXME: Target hook & command line option for initial section. 165a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar Str.get()->SwitchSection(Ctx.GetSection("__TEXT,__text,regular,pure_instructions")); 166a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar 167c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner AsmParser Parser(SrcMgr, Ctx, *Str.get()); 16827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return Parser.Run(); 16927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner} 17027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 171b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 172b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) { 173b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner // Print a stack trace if we signal out. 174b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner sys::PrintStackTraceOnErrorSignal(); 175b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner PrettyStackTraceProgram X(argc, argv); 176b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 177b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); 178b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 179b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner switch (Action) { 180b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner default: 18127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner case AC_AsLex: 18227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return AsLexInput(argv[0]); 183b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner case AC_Assemble: 184b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner return AssembleInput(argv[0]); 185b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner } 186b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 187f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner return 0; 188f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner} 189f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 190