Skip to content

Commit f4e8ac2

Browse files
committed
auto merge of #5135 : brson/rust/start, r=pcwalton
r? #3406 Pretty straightforward. I'm using opaque pointers instead trying to get trans and core to agree on the types of the main function and crate map. One oddity is that this required changing the order of the `-lrustrt` argument to the linker in order to resolve `upcall_new_stack`. Linkers are mysterious.
2 parents a3dbd07 + f432723 commit f4e8ac2

File tree

4 files changed

+58
-18
lines changed

4 files changed

+58
-18
lines changed

src/libcore/rt.rs

+16-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
//! Runtime calls emitted by the compiler.
1212
1313
use cast::transmute;
14-
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t};
14+
use libc::{c_char, c_uchar, c_void, size_t, uintptr_t, c_int};
1515
use managed::raw::BoxRepr;
1616
use str;
1717
use sys;
@@ -121,6 +121,21 @@ pub unsafe fn strdup_uniq(ptr: *c_uchar, len: uint) -> ~str {
121121
str::raw::from_buf_len(ptr, len)
122122
}
123123

124+
#[lang="start"]
125+
pub fn start(main: *u8, argc: int, argv: *c_char,
126+
crate_map: *u8) -> int {
127+
128+
extern {
129+
fn rust_start(main: *c_void, argc: c_int, argv: *c_char,
130+
crate_map: *c_void) -> c_int;
131+
}
132+
133+
unsafe {
134+
return rust_start(main as *c_void, argc as c_int, argv,
135+
crate_map as *c_void) as int;
136+
}
137+
}
138+
124139
// Local Variables:
125140
// mode: rust;
126141
// fill-column: 78;

