proc_regs.c revision 210688
1139804Simp/*
246197Sphk * Copyright (c) 2010 The FreeBSD Foundation
346197Sphk * All rights reserved.
446197Sphk *
546197Sphk * This software was developed by Rui Paulo under sponsorship from the
646197Sphk * FreeBSD Foundation.
746197Sphk *
846197Sphk * Redistribution and use in source and binary forms, with or without
946155Sphk * modification, are permitted provided that the following conditions
10116182Sobrien * are met:
11116182Sobrien * 1. Redistributions of source code must retain the above copyright
12116182Sobrien *    notice, this list of conditions and the following disclaimer.
13131177Spjd * 2. Redistributions in binary form must reproduce the above copyright
14131177Spjd *    notice, this list of conditions and the following disclaimer in the
1546155Sphk *    documentation and/or other materials provided with the distribution.
1646155Sphk *
1746155Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1846155Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1946155Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2046155Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2146155Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22164032Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2346155Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24124882Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2546155Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2687275Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2787275Srwatson * SUCH DAMAGE.
28113275Smike */
29147185Spjd
30113275Smike#include <sys/cdefs.h>
3146155Sphk__FBSDID("$FreeBSD: head/lib/libproc/proc_regs.c 210688 2010-07-31 16:10:20Z rpaulo $");
32113275Smike
3357163Srwatson#include <sys/types.h>
34113275Smike#include <sys/ptrace.h>
3546155Sphk
3646155Sphk#include <err.h>
3746155Sphk#include <stdio.h>
38163606Srwatson#include <string.h>
39163606Srwatson#include <errno.h>
4046155Sphk#include "_libproc.h"
4146155Sphk
4289414Sarrint
4357163Srwatsonproc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue)
4457163Srwatson{
4557163Srwatson	struct reg regs;
4689414Sarr
4757163Srwatson	if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
4857163Srwatson	    phdl->status == PS_IDLE) {
4957163Srwatson		errno = ENOENT;
5061235Srwatson		return (-1);
5189414Sarr	}
5261235Srwatson	memset(&regs, 0, sizeof(regs));
5361235Srwatson	if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)&regs, 0) < 0)
5461235Srwatson		return (-1);
5568024Srwatson	switch (reg) {
5689414Sarr	case REG_PC:
5768024Srwatson#if defined(__amd64__)
5868024Srwatson		*regvalue = regs.r_rip;
5968024Srwatson#elif defined(__i386__)
60147185Spjd		*regvalue = regs.r_eip;
61147185Spjd#endif
62147185Spjd		break;
63147185Spjd	case REG_SP:
64125804Srwatson#if defined(__amd64__)
65128664Sbmilekic		*regvalue = regs.r_rsp;
66128664Sbmilekic#elif defined(__i386__)
67128664Sbmilekic		*regvalue = regs.r_esp;
68128664Sbmilekic#endif
69128664Sbmilekic		break;
70141543Scperciva	default:
71141543Scperciva		warn("ERROR: no support for reg number %d", reg);
72141543Scperciva		return (-1);
73141543Scperciva	}
74141543Scperciva
75113275Smike	return (0);
76113275Smike}
77113275Smike
78113275Smikeint
79113275Smikeproc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue)
80113275Smike{
81113275Smike	struct reg regs;
82124882Srwatson
83113275Smike	if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD ||
84113275Smike	    phdl->status == PS_IDLE) {
85113275Smike		errno = ENOENT;
86113275Smike		return (-1);
87113275Smike	}
88113275Smike	if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)&regs, 0) < 0)
89113275Smike		return (-1);
90113275Smike	switch (reg) {
91113275Smike	case REG_PC:
92113275Smike#if defined(__amd64__)
93113275Smike		regs.r_rip = regvalue;
94113275Smike#elif defined(__i386__)
95113275Smike		regs.r_eip = regvalue;
9682710Sdillon#endif
9782710Sdillon		break;
98114168Smike	case REG_SP:
99114168Smike#if defined(__amd64__)
100114168Smike		regs.r_rsp = regvalue;
101114168Smike#elif defined(__i386__)
10282710Sdillon		regs.r_esp = regvalue;
10346155Sphk#endif
104114168Smike		break;
10546155Sphk	default:
106113275Smike		warn("ERROR: no support for reg number %d", reg);
107113275Smike		return (-1);
10846155Sphk	}
109113275Smike	if (ptrace(PT_SETREGS, proc_getpid(phdl), (caddr_t)&regs, 0) < 0)
110150652Scsjp		return (-1);
11146155Sphk
112114168Smike	return (0);
11346155Sphk}
11484828Sjhb