| author | |
| committer | |
| log | 17f2af10b56dd508ebd4a22834fd594cb5a49864 |
| tree | 38da45089fee93cf06ff7753eae768c922b5fdab |
| parent | bed4bfa69ad57595e4595caa96653d9241a8dc2e |
Also enable the segfault handler for all the supported architectures
beside MIPS.11 files changed, 264 insertions(+), 84 deletions(-)
lib/std/debug.zig+24-5| ... | ... | @@ -2336,7 +2336,7 @@ fn getDebugInfoAllocator() *mem.Allocator { |
| 2336 | 2336 | } |
| 2337 | 2337 | |
| 2338 | 2338 | /// Whether or not the current target can print useful debug information when a segfault occurs. |
| 2339 | pub const have_segfault_handling_support = (builtin.arch == builtin.Arch.x86_64 and builtin.os == .linux) or builtin.os == .windows; | |
| 2339 | pub const have_segfault_handling_support = builtin.os == .linux or builtin.os == .windows; | |
| 2340 | 2340 | pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler")) |
| 2341 | 2341 | root.enable_segfault_handler |
| 2342 | 2342 | else |
| ... | ... | @@ -2390,12 +2390,31 @@ extern fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *con |
| 2390 | 2390 | // and the resulting segfault will crash the process rather than continually dump stack traces. |
| 2391 | 2391 | resetSegfaultHandler(); |
| 2392 | 2392 | |
| 2393 | const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); | |
| 2394 | const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]); | |
| 2395 | const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]); | |
| 2396 | 2393 | const addr = @ptrToInt(info.fields.sigfault.addr); |
| 2397 | 2394 | std.debug.warn("Segmentation fault at address 0x{x}\n", addr); |
| 2398 | dumpStackTraceFromBase(bp, ip); | |
| 2395 | ||
| 2396 | switch (builtin.arch) { | |
| 2397 | .x86_64 => { | |
| 2398 | const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); | |
| 2399 | const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]); | |
| 2400 | const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]); | |
| 2401 | dumpStackTraceFromBase(bp, ip); | |
| 2402 | }, | |
| 2403 | .arm => { | |
| 2404 | const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); | |
| 2405 | const ip = @intCast(usize, ctx.mcontext.arm_pc); | |
| 2406 | const bp = @intCast(usize, ctx.mcontext.arm_fp); | |
| 2407 | dumpStackTraceFromBase(bp, ip); | |
| 2408 | }, | |
| 2409 | .aarch64 => { | |
| 2410 | const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)); | |
| 2411 | const ip = @intCast(usize, ctx.mcontext.pc); | |
| 2412 | // x29 is the ABI-designated frame pointer | |
| 2413 | const bp = @intCast(usize, ctx.mcontext.regs[29]); | |
| 2414 | dumpStackTraceFromBase(bp, ip); | |
| 2415 | }, | |
| 2416 | else => {}, | |
| 2417 | } | |
| 2399 | 2418 | |
| 2400 | 2419 | // We cannot allow the signal handler to return because when it runs the original instruction |
| 2401 | 2420 | // again, the memory may be mapped and undefined behavior would occur rather than repeating |
lib/std/os/bits/linux.zig+113-18| ... | ... | @@ -140,9 +140,27 @@ pub const WEXITED = 4; |
| 140 | 140 | pub const WCONTINUED = 8; |
| 141 | 141 | pub const WNOWAIT = 0x1000000; |
| 142 | 142 | |
| 143 | pub const SA_NOCLDSTOP = 1; | |
| 144 | pub const SA_NOCLDWAIT = 2; | |
| 145 | pub const SA_SIGINFO = 4; | |
| 143 | pub usingnamespace if (is_mips) | |
| 144 | struct { | |
| 145 | pub const SA_NOCLDSTOP = 1; | |
| 146 | pub const SA_NOCLDWAIT = 0x10000; | |
| 147 | pub const SA_SIGINFO = 8; | |
| 148 | ||
| 149 | pub const SIG_BLOCK = 1; | |
| 150 | pub const SIG_UNBLOCK = 2; | |
| 151 | pub const SIG_SETMASK = 3; | |
| 152 | } | |
| 153 | else | |
| 154 | struct { | |
| 155 | pub const SA_NOCLDSTOP = 1; | |
| 156 | pub const SA_NOCLDWAIT = 2; | |
| 157 | pub const SA_SIGINFO = 4; | |
| 158 | ||
| 159 | pub const SIG_BLOCK = 0; | |
| 160 | pub const SIG_UNBLOCK = 1; | |
| 161 | pub const SIG_SETMASK = 2; | |
| 162 | }; | |
| 163 | ||
| 146 | 164 | pub const SA_ONSTACK = 0x08000000; |
| 147 | 165 | pub const SA_RESTART = 0x10000000; |
| 148 | 166 | pub const SA_NODEFER = 0x40000000; |
| ... | ... | @@ -209,10 +227,6 @@ pub const SEEK_SET = 0; |
| 209 | 227 | pub const SEEK_CUR = 1; |
| 210 | 228 | pub const SEEK_END = 2; |
| 211 | 229 | |
| 212 | pub const SIG_BLOCK = 0; | |
| 213 | pub const SIG_UNBLOCK = 1; | |
| 214 | pub const SIG_SETMASK = 2; | |
| 215 | ||
| 216 | 230 | pub const PROTO_ip = 0o000; |
| 217 | 231 | pub const PROTO_icmp = 0o001; |
| 218 | 232 | pub const PROTO_igmp = 0o002; |
| ... | ... | @@ -786,17 +800,34 @@ pub const winsize = extern struct { |
| 786 | 800 | ws_ypixel: u16, |
| 787 | 801 | }; |
| 788 | 802 | |
| 789 | pub const NSIG = 65; | |
| 803 | pub const NSIG = if (is_mips) 128 else 65; | |
| 790 | 804 | pub const sigset_t = [128 / @sizeOf(usize)]usize; |
| 791 | pub const all_mask = [_]u32{ 0xffffffff, 0xffffffff }; | |
| 792 | pub const app_mask = [_]u32{ 0xfffffffc, 0x7fffffff }; | |
| 793 | 805 | |
| 794 | pub const k_sigaction = extern struct { | |
| 795 | sigaction: ?extern fn (i32, *siginfo_t, *c_void) void, | |
| 796 | flags: usize, | |
| 797 | restorer: extern fn () void, | |
| 798 | mask: [2]u32, | |
| 799 | }; | |
| 806 | pub usingnamespace if (NSIG == 65) | |
| 807 | struct { | |
| 808 | pub const all_mask = [2]u32{ 0xffffffff, 0xffffffff }; | |
| 809 | pub const app_mask = [2]u32{ 0xfffffffc, 0x7fffffff }; | |
| 810 | } | |
| 811 | else | |
| 812 | struct { | |
| 813 | pub const all_mask = [4]u32{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; | |
| 814 | pub const app_mask = [4]u32{ 0xfffffffc, 0x7fffffff, 0xffffffff, 0xffffffff }; | |
| 815 | }; | |
| 816 | ||
| 817 | pub const k_sigaction = if (is_mips) | |
| 818 | extern struct { | |
| 819 | flags: usize, | |
| 820 | sigaction: ?extern fn (i32, *siginfo_t, *c_void) void, | |
| 821 | mask: [4]u32, | |
| 822 | restorer: extern fn () void, | |
| 823 | } | |
| 824 | else | |
| 825 | extern struct { | |
| 826 | sigaction: ?extern fn (i32, *siginfo_t, *c_void) void, | |
| 827 | flags: usize, | |
| 828 | restorer: extern fn () void, | |
| 829 | mask: [2]u32, | |
| 830 | }; | |
| 800 | 831 | |
| 801 | 832 | /// Renamed from `sigaction` to `Sigaction` to avoid conflict with the syscall. |
| 802 | 833 | pub const Sigaction = extern struct { |
| ... | ... | @@ -1030,12 +1061,12 @@ pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t { |
| 1030 | 1061 | //#define CPU_EQUAL(s1,s2) CPU_EQUAL_S(sizeof(cpu_set_t),s1,s2) |
| 1031 | 1062 | |
| 1032 | 1063 | pub const MINSIGSTKSZ = switch (builtin.arch) { |
| 1033 | .i386, .x86_64, .arm => 2048, | |
| 1064 | .i386, .x86_64, .arm, .mipsel => 2048, | |
| 1034 | 1065 | .aarch64 => 5120, |
| 1035 | 1066 | else => @compileError("MINSIGSTKSZ not defined for this architecture"), |
| 1036 | 1067 | }; |
| 1037 | 1068 | pub const SIGSTKSZ = switch (builtin.arch) { |
| 1038 | .i386, .x86_64, .arm => 8192, | |
| 1069 | .i386, .x86_64, .arm, .mipsel => 8192, | |
| 1039 | 1070 | .aarch64 => 16384, |
| 1040 | 1071 | else => @compileError("SIGSTKSZ not defined for this architecture"), |
| 1041 | 1072 | }; |
| ... | ... | @@ -1050,6 +1081,70 @@ pub const stack_t = extern struct { |
| 1050 | 1081 | ss_size: isize, |
| 1051 | 1082 | }; |
| 1052 | 1083 | |
| 1084 | pub const sigval = extern union { | |
| 1085 | int: i32, | |
| 1086 | ptr: *c_void, | |
| 1087 | }; | |
| 1088 | ||
| 1089 | const siginfo_fields_union = extern union { | |
| 1090 | pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8, | |
| 1091 | common: extern struct { | |
| 1092 | first: extern union { | |
| 1093 | piduid: extern struct { | |
| 1094 | pid: pid_t, | |
| 1095 | uid: uid_t, | |
| 1096 | }, | |
| 1097 | timer: extern struct { | |
| 1098 | timerid: i32, | |
| 1099 | overrun: i32, | |
| 1100 | }, | |
| 1101 | }, | |
| 1102 | second: extern union { | |
| 1103 | value: sigval, | |
| 1104 | sigchld: extern struct { | |
| 1105 | status: i32, | |
| 1106 | utime: clock_t, | |
| 1107 | stime: clock_t, | |
| 1108 | }, | |
| 1109 | }, | |
| 1110 | }, | |
| 1111 | sigfault: extern struct { | |
| 1112 | addr: *c_void, | |
| 1113 | addr_lsb: i16, | |
| 1114 | first: extern union { | |
| 1115 | addr_bnd: extern struct { | |
| 1116 | lower: *c_void, | |
| 1117 | upper: *c_void, | |
| 1118 | }, | |
| 1119 | pkey: u32, | |
| 1120 | }, | |
| 1121 | }, | |
| 1122 | sigpoll: extern struct { | |
| 1123 | band: isize, | |
| 1124 | fd: i32, | |
| 1125 | }, | |
| 1126 | sigsys: extern struct { | |
| 1127 | call_addr: *c_void, | |
| 1128 | syscall: i32, | |
| 1129 | arch: u32, | |
| 1130 | }, | |
| 1131 | }; | |
| 1132 | ||
| 1133 | pub const siginfo_t = if (is_mips) | |
| 1134 | extern struct { | |
| 1135 | signo: i32, | |
| 1136 | code: i32, | |
| 1137 | errno: i32, | |
| 1138 | fields: siginfo_fields_union, | |
| 1139 | } | |
| 1140 | else | |
| 1141 | extern struct { | |
| 1142 | signo: i32, | |
| 1143 | errno: i32, | |
| 1144 | code: i32, | |
| 1145 | fields: siginfo_fields_union, | |
| 1146 | }; | |
| 1147 | ||
| 1053 | 1148 | pub const io_uring_params = extern struct { |
| 1054 | 1149 | sq_entries: u32, |
| 1055 | 1150 | cq_entries: u32, |
lib/std/os/bits/linux/arm-eabi.zig+36-2| ... | ... | @@ -1,10 +1,11 @@ |
| 1 | 1 | // arm-eabi-specific declarations that are intended to be imported into the POSIX namespace. |
| 2 | ||
| 3 | const std = @import("../../std.zig"); | |
| 2 | const std = @import("../../../std.zig"); | |
| 4 | 3 | const linux = std.os.linux; |
| 5 | 4 | const socklen_t = linux.socklen_t; |
| 6 | 5 | const iovec = linux.iovec; |
| 7 | 6 | const iovec_const = linux.iovec_const; |
| 7 | const stack_t = linux.stack_t; | |
| 8 | const sigset_t = linux.sigset_t; | |
| 8 | 9 | |
| 9 | 10 | pub const SYS_restart_syscall = 0; |
| 10 | 11 | pub const SYS_exit = 1; |
| ... | ... | @@ -565,4 +566,37 @@ pub const timezone = extern struct { |
| 565 | 566 | tz_dsttime: i32, |
| 566 | 567 | }; |
| 567 | 568 | |
| 569 | pub const mcontext_t = extern struct { | |
| 570 | trap_no: usize, | |
| 571 | error_code: usize, | |
| 572 | oldmask: usize, | |
| 573 | arm_r0: usize, | |
| 574 | arm_r1: usize, | |
| 575 | arm_r2: usize, | |
| 576 | arm_r3: usize, | |
| 577 | arm_r4: usize, | |
| 578 | arm_r5: usize, | |
| 579 | arm_r6: usize, | |
| 580 | arm_r7: usize, | |
| 581 | arm_r8: usize, | |
| 582 | arm_r9: usize, | |
| 583 | arm_r10: usize, | |
| 584 | arm_fp: usize, | |
| 585 | arm_ip: usize, | |
| 586 | arm_sp: usize, | |
| 587 | arm_lr: usize, | |
| 588 | arm_pc: usize, | |
| 589 | arm_cpsr: usize, | |
| 590 | fault_address: usize, | |
| 591 | }; | |
| 592 | ||
| 593 | pub const ucontext_t = extern struct { | |
| 594 | flags: usize, | |
| 595 | link: *ucontext_t, | |
| 596 | stack: stack_t, | |
| 597 | mcontext: mcontext_t, | |
| 598 | sigmask: sigset_t, | |
| 599 | regspace: [64]u64, | |
| 600 | }; | |
| 601 | ||
| 568 | 602 | pub const Elf_Symndx = u32; |
lib/std/os/bits/linux/arm64.zig+21| ... | ... | @@ -8,6 +8,8 @@ const iovec = linux.iovec; |
| 8 | 8 | const iovec_const = linux.iovec_const; |
| 9 | 9 | const uid_t = linux.uid_t; |
| 10 | 10 | const gid_t = linux.gid_t; |
| 11 | const stack_t = linux.stack_t; | |
| 12 | const sigset_t = linux.sigset_t; | |
| 11 | 13 | |
| 12 | 14 | pub const SYS_io_setup = 0; |
| 13 | 15 | pub const SYS_io_destroy = 1; |
| ... | ... | @@ -445,4 +447,23 @@ pub const timezone = extern struct { |
| 445 | 447 | tz_dsttime: i32, |
| 446 | 448 | }; |
| 447 | 449 | |
| 450 | pub const mcontext_t = extern struct { | |
| 451 | fault_address: usize, | |
| 452 | regs: [31]usize, | |
| 453 | sp: usize, | |
| 454 | pc: usize, | |
| 455 | pstate: usize, | |
| 456 | // Make sure the field is correctly aligned since this area | |
| 457 | // holds various FP/vector registers | |
| 458 | reserved1: [256 * 16]u8 align(16), | |
| 459 | }; | |
| 460 | ||
| 461 | pub const ucontext_t = extern struct { | |
| 462 | flags: usize, | |
| 463 | link: *ucontext_t, | |
| 464 | stack: stack_t, | |
| 465 | sigmask: sigset_t, | |
| 466 | mcontext: mcontext_t, | |
| 467 | }; | |
| 468 | ||
| 448 | 469 | pub const Elf_Symndx = u32; |
lib/std/os/bits/linux/x86_64.zig-54| ... | ... | @@ -536,60 +536,6 @@ pub const timezone = extern struct { |
| 536 | 536 | |
| 537 | 537 | pub const Elf_Symndx = u32; |
| 538 | 538 | |
| 539 | pub const sigval = extern union { | |
| 540 | int: i32, | |
| 541 | ptr: *c_void, | |
| 542 | }; | |
| 543 | ||
| 544 | pub const siginfo_t = extern struct { | |
| 545 | signo: i32, | |
| 546 | errno: i32, | |
| 547 | code: i32, | |
| 548 | fields: extern union { | |
| 549 | pad: [128 - 2 * @sizeOf(c_int) - @sizeOf(c_long)]u8, | |
| 550 | common: extern struct { | |
| 551 | first: extern union { | |
| 552 | piduid: extern struct { | |
| 553 | pid: pid_t, | |
| 554 | uid: uid_t, | |
| 555 | }, | |
| 556 | timer: extern struct { | |
| 557 | timerid: i32, | |
| 558 | overrun: i32, | |
| 559 | }, | |
| 560 | }, | |
| 561 | second: extern union { | |
| 562 | value: sigval, | |
| 563 | sigchld: extern struct { | |
| 564 | status: i32, | |
| 565 | utime: clock_t, | |
| 566 | stime: clock_t, | |
| 567 | }, | |
| 568 | }, | |
| 569 | }, | |
| 570 | sigfault: extern struct { | |
| 571 | addr: *c_void, | |
| 572 | addr_lsb: i16, | |
| 573 | first: extern union { | |
| 574 | addr_bnd: extern struct { | |
| 575 | lower: *c_void, | |
| 576 | upper: *c_void, | |
| 577 | }, | |
| 578 | pkey: u32, | |
| 579 | }, | |
| 580 | }, | |
| 581 | sigpoll: extern struct { | |
| 582 | band: isize, | |
| 583 | fd: i32, | |
| 584 | }, | |
| 585 | sigsys: extern struct { | |
| 586 | call_addr: *c_void, | |
| 587 | syscall: i32, | |
| 588 | arch: u32, | |
| 589 | }, | |
| 590 | }, | |
| 591 | }; | |
| 592 | ||
| 593 | 539 | pub const greg_t = usize; |
| 594 | 540 | pub const gregset_t = [23]greg_t; |
| 595 | 541 | pub const fpstate = extern struct { |
lib/std/os/linux.zig+7-4| ... | ... | @@ -673,15 +673,18 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti |
| 673 | 673 | assert(sig >= 1); |
| 674 | 674 | assert(sig != SIGKILL); |
| 675 | 675 | assert(sig != SIGSTOP); |
| 676 | ||
| 677 | const restorer_fn = if ((act.flags & SA_SIGINFO) != 0) restore_rt else restore; | |
| 676 | 678 | var ksa = k_sigaction{ |
| 677 | 679 | .sigaction = act.sigaction, |
| 678 | 680 | .flags = act.flags | SA_RESTORER, |
| 679 | 681 | .mask = undefined, |
| 680 | .restorer = @ptrCast(extern fn () void, restore_rt), | |
| 682 | .restorer = @ptrCast(extern fn () void, restorer_fn), | |
| 681 | 683 | }; |
| 682 | 684 | var ksa_old: k_sigaction = undefined; |
| 683 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), 8); | |
| 684 | const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), @sizeOf(@typeOf(ksa.mask))); | |
| 685 | const ksa_mask_size = @sizeOf(@typeOf(ksa_old.mask)); | |
| 686 | @memcpy(@ptrCast([*]u8, &ksa.mask), @ptrCast([*]const u8, &act.mask), ksa_mask_size); | |
| 687 | const result = syscall4(SYS_rt_sigaction, sig, @ptrToInt(&ksa), @ptrToInt(&ksa_old), ksa_mask_size); | |
| 685 | 688 | const err = getErrno(result); |
| 686 | 689 | if (err != 0) { |
| 687 | 690 | return result; |
| ... | ... | @@ -689,7 +692,7 @@ pub fn sigaction(sig: u6, noalias act: *const Sigaction, noalias oact: ?*Sigacti |
| 689 | 692 | if (oact) |old| { |
| 690 | 693 | old.sigaction = ksa_old.sigaction; |
| 691 | 694 | old.flags = @truncate(u32, ksa_old.flags); |
| 692 | @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), @sizeOf(@typeOf(ksa_old.mask))); | |
| 695 | @memcpy(@ptrCast([*]u8, &old.mask), @ptrCast([*]const u8, &ksa_old.mask), ksa_mask_size); | |
| 693 | 696 | } |
| 694 | 697 | return 0; |
| 695 | 698 | } |
lib/std/os/linux/arm-eabi.zig+18| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | usingnamespace @import("../bits.zig"); | |
| 2 | ||
| 1 | 3 | pub fn syscall0(number: usize) usize { |
| 2 | 4 | return asm volatile ("svc #0" |
| 3 | 5 | : [ret] "={r0}" (-> usize) |
| ... | ... | @@ -94,3 +96,19 @@ pub extern fn getThreadPointer() usize { |
| 94 | 96 | : [ret] "=r" (-> usize) |
| 95 | 97 | ); |
| 96 | 98 | } |
| 99 | ||
| 100 | pub nakedcc fn restore() void { | |
| 101 | return asm volatile ("svc #0" | |
| 102 | : | |
| 103 | : [number] "{r7}" (usize(SYS_sigreturn)) | |
| 104 | : "memory" | |
| 105 | ); | |
| 106 | } | |
| 107 | ||
| 108 | pub nakedcc fn restore_rt() void { | |
| 109 | return asm volatile ("svc #0" | |
| 110 | : | |
| 111 | : [number] "{r7}" (usize(SYS_rt_sigreturn)) | |
| 112 | : "memory" | |
| 113 | ); | |
| 114 | } |
lib/std/os/linux/arm64.zig+12| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | usingnamespace @import("../bits.zig"); | |
| 2 | ||
| 1 | 3 | pub fn syscall0(number: usize) usize { |
| 2 | 4 | return asm volatile ("svc #0" |
| 3 | 5 | : [ret] "={x0}" (-> usize) |
| ... | ... | @@ -85,3 +87,13 @@ pub fn syscall6( |
| 85 | 87 | |
| 86 | 88 | /// This matches the libc clone function. |
| 87 | 89 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 90 | ||
| 91 | pub const restore = restore_rt; | |
| 92 | ||
| 93 | pub nakedcc fn restore_rt() void { | |
| 94 | return asm volatile ("svc #0" | |
| 95 | : | |
| 96 | : [number] "{x8}" (usize(SYS_rt_sigreturn)) | |
| 97 | : "memory", "cc" | |
| 98 | ); | |
| 99 | } |
lib/std/os/linux/mipsel.zig+18| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | usingnamespace @import("../bits.zig"); | |
| 2 | ||
| 1 | 3 | pub fn syscall0(number: usize) usize { |
| 2 | 4 | return asm volatile ( |
| 3 | 5 | \\ syscall |
| ... | ... | @@ -122,3 +124,19 @@ pub fn syscall6( |
| 122 | 124 | |
| 123 | 125 | /// This matches the libc clone function. |
| 124 | 126 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 127 | ||
| 128 | pub nakedcc fn restore() void { | |
| 129 | return asm volatile ("syscall" | |
| 130 | : | |
| 131 | : [number] "{$2}" (usize(SYS_sigreturn)) | |
| 132 | : "memory", "cc", "$7" | |
| 133 | ); | |
| 134 | } | |
| 135 | ||
| 136 | pub nakedcc fn restore_rt() void { | |
| 137 | return asm volatile ("syscall" | |
| 138 | : | |
| 139 | : [number] "{$2}" (usize(SYS_rt_sigreturn)) | |
| 140 | : "memory", "cc", "$7" | |
| 141 | ); | |
| 142 | } |
lib/std/os/linux/riscv64.zig+12| ... | ... | @@ -1,3 +1,5 @@ |
| 1 | usingnamespace @import("../bits.zig"); | |
| 2 | ||
| 1 | 3 | pub fn syscall0(number: usize) usize { |
| 2 | 4 | return asm volatile ("ecall" |
| 3 | 5 | : [ret] "={x10}" (-> usize) |
| ... | ... | @@ -84,3 +86,13 @@ pub fn syscall6( |
| 84 | 86 | } |
| 85 | 87 | |
| 86 | 88 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: u32, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 89 | ||
| 90 | pub const restore = restore_rt; | |
| 91 | ||
| 92 | pub nakedcc fn restore_rt() void { | |
| 93 | return asm volatile ("ecall" | |
| 94 | : | |
| 95 | : [number] "{x17}" (usize(SYS_rt_sigreturn)) | |
| 96 | : "memory" | |
| 97 | ); | |
| 98 | } |
lib/std/os/linux/x86_64.zig+3-1| ... | ... | @@ -88,10 +88,12 @@ pub fn syscall6( |
| 88 | 88 | /// This matches the libc clone function. |
| 89 | 89 | pub extern fn clone(func: extern fn (arg: usize) u8, stack: usize, flags: usize, arg: usize, ptid: *i32, tls: usize, ctid: *i32) usize; |
| 90 | 90 | |
| 91 | pub const restore = restore_rt; | |
| 92 | ||
| 91 | 93 | pub nakedcc fn restore_rt() void { |
| 92 | 94 | return asm volatile ("syscall" |
| 93 | 95 | : |
| 94 | 96 | : [number] "{rax}" (usize(SYS_rt_sigreturn)) |
| 95 | : "rcx", "r11" | |
| 97 | : "rcx", "r11", "memory" | |
| 96 | 98 | ); |
| 97 | 99 | } |