aboutsummaryrefslogtreecommitdiff
path: root/std/special/bootstrap.zig
diff options
context:
space:
mode:
authorAndrew Kelley <superjoe30@gmail.com>2017-03-26 06:39:28 -0400
committerAndrew Kelley <superjoe30@gmail.com>2017-03-26 06:39:28 -0400
commit5bc9feb5cb98fc13db62d01b2b9fec15677310a7 (patch)
tree12972dfc1f9b964bb74428ec0d6766e77b9b0be7 /std/special/bootstrap.zig
parent7ce753a16b0c16b4c6494467f42f2d5fe9a235e6 (diff)
downloadzig-5bc9feb5cb98fc13db62d01b2b9fec15677310a7.tar.gz
zig-5bc9feb5cb98fc13db62d01b2b9fec15677310a7.zip
organize std and make import relative to current file
closes #216
Diffstat (limited to 'std/special/bootstrap.zig')
-rw-r--r--std/special/bootstrap.zig59
1 files changed, 59 insertions, 0 deletions
diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig
new file mode 100644
index 0000000000..c9a36a0703
--- /dev/null
+++ b/std/special/bootstrap.zig
@@ -0,0 +1,59 @@
+// This file is in a package which has the root source file exposed as "@root".
+// It is included in the compilation unit when exporting an executable.
+
+const root = @import("@root");
+const std = @import("std");
+
+const want_main_symbol = std.target.linking_libc;
+const want_start_symbol = !want_main_symbol;
+
+const exit = std.os.posix.exit;
+
+var argc: usize = undefined;
+var argv: &&u8 = undefined;
+
+export nakedcc fn _start() -> noreturn {
+ @setFnVisible(this, want_start_symbol);
+ if (!want_start_symbol) {
+ unreachable;
+ }
+
+ switch (@compileVar("arch")) {
+ Arch.x86_64 => {
+ argc = asm("mov %[argc], [rsp]": [argc] "=r" (-> usize));
+ argv = asm("lea %[argv], [rsp + 8h]": [argv] "=r" (-> &&u8));
+ },
+ Arch.i386 => {
+ argc = asm("mov %[argc], [esp]": [argc] "=r" (-> usize));
+ argv = asm("lea %[argv], [esp + 4h]": [argv] "=r" (-> &&u8));
+ },
+ else => @compileError("unsupported arch"),
+ }
+ callMainAndExit()
+}
+
+fn callMain() -> %void {
+ const args = @alloca([]u8, argc);
+ for (args) |_, i| {
+ const ptr = argv[i];
+ args[i] = ptr[0...std.cstr.len(ptr)];
+ }
+ return root.main(args);
+}
+
+fn callMainAndExit() -> noreturn {
+ callMain() %% exit(1);
+ exit(0);
+}
+
+export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
+ @setFnVisible(this, want_main_symbol);
+ if (!want_main_symbol) {
+ unreachable;
+ }
+
+ argc = usize(c_argc);
+ argv = c_argv;
+ callMain() %% return 1;
+ return 0;
+}