authorgravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2020-11-27 23:02:22+07:00
committergravatar for koachan@protonmail.comKoakuma <koachan@protonmail.com> 2020-11-27 23:02:22+07:00
log41c40f4bbec35ac260b6a7af6b0db0dafccb56ca
tree4ae6c1d7792ff784beea71c863bd176a1fe93144
parentcf2ee4ae2c6608261e849f0d75209669d435624c

Fix fork() on Linux/sparc64

fork() on Linux/sparc64 seems to return its result in two registers, with %o0 always holding the current process' PID, and the parent/child status returned in %o1. Add some glue code to convert those into the libc-style return value.

2 files changed, 20 insertions(+), 1 deletions(-)

lib/std/os/linux.zig+3-1
......@@ -112,7 +112,9 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:
112112}
113113
114114pub fn fork() usize {
115 if (@hasField(SYS, "fork")) {
115 if (comptime builtin.arch.isSPARC()) {
116 return syscall_fork();
117 } else if (@hasField(SYS, "fork")) {
116118 return syscall0(.fork);
117119 } else {
118120 return syscall2(.clone, SIGCHLD, 0);
lib/std/os/linux/sparc64.zig+17
......@@ -21,6 +21,23 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
2121 );
2222}
2323
24pub fn syscall_fork() usize {
25 return asm volatile (
26 \\ t 0x6d
27 \\ bcc,pt %%xcc, 1f
28 \\ nop
29 \\ ba 2f
30 \\ neg %%o0
31 \\ 1:
32 \\ dec %%o1
33 \\ and %%o1, %%o0, %%o0
34 \\ 2:
35 : [ret] "={o0}" (-> usize)
36 : [number] "{g1}" (@enumToInt(SYS.fork))
37 : "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
38 );
39}
40
2441pub fn syscall0(number: SYS) usize {
2542 return asm volatile (
2643 \\ t 0x6d