llvm-mc.cpp revision a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1
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: 8314ee48a5bae352780b767a14bd97e8e91800a95bChris Lattner Lexer.PrintMessage(Lexer.getLoc(), "driver: unknown token"); 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; 1014651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::EndOfStatement: outs() << "EndOfStatement\n"; break; 102a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner case asmtok::Colon: outs() << "Colon\n"; break; 103a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner case asmtok::Plus: outs() << "Plus\n"; break; 104a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner case asmtok::Minus: outs() << "Minus\n"; break; 10574ec1a3b115a889e1a70dd22d8dcc6a5e753a5d2Chris Lattner case asmtok::Tilde: outs() << "Tilde\n"; break; 1064651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Slash: outs() << "Slash\n"; break; 1074651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::LParen: outs() << "LParen\n"; break; 1084651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::RParen: outs() << "RParen\n"; break; 1094651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Star: outs() << "Star\n"; break; 1104651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Comma: outs() << "Comma\n"; break; 1114651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner case asmtok::Dollar: outs() << "Dollar\n"; break; 112a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner } 113a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner 114a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner Tok = Lexer.Lex(); 115a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner } 116f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 11727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return Error; 118b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner} 119b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 12027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattnerstatic int AssembleInput(const char *ProgName) { 12127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner std::string ErrorMessage; 12227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, 12327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner &ErrorMessage); 12427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner if (Buffer == 0) { 12527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << ProgName << ": "; 12627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner if (ErrorMessage.size()) 12727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << ErrorMessage << "\n"; 12827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner else 12927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner errs() << "input file didn't read correctly.\n"; 13027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return 1; 13127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner } 13227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 13327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SourceMgr SrcMgr; 13427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 13527aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // Tell SrcMgr about this buffer, which is what TGParser will pick up. 13627aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); 13727aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 13827aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // Record the location of the include directories so that the lexer can find 13927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner // it later. 14027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner SrcMgr.setIncludeDirs(IncludeDirs); 14127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 142cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner MCContext Ctx; 143cbc23f75cd8cd6889fd02f65b63f6c02512460bdChris Lattner OwningPtr<MCStreamer> Str(createAsmStreamer(Ctx, outs())); 144a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar 145a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar // FIXME: Target hook & command line option for initial section. 146a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar Str.get()->SwitchSection(Ctx.GetSection("__TEXT,__text,regular,pure_instructions")); 147a0d1426af0bd05e1ae69481cdb75d2913e7e1ac1Daniel Dunbar 148c69485e34d57e17fe2c3acab64e519d6a6945197Chris Lattner AsmParser Parser(SrcMgr, Ctx, *Str.get()); 14927aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return Parser.Run(); 15027aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner} 15127aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner 152b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 153b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattnerint main(int argc, char **argv) { 154b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner // Print a stack trace if we signal out. 155b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner sys::PrintStackTraceOnErrorSignal(); 156b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner PrettyStackTraceProgram X(argc, argv); 157b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 158b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); 159b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 160b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner switch (Action) { 161b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner default: 16227aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner case AC_AsLex: 16327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner return AsLexInput(argv[0]); 164b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner case AC_Assemble: 165b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner return AssembleInput(argv[0]); 166b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner } 167b23677e076bea7c3bf4763ba14d8ee96faf8a74bChris Lattner 168f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner return 0; 169f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner} 170f9f065e45500823cdeb25bde2154d871ab6e9125Chris Lattner 171