^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2004 PathScale, Inc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <sys/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <sysdep/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <sysdep/ptrace_user.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <registers.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) int save_registers(int pid, struct uml_pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) int restore_pid_registers(int pid, struct uml_pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) /* This is set once at boot time and not changed thereafter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static unsigned long exec_regs[MAX_REG_NR];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static unsigned long exec_fp_regs[FP_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int init_pid_registers(int pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) return -errno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) arch_init_registers(pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) get_fp_registers(pid, exec_fp_regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) memcpy(regs, exec_regs, sizeof(exec_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (fp_regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }