18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2004 PathScale, Inc
48c2ecf20Sopenharmony_ci * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <errno.h>
88c2ecf20Sopenharmony_ci#include <string.h>
98c2ecf20Sopenharmony_ci#include <sys/ptrace.h>
108c2ecf20Sopenharmony_ci#include <sysdep/ptrace.h>
118c2ecf20Sopenharmony_ci#include <sysdep/ptrace_user.h>
128c2ecf20Sopenharmony_ci#include <registers.h>
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciint save_registers(int pid, struct uml_pt_regs *regs)
158c2ecf20Sopenharmony_ci{
168c2ecf20Sopenharmony_ci	int err;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
198c2ecf20Sopenharmony_ci	if (err < 0)
208c2ecf20Sopenharmony_ci		return -errno;
218c2ecf20Sopenharmony_ci	return 0;
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciint restore_pid_registers(int pid, struct uml_pt_regs *regs)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	int err;
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
298c2ecf20Sopenharmony_ci	if (err < 0)
308c2ecf20Sopenharmony_ci		return -errno;
318c2ecf20Sopenharmony_ci	return 0;
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/* This is set once at boot time and not changed thereafter */
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cistatic unsigned long exec_regs[MAX_REG_NR];
378c2ecf20Sopenharmony_cistatic unsigned long exec_fp_regs[FP_SIZE];
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciint init_pid_registers(int pid)
408c2ecf20Sopenharmony_ci{
418c2ecf20Sopenharmony_ci	int err;
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci	err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
448c2ecf20Sopenharmony_ci	if (err < 0)
458c2ecf20Sopenharmony_ci		return -errno;
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci	arch_init_registers(pid);
488c2ecf20Sopenharmony_ci	get_fp_registers(pid, exec_fp_regs);
498c2ecf20Sopenharmony_ci	return 0;
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
538c2ecf20Sopenharmony_ci{
548c2ecf20Sopenharmony_ci	memcpy(regs, exec_regs, sizeof(exec_regs));
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	if (fp_regs)
578c2ecf20Sopenharmony_ci		memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
588c2ecf20Sopenharmony_ci}
59