Don't put a copy of main (the C one) in each binary we produce. This is a step
in getting a driver that works on all linux systems. Sorry for the linker hacks, I will remove them after snapshotting a new compiler.
This commit is contained in:
parent
df9cf0be9b
commit
b1d6f12a05
|
@ -144,9 +144,9 @@ COMPILER_INPUTS := $(wildcard $(addprefix $(S)src/comp/, \
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
LREQ := rt/$(CFG_RUNTIME) rustllvm/$(CFG_RUSTLLVM)
|
LREQ := rt/$(CFG_RUNTIME) rustllvm/$(CFG_RUSTLLVM)
|
||||||
SREQ0 := stage0/rustc$(X) $(LREQ) stage1/glue.o stage1/$(CFG_STDLIB)
|
SREQ0 := stage0/rustc$(X) $(LREQ) rt/main.a stage1/glue.o stage1/$(CFG_STDLIB)
|
||||||
SREQ1 := stage1/rustc$(X) $(LREQ) stage2/glue.o stage2/$(CFG_STDLIB)
|
SREQ1 := stage1/rustc$(X) $(LREQ) rt/main.a stage2/glue.o stage2/$(CFG_STDLIB)
|
||||||
SREQ2 := stage2/rustc$(X) $(LREQ) stage3/glue.o stage3/$(CFG_STDLIB)
|
SREQ2 := stage2/rustc$(X) $(LREQ) rt/main.a stage3/glue.o stage3/$(CFG_STDLIB)
|
||||||
|
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
|
@ -28,6 +28,8 @@ clean:
|
||||||
$(Q)rm -f stage3/rustc$(X) stage3/$(CFG_STDLIB) stage3/glue*
|
$(Q)rm -f stage3/rustc$(X) stage3/$(CFG_STDLIB) stage3/glue*
|
||||||
$(Q)rm -f rustllvm/$(CFG_RUSTLLVM) rustllvm/rustllvmbits.a
|
$(Q)rm -f rustllvm/$(CFG_RUSTLLVM) rustllvm/rustllvmbits.a
|
||||||
$(Q)rm -f rt/$(CFG_RUNTIME)
|
$(Q)rm -f rt/$(CFG_RUNTIME)
|
||||||
|
$(Q)rm -f rt/main.o
|
||||||
|
$(Q)rm -f rt/main.a
|
||||||
$(Q)rm -Rf $(PKG_NAME)-*.tar.gz dist
|
$(Q)rm -Rf $(PKG_NAME)-*.tar.gz dist
|
||||||
$(Q)rm -f $(foreach ext,o a d bc s exe,$(wildcard stage*/*.$(ext)))
|
$(Q)rm -f $(foreach ext,o a d bc s exe,$(wildcard stage*/*.$(ext)))
|
||||||
$(Q)rm -Rf $(foreach ext,out out.tmp \
|
$(Q)rm -Rf $(foreach ext,out out.tmp \
|
||||||
|
|
12
mk/rt.mk
12
mk/rt.mk
|
@ -76,6 +76,18 @@ rt/%.o: rt/%.s $(MKFILES)
|
||||||
@$(call E, compile: $@)
|
@$(call E, compile: $@)
|
||||||
$(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
|
$(Q)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
|
||||||
|
|
||||||
|
ifdef CFG_WINDOWSY
|
||||||
|
rt/main.ll: rt/main.ll.in
|
||||||
|
sed 's/MAIN/WinMain@16/' < $^ > $@
|
||||||
|
else
|
||||||
|
rt/main.ll: rt/main.ll.in
|
||||||
|
sed 's/MAIN/main/' < $^ > $@
|
||||||
|
endif
|
||||||
|
|
||||||
|
rt/main.a: rt/main.o
|
||||||
|
rm -f $@
|
||||||
|
ar crs $@ $^
|
||||||
|
|
||||||
rt/%.o: rt/%.ll $(MKFILES)
|
rt/%.o: rt/%.ll $(MKFILES)
|
||||||
@$(call E, llc: $@)
|
@$(call E, llc: $@)
|
||||||
$(Q)$(LLC) -filetype=obj -relocation-model=pic -march=x86 -o $@ $<
|
$(Q)$(LLC) -filetype=obj -relocation-model=pic -march=x86 -o $@ $<
|
||||||
|
|
|
@ -44,7 +44,7 @@ stage1/%.o: stage1/%.s
|
||||||
stage1/%$(X): stage1/%.o $(SREQ0)
|
stage1/%$(X): stage1/%.o $(SREQ0)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage1/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage1/glue.o -o $@ $< \
|
||||||
-Lstage1 -Lrustllvm -Lrt -lrustrt -lrustllvm -lstd -lm
|
-Lstage1 -Lrustllvm -Lrt rt/main.a -lrustrt -lrustllvm -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
|
|
@ -44,7 +44,7 @@ stage2/%.o: stage2/%.s
|
||||||
stage2/%$(X): stage2/%.o $(SREQ1)
|
stage2/%$(X): stage2/%.o $(SREQ1)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage2/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage2/glue.o -o $@ $< \
|
||||||
-Lstage2 -Lrustllvm -Lrt -lrustrt -lrustllvm -lstd -lm
|
-Lstage2 -Lrustllvm -Lrt rt/main.a -lrustrt -lrustllvm -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
|
|
@ -23,7 +23,7 @@ stage3/rustc.o: $(COMPILER_CRATE) $(COMPILER_INPUTS) $(SREQ2)
|
||||||
$(STAGE2) -c -o $@ $<
|
$(STAGE2) -c -o $@ $<
|
||||||
|
|
||||||
stage3/glue.o: stage2/rustc$(X) stage2/$(CFG_STDLIB) stage2/intrinsics.bc \
|
stage3/glue.o: stage2/rustc$(X) stage2/$(CFG_STDLIB) stage2/intrinsics.bc \
|
||||||
rustllvm/$(CFG_RUSTLLVM) rt/$(CFG_RUNTIME)
|
rustllvm/$(CFG_RUSTLLVM) rt/$(CFG_RUNTIME)
|
||||||
@$(call E, generate: $@)
|
@$(call E, generate: $@)
|
||||||
$(STAGE2) -c -o $@ --glue
|
$(STAGE2) -c -o $@ --glue
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ stage3/%.o: stage3/%.s
|
||||||
stage3/%$(X): stage3/%.o $(SREQ2)
|
stage3/%$(X): stage3/%.o $(SREQ2)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage3/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage3/glue.o -o $@ $< \
|
||||||
-Lstage3 -Lrustllvm -Lrt -lrustrt -lrustllvm -lstd -lm
|
-Lstage3 -Lrustllvm -Lrt rt/main.a -lrustrt -lrustllvm -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
|
|
@ -185,7 +185,7 @@ compile-check: tidy \
|
||||||
%.stage0$(X): %.stage0.o $(SREQ0)
|
%.stage0$(X): %.stage0.o $(SREQ0)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage1/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage1/glue.o -o $@ $< \
|
||||||
-Lstage1 -Lrt -lrustrt -lstd -lm
|
-Lstage1 -Lrt rt/main.a -lrustrt -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
@ -194,7 +194,7 @@ compile-check: tidy \
|
||||||
%.stage1$(X): %.stage1.o $(SREQ1)
|
%.stage1$(X): %.stage1.o $(SREQ1)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage2/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage2/glue.o -o $@ $< \
|
||||||
-Lstage2 -Lrt -lrustrt -lstd -lm
|
-Lstage2 -Lrt rt/main.a -lrustrt -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
@ -203,7 +203,7 @@ compile-check: tidy \
|
||||||
%.stage2$(X): %.stage2.o $(SREQ2)
|
%.stage2$(X): %.stage2.o $(SREQ2)
|
||||||
@$(call E, link [gcc]: $@)
|
@$(call E, link [gcc]: $@)
|
||||||
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage3/glue.o -o $@ $< \
|
$(Q)gcc $(CFG_GCCISH_CFLAGS) stage3/glue.o -o $@ $< \
|
||||||
-Lstage3 -Lrt -lrustrt -lstd -lm
|
-Lstage3 -Lrt rt/main.a -lrustrt -lstd -lm
|
||||||
@# dsymutil sometimes fails or prints a warning, but the
|
@# dsymutil sometimes fails or prints a warning, but the
|
||||||
@# program still runs. Since it simplifies debugging other
|
@# program still runs. Since it simplifies debugging other
|
||||||
@# programs, I\'ll live with the noise.
|
@# programs, I\'ll live with the noise.
|
||||||
|
|
|
@ -338,6 +338,9 @@ fn get_type_sha1(&@crate_ctxt ccx, &ty::t t) -> str {
|
||||||
|
|
||||||
fn mangle(&vec[str] ss) -> str {
|
fn mangle(&vec[str] ss) -> str {
|
||||||
|
|
||||||
|
if (vec::len(ss) > 0u && str::eq(vec::top(ss), "main")) {
|
||||||
|
ret "_rust_main";
|
||||||
|
}
|
||||||
// Follow C++ namespace-mangling style
|
// Follow C++ namespace-mangling style
|
||||||
|
|
||||||
auto n = "_ZN"; // Begin name-sequence.
|
auto n = "_ZN"; // Begin name-sequence.
|
||||||
|
@ -369,7 +372,7 @@ fn mangle_name_by_path_and_seq(&@crate_ctxt ccx, &vec[str] path,
|
||||||
ret mangle(path + [ccx.names.next(flav)]);
|
ret mangle(path + [ccx.names.next(flav)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mangle_name_by_path(&@crate_ctxt ccx, &vec[str] path) -> str {
|
fn mangle_name_by_path(&vec[str] path) -> str {
|
||||||
ret mangle(path);
|
ret mangle(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7095,7 +7098,7 @@ fn create_vtbl(@local_ctxt cx,
|
||||||
|
|
||||||
let @local_ctxt mcx = @rec(path = cx.path + ["method",
|
let @local_ctxt mcx = @rec(path = cx.path + ["method",
|
||||||
m.node.ident] with *cx);
|
m.node.ident] with *cx);
|
||||||
let str s = mangle_name_by_path(mcx.ccx, mcx.path);
|
let str s = mangle_name_by_path(mcx.path);
|
||||||
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s,
|
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s,
|
||||||
llfnty);
|
llfnty);
|
||||||
cx.ccx.item_ids.insert(m.node.id, llfn);
|
cx.ccx.item_ids.insert(m.node.id, llfn);
|
||||||
|
@ -7107,7 +7110,7 @@ fn create_vtbl(@local_ctxt cx,
|
||||||
methods += [llfn];
|
methods += [llfn];
|
||||||
}
|
}
|
||||||
auto vtbl = C_struct(methods);
|
auto vtbl = C_struct(methods);
|
||||||
auto vtbl_name = mangle_name_by_path(cx.ccx, cx.path + ["vtbl"]);
|
auto vtbl_name = mangle_name_by_path(cx.path + ["vtbl"]);
|
||||||
auto gvar = llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl),
|
auto gvar = llvm::LLVMAddGlobal(cx.ccx.llmod, val_ty(vtbl),
|
||||||
str::buf(vtbl_name));
|
str::buf(vtbl_name));
|
||||||
llvm::LLVMSetInitializer(gvar, vtbl);
|
llvm::LLVMSetInitializer(gvar, vtbl);
|
||||||
|
@ -7124,7 +7127,7 @@ fn trans_dtor(@local_ctxt cx,
|
||||||
&@ast::method dtor) -> ValueRef {
|
&@ast::method dtor) -> ValueRef {
|
||||||
|
|
||||||
auto llfnty = T_dtor(cx.ccx, dtor.span, llself_ty);
|
auto llfnty = T_dtor(cx.ccx, dtor.span, llself_ty);
|
||||||
let str s = mangle_name_by_path(cx.ccx, cx.path + ["drop"]);
|
let str s = mangle_name_by_path(cx.path + ["drop"]);
|
||||||
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
|
let ValueRef llfn = decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
|
||||||
cx.ccx.item_ids.insert(dtor.node.id, llfn);
|
cx.ccx.item_ids.insert(dtor.node.id, llfn);
|
||||||
cx.ccx.item_symbols.insert(dtor.node.id, s);
|
cx.ccx.item_symbols.insert(dtor.node.id, s);
|
||||||
|
@ -7518,7 +7521,7 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Declare the function itself.
|
// Declare the function itself.
|
||||||
let str s = mangle_name_by_path(ccx, path);
|
let str s = mangle_name_by_path(path);
|
||||||
let ValueRef llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfty);
|
let ValueRef llfn = decl_internal_fastcall_fn(ccx.llmod, s, llfty);
|
||||||
|
|
||||||
// Declare the global constant pair that points to it.
|
// Declare the global constant pair that points to it.
|
||||||
|
@ -7532,6 +7535,8 @@ fn decl_fn_and_pair(&@crate_ctxt ccx, &span sp,
|
||||||
ccx.sess.span_err(sp, "multiple 'main' functions");
|
ccx.sess.span_err(sp, "multiple 'main' functions");
|
||||||
}
|
}
|
||||||
log #fmt("registering %s as main function for crate", ps);
|
log #fmt("registering %s as main function for crate", ps);
|
||||||
|
llvm::LLVMSetLinkage(llfn, lib::llvm::LLVMExternalLinkage
|
||||||
|
as llvm::Linkage);
|
||||||
ccx.main_fn = some(llfn);
|
ccx.main_fn = some(llfn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7593,7 +7598,7 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx,
|
||||||
// Declare the wrapper.
|
// Declare the wrapper.
|
||||||
auto t = node_ann_type(ccx, ann);
|
auto t = node_ann_type(ccx, ann);
|
||||||
auto wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
|
auto wrapper_type = native_fn_wrapper_type(ccx, sp, num_ty_param, t);
|
||||||
let str s = mangle_name_by_path(ccx, path);
|
let str s = mangle_name_by_path(path);
|
||||||
let ValueRef wrapper_fn = decl_internal_fastcall_fn(ccx.llmod, s,
|
let ValueRef wrapper_fn = decl_internal_fastcall_fn(ccx.llmod, s,
|
||||||
wrapper_type);
|
wrapper_type);
|
||||||
|
|
||||||
|
@ -7996,51 +8001,6 @@ fn create_typedefs(&@crate_ctxt cx) {
|
||||||
llvm::LLVMAddTypeName(cx.llmod, str::buf("tydesc"), T_tydesc(cx.tn));
|
llvm::LLVMAddTypeName(cx.llmod, str::buf("tydesc"), T_tydesc(cx.tn));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_main_fn(@local_ctxt cx, ValueRef crate_map) {
|
|
||||||
auto T_main_args = [T_int(), T_int()];
|
|
||||||
auto T_rust_start_args = [T_int(), T_int(), T_int(), T_int()];
|
|
||||||
|
|
||||||
auto main_name;
|
|
||||||
if (str::eq(std::os::target_os(), "win32")) {
|
|
||||||
main_name = "WinMain@16";
|
|
||||||
} else {
|
|
||||||
main_name = "main";
|
|
||||||
}
|
|
||||||
|
|
||||||
auto llmain =
|
|
||||||
decl_cdecl_fn(cx.ccx.llmod, main_name, T_fn(T_main_args, T_int()));
|
|
||||||
|
|
||||||
auto llrust_start = decl_cdecl_fn(cx.ccx.llmod, "rust_start",
|
|
||||||
T_fn(T_rust_start_args, T_int()));
|
|
||||||
|
|
||||||
auto llargc = llvm::LLVMGetParam(llmain, 0u);
|
|
||||||
auto llargv = llvm::LLVMGetParam(llmain, 1u);
|
|
||||||
auto llrust_main = alt (cx.ccx.main_fn) {
|
|
||||||
case (none) {
|
|
||||||
cx.ccx.sess.err("missing 'main' function");
|
|
||||||
// FIXME: shouldn't sess.err's ! result unify with f?
|
|
||||||
C_nil()
|
|
||||||
}
|
|
||||||
case (some(?f)) { f }
|
|
||||||
};
|
|
||||||
|
|
||||||
//
|
|
||||||
// Emit the moral equivalent of:
|
|
||||||
//
|
|
||||||
// main(int argc, char **argv) {
|
|
||||||
// rust_start(&_rust.main, argc, argv);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
|
|
||||||
let BasicBlockRef llbb =
|
|
||||||
llvm::LLVMAppendBasicBlock(llmain, str::buf(""));
|
|
||||||
auto b = new_builder(llbb);
|
|
||||||
|
|
||||||
auto start_args = [p2i(llrust_main), llargc, llargv, p2i(crate_map)];
|
|
||||||
|
|
||||||
b.Ret(b.Call(llrust_start, start_args));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] {
|
fn declare_intrinsics(ModuleRef llmod) -> hashmap[str,ValueRef] {
|
||||||
|
|
||||||
let vec[TypeRef] T_memmove32_args = [T_ptr(T_i8()), T_ptr(T_i8()),
|
let vec[TypeRef] T_memmove32_args = [T_ptr(T_i8()), T_ptr(T_i8()),
|
||||||
|
@ -8211,8 +8171,6 @@ fn create_module_map(&@crate_ctxt ccx) -> ValueRef {
|
||||||
auto maptype = T_array(elttype, ccx.module_data.size() + 1u);
|
auto maptype = T_array(elttype, ccx.module_data.size() + 1u);
|
||||||
auto map = llvm::LLVMAddGlobal(ccx.llmod, maptype,
|
auto map = llvm::LLVMAddGlobal(ccx.llmod, maptype,
|
||||||
str::buf("_rust_mod_map"));
|
str::buf("_rust_mod_map"));
|
||||||
llvm::LLVMSetLinkage(map, lib::llvm::LLVMInternalLinkage
|
|
||||||
as llvm::Linkage);
|
|
||||||
let vec[ValueRef] elts = [];
|
let vec[ValueRef] elts = [];
|
||||||
for each (@tup(str, ValueRef) item in ccx.module_data.items()) {
|
for each (@tup(str, ValueRef) item in ccx.module_data.items()) {
|
||||||
auto elt = C_struct([p2i(C_cstr(ccx, item._0)), p2i(item._1)]);
|
auto elt = C_struct([p2i(C_cstr(ccx, item._0)), p2i(item._1)]);
|
||||||
|
@ -8245,7 +8203,14 @@ fn create_crate_map(&@crate_ctxt ccx) -> ValueRef {
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
vec::push[ValueRef](subcrates, C_int(0));
|
vec::push[ValueRef](subcrates, C_int(0));
|
||||||
auto sym_name = "_rust_crate_map_" + crate_name(ccx, "__none__");
|
auto cname = crate_name(ccx, "__none__");
|
||||||
|
auto mapname;
|
||||||
|
if (ccx.sess.get_opts().shared) {
|
||||||
|
mapname = cname;
|
||||||
|
} else {
|
||||||
|
mapname = "toplevel";
|
||||||
|
}
|
||||||
|
auto sym_name = "_rust_crate_map_" + mapname;
|
||||||
auto arrtype = T_array(T_int(), vec::len[ValueRef](subcrates));
|
auto arrtype = T_array(T_int(), vec::len[ValueRef](subcrates));
|
||||||
auto maptype = T_struct([T_int(), arrtype]);
|
auto maptype = T_struct([T_int(), arrtype]);
|
||||||
auto map = llvm::LLVMAddGlobal(ccx.llmod, maptype, str::buf(sym_name));
|
auto map = llvm::LLVMAddGlobal(ccx.llmod, maptype, str::buf(sym_name));
|
||||||
|
@ -8322,9 +8287,17 @@ fn trans_crate(&session::session sess, &@ast::crate crate,
|
||||||
trans_constants(ccx, crate);
|
trans_constants(ccx, crate);
|
||||||
trans_mod(cx, crate.node.module);
|
trans_mod(cx, crate.node.module);
|
||||||
auto crate_map = create_crate_map(ccx);
|
auto crate_map = create_crate_map(ccx);
|
||||||
|
|
||||||
if (!sess.get_opts().shared) {
|
if (!sess.get_opts().shared) {
|
||||||
trans_main_fn(cx, crate_map);
|
auto gvar = llvm::LLVMAddGlobal(cx.ccx.llmod, T_ptr(T_int()),
|
||||||
}
|
str::buf("_rust_fetch_this_object_hack"));
|
||||||
|
|
||||||
|
auto gvar2 = llvm::LLVMAddGlobal(cx.ccx.llmod, T_ptr(T_ptr(T_int())),
|
||||||
|
str::buf("_rust_fetch_this_object_hack2"));
|
||||||
|
llvm::LLVMSetInitializer(gvar2, gvar);
|
||||||
|
llvm::LLVMSetGlobalConstant(gvar, True);
|
||||||
|
llvm::LLVMSetGlobalConstant(gvar2, True);
|
||||||
|
}
|
||||||
|
|
||||||
emit_tydescs(ccx);
|
emit_tydescs(ccx);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
%0 = type { i32, [1 x i32] }
|
||||||
|
%1 = type { i32, i32 }
|
||||||
|
%2 = type { i32, %3 }
|
||||||
|
%3 = type { %tydesc*, %4, i1, {} }
|
||||||
|
%4 = type { i1*, i1* }
|
||||||
|
%5 = type { i32, i32, i32, i32, [0 x %6*] }
|
||||||
|
%6 = type { i32, i32, i32, i32, [0 x i8] }
|
||||||
|
|
||||||
|
|
||||||
|
@_rust_crate_map_toplevel = external global %0
|
||||||
|
|
||||||
|
declare fastcc void @_rust_main(i1* nocapture, %task*, %2* nocapture, %5*);
|
||||||
|
declare i32 @rust_start(i32, i32, i32, i32)
|
||||||
|
|
||||||
|
%tydesc = type { %tydesc**, i32, i32, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*)*, void (i1*, %task*, i1*, %tydesc**, i8*, i8*, i8)* }
|
||||||
|
|
||||||
|
%task = type { i32, i32, i32, i32, i32, i32, i32, i32 }
|
||||||
|
|
||||||
|
@_rust_fetch_this_object_hack = global i32 0
|
||||||
|
|
||||||
|
define i32 @"MAIN"(i32, i32) {
|
||||||
|
%3 = tail call i32 @rust_start(i32 ptrtoint (void (i1*, %task*, %2*, %5*)* @_rust_main to i32), i32 %0, i32 %1, i32 ptrtoint (%0* @_rust_crate_map_toplevel to i32))
|
||||||
|
ret i32 %3
|
||||||
|
}
|
Loading…
Reference in New Issue