| author | |
| committer | |
| log | 15df64ade8e460141d6485340ca0f88d21f03c47 |
| tree | 1ad5584aa242f04c28a118d656cec0888da22132 |
| parent | 1bab8548688ec13d29abbf3820bb2f9723e09c66 |
These are needed because clang doesn't support anything in naked
functions, not even assembly register inputs.8 files changed, 80 insertions(+), 36 deletions(-)
lib/std/os/linux/arm64.zig+14-5| ... | @@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * | ... | @@ -106,11 +106,20 @@ pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: * |
| 106 | pub const restore = restore_rt; | 106 | pub const restore = restore_rt; |
| 107 | 107 | ||
| 108 | pub fn restore_rt() callconv(.Naked) void { | 108 | pub fn restore_rt() callconv(.Naked) void { |
| 109 | return asm volatile ("svc #0" | 109 | switch (@import("builtin").zig_backend) { |
| 110 | : | 110 | .stage2_c => return asm volatile ( |
| 111 | : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), | 111 | \\ mov x8, %[number] |
| 112 | : "memory", "cc" | 112 | \\ svc #0 |
| 113 | ); | 113 | : |
| 114 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 115 | : "memory", "cc" | ||
| 116 | ), | ||
| 117 | else => return asm volatile ("svc #0" | ||
| 118 | : | ||
| 119 | : [number] "{x8}" (@enumToInt(SYS.rt_sigreturn)), | ||
| 120 | : "memory", "cc" | ||
| 121 | ), | ||
| 122 | } | ||
| 114 | } | 123 | } |
| 115 | 124 | ||
| 116 | pub const O = struct { | 125 | pub const O = struct { |
lib/std/os/linux/i386.zig+28-10| ... | @@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8); | ... | @@ -124,19 +124,37 @@ const CloneFn = std.meta.FnPtr(fn (arg: usize) callconv(.C) u8); |
| 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; | 124 | pub extern fn clone(func: CloneFn, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 125 | 125 | ||
| 126 | pub fn restore() callconv(.Naked) void { | 126 | pub fn restore() callconv(.Naked) void { |
| 127 | return asm volatile ("int $0x80" | 127 | switch (@import("builtin").zig_backend) { |
| 128 | : | 128 | .stage2_c => return asm volatile ( |
| 129 | : [number] "{eax}" (@enumToInt(SYS.sigreturn)), | 129 | \\ movl %[number], %%eax |
| 130 | : "memory" | 130 | \\ int $0x80 |
| 131 | ); | 131 | : |
| 132 | : [number] "i" (@enumToInt(SYS.sigreturn)), | ||
| 133 | : "memory" | ||
| 134 | ), | ||
| 135 | else => return asm volatile ("int $0x80" | ||
| 136 | : | ||
| 137 | : [number] "{eax}" (@enumToInt(SYS.sigreturn)), | ||
| 138 | : "memory" | ||
| 139 | ), | ||
| 140 | } | ||
| 132 | } | 141 | } |
| 133 | 142 | ||
| 134 | pub fn restore_rt() callconv(.Naked) void { | 143 | pub fn restore_rt() callconv(.Naked) void { |
| 135 | return asm volatile ("int $0x80" | 144 | switch (@import("builtin").zig_backend) { |
| 136 | : | 145 | .stage2_c => return asm volatile ( |
| 137 | : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), | 146 | \\ movl %[number], %%eax |
| 138 | : "memory" | 147 | \\ int $0x80 |
| 139 | ); | 148 | : |
| 149 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 150 | : "memory" | ||
| 151 | ), | ||
| 152 | else => return asm volatile ("int $0x80" | ||
| 153 | : | ||
| 154 | : [number] "{eax}" (@enumToInt(SYS.rt_sigreturn)), | ||
| 155 | : "memory" | ||
| 156 | ), | ||
| 157 | } | ||
| 140 | } | 158 | } |
| 141 | 159 | ||
| 142 | pub const O = struct { | 160 | pub const O = struct { |
lib/std/os/linux/x86_64.zig+8-5| ... | @@ -109,11 +109,14 @@ pub const restore = restore_rt; | ... | @@ -109,11 +109,14 @@ pub const restore = restore_rt; |
| 109 | 109 | ||
| 110 | pub fn restore_rt() callconv(.Naked) void { | 110 | pub fn restore_rt() callconv(.Naked) void { |
| 111 | switch (@import("builtin").zig_backend) { | 111 | switch (@import("builtin").zig_backend) { |
| 112 | .stage2_c => return asm volatile (std.fmt.comptimePrint( | 112 | .stage2_c => return asm volatile ( |
| 113 | \\ movl ${d}, %%eax | 113 | \\ movl %[number], %%eax |
| 114 | \\ syscall | 114 | \\ syscall |
| 115 | \\ retq | 115 | \\ retq |
| 116 | , .{@enumToInt(SYS.rt_sigreturn)}) ::: "rcx", "r11", "memory"), | 116 | : |
| 117 | : [number] "i" (@enumToInt(SYS.rt_sigreturn)), | ||
| 118 | : "rcx", "r11", "memory" | ||
| 119 | ), | ||
| 117 | else => return asm volatile ("syscall" | 120 | else => return asm volatile ("syscall" |
| 118 | : | 121 | : |
| 119 | : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), | 122 | : [number] "{rax}" (@enumToInt(SYS.rt_sigreturn)), |
lib/std/start.zig+26-12| ... | @@ -265,23 +265,37 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv | ... | @@ -265,23 +265,37 @@ fn EfiMain(handle: uefi.Handle, system_table: *uefi.tables.SystemTable) callconv |
| 265 | 265 | ||
| 266 | fn _start() callconv(.Naked) noreturn { | 266 | fn _start() callconv(.Naked) noreturn { |
| 267 | switch (builtin.zig_backend) { | 267 | switch (builtin.zig_backend) { |
| 268 | .stage2_c => switch (native_arch) { | 268 | .stage2_c => { |
| 269 | .x86_64 => { | 269 | @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); |
| 270 | @export(argc_argv_ptr, .{ .name = "argc_argv_ptr" }); | 270 | @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); |
| 271 | @export(posixCallMainAndExit, .{ .name = "_posixCallMainAndExit" }); | 271 | switch (native_arch) { |
| 272 | asm volatile ( | 272 | .x86_64 => asm volatile ( |
| 273 | \\ xor %%rbp, %%rbp | 273 | \\ xorl %%ebp, %%ebp |
| 274 | \\ mov %%rsp, argc_argv_ptr | 274 | \\ movq %%rsp, argc_argv_ptr |
| 275 | \\ andq $-16, %%rsp | ||
| 275 | \\ call _posixCallMainAndExit | 276 | \\ call _posixCallMainAndExit |
| 276 | ); | 277 | ), |
| 277 | unreachable; | 278 | .i386 => asm volatile ( |
| 278 | }, | 279 | \\ xorl %%ebp, %%ebp |
| 279 | else => @compileError("unsupported arch"), | 280 | \\ movl %%esp, argc_argv_ptr |
| 281 | \\ andl $-16, %%esp | ||
| 282 | \\ jmp _posixCallMainAndExit | ||
| 283 | ), | ||
| 284 | .aarch64, .aarch64_be, .arm, .armeb, .thumb => asm volatile ( | ||
| 285 | \\ mov fp, #0 | ||
| 286 | \\ mov lr, #0 | ||
| 287 | \\ str sp, argc_argv_ptr | ||
| 288 | \\ and sp, #-16 | ||
| 289 | \\ b _posixCallMainAndExit | ||
| 290 | ), | ||
| 291 | else => @compileError("unsupported arch"), | ||
| 292 | } | ||
| 293 | unreachable; | ||
| 280 | }, | 294 | }, |
| 281 | else => switch (native_arch) { | 295 | else => switch (native_arch) { |
| 282 | .x86_64 => { | 296 | .x86_64 => { |
| 283 | argc_argv_ptr = asm volatile ( | 297 | argc_argv_ptr = asm volatile ( |
| 284 | \\ xor %%rbp, %%rbp | 298 | \\ xor %%ebp, %%ebp |
| 285 | : [argc] "={rsp}" (-> [*]usize), | 299 | : [argc] "={rsp}" (-> [*]usize), |
| 286 | ); | 300 | ); |
| 287 | }, | 301 | }, |
test/cases/aarch64-macos/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=aarch64-macos | 3 | // target=aarch64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-linux/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-linux | 3 | // target=x86_64-linux |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-macos/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-macos | 3 | // target=x86_64-macos |
| 4 | // | 4 | // |
| 5 | // :109:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :108:9: error: root struct of file 'tmp' has no member named 'main' |
test/cases/x86_64-windows/hello_world_with_updates.0.zig+1-1| ... | @@ -2,4 +2,4 @@ | ... | @@ -2,4 +2,4 @@ |
| 2 | // output_mode=Exe | 2 | // output_mode=Exe |
| 3 | // target=x86_64-windows | 3 | // target=x86_64-windows |
| 4 | // | 4 | // |
| 5 | // :130:9: error: root struct of file 'tmp' has no member named 'main' | 5 | // :129:9: error: root struct of file 'tmp' has no member named 'main' |