Home | History | Annotate | Download | only in include
History log of /src/sys/arch/i386/include/ptrace.h
RevisionDateAuthorComments
 1.28  12-Aug-2025  gutteridge i386/include/ptrace.h: move __HAVE_PROCFS_MACHDEP under _KERNEL

For consistency and readability, guard with _KERNEL and move to be next
to the PROCFS_MACHDEP_NODE_TYPES definition, as is done already with
other ports like powerpc.

As discussed in PR port-i386/59402. NFCI.
 1.27  20-Nov-2023  simonb Note some large xstate stack objects what Somebody(tm) should look at
when they find some round tuits.
 1.26  30-May-2020  maxv Introduce PTRACE_REGS_ALIGN, and on x86, enforce a 16-byte alignment, due
to fpregs having fxsave which requires 16-byte alignment.

Reported-by: syzbot+f44d47e617ebf7fda081@syzkaller.appspotmail.com
 1.25  09-Jan-2020  kamil Add missing compat define of PT32_GETXSTATE

Fixes i386 build.

Reviewed by <mgorny>
 1.24  08-Jan-2020  mgorny Include XSTATE note in x86 core dumps

Introduce a simple COREDUMP_MACHDEP_LWP_NOTES logic to provide machdep
API for injecting per-LWP notes into coredumps, and use it to append
PT_GETXSTATE note.

Since the XSTATE block uses the same format on i386 and amd64, the code
does not have to conditionalize between 32-bit and 64-bit ELF format
on that. However, it does need to distinguish between 32-bit and 64-bit
PT_* values. In order to do that, it reuses PT32_* constant already
present for ptrace(), and adds a matching PT64_GETXSTATE to satisfy
the cpp logic.
 1.23  26-Jun-2019  mgorny branches: 1.23.4;
Implement PT_GETXSTATE and PT_SETXSTATE

Introduce two new ptrace() requests: PT_GETXSTATE and PT_SETXSTATE,
that provide access to the extended (and extensible) set of FPU
registers on amd64 and i386. At the moment, this covers AVX (YMM)
and AVX-512 (ZMM, opmask) registers. It can be easily extended
to cover further register types without breaking backwards
compatibility.

PT_GETXSTATE issues the XSAVE instruction with all kernel-supported
extended components enabled. The data is copied into 'struct xstate'
(which -- unlike the XSAVE area itself -- has stable format
and offsets).

PT_SETXSTATE issues the XRSTOR instruction to restore the register
values from user-provided 'struct xstate'. The function replaces only
the specific XSAVE components that are listed in 'xs_rfbm' field,
making it possible to issue partial updates.

Both syscalls take a 'struct iovec' pointer rather than a direct
argument. This requires the caller to explicitly specify the buffer
size. As a result, existing code will continue to work correctly
when the structure is extended (performing partial reads/updates).
 1.22  18-Jun-2019  kamil Introduce PTRACE_REG_FP() a helper macro to retrieve the frame pointer

The macro is dummy for ia64 (the FP register is unknown and can change
freely) and sparc/sparc64 (not stored in struct reg).
 1.21  17-Jun-2019  kamil Define PTRACE_ILLEGAL_ASM for i386
 1.20  22-May-2018  kamil branches: 1.20.2;
Define PTRACE_BREAKPOINT_ASM for i386 in the MD part of <sys/ptrace.h>

x86 uses int3 for software breakpoint on i386 and amd64.

Sponsored by <The NetBSD Foundation>
 1.19  08-Apr-2017  kamil branches: 1.19.12;
Define PT_SETSTEP and PT_CLEARSTEP for i386 (ptrace(2))

Sponsored by <The NetBSD Foundation>
 1.18  23-Feb-2017  kamil Introduce PT_GETDBREGS and PT_SETDBREGS in ptrace(2) on i386 and amd64

This interface is modeled after FreeBSD API with the usage.

This replaced previous watchpoint API. The previous one was introduced
recently in NetBSD-current and remove its spurs without any
backward-compatibility.

Design choices for Debug Register accessors:
- exec() (TRAP_EXEC event) must remove debug registers from LWP
- debug registers are only per-LWP, not per-process globally
- debug registers must not be inherited after (v)forking a process
- debug registers must not be inherited after forking a thread
- a debugger is responsible to set global watchpoints/breakpoints with the
debug registers, to achieve this PTRACE_LWP_CREATE/PTRACE_LWP_EXIT event
monitoring function is designed to be used
- debug register traps must generate SIGTRAP with si_code TRAP_DBREG
- debugger is responsible to retrieve debug register state to distinguish
the exact debug register trap (DR6 is Status Register on x86)
- kernel must not remove debug register traps after triggering a trap event
a debugger is responsible to detach this trap with appropriate PT_SETDBREGS
call (DR7 is Control Register on x86)
- debug registers must not be exposed in mcontext
- userland must not be allowed to set a trap on the kernel

