| 1 | /*	$NetBSD: ptrace.h,v 1.77 2025/01/11 19:42:04 christos Exp $	*/ |
| 2 | |
| 3 | /*- |
| 4 | * Copyright (c) 1984, 1993 |
| 5 | *	The Regents of the University of California. All rights reserved. |
| 6 | * |
| 7 | * Redistribution and use in source and binary forms, with or without |
| 8 | * modification, are permitted provided that the following conditions |
| 9 | * are met: |
| 10 | * 1. Redistributions of source code must retain the above copyright |
| 11 | * notice, this list of conditions and the following disclaimer. |
| 12 | * 2. Redistributions in binary form must reproduce the above copyright |
| 13 | * notice, this list of conditions and the following disclaimer in the |
| 14 | * documentation and/or other materials provided with the distribution. |
| 15 | * 3. Neither the name of the University nor the names of its contributors |
| 16 | * may be used to endorse or promote products derived from this software |
| 17 | * without specific prior written permission. |
| 18 | * |
| 19 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 29 | * SUCH DAMAGE. |
| 30 | * |
| 31 | *	@(#)ptrace.h	8.2 (Berkeley) 1/4/94 |
| 32 | */ |
| 33 | |
| 34 | #ifndef	_SYS_PTRACE_H_ |
| 35 | #define	_SYS_PTRACE_H_ |
| 36 | |
| 37 | #include <sys/siginfo.h> |
| 38 | #include <sys/signal.h> |
| 39 | |
| 40 | #define	PT_TRACE_ME		0	/* child declares it's being traced */ |
| 41 | #define	PT_READ_I		1	/* read word in child's I space */ |
| 42 | #define	PT_READ_D		2	/* read word in child's D space */ |
| 43 | #define	PT_WRITE_I		4	/* write word in child's I space */ |
| 44 | #define	PT_WRITE_D		5	/* write word in child's D space */ |
| 45 | #define	PT_CONTINUE		7	/* continue the child */ |
| 46 | #define	PT_KILL			8	/* kill the child process */ |
| 47 | #define	PT_ATTACH		9	/* attach to running process */ |
| 48 | #define	PT_DETACH		10	/* detach from running process */ |
| 49 | #define	PT_IO			11	/* do I/O to/from the stopped process */ |
| 50 | #define	PT_DUMPCORE		12	/* make child generate a core dump */ |
| 51 | #if defined(__LEGACY_PT_LWPINFO) || defined(_KERNEL) |
| 52 | #define	PT_LWPINFO		13	/* OBSOLETE: get info about the LWP */ |
| 53 | #endif |
| 54 | #define	PT_SYSCALL		14	/* stop on syscall entry/exit */ |
| 55 | #define	PT_SYSCALLEMU		15	/* cancel syscall, tracer emulates it */ |
| 56 | #define	PT_SET_EVENT_MASK	16	/* set the event mask, defined below */ |
| 57 | #define	PT_GET_EVENT_MASK	17	/* get the event mask, defined below */ |
| 58 | #define	PT_GET_PROCESS_STATE	18	/* get process state, defined below */ |
| 59 | #define	PT_SET_SIGINFO		19	/* set signal state, defined below */ |
| 60 | #define	PT_GET_SIGINFO		20	/* get signal state, defined below */ |
| 61 | #define	PT_RESUME		21	/* allow execution of the LWP */ |
| 62 | #define	PT_SUSPEND		22	/* prevent execution of the LWP */ |
| 63 | #define	PT_STOP			23	/* stop the child process */ |
| 64 | #define	PT_LWPSTATUS		24	/* get info about the LWP */ |
| 65 | #define	PT_LWPNEXT		25	/* get info about next LWP */ |
| 66 | #define	PT_SET_SIGPASS		26	/* set signals to pass to debuggee */ |
| 67 | #define	PT_GET_SIGPASS		27	/* get signals to pass to debuggee */ |
| 68 | |
| 69 | #define	PT_FIRSTMACH		32	/* for machine-specific requests */ |
| 70 | #include <machine/ptrace.h>		/* machine-specific requests, if any */ |
| 71 | #ifndef PT_MACHDEP_STRINGS |
| 72 | # define PT_MACHDEP_STRINGS |
| 73 | #endif |
| 74 | |
| 75 | #define PT_STRINGS \ |
| 76 | /* 0 */ "PT_TRACE_ME", \ |
| 77 | /* 1 */ "PT_READ_I", \ |
| 78 | /* 2 */ "PT_READ_D", \ |
| 79 | /* 3 */ "*PT_INVALID_3*", \ |
| 80 | /* 4 */ "PT_WRITE_I", \ |
| 81 | /* 5 */ "PT_WRITE_D", \ |
| 82 | /* 6 */ "*PT_INVALID_6*", \ |
| 83 | /* 7 */ "PT_CONTINUE", \ |
| 84 | /* 8 */ "PT_KILL", \ |
| 85 | /* 9 */ "PT_ATTACH", \ |
| 86 | /* 10 */ "PT_DETACH", \ |
| 87 | /* 11 */ "PT_IO", \ |
| 88 | /* 12 */ "PT_DUMPCORE", \ |
| 89 | /* 13 */ "PT_LWPINFO", \ |
| 90 | /* 14 */ "PT_SYSCALL", \ |
| 91 | /* 15 */ "PT_SYSCALLEMU", \ |
| 92 | /* 16 */ "PT_SET_EVENT_MASK", \ |
| 93 | /* 17 */ "PT_GET_EVENT_MASK", \ |
| 94 | /* 18 */ "PT_GET_PROCESS_STATE", \ |
| 95 | /* 19 */ "PT_SET_SIGINFO", \ |
| 96 | /* 20 */ "PT_GET_SIGINFO", \ |
| 97 | /* 21 */ "PT_RESUME", \ |
| 98 | /* 22 */ "PT_SUSPEND", \ |
| 99 | /* 23 */ "PT_STOP", \ |
| 100 | /* 24 */ "PT_LWPSTATUS", \ |
| 101 | /* 25 */ "PT_LWPNEXT", \ |
| 102 | /* 26 */ "PT_SET_SIGPASS", \ |
| 103 | /* 27 */ "PT_GET_SIGPASS", \ |
| 104 | /* 28 */ "*PT_INVALID_28", \ |
| 105 | /* 29 */ "*PT_INVALID_29", \ |
| 106 | /* 30 */ "*PT_INVALID_30", \ |
| 107 | /* 31 */ "*PT_INVALID_31", \ |
| 108 | PT_MACHDEP_STRINGS |
| 109 | |
| 110 | /* PT_{G,S}EVENT_MASK */ |
| 111 | typedef struct ptrace_event { |
| 112 | 	int	pe_set_event; |
| 113 | } ptrace_event_t; |
| 114 | |
| 115 | /* PT_GET_PROCESS_STATE */ |
| 116 | typedef struct ptrace_state { |
| 117 | 	int	pe_report_event; |
| 118 | 	union { |
| 119 | 		pid_t	_pe_other_pid; |
| 120 | 		lwpid_t	_pe_lwp; |
| 121 | 	} _option; |
| 122 | } ptrace_state_t; |
| 123 | |
| 124 | #define	pe_other_pid	_option._pe_other_pid |
| 125 | #define	pe_lwp		_option._pe_lwp |
| 126 | |
| 127 | #define	PTRACE_FORK		0x0001	/* Report forks */ |
| 128 | #define	PTRACE_VFORK		0x0002	/* Report vforks */ |
| 129 | #define	PTRACE_VFORK_DONE	0x0004	/* Report parent resumed from vforks */ |
| 130 | #define	PTRACE_LWP_CREATE	0x0008	/* Report LWP creation */ |
| 131 | #define	PTRACE_LWP_EXIT		0x0010	/* Report LWP termination */ |
| 132 | #define	PTRACE_POSIX_SPAWN	0x0020	/* Report posix_spawn */ |
| 133 | |
| 134 | /* |
| 135 | * Argument structure for PT_IO. |
| 136 | */ |
| 137 | struct ptrace_io_desc { |
| 138 | 	int	piod_op;	/* I/O operation (see below) */ |
| 139 | 	void	*piod_offs;	/* child offset */ |
| 140 | 	void	*piod_addr;	/* parent offset */ |
| 141 | 	size_t	piod_len;	/* request length (in)/actual count (out) */ |
| 142 | }; |
| 143 | |
| 144 | /* piod_op */ |
| 145 | #define	PIOD_READ_D	1	/* read from D space */ |
| 146 | #define	PIOD_WRITE_D	2	/* write to D space */ |
| 147 | #define	PIOD_READ_I	3	/* read from I space */ |
| 148 | #define	PIOD_WRITE_I	4	/* write to I space */ |
| 149 | #define PIOD_READ_AUXV	5	/* Read from aux array */ |
| 150 | |
| 151 | #if defined(__LEGACY_PT_LWPINFO) || defined(_KERNEL) |
| 152 | /* |
| 153 | * Argument structure for PT_LWPINFO. |
| 154 | * |
| 155 | * DEPRECATED: Use ptrace_lwpstatus. |
| 156 | */ |
| 157 | struct ptrace_lwpinfo { |
| 158 | 	lwpid_t	pl_lwpid;	/* LWP described */ |
| 159 | 	int	pl_event;	/* Event that stopped the LWP */ |
| 160 | }; |
| 161 | |
| 162 | #define PL_EVENT_NONE		0 |
| 163 | #define PL_EVENT_SIGNAL		1 |
| 164 | #define PL_EVENT_SUSPENDED	2 |
| 165 | #endif |
| 166 | |
| 167 | /* |
| 168 | * Argument structure for PT_LWPSTATUS. |
| 169 | */ |
| 170 | |
| 171 | #define PL_LNAMELEN	20	/* extra 4 for alignment */ |
| 172 | |
| 173 | struct ptrace_lwpstatus { |
| 174 | 	lwpid_t		pl_lwpid;		/* LWP described */ |
| 175 | 	sigset_t	pl_sigpend;		/* LWP signals pending */ |
| 176 | 	sigset_t	pl_sigmask;		/* LWP signal mask */ |
| 177 | 	char		pl_name[PL_LNAMELEN];	/* LWP name, may be empty */ |
| 178 | 	void		*pl_private;		/* LWP private data */ |
| 179 | 	/* Add fields at the end */ |
| 180 | }; |
| 181 | |
| 182 | /* |
| 183 | * Signal Information structure |
| 184 | */ |
| 185 | typedef struct ptrace_siginfo { |
| 186 | 	siginfo_t	psi_siginfo;	/* signal information structure */ |
| 187 | 	lwpid_t		psi_lwpid;	/* destination LWP of the signal |
| 188 | 					 * value 0 means the whole process |
| 189 | 					 * (route signal to all LWPs) */ |
| 190 | } ptrace_siginfo_t; |
| 191 | |
| 192 | #ifdef _KERNEL |
| 193 | |
| 194 | #ifdef _KERNEL_OPT |
| 195 | #include "opt_compat_netbsd32.h" |
| 196 | #endif |
| 197 | |
| 198 | #ifdef COMPAT_NETBSD32 |
| 199 | #include <compat/netbsd32/netbsd32.h> |
| 200 | #define process_read_lwpstatus32	netbsd32_read_lwpstatus |
| 201 | #define process_lwpstatus32		struct netbsd32_ptrace_lwpstatus |
| 202 | #endif |
| 203 | |
| 204 | #ifndef process_lwpstatus32 |
| 205 | #define process_lwpstatus32 struct ptrace_lwpstatus |
| 206 | #endif |
| 207 | #ifndef process_lwpstatus64 |
| 208 | #define process_lwpstatus64 struct ptrace_lwpstatus |
| 209 | #endif |
| 210 | |
| 211 | #if defined(PT_GETREGS) || defined(PT_SETREGS) |
| 212 | struct reg; |
| 213 | #ifndef process_reg32 |
| 214 | #define process_reg32 struct reg |
| 215 | #endif |
| 216 | #ifndef process_reg64 |
| 217 | #define process_reg64 struct reg |
| 218 | #endif |
| 219 | #endif |
| 220 | |
| 221 | #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) |
| 222 | struct fpreg; |
| 223 | #ifndef process_fpreg32 |
| 224 | #define process_fpreg32 struct fpreg |
| 225 | #endif |
| 226 | #ifndef process_fpreg64 |
| 227 | #define process_fpreg64 struct fpreg |
| 228 | #endif |
| 229 | #endif |
| 230 | |
| 231 | #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) |
| 232 | struct dbreg; |
| 233 | #ifndef process_dbreg32 |
| 234 | #define process_dbreg32 struct dbreg |
| 235 | #endif |
| 236 | #ifndef process_dbreg64 |
| 237 | #define process_dbreg64 struct dbreg |
| 238 | #endif |
| 239 | #endif |
| 240 | |
| 241 | struct ptrace_methods { |
| 242 | 	int (*ptm_copyin_piod)(struct ptrace_io_desc *, const void *, size_t); |
| 243 | 	int (*ptm_copyout_piod)(const struct ptrace_io_desc *, void *, size_t); |
| 244 | 	int (*ptm_copyin_siginfo)(struct ptrace_siginfo *, const void *, size_t); |
| 245 | 	int (*ptm_copyout_siginfo)(const struct ptrace_siginfo *, void *, size_t); |
| 246 | 	int (*ptm_copyout_lwpstatus)(const struct ptrace_lwpstatus *, void *, size_t); |
| 247 | 	int (*ptm_doregs)(struct lwp *, struct lwp *, struct uio *); |
| 248 | 	int (*ptm_dofpregs)(struct lwp *, struct lwp *, struct uio *); |
| 249 | 	int (*ptm_dodbregs)(struct lwp *, struct lwp *, struct uio *); |
| 250 | }; |
| 251 | |
| 252 | int	ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid); |
| 253 | void	ptrace_hooks(void); |
| 254 | |
| 255 | int	process_doregs(struct lwp *, struct lwp *, struct uio *); |
| 256 | int	process_validregs(struct lwp *); |
| 257 | |
| 258 | int	process_dofpregs(struct lwp *, struct lwp *, struct uio *); |
| 259 | int	process_validfpregs(struct lwp *); |
| 260 | |
| 261 | int	process_dodbregs(struct lwp *, struct lwp *, struct uio *); |
| 262 | int	process_validdbregs(struct lwp *); |
| 263 | |
| 264 | int	process_domem(struct lwp *, struct lwp *, struct uio *); |
| 265 | |
| 266 | void	proc_stoptrace(int, int, const register_t[], const register_t *, int); |
| 267 | void	proc_reparent(struct proc *, struct proc *); |
| 268 | void	proc_changeparent(struct proc *, struct proc *); |
| 269 | |
| 270 | |
| 271 | int	do_ptrace(struct ptrace_methods *, struct lwp *, int, pid_t, void *, |
| 272 | 	 int, register_t *); |
| 273 | |
| 274 | void	ptrace_read_lwpstatus(struct lwp *, struct ptrace_lwpstatus *); |
| 275 | |
| 276 | void	process_read_lwpstatus(struct lwp *, struct ptrace_lwpstatus *); |
| 277 | #ifndef process_read_lwpstatus32 |
| 278 | #define process_read_lwpstatus32 process_read_lwpstatus |
| 279 | #endif |
| 280 | #ifndef process_read_lwpstatus64 |
| 281 | #define process_read_lwpstatus64 process_read_lwpstatus |
| 282 | #endif |
| 283 | |
| 284 | /* |
| 285 | * 64bit architectures that support 32bit emulation (amd64 and sparc64) |
| 286 | * will #define process_read_regs32 to netbsd32_process_read_regs (etc). |
| 287 | * In all other cases these #defines drop the size suffix. |
| 288 | */ |
| 289 | |
| 290 | #ifdef PT_GETDBREGS |
| 291 | int	process_read_dbregs(struct lwp *, struct dbreg *, size_t *); |
| 292 | #ifndef process_read_dbregs32 |
| 293 | #define process_read_dbregs32	process_read_dbregs |
| 294 | #endif |
| 295 | #ifndef process_read_dbregs64 |
| 296 | #define process_read_dbregs64	process_read_dbregs |
| 297 | #endif |
| 298 | #endif |
| 299 | #ifdef PT_GETFPREGS |
| 300 | int	process_read_fpregs(struct lwp *, struct fpreg *, size_t *); |
| 301 | #ifndef process_read_fpregs32 |
| 302 | #define process_read_fpregs32	process_read_fpregs |
| 303 | #endif |
| 304 | #ifndef process_read_fpregs64 |
| 305 | #define process_read_fpregs64	process_read_fpregs |
| 306 | #endif |
| 307 | #endif |
| 308 | #ifdef PT_GETREGS |
| 309 | int	process_read_regs(struct lwp *, struct reg *); |
| 310 | #ifndef process_read_regs32 |
| 311 | #define process_read_regs32	process_read_regs |
| 312 | #endif |
| 313 | #ifndef process_read_regs64 |
| 314 | #define process_read_regs64	process_read_regs |
| 315 | #endif |
| 316 | #endif |
| 317 | int	process_set_pc(struct lwp *, void *); |
| 318 | int	process_sstep(struct lwp *, int); |
| 319 | #ifdef PT_SETDBREGS |
| 320 | int	process_write_dbregs(struct lwp *, const struct dbreg *, size_t); |
| 321 | #ifndef process_write_dbregs32 |
| 322 | #define process_write_dbregs32	process_write_dbregs |
| 323 | #endif |
| 324 | #ifndef process_write_dbregs64 |
| 325 | #define process_write_dbregs64	process_write_dbregs |
| 326 | #endif |
| 327 | #endif |
| 328 | #ifdef PT_SETFPREGS |
| 329 | int	process_write_fpregs(struct lwp *, const struct fpreg *, size_t); |
| 330 | #ifndef process_write_fpregs32 |
| 331 | #define process_write_fpregs32	process_write_fpregs |
| 332 | #endif |
| 333 | #ifndef process_write_fpregs64 |
| 334 | #define process_write_fpregs64	process_write_fpregs |
| 335 | #endif |
| 336 | #endif |
| 337 | #ifdef PT_SETREGS |
| 338 | int	process_write_regs(struct lwp *, const struct reg *); |
| 339 | #ifndef process_write_regs32 |
| 340 | #define process_write_regs32	process_write_regs |
| 341 | #endif |
| 342 | #ifndef process_write_regs64 |
| 343 | #define process_write_regs64	process_write_regs |
| 344 | #endif |
| 345 | #endif |
| 346 | |
| 347 | int	ptrace_machdep_dorequest(struct lwp *, struct lwp **, int, |
| 348 | 	 void *, int); |
| 349 | |
| 350 | #ifndef FIX_SSTEP |
| 351 | #define FIX_SSTEP(p) |
| 352 | #endif |
| 353 | |
| 354 | typedef int (*ptrace_regrfunc_t)(struct lwp *, void *, size_t *); |
| 355 | typedef int (*ptrace_regwfunc_t)(struct lwp *, void *, size_t); |
| 356 | |
| 357 | #if defined(PTRACE) |
| 358 | # if defined(PT_SETREGS) || defined(PT_GETREGS) |
| 359 | # define PT_REGS |
| 360 | # endif |
| 361 | # if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) |
| 362 | # define PT_FPREGS |
| 363 | # endif |
| 364 | # if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) |
| 365 | # define PT_DBREGS |
| 366 | # endif |
| 367 | # if defined(PT_REGS) || defined(PT_FPREGS) || defined(PT_DBREGS) |
| 368 | # define PT_REGISTERS |
| 369 | # endif |
| 370 | #endif /* PTRACE */ |
| 371 | |
| 372 | #else /* !_KERNEL */ |
| 373 | |
| 374 | #include <sys/cdefs.h> |
| 375 | |
| 376 | __BEGIN_DECLS |
| 377 | int	ptrace(int _request, pid_t _pid, void *_addr, int _data); |
| 378 | __END_DECLS |
| 379 | |
| 380 | #endif /* !_KERNEL */ |
| 381 | |
| 382 | #endif	/* !_SYS_PTRACE_H_ */ |