| ... | ... | @@ -5,6 +5,7 @@ pub const Native = if (@hasDecl(root, "debug") and @hasDecl(root.debug, "CpuCont |
| 5 | 5 | root.debug.CpuContext |
| 6 | 6 | else switch (native_arch) { |
| 7 | 7 | .aarch64, .aarch64_be => Aarch64, |
| 8 | .arc => Arc, |
| 8 | 9 | .arm, .armeb, .thumb, .thumbeb => Arm, |
| 9 | 10 | .csky => Csky, |
| 10 | 11 | .hexagon => Hexagon, |
| ... | ... | @@ -35,7 +36,20 @@ pub fn fromPosixSignalContext(ctx_ptr: ?*const anyopaque) ?Native { |
| 35 | 36 | const uc: *const signal_ucontext_t = @ptrCast(@alignCast(ctx_ptr)); |
| 36 | 37 | |
| 37 | 38 | // Deal with some special cases first. |
| 38 | | if (native_arch.isMIPS32() and native_os == .linux) { |
| 39 | if (native_arch == .arc and native_os == .linux) { |
| 40 | var native: Native = .{ |
| 41 | .r = [_]u32{ uc.mcontext.r31, uc.mcontext.r30, 0, uc.mcontext.r28 } ++ |
| 42 | uc.mcontext.r27_26 ++ |
| 43 | uc.mcontext.r25_13 ++ |
| 44 | uc.mcontext.r12_0, |
| 45 | .pcl = uc.mcontext.pcl, |
| 46 | }; |
| 47 | |
| 48 | // I have no idea why the kernel is storing these registers in such a bizarre order... |
| 49 | std.mem.reverse(native.r[0..]); |
| 50 | |
| 51 | return native; |
| 52 | } else if (native_arch.isMIPS32() and native_os == .linux) { |
| 39 | 53 | // The O32 kABI uses 64-bit fields for some reason. |
| 40 | 54 | return .{ |
| 41 | 55 | .r = s: { |
| ... | ... | @@ -327,6 +341,68 @@ const X86_64 = struct { |
| 327 | 341 | } |
| 328 | 342 | }; |
| 329 | 343 | |
| 344 | /// This is an `extern struct` so that inline assembly in `current` can use field offsets. |
| 345 | const Arc = extern struct { |
| 346 | /// The numbered general-purpose registers r0 - r31. |
| 347 | r: [32]u32, |
| 348 | pcl: u32, |
| 349 | |
| 350 | pub inline fn current() Arc { |
| 351 | var ctx: Arc = undefined; |
| 352 | asm volatile ( |
| 353 | \\ st r0, [r8, 0] |
| 354 | \\ st r1, [r8, 4] |
| 355 | \\ st r2, [r8, 8] |
| 356 | \\ st r3, [r8, 12] |
| 357 | \\ st r4, [r8, 16] |
| 358 | \\ st r5, [r8, 20] |
| 359 | \\ st r6, [r8, 24] |
| 360 | \\ st r7, [r8, 28] |
| 361 | \\ st r8, [r8, 32] |
| 362 | \\ st r9, [r8, 36] |
| 363 | \\ st r10, [r8, 40] |
| 364 | \\ st r11, [r8, 44] |
| 365 | \\ st r12, [r8, 48] |
| 366 | \\ st r13, [r8, 52] |
| 367 | \\ st r14, [r8, 56] |
| 368 | \\ st r15, [r8, 60] |
| 369 | \\ st r16, [r8, 64] |
| 370 | \\ st r17, [r8, 68] |
| 371 | \\ st r18, [r8, 72] |
| 372 | \\ st r19, [r8, 76] |
| 373 | \\ st r20, [r8, 80] |
| 374 | \\ st r21, [r8, 84] |
| 375 | \\ st r22, [r8, 88] |
| 376 | \\ st r23, [r8, 92] |
| 377 | \\ st r24, [r8, 96] |
| 378 | \\ st r25, [r8, 100] |
| 379 | \\ st r26, [r8, 104] |
| 380 | \\ st r27, [r8, 108] |
| 381 | \\ st r28, [r8, 112] |
| 382 | \\ st r29, [r8, 116] |
| 383 | \\ st r30, [r8, 120] |
| 384 | \\ st r31, [r8, 124] |
| 385 | \\ st pcl, [r8, 128] |
| 386 | : |
| 387 | : [ctx] "{r8}" (&ctx), |
| 388 | : .{ .memory = true }); |
| 389 | return ctx; |
| 390 | } |
| 391 | |
| 392 | pub fn dwarfRegisterBytes(ctx: *Arc, register_num: u16) DwarfRegisterError![]u8 { |
| 393 | switch (register_num) { |
| 394 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| 395 | 160 => return @ptrCast(&ctx.pcl), |
| 396 | |
| 397 | 32...57 => return error.UnsupportedRegister, // Extension Core Registers |
| 398 | 58...127 => return error.UnsupportedRegister, // Reserved |
| 399 | 128...159 => return error.UnsupportedRegister, // f0 - f31 |
| 400 | |
| 401 | else => return error.InvalidRegister, |
| 402 | } |
| 403 | } |
| 404 | }; |
| 405 | |
| 330 | 406 | const Arm = struct { |
| 331 | 407 | /// The numbered general-purpose registers R0 - R15. |
| 332 | 408 | r: [16]u32, |
| ... | ... | @@ -1517,7 +1593,7 @@ const signal_ucontext_t = switch (native_os) { |
| 1517 | 1593 | _count: u32, |
| 1518 | 1594 | }, |
| 1519 | 1595 | _status32: u32, |
| 1520 | | pc: u32, |
| 1596 | pcl: u32, |
| 1521 | 1597 | r31: u32, |
| 1522 | 1598 | r27_26: [2]u32, |
| 1523 | 1599 | r12_0: [13]u32, |