move register layout struct to Linux OS layer; use only GPR portion of

the layout struct for reg r/w; handle orig_rax
This commit is contained in:
Nikita Smith
2026-01-12 16:48:31 -08:00
parent fd6c3ef0e0
commit 12b53f4174
3 changed files with 121 additions and 109 deletions
+60 -59
View File
@@ -794,38 +794,38 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread)
//- rjf: read GPR
B32 got_gpr = 0;
{
DMN_LNX_UserX64 ctx = {0};
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_len = sizeof(ctx), .iov_base = &ctx }));
if(ptrace_result != -1)
OS_LNX_GprsX64 src;
int ptrace_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_GETREGSET, tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_len = sizeof(src), .iov_base = &src }));
if(ptrace_result >= 0)
{
got_gpr = 1;
DMN_LNX_UserX64 *src = &ctx;
dst->rax.u64 = src->regs.rax;
dst->rcx.u64 = src->regs.rcx;
dst->rdx.u64 = src->regs.rdx;
dst->rbx.u64 = src->regs.rbx;
dst->rsp.u64 = src->regs.rsp;
dst->rbp.u64 = src->regs.rbp;
dst->rsi.u64 = src->regs.rsi;
dst->rdi.u64 = src->regs.rdi;
dst->r8.u64 = src->regs.r8;
dst->r9.u64 = src->regs.r9;
dst->r10.u64 = src->regs.r10;
dst->r11.u64 = src->regs.r11;
dst->r12.u64 = src->regs.r12;
dst->r13.u64 = src->regs.r13;
dst->r14.u64 = src->regs.r14;
dst->r15.u64 = src->regs.r15;
dst->cs.u16 = src->regs.cs;
dst->ds.u16 = src->regs.ds;
dst->es.u16 = src->regs.es;
dst->fs.u16 = src->regs.fs;
dst->gs.u16 = src->regs.gs;
dst->ss.u16 = src->regs.ss;
dst->fsbase.u64 = src->regs.fsbase;
dst->gsbase.u64 = src->regs.gsbase;
dst->rip.u64 = src->regs.rip;
dst->rflags.u64 = src->regs.rflags;
dst->r15.u64 = src.r15;
dst->r14.u64 = src.r14;
dst->r13.u64 = src.r13;
dst->r12.u64 = src.r12;
dst->rbp.u64 = src.rbp;
dst->rbx.u64 = src.rbx;
dst->r11.u64 = src.r11;
dst->r10.u64 = src.r10;
dst->r9.u64 = src.r9;
dst->r8.u64 = src.r8;
dst->rax.u64 = src.rax;
dst->rcx.u64 = src.rcx;
dst->rdx.u64 = src.rdx;
dst->rsi.u64 = src.rsi;
dst->rdi.u64 = src.rdi;
dst->rip.u64 = src.rip;
dst->cs.u16 = src.cs;
dst->rflags.u64 = src.rflags;
dst->rsp.u64 = src.rsp;
dst->ss.u16 = src.ss;
dst->fsbase.u64 = src.fsbase;
dst->gsbase.u64 = src.gsbase;
dst->ds.u16 = src.ds;
dst->es.u16 = src.es;
dst->fs.u16 = src.fs;
dst->gs.u16 = src.gs;
thread->orig_rax = src.orig_rax;
}
else { Assert(0 && "failed to get gprs"); }
}
@@ -967,7 +967,7 @@ dmn_lnx_thread_read_reg_block(DMN_LNX_Entity *thread)
{
if(n != 4 && n != 5)
{
U64 offset = OffsetOf(DMN_LNX_UserX64, u_debugreg[n]);
U64 offset = OffsetOf(OS_LNX_UserX64, u_debugreg[n]);
errno = 0;
long peek_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_PEEKUSER, tid, PtrFromInt(offset), 0));
if(errno == 0)
@@ -1017,33 +1017,34 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread)
//- rjf: write GPR
B32 did_gpr = 0;
{
DMN_LNX_UserX64 dst = {0};
dst.regs.rax = src->rax.u64;
dst.regs.rcx = src->rcx.u64;
dst.regs.rdx = src->rdx.u64;
dst.regs.rbx = src->rbx.u64;
dst.regs.rsp = src->rsp.u64;
dst.regs.rbp = src->rbp.u64;
dst.regs.rsi = src->rsi.u64;
dst.regs.rdi = src->rdi.u64;
dst.regs.r8 = src->r8.u64;
dst.regs.r9 = src->r9.u64;
dst.regs.r10 = src->r10.u64;
dst.regs.r11 = src->r11.u64;
dst.regs.r12 = src->r12.u64;
dst.regs.r13 = src->r13.u64;
dst.regs.r14 = src->r14.u64;
dst.regs.r15 = src->r15.u64;
dst.regs.cs = src->cs.u16;
dst.regs.ds = src->ds.u16;
dst.regs.es = src->es.u16;
dst.regs.fs = src->fs.u16;
dst.regs.gs = src->gs.u16;
dst.regs.ss = src->ss.u16;
dst.regs.fsbase = src->fsbase.u64;
dst.regs.gsbase = src->gsbase.u64;
dst.regs.rip = src->rip.u64;
dst.regs.rflags = src->rflags.u64;
OS_LNX_GprsX64 dst;
dst.r15 = src->r15.u64;
dst.r14 = src->r14.u64;
dst.r13 = src->r13.u64;
dst.r12 = src->r12.u64;
dst.rbp = src->rbp.u64;
dst.rbx = src->rbx.u64;
dst.r11 = src->r11.u64;
dst.r10 = src->r10.u64;
dst.r9 = src->r9.u64;
dst.r8 = src->r8.u64;
dst.rax = src->rax.u64;
dst.rcx = src->rcx.u64;
dst.rdx = src->rdx.u64;
dst.rsi = src->rsi.u64;
dst.rdi = src->rdi.u64;
dst.orig_rax = thread->orig_rax;
dst.rip = src->rip.u64;
dst.cs = src->cs.u16;
dst.rflags = src->rflags.u64;
dst.rsp = src->rsp.u64;
dst.ss = src->ss.u16;
dst.fsbase = src->fsbase.u64;
dst.gsbase = src->gsbase.u64;
dst.ds = src->ds.u16;
dst.es = src->es.u16;
dst.fs = src->fs.u16;
dst.gs = src->gs.u16;
did_gpr = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_SETREGSET, tid, (void *)NT_PRSTATUS, &(struct iovec){ .iov_base = &dst, .iov_len = sizeof(dst) }) >= 0);
}
@@ -1192,7 +1193,7 @@ dmn_lnx_thread_write_reg_block(DMN_LNX_Entity *thread)
{
if(n != 4 && n != 5)
{
U64 offset = OffsetOf(DMN_LNX_UserX64, u_debugreg[n]);
U64 offset = OffsetOf(OS_LNX_UserX64, u_debugreg[n]);
int poke_result = OS_LNX_RETRY_ON_EINTR(ptrace(PTRACE_POKEUSER, tid, PtrFromInt(offset), (void*)(uintptr_t)dr_s[n].u64));
if(poke_result < 0)
{
+1 -50
View File
@@ -11,56 +11,6 @@
#include <sys/uio.h>
#include <elf.h>
////////////////////////////////
//~ rjf: Register Layouts
//
// These are defined in <sys/user.h>, but only for one architecture at a time
typedef struct DMN_LNX_UserX64 DMN_LNX_UserX64;
struct DMN_LNX_UserX64
{
struct
{
U64 r15;
U64 r14;
U64 r13;
U64 r12;
U64 rbp;
U64 rbx;
U64 r11;
U64 r10;
U64 r9;
U64 r8;
U64 rax;
U64 rcx;
U64 rdx;
U64 rsi;
U64 rdi;
U64 orig_rax;
U64 rip;
U64 cs;
U64 rflags;
U64 rsp;
U64 ss;
U64 fsbase;
U64 gsbase;
U64 ds;
U64 es;
U64 fs;
U64 gs;
} regs;
S32 u_fpvalid, _pad0;
X64_FXSave i387;
U64 u_tsize, u_dsize, u_ssize, start_code, start_stack;
U64 signal;
S32 reserved, _pad1;
U64 u_ar0, u_fpstate;
U64 magic;
U8 u_comm[32];
U64 u_debugreg[8];
};
StaticAssert(sizeof(DMN_LNX_UserX64) == 912, g_dmn_lnx_user_x64_size_check);
////////////////////////////////
typedef struct DMN_LNX_DbDesc DMN_LNX_DbDesc;
@@ -216,6 +166,7 @@ struct DMN_LNX_Entity
U64 pass_through_signo;
DMN_LNX_ThreadState thread_state;
U64 thread_local_base;
U64 orig_rax;
// module
U64 module_name_vaddr;
+60
View File
@@ -49,6 +49,66 @@ typedef struct timespec timespec;
__ret; \
}))
////////////////////////////////
//~ rjf: Register Layouts
//
// These are defined in <sys/user.h>, but only for one architecture at a time
typedef struct OS_LNX_GprsX64 OS_LNX_GprsX64;
struct OS_LNX_GprsX64
{
U64 r15;
U64 r14;
U64 r13;
U64 r12;
U64 rbp;
U64 rbx;
U64 r11;
U64 r10;
U64 r9;
U64 r8;
U64 rax;
U64 rcx;
U64 rdx;
U64 rsi;
U64 rdi;
U64 orig_rax;
U64 rip;
U64 cs;
U64 rflags;
U64 rsp;
U64 ss;
U64 fsbase;
U64 gsbase;
U64 ds;
U64 es;
U64 fs;
U64 gs;
};
typedef struct OS_LNX_UserX64 OS_LNX_UserX64;
struct OS_LNX_UserX64
{
OS_LNX_GprsX64 regs;
S32 u_fpvalid;
U32 _pad0;
X64_FXSave i387;
U64 u_tsize;
U64 u_dsize;
U64 u_ssize;
U64 start_code;
U64 start_stack;
U64 signal;
U32 reserved;
U32 _pad1;
U64 u_ar0;
U64 u_fpstate;
U64 magic;
U8 u_comm[32];
U64 u_debugreg[8];
};
StaticAssert(sizeof(OS_LNX_UserX64) == 912, g_os_lnx_user_x64_size_check);
////////////////////////////////
//~ rjf: File Iterator