blob: 2ff8d4fe83c4fd2d202ab5a6e45028f844978d83 [file] [log] [blame]
Jeff Dike42daba32007-10-16 01:26:47 -07001/*
2 * Copyright (C) 2004 PathScale, Inc
Jeff Dikeba180fd2007-10-16 01:27:00 -07003 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
Jeff Dike42daba32007-10-16 01:26:47 -07004 * Licensed under the GPL
5 */
6
7#include <errno.h>
8#include <string.h>
9#include <sys/ptrace.h>
Al Viro37185b32012-10-08 03:27:32 +010010#include <sysdep/ptrace.h>
11#include <sysdep/ptrace_user.h>
12#include <registers.h>
Jeff Dike42daba32007-10-16 01:26:47 -070013
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080014int save_registers(int pid, struct uml_pt_regs *regs)
Jeff Dike42daba32007-10-16 01:26:47 -070015{
16 int err;
17
Jeff Dike18baddd2007-10-16 01:27:07 -070018 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
Jeff Dikeba180fd2007-10-16 01:27:00 -070019 if (err < 0)
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080020 return -errno;
21 return 0;
Jeff Dike42daba32007-10-16 01:26:47 -070022}
23
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080024int restore_registers(int pid, struct uml_pt_regs *regs)
Jeff Dike42daba32007-10-16 01:26:47 -070025{
26 int err;
27
Jeff Dike18baddd2007-10-16 01:27:07 -070028 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
Jeff Dikeba180fd2007-10-16 01:27:00 -070029 if (err < 0)
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080030 return -errno;
31 return 0;
Jeff Dike42daba32007-10-16 01:26:47 -070032}
33
Jeff Diked25f2e12008-02-04 22:30:57 -080034/* This is set once at boot time and not changed thereafter */
35
36static unsigned long exec_regs[MAX_REG_NR];
Ingo van Lilfbfe9c82011-09-14 16:21:23 -070037static unsigned long exec_fp_regs[FP_SIZE];
Jeff Diked25f2e12008-02-04 22:30:57 -080038
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080039int init_registers(int pid)
Jeff Dike42daba32007-10-16 01:26:47 -070040{
41 int err;
42
43 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080044 if (err < 0)
45 return -errno;
Jeff Dikea5f6096c2007-10-16 01:27:15 -070046
47 arch_init_registers(pid);
Ingo van Lilfbfe9c82011-09-14 16:21:23 -070048 get_fp_registers(pid, exec_fp_regs);
Jeff Dike3e6f2ac2008-02-04 22:30:58 -080049 return 0;
Jeff Dike42daba32007-10-16 01:26:47 -070050}
51
Ingo van Lilfbfe9c82011-09-14 16:21:23 -070052void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
Jeff Dike42daba32007-10-16 01:26:47 -070053{
54 memcpy(regs, exec_regs, sizeof(exec_regs));
Ingo van Lilfbfe9c82011-09-14 16:21:23 -070055
56 if (fp_regs)
57 memcpy(fp_regs, exec_fp_regs, sizeof(exec_fp_regs));
Jeff Dike42daba32007-10-16 01:26:47 -070058}