From ef63f09dcd65729f84a4f49432467ad5ace86906 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Thu, 20 Oct 2011 13:48:10 +0200 Subject: [PATCH] Don't rely on main.ll anymore I'll remove the actual file after I register a snapshot. Issue #992 --- src/comp/back/link.rs | 8 +--- src/comp/middle/trans.rs | 84 +++++++++++++++++++++++---------- src/comp/middle/trans_common.rs | 3 +- src/rt/main.ll.in | 11 ----- src/rt/rust.cpp | 4 +- 5 files changed, 63 insertions(+), 47 deletions(-) diff --git a/src/comp/back/link.rs b/src/comp/back/link.rs index 562c7f0d6f1..6988f0c1f21 100644 --- a/src/comp/back/link.rs +++ b/src/comp/back/link.rs @@ -503,12 +503,6 @@ fn mangle_internal_name_by_seq(ccx: @crate_ctxt, flav: str) -> str { // gcc to link the object file with some libs fn link_binary(sess: session::session, saved_out_filename: str) { - let main: str = alt filesearch::search( - sess.filesearch(), bind filesearch::pick_file("main.o", _)) { - option::some(f) { f } - option::none. { sess.fatal("can't find main.o") } - }; - // The default library location, we need this to find the runtime. // The location of crates will be determined as needed. let stage: str = "-L" + sess.filesearch().get_target_lib_path(); @@ -579,7 +573,7 @@ fn rmext(filename: str) -> str { } } else { // FIXME: why do we hardcode -lm? - gcc_args += ["-lm", main]; + gcc_args += ["-lm"]; } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 83d1de8bfaf..6c6b2c590af 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -5632,6 +5632,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, let llfn = create_main(ccx, sp, main_llfn, main_takes_argv); ccx.main_fn = some(llfn); + create_entry_fn(ccx, llfn); fn create_main(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, takes_argv: bool) -> ValueRef { @@ -5664,6 +5665,35 @@ fn create_main(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, ret llfdecl; } + + fn create_entry_fn(ccx: @crate_ctxt, rust_main: ValueRef) { + #[cfg(target_os = "win32")] + fn main_name() -> str { ret "WinMain@16"; } + #[cfg(target_os = "macos")] + fn main_name() -> str { ret "main"; } + #[cfg(target_os = "linux")] + fn main_name() -> str { ret "main"; } + let llfty = T_fn([T_int(), T_int()], T_int()); + let llfn = decl_cdecl_fn(ccx.llmod, main_name(), llfty); + let llbb = str::as_buf("top", {|buf| + llvm::LLVMAppendBasicBlock(llfn, buf) + }); + let bld = *ccx.builder; + llvm::LLVMPositionBuilderAtEnd(bld, llbb); + let crate_map = ccx.crate_map; + let start_ty = T_fn([val_ty(rust_main), T_int(), T_int(), + val_ty(crate_map)], T_int()); + let start = str::as_buf("rust_start", {|buf| + llvm::LLVMAddGlobal(ccx.llmod, start_ty, buf) + }); + let args = [rust_main, llvm::LLVMGetParam(llfn, 0u), + llvm::LLVMGetParam(llfn, 1u), crate_map]; + let result = unsafe { + llvm::LLVMBuildCall(bld, start, vec::to_ptr(args), + vec::len(args), noname()) + }; + llvm::LLVMBuildRet(bld, result); + } } // Create a /real/ closure: this is like create_fn_pair, but creates a @@ -6146,38 +6176,39 @@ fn create_module_map(ccx: @crate_ctxt) -> ValueRef { } +fn decl_crate_map(sess: session::session, mapname: str, + llmod: ModuleRef) -> ValueRef { + let n_subcrates = 1; + let cstore = sess.get_cstore(); + while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } + if !sess.get_opts().library { mapname = "toplevel"; } + let sym_name = "_rust_crate_map_" + mapname; + let arrtype = T_array(T_int(), n_subcrates as uint); + let maptype = T_struct([T_int(), arrtype]); + let map = str::as_buf(sym_name, {|buf| + llvm::LLVMAddGlobal(llmod, maptype, buf) + }); + llvm::LLVMSetLinkage(map, lib::llvm::LLVMExternalLinkage + as llvm::Linkage); + ret map; +} + // FIXME use hashed metadata instead of crate names once we have that -fn create_crate_map(ccx: @crate_ctxt) -> ValueRef { +fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { let subcrates: [ValueRef] = []; let i = 1; let cstore = ccx.sess.get_cstore(); while cstore::have_crate_data(cstore, i) { let nm = "_rust_crate_map_" + cstore::get_crate_data(cstore, i).name; - let cr = - str::as_buf(nm, - {|buf| - llvm::LLVMAddGlobal(ccx.llmod, T_int(), buf) - }); + let cr = str::as_buf(nm, {|buf| + llvm::LLVMAddGlobal(ccx.llmod, T_int(), buf) + }); subcrates += [p2i(cr)]; i += 1; } subcrates += [C_int(0)]; - let mapname; - if ccx.sess.get_opts().library { - mapname = ccx.link_meta.name; - } else { mapname = "toplevel"; } - let sym_name = "_rust_crate_map_" + mapname; - let arrtype = T_array(T_int(), std::vec::len::(subcrates)); - let maptype = T_struct([T_int(), arrtype]); - let map = - str::as_buf(sym_name, - {|buf| llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) }); - llvm::LLVMSetLinkage(map, - lib::llvm::LLVMExternalLinkage as llvm::Linkage); - llvm::LLVMSetInitializer(map, - C_struct([p2i(create_module_map(ccx)), - C_array(T_int(), subcrates)])); - ret map; + llvm::LLVMSetInitializer(map, C_struct([p2i(create_module_map(ccx)), + C_array(T_int(), subcrates)])); } fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) { @@ -6242,6 +6273,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, let sha1s = map::mk_hashmap::(hasher, eqer); let short_names = map::mk_hashmap::(hasher, eqer); let sha = std::sha1::mk_sha1(); + let link_meta = link::build_link_meta(sess, *crate, output, sha); + let crate_map = decl_crate_map(sess, link_meta.name, llmod); let ccx = @{sess: sess, llmod: llmod, @@ -6253,7 +6286,7 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, ast_map: amap, item_symbols: new_int_hash::(), mutable main_fn: none::, - link_meta: link::build_link_meta(sess, *crate, output, sha), + link_meta: link_meta, tag_sizes: tag_sizes, discrims: new_int_hash::(), discrim_symbols: new_int_hash::(), @@ -6283,13 +6316,14 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, task_type: task_type, builder: BuilderRef_res(llvm::LLVMCreateBuilder()), shape_cx: shape::mk_ctxt(llmod), - gc_cx: gc::mk_ctxt()}; + gc_cx: gc::mk_ctxt(), + crate_map: crate_map}; let cx = new_local_ctxt(ccx); collect_items(ccx, crate); collect_tag_ctors(ccx, crate); trans_constants(ccx, crate); trans_mod(cx, crate.node.module); - create_crate_map(ccx); + fill_crate_map(ccx, crate_map); emit_tydescs(ccx); shape::gen_shape_tables(ccx); write_abi_version(ccx); diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 76e04bb9aab..2218b5a8ee8 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -123,7 +123,8 @@ task_type: TypeRef, builder: BuilderRef_res, shape_cx: shape::ctxt, - gc_cx: gc::ctxt}; + gc_cx: gc::ctxt, + crate_map: ValueRef}; type local_ctxt = {path: [str], diff --git a/src/rt/main.ll.in b/src/rt/main.ll.in index a953ef90444..8c19b2df251 100644 --- a/src/rt/main.ll.in +++ b/src/rt/main.ll.in @@ -11,14 +11,3 @@ %task = type { i32, i32, i32, i32, i32, i32, i32, i32 } %vec = type { i32, i32, [0 x i8] } - -@_rust_crate_map_toplevel = external global %0 - -declare i32 @rust_start(i32, i32, i32, i32) - -declare external void @_rust_main(i1* nocapture, %task*, %2* nocapture, %vec*) - -define i32 @"MAIN"(i32, i32) { - %result = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %vec*)* @_rust_main to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32)) - ret i32 %result -} diff --git a/src/rt/rust.cpp b/src/rt/rust.cpp index 122c7b306bf..b8a3cde5a93 100644 --- a/src/rt/rust.cpp +++ b/src/rt/rust.cpp @@ -74,9 +74,7 @@ command_line_args : public kernel_owned int check_claims = 0; extern "C" CDECL int -rust_start(uintptr_t main_fn, int argc, char **argv, - void* crate_map) { - +rust_start(uintptr_t main_fn, int argc, char **argv, void* crate_map) { rust_env *env = load_env(); update_log_settings(crate_map, env->logspec); -- GitLab