Index: src/CodeGen/FixMain.cc
===================================================================
--- src/CodeGen/FixMain.cc	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/CodeGen/FixMain.cc	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -1,1 +1,55 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// FixMain.cc -- 
+//
+// Author           : Thierry Delisle
+// Created On       : Thr Jan 12 14:11:09 2017
+// Last Modified By : 
+// Last Modified On : 
+// Update Count     : 0
+//
 
+
+#include "FixMain.h"	
+
+#include <fstream>
+#include <iostream>
+
+#include "Common/SemanticError.h"
+#include "SynTree/Declaration.h"
+
+namespace CodeGen {
+	bool FixMain::replace_main = false;
+	std::unique_ptr<FunctionDecl> FixMain::main_signature = nullptr;
+	
+	void FixMain::registerMain(FunctionDecl* functionDecl) 
+	{
+		if(main_signature) { 
+			throw SemanticError("Multiple definition of main routine\n", functionDecl); 
+		}
+		main_signature.reset( functionDecl->clone() );
+	}
+
+	void FixMain::fix(std::ostream &os, const char* bootloader_filename) {
+		if( main_signature ) {
+			os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
+
+			os << main_signature->get_scopedMangleName() << "(";
+			switch(main_signature->get_functionType()->get_parameters().size()) {
+				case 3: os << "argc, argv, envp"; break;
+				case 2: os << "argc, argv"; break;
+				case 0: break;
+				default : assert(false);
+			}
+			os << "); }\n";
+
+			std::ifstream bootloader(bootloader_filename, std::ios::in);
+			assertf( bootloader.is_open(), "cannot open bootloader.c\n" );
+			os << bootloader.rdbuf();
+		}
+	}
+};
Index: src/CodeGen/FixMain.h
===================================================================
--- src/CodeGen/FixMain.h	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
+++ src/CodeGen/FixMain.h	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -0,0 +1,47 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// FixMain.h -- 
+//
+// Author           : Thierry Delisle
+// Created On       : Thr Jan 12 14:11:09 2017
+// Last Modified By : 
+// Last Modified On : 
+// Update Count     : 0
+//
+
+#ifndef FIXMAIN_H
+#define FIXMAIN_H
+
+#include <iosfwd>
+#include <memory>
+
+#include "Parser/LinkageSpec.h"
+
+class FunctionDecl;
+
+namespace CodeGen {
+	class FixMain {
+	  public :
+		static inline LinkageSpec::Spec mainLinkage() {
+			return replace_main ? LinkageSpec::Cforall : LinkageSpec::C;
+		}
+		
+		static inline void setReplaceMain(bool val) {
+			replace_main = val;
+		}
+
+		static void registerMain(FunctionDecl* val);
+
+		static void fix(std::ostream &os, const char* bootloader_filename);
+
+	  private:
+  		static bool replace_main;
+		static std::unique_ptr<FunctionDecl> main_signature;
+	};
+};
+
+#endif //FIXMAIN_H
Index: src/CodeGen/FixNames.cc
===================================================================
--- src/CodeGen/FixNames.cc	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/CodeGen/FixNames.cc	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -22,6 +22,5 @@
 #include "SymTab/Mangler.h"
 #include "OperatorTable.h"
-
-extern std::unique_ptr<FunctionDecl> translation_unit_main_signature;
+#include "FixMain.h"
 
 namespace CodeGen {
@@ -119,10 +118,10 @@
 
 		if(is_main( SymTab::Mangler::mangle(functionDecl, true, true) )) {
-			if(translation_unit_main_signature) { 
-				throw SemanticError("Multiple definition of main routine\n", functionDecl); 
+			int nargs = functionDecl->get_functionType()->get_parameters().size();
+			if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
+				throw SemanticError("Main expected to have 0, 2 or 3 arguments\n", main_signature.get()); 
 			}
-
 			functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), "0") ) ) );
-			translation_unit_main_signature.reset( functionDecl->clone() );
+			CodeGen::FixMain::registerMain( functionDecl );
 		}
 	}
Index: src/SynTree/FunctionDecl.cc
===================================================================
--- src/SynTree/FunctionDecl.cc	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/SynTree/FunctionDecl.cc	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -22,4 +22,5 @@
 #include "Common/utility.h"
 #include "InitTweak/InitTweak.h"
+#include "CodeGen/FixMain.h"
 
 extern bool translation_unit_nomain;
@@ -32,5 +33,5 @@
 	// because we want to replace the main even if it is inside an extern
 	if ( name == "main" ) {
-		set_linkage( translation_unit_nomain ? LinkageSpec::C : LinkageSpec::Cforall );
+		set_linkage( CodeGen::FixMain::mainLinkage() );
 	} // if
 }
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/main.cc	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -14,5 +14,4 @@
 //
 
-#include <memory>
 #include <iostream>
 #include <fstream>
@@ -35,4 +34,5 @@
 #include "CodeGen/Generate.h"
 #include "CodeGen/FixNames.h"
+#include "CodeGen/FixMain.h"
 #include "ControlStruct/Mutate.h"
 #include "SymTab/Validate.h"
@@ -80,7 +80,4 @@
 static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
 
