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.
master
Koakuma 2020-11-27 23:02:22 +07:00
parent cf2ee4ae2c
commit 41c40f4bbe
2 changed files with 20 additions and 1 deletions

View File

@ -112,7 +112,9 @@ pub fn execve(path: [*:0]const u8, argv: [*:null]const ?[*:0]const u8, envp: [*:
}
pub fn fork() usize {
if (@hasField(SYS, "fork")) {
if (comptime builtin.arch.isSPARC()) {
return syscall_fork();
} else if (@hasField(SYS, "fork")) {
return syscall0(.fork);
} else {
return syscall2(.clone, SIGCHLD, 0);

View File

@ -21,6 +21,23 @@ pub fn syscall_pipe(fd: *[2]i32) usize {
);
}
pub fn syscall_fork() usize {
return asm volatile (
\\ t 0x6d
\\ bcc,pt %%xcc, 1f
\\ nop
\\ ba 2f
\\ neg %%o0
\\ 1:
\\ dec %%o1
\\ and %%o1, %%o0, %%o0
\\ 2:
: [ret] "={o0}" (-> usize)
: [number] "{g1}" (@enumToInt(SYS.fork))
: "memory", "xcc", "o1", "o2", "o3", "o4", "o5", "o7"
);
}
pub fn syscall0(number: SYS) usize {
return asm volatile (
\\ t 0x6d