Implementation notes on i386 and amd64:
- the initial state of debug register is retrieved on boot and this value is
stored in a local copy (initdbregs), this value is used to initialize dbreg
context after PT_GETDBREGS
- struct dbregs is stored in pcb as a pointer and by default not initialized
- reserved registers (DR4-DR5, DR9-DR15) are ignored

Further ideas:
- restrict this interface with securelevel

Tested on real hardware i386 (Intel Pentium IV) and amd64 (Intel i7).

This commit enables 390 debug register ATF tests in kernel/arch/x86.
All tests are passing.

This commit does not cover netbsd32 compat code. Currently other interface
PT_GET_SIGINFO/PT_SET_SIGINFO is required in netbsd32 compat code in order to
validate reliably PT_GETDBREGS/PT_SETDBREGS.

This implementation does not cover FreeBSD specific defines in their
<x86/reg.h>: DBREG_DR7_LOCAL_ENABLE, DBREG_DR7_GLOBAL_ENABLE, DBREG_DR7_LEN_1
etc. These values tend to be reinvented by each tracer on its own. GNU
Debugger (GDB) works with NetBSD debug registers after adding this patch:

--- gdb/amd64bsd-nat.c.orig 2016-02-10 03:19:39.000000000 +0000
+++ gdb/amd64bsd-nat.c
@@ -167,6 +167,10 @@ amd64bsd_target (void)

#ifdef HAVE_PT_GETDBREGS

