| ... | @@ -250,6 +250,13 @@ const Aarch64 = extern struct { | ... | @@ -250,6 +250,13 @@ const Aarch64 = extern struct { |
| 250 | return ctx; | 250 | return ctx; |
| 251 | } | 251 | } |
| 252 | | 252 | |
| | 253 | pub fn getFp(ctx: *const Aarch64) u64 { |
| | 254 | return ctx.x[29]; |
| | 255 | } |
| | 256 | pub fn getPc(ctx: *const Aarch64) u64 { |
| | 257 | return ctx.pc; |
| | 258 | } |
| | 259 | |
| 253 | pub fn dwarfRegisterBytes(ctx: *Aarch64, register_num: u16) DwarfRegisterError![]u8 { | 260 | pub fn dwarfRegisterBytes(ctx: *Aarch64, register_num: u16) DwarfRegisterError![]u8 { |
| 254 | // DWARF for the Arm(r) 64-bit Architecture (AArch64) § 4.1 "DWARF register names" | 261 | // DWARF for the Arm(r) 64-bit Architecture (AArch64) § 4.1 "DWARF register names" |
| 255 | switch (register_num) { | 262 | switch (register_num) { |
| ... | @@ -324,6 +331,13 @@ const Arc = extern struct { | ... | @@ -324,6 +331,13 @@ const Arc = extern struct { |
| 324 | return ctx; | 331 | return ctx; |
| 325 | } | 332 | } |
| 326 | | 333 | |
| | 334 | pub fn getFp(ctx: *const Arc) u32 { |
| | 335 | return ctx.r[27]; |
| | 336 | } |
| | 337 | pub fn getPc(ctx: *const Arc) u32 { |
| | 338 | return ctx.pcl; |
| | 339 | } |
| | 340 | |
| 327 | pub fn dwarfRegisterBytes(ctx: *Arc, register_num: u16) DwarfRegisterError![]u8 { | 341 | pub fn dwarfRegisterBytes(ctx: *Arc, register_num: u16) DwarfRegisterError![]u8 { |
| 328 | switch (register_num) { | 342 | switch (register_num) { |
| 329 | 0...31 => return @ptrCast(&ctx.r[register_num]), | 343 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -356,6 +370,13 @@ const Arm = struct { | ... | @@ -356,6 +370,13 @@ const Arm = struct { |
| 356 | return ctx; | 370 | return ctx; |
| 357 | } | 371 | } |
| 358 | | 372 | |
| | 373 | pub fn getFp(ctx: *const Arm) u32 { |
| | 374 | return ctx.r[11]; |
| | 375 | } |
| | 376 | pub fn getPc(ctx: *const Arm) u32 { |
| | 377 | return ctx.r[15]; |
| | 378 | } |
| | 379 | |
| 359 | pub fn dwarfRegisterBytes(ctx: *Arm, register_num: u16) DwarfRegisterError![]u8 { | 380 | pub fn dwarfRegisterBytes(ctx: *Arm, register_num: u16) DwarfRegisterError![]u8 { |
| 360 | // DWARF for the Arm(r) Architecture § 4.1 "DWARF register names" | 381 | // DWARF for the Arm(r) Architecture § 4.1 "DWARF register names" |
| 361 | switch (register_num) { | 382 | switch (register_num) { |
| ... | @@ -415,6 +436,13 @@ const Csky = extern struct { | ... | @@ -415,6 +436,13 @@ const Csky = extern struct { |
| 415 | return ctx; | 436 | return ctx; |
| 416 | } | 437 | } |
| 417 | | 438 | |
| | 439 | pub fn getFp(ctx: *const Csky) u32 { |
| | 440 | return ctx.r[14]; |
| | 441 | } |
| | 442 | pub fn getPc(ctx: *const Csky) u32 { |
| | 443 | return ctx.pc; |
| | 444 | } |
| | 445 | |
| 418 | pub fn dwarfRegisterBytes(ctx: *Csky, register_num: u16) DwarfRegisterError![]u8 { | 446 | pub fn dwarfRegisterBytes(ctx: *Csky, register_num: u16) DwarfRegisterError![]u8 { |
| 419 | switch (register_num) { | 447 | switch (register_num) { |
| 420 | 0...31 => return @ptrCast(&ctx.r[register_num]), | 448 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -476,6 +504,13 @@ const Hexagon = extern struct { | ... | @@ -476,6 +504,13 @@ const Hexagon = extern struct { |
| 476 | return ctx; | 504 | return ctx; |
| 477 | } | 505 | } |
| 478 | | 506 | |
| | 507 | pub fn getFp(ctx: *const Hexagon) u32 { |
| | 508 | return ctx.r[30]; |
| | 509 | } |
| | 510 | pub fn getPc(ctx: *const Hexagon) u32 { |
| | 511 | return ctx.pc; |
| | 512 | } |
| | 513 | |
| 479 | pub fn dwarfRegisterBytes(ctx: *Hexagon, register_num: u16) DwarfRegisterError![]u8 { | 514 | pub fn dwarfRegisterBytes(ctx: *Hexagon, register_num: u16) DwarfRegisterError![]u8 { |
| 480 | // Sourced from LLVM's HexagonRegisterInfo.td, which disagrees with LLDB... | 515 | // Sourced from LLVM's HexagonRegisterInfo.td, which disagrees with LLDB... |
| 481 | switch (register_num) { | 516 | switch (register_num) { |
| ... | @@ -544,6 +579,13 @@ const Kvx = extern struct { | ... | @@ -544,6 +579,13 @@ const Kvx = extern struct { |
| 544 | return ctx; | 579 | return ctx; |
| 545 | } | 580 | } |
| 546 | | 581 | |
| | 582 | pub fn getFp(ctx: *const Kvx) u64 { |
| | 583 | return ctx.r[14]; |
| | 584 | } |
| | 585 | pub fn getPc(ctx: *const Kvx) u64 { |
| | 586 | return ctx.pc; |
| | 587 | } |
| | 588 | |
| 547 | pub fn dwarfRegisterBytes(ctx: *Kvx, register_num: u16) DwarfRegisterError![]u8 { | 589 | pub fn dwarfRegisterBytes(ctx: *Kvx, register_num: u16) DwarfRegisterError![]u8 { |
| 548 | switch (register_num) { | 590 | switch (register_num) { |
| 549 | 0...63 => return @ptrCast(&ctx.r[register_num]), | 591 | 0...63 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -604,6 +646,13 @@ const Lanai = extern struct { | ... | @@ -604,6 +646,13 @@ const Lanai = extern struct { |
| 604 | return ctx; | 646 | return ctx; |
| 605 | } | 647 | } |
| 606 | | 648 | |
| | 649 | pub fn getFp(ctx: *const Lanai) u32 { |
| | 650 | return ctx.r[5]; |
| | 651 | } |
| | 652 | pub fn getPc(ctx: *const Lanai) u32 { |
| | 653 | return ctx.r[2]; |
| | 654 | } |
| | 655 | |
| 607 | pub fn dwarfRegisterBytes(ctx: *Lanai, register_num: u16) DwarfRegisterError![]u8 { | 656 | pub fn dwarfRegisterBytes(ctx: *Lanai, register_num: u16) DwarfRegisterError![]u8 { |
| 608 | switch (register_num) { | 657 | switch (register_num) { |
| 609 | 0...31 => return @ptrCast(&ctx.s[register_num]), | 658 | 0...31 => return @ptrCast(&ctx.s[register_num]), |
| ... | @@ -701,6 +750,13 @@ const LoongArch = extern struct { | ... | @@ -701,6 +750,13 @@ const LoongArch = extern struct { |
| 701 | return ctx; | 750 | return ctx; |
| 702 | } | 751 | } |
| 703 | | 752 | |
| | 753 | pub fn getFp(ctx: *const LoongArch) Gpr { |
| | 754 | return ctx.r[22]; |
| | 755 | } |
| | 756 | pub fn getPc(ctx: *const LoongArch) Gpr { |
| | 757 | return ctx.pc; |
| | 758 | } |
| | 759 | |
| 704 | pub fn dwarfRegisterBytes(ctx: *LoongArch, register_num: u16) DwarfRegisterError![]u8 { | 760 | pub fn dwarfRegisterBytes(ctx: *LoongArch, register_num: u16) DwarfRegisterError![]u8 { |
| 705 | switch (register_num) { | 761 | switch (register_num) { |
| 706 | 0...31 => return @ptrCast(&ctx.r[register_num]), | 762 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -733,6 +789,13 @@ const M68k = extern struct { | ... | @@ -733,6 +789,13 @@ const M68k = extern struct { |
| 733 | return ctx; | 789 | return ctx; |
| 734 | } | 790 | } |
| 735 | | 791 | |
| | 792 | pub fn getFp(ctx: *const M68k) u32 { |
| | 793 | return ctx.a[6]; |
| | 794 | } |
| | 795 | pub fn getPc(ctx: *const M68k) u32 { |
| | 796 | return ctx.pc; |
| | 797 | } |
| | 798 | |
| 736 | pub fn dwarfRegisterBytes(ctx: *M68k, register_num: u16) DwarfRegisterError![]u8 { | 799 | pub fn dwarfRegisterBytes(ctx: *M68k, register_num: u16) DwarfRegisterError![]u8 { |
| 737 | switch (register_num) { | 800 | switch (register_num) { |
| 738 | 0...7 => return @ptrCast(&ctx.d[register_num]), | 801 | 0...7 => return @ptrCast(&ctx.d[register_num]), |
| ... | @@ -845,6 +908,15 @@ const Mips = extern struct { | ... | @@ -845,6 +908,15 @@ const Mips = extern struct { |
| 845 | return ctx; | 908 | return ctx; |
| 846 | } | 909 | } |
| 847 | | 910 | |
| | 911 | pub fn getFp(ctx: *const Mips) usize { |
| | 912 | // On N32, `Gpr` is 64 bits but `usize` is 32 bits. |
| | 913 | return @intCast(ctx.r[30]); |
| | 914 | } |
| | 915 | pub fn getPc(ctx: *const Mips) usize { |
| | 916 | // On N32, `Gpr` is 64 bits but `usize` is 32 bits. |
| | 917 | return @intCast(ctx.pc); |
| | 918 | } |
| | 919 | |
| 848 | pub fn dwarfRegisterBytes(ctx: *Mips, register_num: u16) DwarfRegisterError![]u8 { | 920 | pub fn dwarfRegisterBytes(ctx: *Mips, register_num: u16) DwarfRegisterError![]u8 { |
| 849 | switch (register_num) { | 921 | switch (register_num) { |
| 850 | 0...31 => return @ptrCast(&ctx.r[register_num]), | 922 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -917,6 +989,13 @@ const Or1k = extern struct { | ... | @@ -917,6 +989,13 @@ const Or1k = extern struct { |
| 917 | return ctx; | 989 | return ctx; |
| 918 | } | 990 | } |
| 919 | | 991 | |
| | 992 | pub fn getFp(ctx: *const Or1k) u32 { |
| | 993 | return ctx.r[2]; |
| | 994 | } |
| | 995 | pub fn getPc(ctx: *const Or1k) u32 { |
| | 996 | return ctx.pc; |
| | 997 | } |
| | 998 | |
| 920 | pub fn dwarfRegisterBytes(ctx: *Or1k, register_num: u16) DwarfRegisterError![]u8 { | 999 | pub fn dwarfRegisterBytes(ctx: *Or1k, register_num: u16) DwarfRegisterError![]u8 { |
| 921 | switch (register_num) { | 1000 | switch (register_num) { |
| 922 | 0...31 => return @ptrCast(&ctx.r[register_num]), | 1001 | 0...31 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -1022,6 +1101,13 @@ const Powerpc = extern struct { | ... | @@ -1022,6 +1101,13 @@ const Powerpc = extern struct { |
| 1022 | return ctx; | 1101 | return ctx; |
| 1023 | } | 1102 | } |
| 1024 | | 1103 | |
| | 1104 | pub fn getFp(ctx: *const Powerpc) Gpr { |
| | 1105 | return ctx.r[1]; |
| | 1106 | } |
| | 1107 | pub fn getPc(ctx: *const Powerpc) Gpr { |
| | 1108 | return ctx.pc; |
| | 1109 | } |
| | 1110 | |
| 1025 | pub fn dwarfRegisterBytes(ctx: *Powerpc, register_num: u16) DwarfRegisterError![]u8 { | 1111 | pub fn dwarfRegisterBytes(ctx: *Powerpc, register_num: u16) DwarfRegisterError![]u8 { |
| 1026 | // References: | 1112 | // References: |
| 1027 | // | 1113 | // |
| ... | @@ -1168,6 +1254,13 @@ const Riscv = extern struct { | ... | @@ -1168,6 +1254,13 @@ const Riscv = extern struct { |
| 1168 | return ctx; | 1254 | return ctx; |
| 1169 | } | 1255 | } |
| 1170 | | 1256 | |
| | 1257 | pub fn getFp(ctx: *const Riscv) Gpr { |
| | 1258 | return ctx.x[8]; |
| | 1259 | } |
| | 1260 | pub fn getPc(ctx: *const Riscv) Gpr { |
| | 1261 | return ctx.pc; |
| | 1262 | } |
| | 1263 | |
| 1171 | pub fn dwarfRegisterBytes(ctx: *Riscv, register_num: u16) DwarfRegisterError![]u8 { | 1264 | pub fn dwarfRegisterBytes(ctx: *Riscv, register_num: u16) DwarfRegisterError![]u8 { |
| 1172 | switch (register_num) { | 1265 | switch (register_num) { |
| 1173 | 0...31 => return @ptrCast(&ctx.x[register_num]), | 1266 | 0...31 => return @ptrCast(&ctx.x[register_num]), |
| ... | @@ -1208,6 +1301,13 @@ const S390x = extern struct { | ... | @@ -1208,6 +1301,13 @@ const S390x = extern struct { |
| 1208 | return ctx; | 1301 | return ctx; |
| 1209 | } | 1302 | } |
| 1210 | | 1303 | |
| | 1304 | pub fn getFp(ctx: *const S390x) u64 { |
| | 1305 | return ctx.r[11]; |
| | 1306 | } |
| | 1307 | pub fn getPc(ctx: *const S390x) u64 { |
| | 1308 | return ctx.psw.addr; |
| | 1309 | } |
| | 1310 | |
| 1211 | pub fn dwarfRegisterBytes(ctx: *S390x, register_num: u16) DwarfRegisterError![]u8 { | 1311 | pub fn dwarfRegisterBytes(ctx: *S390x, register_num: u16) DwarfRegisterError![]u8 { |
| 1212 | switch (register_num) { | 1312 | switch (register_num) { |
| 1213 | 0...15 => return @ptrCast(&ctx.r[register_num]), | 1313 | 0...15 => return @ptrCast(&ctx.r[register_num]), |
| ... | @@ -1310,6 +1410,13 @@ const Sparc = extern struct { | ... | @@ -1310,6 +1410,13 @@ const Sparc = extern struct { |
| 1310 | asm volatile ("ta 3" ::: .{ .memory = true }); // ST_FLUSH_WINDOWS | 1410 | asm volatile ("ta 3" ::: .{ .memory = true }); // ST_FLUSH_WINDOWS |
| 1311 | } | 1411 | } |
| 1312 | | 1412 | |
| | 1413 | pub fn getFp(ctx: *const Sparc) Gpr { |
| | 1414 | return ctx.i[6]; |
| | 1415 | } |
| | 1416 | pub fn getPc(ctx: *const Sparc) Gpr { |
| | 1417 | return ctx.pc; |
| | 1418 | } |
| | 1419 | |
| 1313 | pub fn dwarfRegisterBytes(ctx: *Sparc, register_num: u16) DwarfRegisterError![]u8 { | 1420 | pub fn dwarfRegisterBytes(ctx: *Sparc, register_num: u16) DwarfRegisterError![]u8 { |
| 1314 | switch (register_num) { | 1421 | switch (register_num) { |
| 1315 | 0...7 => return @ptrCast(&ctx.g[register_num]), | 1422 | 0...7 => return @ptrCast(&ctx.g[register_num]), |
| ... | @@ -1404,6 +1511,13 @@ const Ve = extern struct { | ... | @@ -1404,6 +1511,13 @@ const Ve = extern struct { |
| 1404 | return ctx; | 1511 | return ctx; |
| 1405 | } | 1512 | } |
| 1406 | | 1513 | |
| | 1514 | pub fn getFp(ctx: *const Ve) u64 { |
| | 1515 | return ctx.s[9]; |
| | 1516 | } |
| | 1517 | pub fn getPc(ctx: *const Ve) u64 { |
| | 1518 | return ctx.ic; |
| | 1519 | } |
| | 1520 | |
| 1407 | pub fn dwarfRegisterBytes(ctx: *Ve, register_num: u16) DwarfRegisterError![]u8 { | 1521 | pub fn dwarfRegisterBytes(ctx: *Ve, register_num: u16) DwarfRegisterError![]u8 { |
| 1408 | switch (register_num) { | 1522 | switch (register_num) { |
| 1409 | 0...63 => return @ptrCast(&ctx.s[register_num]), | 1523 | 0...63 => return @ptrCast(&ctx.s[register_num]), |
| ... | @@ -1444,6 +1558,13 @@ const X86_16 = struct { | ... | @@ -1444,6 +1558,13 @@ const X86_16 = struct { |
| 1444 | return ctx; | 1558 | return ctx; |
| 1445 | } | 1559 | } |
| 1446 | | 1560 | |
| | 1561 | pub fn getFp(ctx: *const X86_16) u16 { |
| | 1562 | return ctx.regs.get(.bp); |
| | 1563 | } |
| | 1564 | pub fn getPc(ctx: *const X86_16) u16 { |
| | 1565 | return ctx.regs.get(.ip); |
| | 1566 | } |
| | 1567 | |
| 1447 | // NOTE: There doesn't seem to be any standard for DWARF x86-16 so we'll just reuse the ones for x86. | 1568 | // NOTE: There doesn't seem to be any standard for DWARF x86-16 so we'll just reuse the ones for x86. |
| 1448 | pub fn dwarfRegisterBytes(ctx: *X86_16, register_num: u16) DwarfRegisterError![]u8 { | 1569 | pub fn dwarfRegisterBytes(ctx: *X86_16, register_num: u16) DwarfRegisterError![]u8 { |
| 1449 | switch (register_num) { | 1570 | switch (register_num) { |
| ... | @@ -1490,6 +1611,13 @@ const X86 = struct { | ... | @@ -1490,6 +1611,13 @@ const X86 = struct { |
| 1490 | return ctx; | 1611 | return ctx; |
| 1491 | } | 1612 | } |
| 1492 | | 1613 | |
| | 1614 | pub fn getFp(ctx: *const X86) u32 { |
| | 1615 | return ctx.gprs.get(.ebp); |
| | 1616 | } |
| | 1617 | pub fn getPc(ctx: *const X86) u32 { |
| | 1618 | return ctx.gprs.get(.eip); |
| | 1619 | } |
| | 1620 | |
| 1493 | pub fn dwarfRegisterBytes(ctx: *X86, register_num: u16) DwarfRegisterError![]u8 { | 1621 | pub fn dwarfRegisterBytes(ctx: *X86, register_num: u16) DwarfRegisterError![]u8 { |
| 1494 | // System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.1 | 1622 | // System V Application Binary Interface Intel386 Architecture Processor Supplement Version 1.1 |
| 1495 | // § 2.4.2 "DWARF Register Number Mapping" | 1623 | // § 2.4.2 "DWARF Register Number Mapping" |
| ... | @@ -1558,6 +1686,15 @@ const X86_64 = struct { | ... | @@ -1558,6 +1686,15 @@ const X86_64 = struct { |
| 1558 | return ctx; | 1686 | return ctx; |
| 1559 | } | 1687 | } |
| 1560 | | 1688 | |
| | 1689 | pub fn getFp(ctx: *const X86_64) usize { |
| | 1690 | // On x32, registers are 64 bits but `usize` is 32 bits. |
| | 1691 | return @intCast(ctx.gprs.get(.rbp)); |
| | 1692 | } |
| | 1693 | pub fn getPc(ctx: *const X86_64) usize { |
| | 1694 | // On x32, registers are 64 bits but `usize` is 32 bits. |
| | 1695 | return @intCast(ctx.gprs.get(.rip)); |
| | 1696 | } |
| | 1697 | |
| 1561 | pub fn dwarfRegisterBytes(ctx: *X86_64, register_num: u16) DwarfRegisterError![]u8 { | 1698 | pub fn dwarfRegisterBytes(ctx: *X86_64, register_num: u16) DwarfRegisterError![]u8 { |
| 1562 | // System V Application Binary Interface AMD64 Architecture Processor Supplement | 1699 | // System V Application Binary Interface AMD64 Architecture Processor Supplement |
| 1563 | // § 3.6.2 "DWARF Register Number Mapping" | 1700 | // § 3.6.2 "DWARF Register Number Mapping" |