src/librustc/back/link.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -838,9 +838,6 @@ pub fn link_binary(sess: Session,
838838
}
839839
}
840840
841-
// Always want the runtime linked in
842-
cc_args.push(~"-lrustrt");
843-
844841
// On linux librt and libdl are an indirect dependencies via rustrt,
845842
// and binutils 2.22+ won't add them automatically
846843
if sess.targ_cfg.os == session::os_linux {
@@ -880,6 +877,9 @@ pub fn link_binary(sess: Session,
880877
cc_args.push(~"-lmorestack");
881878
}
882879

880+
// Always want the runtime linked in
881+
cc_args.push(~"-lrustrt");
882+
883883
// FIXME (#2397): At some point we want to rpath our guesses as to where
884884
// extern libraries might live, based on the addl_lib_search_paths
885885
cc_args.push_all(rpath::get_rpath_flags(sess, &output));

src/librustc/middle/lang_items.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,18 @@ pub enum LangItem {
7575
ReturnToMutFnLangItem, // 31
7676
CheckNotBorrowedFnLangItem, // 32
7777
StrDupUniqFnLangItem, // 33
78+
79+
StartFnLangItem, // 34
7880
}
7981

8082
pub struct LanguageItems {
81-
items: [ Option<def_id> * 34 ]
83+
items: [ Option<def_id> * 35 ]
8284
}
8385

8486
pub impl LanguageItems {
8587
static pub fn new(&self) -> LanguageItems {
8688
LanguageItems {
87-
items: [ None, ..34 ]
89+
items: [ None, ..35 ]
8890
}
8991
}
9092

@@ -136,6 +138,8 @@ pub impl LanguageItems {
136138
32 => "check_not_borrowed",
137139
33 => "strdup_uniq",
138140

141+
34 => "start",
142+
139143
_ => "???"
140144
}
141145
}
@@ -248,6 +252,9 @@ pub impl LanguageItems {
248252
pub fn strdup_uniq_fn(&const self) -> def_id {
249253
self.items[StrDupUniqFnLangItem as uint].get()
250254
}
255+
pub fn start_fn(&const self) -> def_id {
256+
self.items[StartFnLangItem as uint].get()
257+
}
251258
}
252259

253260
fn LanguageItemCollector(crate: @crate,
@@ -296,6 +303,7 @@ fn LanguageItemCollector(crate: @crate,
296303
item_refs.insert(@~"check_not_borrowed",
297304
CheckNotBorrowedFnLangItem as uint);
298305
item_refs.insert(@~"strdup_uniq", StrDupUniqFnLangItem as uint);
306+
item_refs.insert(@~"start", StartFnLangItem as uint);
299307

300308
LanguageItemCollector {
301309
crate: crate,

src/librustc/middle/trans/base.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -2267,7 +2267,7 @@ pub fn create_main_wrapper(ccx: @CrateContext,
22672267
fn main_name() -> ~str { return ~"WinMain@16"; }
22682268
#[cfg(unix)]
22692269
fn main_name() -> ~str { return ~"main"; }
2270-
let llfty = T_fn(~[ccx.int_type, ccx.int_type], ccx.int_type);
2270+
let llfty = T_fn(~[ccx.int_type, T_ptr(T_i8())], ccx.int_type);
22712271
22722272
// FIXME #4404 android JNI hacks
22732273
let llfn = if *ccx.sess.building_library {
@@ -2285,33 +2285,50 @@ pub fn create_main_wrapper(ccx: @CrateContext,
22852285
llvm::LLVMPositionBuilderAtEnd(bld, llbb);
22862286
}
22872287
let crate_map = ccx.crate_map;
2288-
let start_ty = T_fn(~[val_ty(rust_main), ccx.int_type, ccx.int_type,
2289-
val_ty(crate_map)], ccx.int_type);
2290-
let start = decl_cdecl_fn(ccx.llmod, ~"rust_start", start_ty);
2288+
let start_def_id = ccx.tcx.lang_items.start_fn();
2289+
let start_fn = if start_def_id.crate == ast::local_crate {
2290+
ccx.sess.bug(~"start lang item is never in the local crate")
2291+
} else {
2292+
let start_fn_type = csearch::get_type(ccx.tcx,
2293+
start_def_id).ty;
2294+
trans_external_path(ccx, start_def_id, start_fn_type)
2295+
};
2296+
2297+
let retptr = unsafe {
2298+
llvm::LLVMBuildAlloca(bld, ccx.int_type, noname())
2299+
};
22912300
22922301
let args = unsafe {
2302+
let opaque_rust_main = llvm::LLVMBuildPointerCast(
2303+
bld, rust_main, T_ptr(T_i8()), noname());
2304+
let opaque_crate_map = llvm::LLVMBuildPointerCast(
2305+
bld, crate_map, T_ptr(T_i8()), noname());
2306+
22932307
if *ccx.sess.building_library {
22942308
~[
2295-
rust_main,
2309+
retptr,
2310+
C_null(T_opaque_box_ptr(ccx)),
2311+
opaque_rust_main,
22962312
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
22972313
llvm::LLVMConstInt(T_i32(), 0u as c_ulonglong, False),
2298-
crate_map
2314+
opaque_crate_map
22992315
]
23002316
} else {
23012317
~[
2302-
rust_main,
2318+
retptr,
2319+
C_null(T_opaque_box_ptr(ccx)),
2320+
opaque_rust_main,
23032321
llvm::LLVMGetParam(llfn, 0 as c_uint),
23042322
llvm::LLVMGetParam(llfn, 1 as c_uint),
2305-
crate_map
2323+
opaque_crate_map
23062324
]
23072325
}
23082326
};
23092327
2310-
let result = unsafe {
2311-
llvm::LLVMBuildCall(bld, start, vec::raw::to_ptr(args),
2312-
args.len() as c_uint, noname())
2313-
};
23142328
unsafe {
2329+
llvm::LLVMBuildCall(bld, start_fn, vec::raw::to_ptr(args),
2330+
args.len() as c_uint, noname());
2331+
let result = llvm::LLVMBuildLoad(bld, retptr, noname());
23152332
llvm::LLVMBuildRet(bld, result);
23162333
}
23172334
}

0 commit comments

Comments
 (0)