Skip to content

Commit c2fe69b

Browse files
committed
rustc: Fix main() entry point signature on 64bit
To match the C signature, main() should be generated with C int type for the argc parameter and result, i.e. i32 instead of i64 on 64bit. That way it no longer relies on the upper 32 bits being zero, which I'm not sure is guaranteed by ABIs or startup code.
1 parent 6c9a4ba commit c2fe69b

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

src/librustc_trans/base.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,6 @@ use value::Value;
7777
use rustc::util::nodemap::{NodeSet, FxHashMap, FxHashSet, DefIdSet};
7878
use CrateInfo;
7979

80-
use libc::c_uint;
8180
use std::any::Any;
8281
use std::cell::RefCell;
8382
use std::ffi::{CStr, CString};
@@ -692,7 +691,8 @@ fn maybe_create_entry_wrapper(ccx: &CrateContext) {
692691
sp: Span,
693692
rust_main: ValueRef,
694693
use_start_lang_item: bool) {
695-
let llfty = Type::func(&[ccx.isize_ty(), Type::i8p(ccx).ptr_to()], &ccx.isize_ty());
694+
// Signature of native main(), corresponding to C's `int main(int, char **)`
695+
let llfty = Type::func(&[Type::c_int(ccx), Type::i8p(ccx).ptr_to()], &Type::c_int(ccx));
696696

697697
if declare::get_defined_value(ccx, "main").is_some() {
698698
// FIXME: We should be smart and show a better diagnostic here.
@@ -711,19 +711,27 @@ fn maybe_create_entry_wrapper(ccx: &CrateContext) {
711711

712712
debuginfo::gdb::insert_reference_to_gdb_debug_scripts_section_global(ccx, &bld);
713713

714+
// Params from native main() used as args for rust start function
715+
let param_argc = get_param(llfn, 0);
716+
let param_argv = get_param(llfn, 1);
717+
let arg_argc = bld.intcast(param_argc, ccx.isize_ty(), true);
718+
let arg_argv = param_argv;
719+
714720
let (start_fn, args) = if use_start_lang_item {
715721
let start_def_id = ccx.tcx().require_lang_item(StartFnLangItem);
716722
let start_instance = Instance::mono(ccx.tcx(), start_def_id);
717723
let start_fn = callee::get_fn(ccx, start_instance);
718-
(start_fn, vec![bld.pointercast(rust_main, Type::i8p(ccx).ptr_to()), get_param(llfn, 0),
719-
get_param(llfn, 1)])
724+
(start_fn, vec![bld.pointercast(rust_main, Type::i8p(ccx).ptr_to()),
725+
arg_argc, arg_argv])
720726
} else {
721727
debug!("using user-defined start fn");
722-
(rust_main, vec![get_param(llfn, 0 as c_uint), get_param(llfn, 1 as c_uint)])
728+
(rust_main, vec![arg_argc, arg_argv])
723729
};
724730

725731
let result = bld.call(start_fn, &args, None);
726-
bld.ret(result);
732+
733+
// Return rust start function's result from native main()
734+
bld.ret(bld.intcast(result, Type::c_int(ccx), true));
727735
}
728736
}
729737

0 commit comments

Comments
 (0)