+#ifndef DBREG_DRX
+#define DBREG_DRX(d,x) ((d)->dr[(x)])
+#endif
+
static unsigned long
amd64bsd_dr_get (ptid_t ptid, int regnum)
{


Another reason to stop introducing unpopular defines covering machine
specific register macros is that these value varies across generations of
the same CPU family.

GDB demo:
(gdb) c
Continuing.

Watchpoint 2: traceme

Old value = 0
New value = 16
main (argc=1, argv=0x7f7fff79fe30) at test.c:8
8 printf("traceme=%d\n", traceme);

(Currently the GDB interface is not reliable due to NetBSD support bugs)

Sponsored by <The NetBSD Foundation>
 1.17  16-Jan-2017  kamil Refactor ptrace_watchpoint structure to allow extensions

Add new field pw_type in the ptrace_watchpoint structure.

amd64 and i386 offer the current set of watchpoints as
PTRACE_PW_TYPE_DBREGS.

On other archs than x86, there are readily available different types of
hardware assisted watchpoints like for code-only or data-only registers on
ARM. Also in future there is an option to implement MMU-based watchpoints
and future per-port or per-cpu extensions.

Next step is to alter this interface on x86 to generate SIGTRAP with
si_code TRAP_HWWTRAP with additional information on occurred event:
- which watchpoint fired,
- additional watchpoint-type specific information, like on amd64 with
PTRACE_PW_TYPE_DBREGS.:
* only watchpoint fired
* watchpoint fired and single step occurred

Adjust ATF tests for the pw_type change.

Sponsored by <The NetBSD Foundation>
 1.16  15-Dec-2016  kamil branches: 1.16.2;
Add support for hardware assisted watchpoints/breakpoints API in ptrace(2)

Add new ptrace(2) calls:
- PT_COUNT_WATCHPOINTS - count the number of available hardware watchpoints
- PT_READ_WATCHPOINT - read struct ptrace_watchpoint from the kernel state
- PT_WRITE_WATCHPOINT - write new struct ptrace_watchpoint state, this
includes enabling and disabling watchpoints

The ptrace_watchpoint structure contains MI and MD parts:

typedef struct ptrace_watchpoint {
int pw_index; /* HW Watchpoint ID (count from 0) */
lwpid_t pw_lwpid; /* LWP described */
struct mdpw pw_md; /* MD fields */
} ptrace_watchpoint_t;

For example amd64 defines MD as follows:
struct mdpw {
void *md_address;
int md_condition;
int md_length;
};

These calls are protected with the __HAVE_PTRACE_WATCHPOINTS guard.

Tested on amd64, initial support added for i386 and XEN.

Sponsored by <The NetBSD Foundation>
 1.15  25-Sep-2015  christos branches: 1.15.2;
For processors that have memory breakpoints, add macros for them to help
libproc
 1.14  15-Sep-2015  christos Provide access to pc/sp/syscall-return registers like we have for mcontext
 1.13  05-Mar-2006  christos branches: 1.13.2; 1.13.116; 1.13.136;
provide strings for the machdep ptrace calls.
 1.12  11-Dec-2005  christos branches: 1.12.4; 1.12.6;
merge ktrace-lwp.
 1.11  29-Jun-2003  fvdl branches: 1.11.2; 1.11.18;
Back out the lwp/ktrace changes. They contained a lot of colateral damage,
and need to be examined and discussed more.
 1.10  28-Jun-2003  darrenr Pass lwp pointers throughtout the kernel, as required, so that the lwpid can
be inserted into ktrace records. The general change has been to replace
"struct proc *" with "struct lwp *" in various function prototypes, pass
the lwp through and use l_proc to get the process pointer when needed.

Bump the kernel rev up to 1.6V
 1.9  17-Jan-2003  thorpej Merge the nathanw_sa branch.
 1.8  09-May-2002  thorpej branches: 1.8.4;
Mirror cleanup wrt. procfs-centric naming made to the MI ptrace code.
 1.7  05-Dec-2001  thorpej * Allow machine-dependent code to specify hooks for ptrace(2)
(__HAVE_PTRACE_MACHDEP) and procfs (__HAVE_PROCFS_MACHDEP).
These changes will allow platforms like x86 (XMM) and PowerPC
(AltiVec) to export extended register sets in a sane manner.

* Use __HAVE_PTRACE_MACHDEP to export x86 XMM registers (standard
FP + SSE/SSE2) using PT_{GET,SET}XMMREGS (in the machdep
ptrace request space).
* Use __HAVE_PROCFS_MACHDEP to export x86 XMM registers via
/proc/N/xmmregs in procfs.
 1.6  06-Aug-1995  mycroft branches: 1.6.46; 1.6.48;
Move the `used fpu' flag into mdproc, so it can be referenced when a process
is swapped out. Implement process_{read,write}_fpregs.
 1.5  27-Oct-1994  cgd new RCS ID format.
 1.4  28-Jan-1994  jtc branches: 1.4.2;
Fix spelling error in Copyright notice
 1.3  28-Jan-1994  cgd getting and setting FP regs aren't appropriate yet
 1.2  09-Jan-1994  cgd define PT_STEP, and clean up some
 1.1  08-Jan-1994  cgd code reorg
 1.4.2.2  28-Jan-1994  jtc Fix spelling error in Copyright notice
 1.4.2.1  28-Jan-1994  jtc file ptrace.h was added on branch magnum on 1994-01-28 23:44:22 +0000
 1.6.48.2  23-Jun-2002  jdolecek catch up with -current on kqueue branch
 1.6.48.1  10-Jan-2002  thorpej Sync kqueue branch with -current.
 1.6.46.5  15-Oct-2002  nathanw Make _validfoo() routines go back to taking a proc.
 1.6.46.4  21-Jun-2002  gmcgarry LWPify
 1.6.46.3  20-Jun-2002  nathanw Catch up to -current.
 1.6.46.2  09-Jan-2002  nathanw Adapt xmm handling to LWPs.
 1.6.46.1  08-Jan-2002  nathanw Catch up to -current.
 1.8.4.2  09-May-2002  thorpej Mirror cleanup wrt. procfs-centric naming made to the MI ptrace code.
 1.8.4.1  09-May-2002  thorpej file ptrace.h was added on branch sommerfeld_i386mp_1 on 2002-05-09 16:28:13 +0000
 1.11.18.1  21-Jun-2006  yamt sync with head.
 1.11.2.3  21-Sep-2004  skrll Fix the sync with head I botched.
 1.11.2.2  18-Sep-2004  skrll Sync with HEAD.
 1.11.2.1  02-Jul-2003  darrenr Apply the aborted ktrace-lwp changes to a specific branch. This is just for
others to review, I'm concerned that patch fuziness may have resulted in some
errant code being generated but I'll look at that later by comparing the diff
from the base to the branch with the file I attempt to apply to it. This will,
at the very least, put the changes in a better context for others to review
them and attempt to tinker with removing passing of 'struct lwp' through
the kernel.
 1.12.6.1  22-Apr-2006  simonb Sync with head.
 1.12.4.1  09-Sep-2006  rpaulo sync with head
 1.13.136.4  28-Aug-2017  skrll Sync with HEAD
 1.13.136.3  05-Feb-2017  skrll Sync with HEAD
 1.13.136.2  27-Dec-2015  skrll Sync with HEAD (as of 26th Dec)
 1.13.136.1  22-Sep-2015  skrll Sync with HEAD
 1.13.116.1  03-Dec-2017  jdolecek update from HEAD
 1.13.2.2  05-Mar-2006  christos provide strings for the machdep ptrace calls.
 1.13.2.1  05-Mar-2006  christos file ptrace.h was added on branch yamt-pdpolicy on 2006-03-05 07:17:22 +0000
 1.15.2.3  26-Apr-2017  pgoyette Sync with HEAD
 1.15.2.2  20-Mar-2017  pgoyette Sync with HEAD
 1.15.2.1  07-Jan-2017  pgoyette Sync with HEAD. (Note that most of these changes are simply $NetBSD$
tag issues.)
 1.16.2.1  21-Apr-2017  bouyer Sync with HEAD
 1.19.12.1  25-Jun-2018  pgoyette Sync with HEAD
 1.20.2.2  13-Apr-2020  martin Mostly merge changes from HEAD upto 20200411
 1.20.2.1  08-Apr-2020  martin Merge changes from current as of 20200406
 1.23.4.1  17-Jan-2020  ad Sync with head.

RSS XML Feed