From 12b53f417475431c86a19112a4abea40e8cad475 Mon Sep 17 00:00:00 2001 From: Nikita Smith Date: Mon, 12 Jan 2026 15:08:29 -0800 Subject: [PATCH] move register layout struct to Linux OS layer; use only GPR portion of the layout struct for reg r/w; handle orig_rax --- src/demon/linux/demon_core_linux.c | 119 +++++++++++++++-------------- src/demon/linux/demon_core_linux.h | 51 +------------ src/os/core/linux/os_core_linux.h | 60 +++++++++++++++ 3 files changed, 121 insertions(+), 109 deletions(-) diff --git a/src/demon/linux/demon_core_linux.c b/src/demon/linux/demon_core_linux.c index 2ead00fb..286aae38 100644 --- a/src/demon/linux/demon_core_linux.c +++ b/src/demon/linux/demon_core_linux.c @@ -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) { diff --git a/src/demon/linux/demon_core_linux.h b/src/demon/linux/demon_core_linux.h index 6bb67868..2e05e8c9 100644 --- a/src/demon/linux/demon_core_linux.h +++ b/src/demon/linux/demon_core_linux.h @@ -11,56 +11,6 @@ #include #include -//////////////////////////////// -//~ rjf: Register Layouts -// -// These are defined in , 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; diff --git a/src/os/core/linux/os_core_linux.h b/src/os/core/linux/os_core_linux.h index d18a2a7e..1f3ab4a0 100644 --- a/src/os/core/linux/os_core_linux.h +++ b/src/os/core/linux/os_core_linux.h @@ -49,6 +49,66 @@ typedef struct timespec timespec; __ret; \ })) +//////////////////////////////// +//~ rjf: Register Layouts +// +// These are defined in , 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