diff --git a/CMakeLists.txt b/CMakeLists.txt index 1c9f374d29..e1bfcf72b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -440,6 +440,7 @@ set(ZIG_STD_FILES "os/windows/error.zig" "os/windows/index.zig" "os/windows/util.zig" + "os/zen.zig" "rand.zig" "sort.zig" "special/bootstrap.zig" diff --git a/src/link.cpp b/src/link.cpp index 28055718c9..4396a0daa6 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -334,6 +334,13 @@ static void construct_linker_job_elf(LinkJob *lj) { if (!g->is_native_target) { lj->args.append("--allow-shlib-undefined"); } + + if (g->zig_target.os == OsZen) { + lj->args.append("-e"); + lj->args.append("main"); + + lj->args.append("--image-base=0x10000000"); + } } //static bool is_target_cyg_mingw(const ZigTarget *target) { diff --git a/std/os/index.zig b/std/os/index.zig index c9a7def1bb..eb192d7d85 100644 --- a/std/os/index.zig +++ b/std/os/index.zig @@ -7,9 +7,11 @@ const os = this; pub const windows = @import("windows/index.zig"); pub const darwin = @import("darwin.zig"); pub const linux = @import("linux.zig"); +pub const zen = @import("zen.zig"); pub const posix = switch(builtin.os) { Os.linux => linux, Os.macosx, Os.ios => darwin, + Os.zen => zen, else => @compileError("Unsupported OS"), }; diff --git a/std/os/zen.zig b/std/os/zen.zig new file mode 100644 index 0000000000..ffc491e404 --- /dev/null +++ b/std/os/zen.zig @@ -0,0 +1,94 @@ +////////////////////////////// +//// Reserved mailboxes //// +////////////////////////////// + +pub const MBOX_TERMINAL = 1; + + +/////////////////////////// +//// Syscall numbers //// +/////////////////////////// + +pub const SYS_createMailbox = 0; +pub const SYS_send = 1; +pub const SYS_receive = 2; +pub const SYS_map = 3; + + +//////////////////// +//// Syscalls //// +//////////////////// + +pub fn createMailbox(id: u16) { + _ = syscall1(SYS_createMailbox, id); +} + +pub fn send(mailbox_id: u16, data: usize) { + _ = syscall2(SYS_send, mailbox_id, data); +} + +pub fn receive(mailbox_id: u16) -> usize { + return syscall1(SYS_receive, mailbox_id); +} + +pub fn map(v_addr: usize, p_addr: usize, size: usize, writable: bool) -> bool { + return syscall4(SYS_map, v_addr, p_addr, size, usize(writable)) != 0; +} + + +///////////////////////// +//// Syscall stubs //// +///////////////////////// + +pub inline fn syscall0(number: usize) -> usize { + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number)); +} + +pub inline fn syscall1(number: usize, arg1: usize) -> usize { + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number), + [arg1] "{ecx}" (arg1)); +} + +pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize { + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number), + [arg1] "{ecx}" (arg1), + [arg2] "{edx}" (arg2)); +} + +pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize { + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number), + [arg1] "{ecx}" (arg1), + [arg2] "{edx}" (arg2), + [arg3] "{ebx}" (arg3)); +} + +pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize { + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number), + [arg1] "{ecx}" (arg1), + [arg2] "{edx}" (arg2), + [arg3] "{ebx}" (arg3), + [arg4] "{esi}" (arg4)); +} + +pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, + arg4: usize, arg5: usize) -> usize +{ + return asm volatile ("int $0x80" + : [ret] "={eax}" (-> usize) + : [number] "{eax}" (number), + [arg1] "{ecx}" (arg1), + [arg2] "{edx}" (arg2), + [arg3] "{ebx}" (arg3), + [arg4] "{esi}" (arg4), + [arg5] "{edi}" (arg5)); +} diff --git a/std/special/bootstrap.zig b/std/special/bootstrap.zig index 177e245400..eea2229c42 100644 --- a/std/special/bootstrap.zig +++ b/std/special/bootstrap.zig @@ -11,6 +11,8 @@ comptime { const strong_linkage = builtin.GlobalLinkage.Strong; if (builtin.link_libc) { @export("main", main, strong_linkage); + } else if (builtin.os == builtin.Os.zen) { + @export("main", zenMain, strong_linkage); } else if (builtin.os == builtin.Os.windows) { @export("WinMainCRTStartup", WinMainCRTStartup, strong_linkage); } else { @@ -18,6 +20,12 @@ comptime { } } +extern fn zenMain() -> noreturn { + // TODO: call exit. + root.main() %% {}; + while (true) {} +} + nakedcc fn _start() -> noreturn { switch (builtin.arch) { builtin.Arch.x86_64 => { diff --git a/std/special/panic.zig b/std/special/panic.zig index 78117a5366..03c2586739 100644 --- a/std/special/panic.zig +++ b/std/special/panic.zig @@ -6,9 +6,13 @@ const builtin = @import("builtin"); pub coldcc fn panic(msg: []const u8) -> noreturn { - if (builtin.os == builtin.Os.freestanding) { - while (true) {} - } else { - @import("std").debug.panic("{}", msg); + switch (builtin.os) { + // TODO: fix panic in zen. + builtin.Os.freestanding, builtin.Os.zen => { + while (true) {} + }, + else => { + @import("std").debug.panic("{}", msg); + }, } }