Add support for ptrace() and gdb breakpoints.

This commit is contained in:
Olivier Houchard 2005-01-10 22:43:16 +00:00
parent 8b64f2f5ad
commit 9026d36c6e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=140001
5 changed files with 80 additions and 16 deletions

View File

@ -64,8 +64,10 @@ __FBSDID("$FreeBSD$");
#include <sys/buf.h>
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/uio.h>
#include <machine/reg.h>
#include <machine/cpu.h>
#include <machine/trap.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@ -289,17 +291,68 @@ set_dbregs(struct thread *td, struct dbreg *regs)
return (0);
}
static int
ptrace_read_int(struct thread *td, vm_offset_t addr, u_int32_t *v)
{
struct iovec iov;
struct uio uio;
iov.iov_base = (caddr_t) v;
iov.iov_len = sizeof(u_int32_t);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_offset = (off_t)addr;
uio.uio_resid = sizeof(u_int32_t);
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = UIO_READ;
uio.uio_td = td;
return proc_rwmem(td->td_proc, &uio);
}
static int
ptrace_write_int(struct thread *td, vm_offset_t addr, u_int32_t v)
{
struct iovec iov;
struct uio uio;
iov.iov_base = (caddr_t) &v;
iov.iov_len = sizeof(u_int32_t);
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
uio.uio_offset = (off_t)addr;
uio.uio_resid = sizeof(u_int32_t);
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_rw = UIO_WRITE;
uio.uio_td = td;
return proc_rwmem(td->td_proc, &uio);
}
int
ptrace_single_step(struct thread *td)
{
/* XXX */
return (0);
int error;
KASSERT(td->td_md.md_ptrace_instr == 0,
("Didn't clear single step"));
error = ptrace_read_int(td, td->td_frame->tf_pc + 4,
&td->td_md.md_ptrace_instr);
if (error)
return (error);
error = ptrace_write_int(td, td->td_frame->tf_pc + 4,
PTRACE_BREAKPOINT);
if (error)
td->td_md.md_ptrace_instr = 0;
td->td_md.md_ptrace_addr = td->td_frame->tf_pc + 4;
return (error);
}
int
ptrace_clear_single_step(struct thread *td)
{
/* XXX */
if (td->td_md.md_ptrace_instr) {
ptrace_write_int(td, td->td_md.md_ptrace_addr,
td->td_md.md_ptrace_instr);
td->td_md.md_ptrace_instr = 0;
}
return (0);
}

View File

@ -100,6 +100,8 @@ __FBSDID("$FreeBSD$");
#include <sys/uio.h>
#include <sys/ktrace.h>
#endif
#include <sys/ptrace.h>
#include <sys/pioctl.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@ -919,6 +921,8 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
if (error == 0) {
td->td_retval[0] = 0;
td->td_retval[1] = 0;
STOPEVENT(p, S_SCE, (callp->sy_narg & SYF_ARGMASK));
PTRACESTOP_SC(p, td, S_PT_SCE);
error = (*callp->sy_call)(td, args);
}
switch (error) {
@ -952,6 +956,8 @@ syscall(struct thread *td, trapframe_t *frame, u_int32_t insn)
CTR4(KTR_SYSC, "syscall exit thread %p pid %d proc %s code %d", td,
td->td_proc->p_pid, td->td_proc->p_comm, code);
STOPEVENT(p, S_SCX, code);
PTRACESTOP_SC(p, td, S_PT_SCX);
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(code, error, td->td_retval[0]);

View File

@ -62,6 +62,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/signalvar.h>
#include <sys/ptrace.h>
#ifdef KDB
#include <sys/kdb.h>
#endif
@ -135,26 +136,17 @@ gdb_trapper(u_int addr, u_int insn, struct trapframe *frame, int code)
struct thread *td;
td = (curthread == NULL) ? &thread0 : curthread;
#if 0
if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) {
if (code == FAULT_USER) {
ksiginfo_t ksi;
KSI_INIT_TRAP(&ksi);
ksi.ksi_signo = SIGTRAP;
ksi.ksi_code = TRAP_BRKPT;
ksi.ksi_addr = (u_int32_t *)addr;
ksi.ksi_trap = 0;
PROC_LOCK(td->td_proc);
trapsignal(td, &ksi);
PROC_UNLOCK(td->td_proc);
trapsignal(td, SIGTRAP, 0);
return 0;
}
#if 0
#ifdef KGDB
return !kgdb_trap(T_BREAKPOINT, frame);
#endif
}
#endif
}
return 1;
}
@ -257,6 +249,11 @@ undefinedinstruction(trapframe_t *frame)
fault_code) == 0)
break;
if (fault_code & FAULT_USER && fault_instruction == PTRACE_BREAKPOINT) {
ptrace_clear_single_step(td);
return;
}
if (uh == NULL && (fault_code & FAULT_USER)) {
/* Fault has not been handled */
trapsignal(td, SIGILL, 0);
@ -272,7 +269,7 @@ undefinedinstruction(trapframe_t *frame)
return;
} else
panic("Undefined instruction in kernel.\n");
}
}
#ifdef FAST_FPE
/* Optimised exit code */

View File

@ -47,6 +47,8 @@ struct md_utrap {
struct mdthread {
register_t md_savecrit;
int md_ptrace_instr;
int md_ptrace_addr;
};
struct mdproc {

View File

@ -1,4 +1,10 @@
/* $NetBSD: trap.h,v 1.1 2001/02/23 03:48:19 ichiro Exp $ */
/* $FreeBSD$ */
#ifndef _MACHINE_TRAP_H_
#define _MACHINE_TRAP_H_
#define GDB_BREAKPOINT 0xe6000011
#define GDB5_BREAKPOINT 0xe7ffdefe
#define PTRACE_BREAKPOINT 0xe7fffff0
#define KERNEL_BREAKPOINT 0xe7ffffff
#endif /* _MACHINE_TRAP_H_ */