feature. See also
. The project being documented here (as the example) is the Zig library itself.
cpu_context.X86
const X86 = struct
File
Code
const X86 = struct {
gprs: std.enums.EnumArray(GprName, Gpr),
pub const GprName = enum {
eax, ecx, edx, ebx,
esp, ebp, esi, edi,
eip,
};
pub const Gpr = u32;
pub inline fn current() X86 {
var ctx: X86 = undefined;
asm volatile (
\\ movl %%eax, 0x00(%%edi)
\\ movl %%ecx, 0x04(%%edi)
\\ movl %%edx, 0x08(%%edi)
\\ movl %%ebx, 0x0c(%%edi)
\\ movl %%esp, 0x10(%%edi)
\\ movl %%ebp, 0x14(%%edi)
\\ movl %%esi, 0x18(%%edi)
\\ movl %%edi, 0x1c(%%edi)
\\ call 1f
\\1:
\\ popl 0x20(%%edi)
:
: [gprs] "{edi}" (&ctx.gprs.values),
: .{ .memory = true });
return ctx;
}
pub fn getFp(ctx: *const X86) usize {
return ctx.gprs.get(.ebp);
}
pub fn getPc(ctx: *const X86) usize {
return ctx.gprs.get(.eip);
}
pub fn dwarfRegisterBytes(ctx: *X86, register_num: u16) DwarfRegisterError![]u8 {
// ยง 2.4.2 "DWARF Register Number Mapping"
switch (register_num) {
//
// x86-macos sometimes uses different mappings (ebp and esp are reversed when the unwind
// information is from `__eh_frame`). This deviation is not considered here, because
// x86-macos is a deprecated target which is not supported by the Zig Standard Library.
0...8 => return @ptrCast(&ctx.gprs.values[register_num]),
9 => return error.UnsupportedRegister,
11...18 => return error.UnsupportedRegister,
21...28 => return error.UnsupportedRegister,
29...36 => return error.UnsupportedRegister,
39 => return error.UnsupportedRegister,
40...45 => return error.UnsupportedRegister,
48 => return error.UnsupportedRegister,
49 => return error.UnsupportedRegister,
93...100 => return error.UnsupportedRegister,
else => return error.InvalidRegister,
}
}
}