diff --git a/lib/std/os/linux/arm64.zig b/lib/std/os/linux/arm64.zig index 8571b260713ab628dff00b10df1b99ea37ca7be7..c3b9f09028e8a5bed25a08bf71a6a4e6dbc9b560 100644 --- a/lib/std/os/linux/arm64.zig +++ b/lib/std/os/linux/arm64.zig @@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * pub const restore = restore_rt; pub fn restore_rt() callconv(.Naked) void { - return asm volatile ("svc #0" - : - : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), - : "memory", "cc" - ); + switch (@import("builtin").zig_backend) { + .stage2_c => return asm volatile ( + \\ mov x8, %[number] + \\ svc #0 + : + : [number] "i" (@enumToInt(SYS.rt_sigreturn)), + : "memory", "cc" + ), + else => return asm volatile ("svc #0" + : + : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), + : "memory", "cc" + ), + } } pub const O = struct { diff --git a/lib/std/os/linux/i386.zig b/lib/std/os/linux/i386.zig index 2766393487b66b379d7041554ac210eec3f1065e..93570025191aecfecc5989b4a094e008963af259 100644 --- a/lib/std/os/linux/i386.zig +++ b/lib/std/os/linux/i386.zig @@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8); pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; pub fn restore() callconv(.Naked) void { - return asm volatile ("int $0x80" - : - : [number] "{eax}" (@enumToInt(SYS.sigreturn)), - : "memory" - ); + switch (@import("builtin").zig_backend) { + .stage2_c => return asm volatile ( + \\ movl %[number], %%eax + \\ int $0x80 + : + : [number] "i" (@enumToInt(SYS.sigreturn)), + : "memory" + ), + else => return asm volatile ("int $0x80" + : + : [number] "{eax}" (@enumToInt(SYS.sigreturn)), + : "memory" + ), + } } pub fn restore_rt() callconv(.Naked) void { - return asm volatile ("int $0x80" - : - : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), - : "memory" - ); + switch (@import("builtin").zig_backend) { + .stage2_c => return asm volatile ( + \\ movl %[number], %%eax + \\ int $0x80 + : + : [number] "i" (@enumToInt(SYS.rt_sigreturn)), + : "memory" + ), + else => return asm volatile ("int $0x80" + : + : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), + : "memory" + ), + } } pub const O = struct { diff --git a/lib/std/os/linux/x86_64.zig b/lib/std/os/linux/x86_64.zig index 7f320c010a8ae86de1e2662cae841ea2d281109c..90aae99082fa7f208bc8343657731a3f8d33e736 100644 --- a/lib/std/os/linux/x86_64.zig +++ b/lib/std/os/linux/x86_64.zig @@ -109,11 +109,14 @@ pub const restore = restore_rt; pub fn restore_rt() callconv(.Naked) void { switch (@import("builtin").zig_backend) { - .stage2_c => return asm volatile (std.fmt.comptimePrint( - \\ movl ${d}, %%eax - \\ syscall - \\ retq - , .{@enumToInt(SYS.rt_sigreturn)}) ::: "rcx", "r11", "memory"), + .stage2_c => return asm volatile ( + \\ movl %[number], %%eax + \\ syscall + \\ retq + : + : [number] "i" (@enumToInt(SYS.rt_sigreturn)), + : "rcx", "r11", "memory" + ), else => return asm volatile ("syscall" : : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), diff --git a/lib/std/start.zig b/lib/std/start.zig index 0563e2adad39326b3aa9d00fbaa868dd24469d8e..cc8a92d7b6444e1a4cbfee934ce6fa852d929578 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -265,23 +265,37 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv fn _start() callconv(.Naked) noreturn { switch (builtin.zig_backend) { - .stage2_c => switch (native_arch) { - .x86_64 => { - @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); - @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); - asm volatile ( - \\ xor %%rbp, %%rbp - \\ mov %%rsp, argc_argv_ptr + .stage2_c => { + @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); + @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); + switch (native_arch) { + .x86_64 => asm volatile ( + \\ xorl %%ebp, %%ebp + \\ movq %%rsp, argc_argv_ptr + \\ andq $-16, %%rsp \\ call _posixCallMainAndExit - ); - unreachable; - }, - else => @compileError("unsupported arch"), + ), + .i386 => asm volatile ( + \\ xorl %%ebp, %%ebp + \\ movl %%esp, argc_argv_ptr + \\ andl $-16, %%esp + \\ jmp _posixCallMainAndExit + ), + .aarch64, .aarch64_be, .arm, .armeb, .thumb => asm volatile ( + \\ mov fp, #0 + \\ mov lr, #0 + \\ str sp, argc_argv_ptr + \\ and sp, #-16 + \\ b _posixCallMainAndExit + ), + else => @compileError("unsupported arch"), + } + unreachable; }, else => switch (native_arch) { .x86_64 => { argc_argv_ptr = asm volatile ( - \\ xor %%rbp, %%rbp + \\ xor %%ebp, %%ebp : [argc] "={rsp}" (-> [*]usize), ); }, diff --git a/test/cases/aarch64-macos/hello_world_with_updates.0.zig b/test/cases/aarch64-macos/hello_world_with_updates.0.zig index 9f516ff1390f02aafc6203c8625793f8e58acdaf..a3bcb8527f7d022a89339467a8c0bdb398d73ba3 100644 --- a/test/cases/aarch64-macos/hello_world_with_updates.0.zig +++ b/test/cases/aarch64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=aarch64-macos // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :108:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-linux/hello_world_with_updates.0.zig b/test/cases/x86_64-linux/hello_world_with_updates.0.zig index 40abdd6c1fa4217b99f077793ecbb56bfa3f89a0..70cec703dad782900b6f9b84809b6b525344173d 100644 --- a/test/cases/x86_64-linux/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-linux/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-linux // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :108:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-macos/hello_world_with_updates.0.zig b/test/cases/x86_64-macos/hello_world_with_updates.0.zig index e0680c81d7420441fabd29498bf9258a5c16f291..3b8758a0e5e43f0e48d2b9a51415e560ee076571 100644 --- a/test/cases/x86_64-macos/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-macos/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-macos // -// :109:9: error: root struct of file 'tmp' has no member named 'main' +// :108:9: error: root struct of file 'tmp' has no member named 'main' diff --git a/test/cases/x86_64-windows/hello_world_with_updates.0.zig b/test/cases/x86_64-windows/hello_world_with_updates.0.zig index 04e1d4cfad0ac9045fb033b9f550e2d5fb1e64c8..e9a55f60610e7d3e4609914ca65340e5bc0916f6 100644 --- a/test/cases/x86_64-windows/hello_world_with_updates.0.zig +++ b/test/cases/x86_64-windows/hello_world_with_updates.0.zig @@ -2,4 +2,4 @@ // output_mode=Exe // target=x86_64-windows // -// :130:9: error: root struct of file 'tmp' has no member named 'main' +// :129:9: error: root struct of file 'tmp' has no member named 'main'