feature. See also
. The project being documented here (as the example) is the Zig library itself.
cpu_context.X86_64
const X86_64 = struct
File
Code
const X86_64 = struct {
gprs: std.enums.EnumArray(GprName, Gpr),
pub const GprName = enum {
rax, rdx, rcx, rbx,
rsi, rdi, rbp, rsp,
r8, r9, r10, r11,
r12, r13, r14, r15,
rip,
};
pub const Gpr = u64;
pub inline fn current() X86_64 {
var ctx: X86_64 = undefined;
asm volatile (
\\ movq %%rax, 0x00(%%rdi)
\\ movq %%rdx, 0x08(%%rdi)
\\ movq %%rcx, 0x10(%%rdi)
\\ movq %%rbx, 0x18(%%rdi)
\\ movq %%rsi, 0x20(%%rdi)
\\ movq %%rdi, 0x28(%%rdi)
\\ movq %%rbp, 0x30(%%rdi)
\\ movq %%rsp, 0x38(%%rdi)
\\ movq %%r8, 0x40(%%rdi)
\\ movq %%r9, 0x48(%%rdi)
\\ movq %%r10, 0x50(%%rdi)
\\ movq %%r11, 0x58(%%rdi)
\\ movq %%r12, 0x60(%%rdi)
\\ movq %%r13, 0x68(%%rdi)
\\ movq %%r14, 0x70(%%rdi)
\\ movq %%r15, 0x78(%%rdi)
\\ leaq (%%rip), %%rax
\\ movq %%rax, 0x80(%%rdi)
:
: [gprs] "{rdi}" (&ctx.gprs.values),
: .{ .rax = true, .memory = true });
return ctx;
}
pub fn getFp(ctx: *const X86_64) usize {
return @intCast(ctx.gprs.get(.rbp));
}
pub fn getPc(ctx: *const X86_64) usize {
return @intCast(ctx.gprs.get(.rip));
}
pub fn dwarfRegisterBytes(ctx: *X86_64, register_num: u16) DwarfRegisterError![]u8 {
// ยง 3.6.2 "DWARF Register Number Mapping"
switch (register_num) {
0...16 => return @ptrCast(&ctx.gprs.values[register_num]),
17...32 => return error.UnsupportedRegister,
33...40 => return error.UnsupportedRegister,
41...48 => return error.UnsupportedRegister,
49 => return error.UnsupportedRegister,
50...55 => return error.UnsupportedRegister,
58...59 => return error.UnsupportedRegister,
62 => return error.UnsupportedRegister,
63 => return error.UnsupportedRegister,
64 => return error.UnsupportedRegister,
65 => return error.UnsupportedRegister,
66 => return error.UnsupportedRegister,
67...82 => return error.UnsupportedRegister,
118...125 => return error.UnsupportedRegister,
130...145 => return error.UnsupportedRegister,
else => return error.InvalidRegister,
}
}
}