mirror of
git://git.yoctoproject.org/linux-yocto.git
synced 2025-10-22 23:13:01 +02:00

Doing this allows using registers as retrieved from an mcontext to be pushed to a process using PTRACE_SETREGS. It is not entirely clear to me why CSGSFS was masked. Doing so creates issues when using the mcontext as process state in seccomp and simply copying the register appears to work perfectly fine for ptrace. Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net> Link: https://patch.msgid.link/20250224181827.647129-2-benjamin@sipsolutions.net Signed-off-by: Johannes Berg <johannes.berg@intel.com>
45 lines
1.3 KiB
C
45 lines
1.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <sys/ucontext.h>
|
|
#define __FRAME_OFFSETS
|
|
#include <asm/ptrace.h>
|
|
#include <sysdep/ptrace.h>
|
|
#include <sysdep/mcontext.h>
|
|
#include <arch.h>
|
|
|
|
void get_regs_from_mc(struct uml_pt_regs *regs, mcontext_t *mc)
|
|
{
|
|
#ifdef __i386__
|
|
#define COPY2(X,Y) regs->gp[X] = mc->gregs[REG_##Y]
|
|
#define COPY(X) regs->gp[X] = mc->gregs[REG_##X]
|
|
#define COPY_SEG(X) regs->gp[X] = mc->gregs[REG_##X] & 0xffff;
|
|
#define COPY_SEG_CPL3(X) regs->gp[X] = (mc->gregs[REG_##X] & 0xffff) | 3;
|
|
COPY_SEG(GS); COPY_SEG(FS); COPY_SEG(ES); COPY_SEG(DS);
|
|
COPY(EDI); COPY(ESI); COPY(EBP);
|
|
COPY2(UESP, ESP); /* sic */
|
|
COPY(EBX); COPY(EDX); COPY(ECX); COPY(EAX);
|
|
COPY(EIP); COPY_SEG_CPL3(CS); COPY(EFL); COPY_SEG_CPL3(SS);
|
|
#else
|
|
#define COPY2(X,Y) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##Y]
|
|
#define COPY(X) regs->gp[X/sizeof(unsigned long)] = mc->gregs[REG_##X]
|
|
COPY(R8); COPY(R9); COPY(R10); COPY(R11);
|
|
COPY(R12); COPY(R13); COPY(R14); COPY(R15);
|
|
COPY(RDI); COPY(RSI); COPY(RBP); COPY(RBX);
|
|
COPY(RDX); COPY(RAX); COPY(RCX); COPY(RSP);
|
|
COPY(RIP);
|
|
COPY2(EFLAGS, EFL);
|
|
COPY2(CS, CSGSFS);
|
|
regs->gp[SS / sizeof(unsigned long)] = mc->gregs[REG_CSGSFS] >> 48;
|
|
#endif
|
|
}
|
|
|
|
void mc_set_rip(void *_mc, void *target)
|
|
{
|
|
mcontext_t *mc = _mc;
|
|
|
|
#ifdef __i386__
|
|
mc->gregs[REG_EIP] = (unsigned long)target;
|
|
#else
|
|
mc->gregs[REG_RIP] = (unsigned long)target;
|
|
#endif
|
|
}
|