-bool translation_unit_nomain = true;
-std::unique_ptr<FunctionDecl> translation_unit_main_signature = nullptr;
-
 static void backtrace( int start ) {					// skip first N stack frames
 	enum { Frames = 50 };
@@ -159,5 +156,5 @@
 
 	parse_cmdline( argc, argv, filename );				// process command-line arguments
-	translation_unit_nomain = nomainp;
+	CodeGen::FixMain::setReplaceMain( !nomainp );
 
 	try {
@@ -178,8 +175,4 @@
 		} // if
 
-		if ( optind < argc ) {							// any commands after the flags and input file ? => output file name
-			output = new ofstream( argv[ optind ] );
-		} // if
-
 		// read in the builtins, extras, and the prelude
 		if ( ! nopreludep ) {							// include gcc builtins
@@ -304,17 +297,11 @@
 		} // if
 
+		if ( optind < argc ) {							// any commands after the flags and input file ? => output file name
+			output = new ofstream( argv[ optind ] );
+		} // if
+
 		CodeGen::generate( translationUnit, *output, ! noprotop );
 
-		if( translation_unit_main_signature ) {
-			*output << "int main(int argc, char** argv) { return ";
-
-			*output << translation_unit_main_signature->get_scopedMangleName() << "(";
-			if(translation_unit_main_signature->get_functionType()->get_parameters().size() != 0){
-				*output << "argc, argv";
-			}
-			*output << ");";
-
-			*output << " }\n";
-		}
+		CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
 
 		if ( output != &cout ) {
Index: src/prelude/bootloader.cf
===================================================================
--- src/prelude/bootloader.cf	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/prelude/bootloader.cf	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -1,3 +1,3 @@
-extern int invoke_main(int argc, char* argv[], char* envp[]);
+extern "C" { static inline int invoke_main(int argc, char* argv[], char* envp[]); }
 
 int main(int argc, char* argv[], char* envp[]) {
Index: src/tests/.expect/32/declarationSpecifier.txt
===================================================================
--- src/tests/.expect/32/declarationSpecifier.txt	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/tests/.expect/32/declarationSpecifier.txt	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -628,4 +628,16 @@
     return ((int )___retval_main__i_1);
 }
-int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
-
+extern void *malloc(long unsigned int __size);
+extern void free(void *__ptr);
+extern void abort(void);
+extern int atexit(void (*__func)(void));
+extern void exit(int __status);
+extern int printf(const char *__restrict __format, ...);
+static inline int invoke_main(int argc, char **argv, char **envp);
+int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
+    int ___retval_main__i_1;
+    int _tmp_cp_ret0;
+    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
+    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    return ((int )___retval_main__i_1);
+}
Index: src/tests/.expect/32/gccExtensions.txt
===================================================================
--- src/tests/.expect/32/gccExtensions.txt	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/tests/.expect/32/gccExtensions.txt	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -165,3 +165,17 @@
     return ((int )___retval_main__i_1);
 }
-int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
+static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
+extern void *malloc(long unsigned int __size);
+extern void free(void *__ptr);
+extern void abort(void);
+extern int atexit(void (*__func)(void));
+extern void exit(int __status);
+extern int printf(const char *__restrict __format, ...);
+static inline int invoke_main(int argc, char **argv, char **envp);
+int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
+    int ___retval_main__i_1;
+    int _tmp_cp_ret0;
+    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
+    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    return ((int )___retval_main__i_1);
+}
Index: src/tests/.expect/64/declarationSpecifier.txt
===================================================================
--- src/tests/.expect/64/declarationSpecifier.txt	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/tests/.expect/64/declarationSpecifier.txt	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -628,3 +628,17 @@
     return ((int )___retval_main__i_1);
 }
-int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
+static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
+extern void *malloc(long unsigned int __size);
+extern void free(void *__ptr);
+extern void abort(void);
+extern int atexit(void (*__func)(void));
+extern void exit(int __status);
+extern int printf(const char *__restrict __format, ...);
+static inline int invoke_main(int argc, char **argv, char **envp);
+int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
+    int ___retval_main__i_1;
+    int _tmp_cp_ret0;
+    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
+    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    return ((int )___retval_main__i_1);
+}
Index: src/tests/.expect/64/gccExtensions.txt
===================================================================
--- src/tests/.expect/64/gccExtensions.txt	(revision 7cc2c8de391b81c66900242eeeedd230a3f06b5f)
+++ src/tests/.expect/64/gccExtensions.txt	(revision 13de47bcd1133e72e5f8fcdee34f7cbc890ec088)
@@ -165,3 +165,17 @@
     return ((int )___retval_main__i_1);
 }
-int main(int argc, char** argv) { return __main__Fi_iPPCc__1(argc, argv); }
+static inline int invoke_main(int argc, char* argv[], char* envp[]) { return __main__Fi_iPPCc__1(argc, argv); }
+extern void *malloc(long unsigned int __size);
+extern void free(void *__ptr);
+extern void abort(void);
+extern int atexit(void (*__func)(void));
+extern void exit(int __status);
+extern int printf(const char *__restrict __format, ...);
+static inline int invoke_main(int argc, char **argv, char **envp);
+int main(int __argc__i_1, char **__argv__PPc_1, char **__envp__PPc_1){
+    int ___retval_main__i_1;
+    int _tmp_cp_ret0;
+    ((void)(___retval_main__i_1=((_tmp_cp_ret0=invoke_main(__argc__i_1, __argv__PPc_1, __envp__PPc_1)) , _tmp_cp_ret0)) /* ?{} */);
+    ((void)(_tmp_cp_ret0) /* ^?{} */);
+    return ((int )___retval_main__i_1);
+}
