diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-03-26 06:39:28 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-03-26 06:39:28 -0400 |
| commit | 5bc9feb5cb98fc13db62d01b2b9fec15677310a7 (patch) | |
| tree | 12972dfc1f9b964bb74428ec0d6766e77b9b0be7 /std/special/bootstrap.zig | |
| parent | 7ce753a16b0c16b4c6494467f42f2d5fe9a235e6 (diff) | |
| download | zig-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.zig | 59 |
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; +} |
