1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #ifndef	_PCONTROL_H
28*0Sstevel@tonic-gate #define	_PCONTROL_H
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0Sstevel@tonic-gate 
32*0Sstevel@tonic-gate /*
33*0Sstevel@tonic-gate  * Implemention-specific include file for libproc process management.
34*0Sstevel@tonic-gate  * This is not to be seen by the clients of libproc.
35*0Sstevel@tonic-gate  */
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate #include <stdio.h>
38*0Sstevel@tonic-gate #include <gelf.h>
39*0Sstevel@tonic-gate #include <synch.h>
40*0Sstevel@tonic-gate #include <procfs.h>
41*0Sstevel@tonic-gate #include <rtld_db.h>
42*0Sstevel@tonic-gate #include <libproc.h>
43*0Sstevel@tonic-gate #include <libctf.h>
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate #ifdef	__cplusplus
46*0Sstevel@tonic-gate extern "C" {
47*0Sstevel@tonic-gate #endif
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate #include "Putil.h"
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate /*
52*0Sstevel@tonic-gate  * Definitions of the process control structures, internal to libproc.
53*0Sstevel@tonic-gate  * These may change without affecting clients of libproc.
54*0Sstevel@tonic-gate  */
55*0Sstevel@tonic-gate 
56*0Sstevel@tonic-gate typedef struct {		/* symbol table */
57*0Sstevel@tonic-gate 	Elf_Data *sym_data;	/* start of table */
58*0Sstevel@tonic-gate 	size_t	sym_symn;	/* number of entries */
59*0Sstevel@tonic-gate 	char	*sym_strs;	/* ptr to strings */
60*0Sstevel@tonic-gate 	size_t	sym_strsz;	/* size of string table */
61*0Sstevel@tonic-gate 	GElf_Shdr sym_hdr;	/* symbol table section header */
62*0Sstevel@tonic-gate 	GElf_Shdr sym_strhdr;	/* string table section header */
63*0Sstevel@tonic-gate 	Elf	*sym_elf;	/* faked-up elf handle from core file */
64*0Sstevel@tonic-gate 	void	*sym_elfmem;	/* data for faked-up elf handle */
65*0Sstevel@tonic-gate 	uint_t	*sym_byname;	/* symbols sorted by name */
66*0Sstevel@tonic-gate 	uint_t	*sym_byaddr;	/* symbols sorted by addr */
67*0Sstevel@tonic-gate 	size_t	sym_count;	/* number of symbols in each sorted list */
68*0Sstevel@tonic-gate } sym_tbl_t;
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate typedef struct file_info {	/* symbol information for a mapped file */
71*0Sstevel@tonic-gate 	list_t	file_list;	/* linked list */
72*0Sstevel@tonic-gate 	char	file_pname[PRMAPSZ];	/* name from prmap_t */
73*0Sstevel@tonic-gate 	struct map_info *file_map;	/* primary (text) mapping */
74*0Sstevel@tonic-gate 	int	file_ref;	/* references from map_info_t structures */
75*0Sstevel@tonic-gate 	int	file_fd;	/* file descriptor for the mapped file */
76*0Sstevel@tonic-gate 	int	file_init;	/* 0: initialization yet to be performed */
77*0Sstevel@tonic-gate 	GElf_Half file_etype;	/* ELF e_type from ehdr */
78*0Sstevel@tonic-gate 	GElf_Half file_class;	/* ELF e_ident[EI_CLASS] from ehdr */
79*0Sstevel@tonic-gate 	rd_loadobj_t *file_lo;	/* load object structure from rtld_db */
80*0Sstevel@tonic-gate 	char	*file_lname;	/* load object name from rtld_db */
81*0Sstevel@tonic-gate 	char	*file_lbase;	/* pointer to basename of file_lname */
82*0Sstevel@tonic-gate 	Elf	*file_elf;	/* elf handle so we can close */
83*0Sstevel@tonic-gate 	void	*file_elfmem;	/* data for faked-up elf handle */
84*0Sstevel@tonic-gate 	sym_tbl_t file_symtab;	/* symbol table */
85*0Sstevel@tonic-gate 	sym_tbl_t file_dynsym;	/* dynamic symbol table */
86*0Sstevel@tonic-gate 	uintptr_t file_dyn_base;	/* load address for ET_DYN files */
87*0Sstevel@tonic-gate 	uintptr_t file_plt_base;	/* base address for PLT */
88*0Sstevel@tonic-gate 	size_t	file_plt_size;	/* size of PLT region */
89*0Sstevel@tonic-gate 	uintptr_t file_jmp_rel;	/* base address of PLT relocations */
90*0Sstevel@tonic-gate 	uintptr_t file_ctf_off;	/* offset of CTF data in object file */
91*0Sstevel@tonic-gate 	size_t	file_ctf_size;	/* size of CTF data in object file */
92*0Sstevel@tonic-gate 	int	file_ctf_dyn;	/* does the CTF data reference the dynsym */
93*0Sstevel@tonic-gate 	void	*file_ctf_buf;	/* CTF data for this file */
94*0Sstevel@tonic-gate 	ctf_file_t *file_ctfp;	/* CTF container for this file */
95*0Sstevel@tonic-gate } file_info_t;
96*0Sstevel@tonic-gate 
97*0Sstevel@tonic-gate typedef struct map_info {	/* description of an address space mapping */
98*0Sstevel@tonic-gate 	prmap_t	map_pmap;	/* /proc description of this mapping */
99*0Sstevel@tonic-gate 	file_info_t *map_file;	/* pointer into list of mapped files */
100*0Sstevel@tonic-gate 	off64_t map_offset;	/* offset into core file (if core) */
101*0Sstevel@tonic-gate 	int map_relocate;	/* associated file_map needs to be relocated */
102*0Sstevel@tonic-gate } map_info_t;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate typedef struct lwp_info {	/* per-lwp information from core file */
105*0Sstevel@tonic-gate 	list_t	lwp_list;	/* linked list */
106*0Sstevel@tonic-gate 	lwpid_t	lwp_id;		/* lwp identifier */
107*0Sstevel@tonic-gate 	lwpsinfo_t lwp_psinfo;	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo data */
108*0Sstevel@tonic-gate 	lwpstatus_t lwp_status;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus data */
109*0Sstevel@tonic-gate #if defined(sparc) || defined(__sparc)
110*0Sstevel@tonic-gate 	gwindows_t *lwp_gwins;	/* /proc/<pid>/lwp/<lwpid>/gwindows data */
111*0Sstevel@tonic-gate 	prxregset_t *lwp_xregs;	/* /proc/<pid>/lwp/<lwpid>/xregs data */
112*0Sstevel@tonic-gate 	int64_t *lwp_asrs;	/* /proc/<pid>/lwp/<lwpid>/asrs data */
113*0Sstevel@tonic-gate #endif
114*0Sstevel@tonic-gate } lwp_info_t;
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate typedef struct core_info {	/* information specific to core files */
117*0Sstevel@tonic-gate 	char core_dmodel;	/* data model for core file */
118*0Sstevel@tonic-gate 	int core_errno;		/* error during initialization if != 0 */
119*0Sstevel@tonic-gate 	list_t core_lwp_head;	/* head of list of lwp info */
120*0Sstevel@tonic-gate 	lwp_info_t *core_lwp;	/* current lwp information */
121*0Sstevel@tonic-gate 	uint_t core_nlwp;	/* number of lwp's in list */
122*0Sstevel@tonic-gate 	off64_t core_size;	/* size of core file in bytes */
123*0Sstevel@tonic-gate 	char *core_platform;	/* platform string from core file */
124*0Sstevel@tonic-gate 	struct utsname *core_uts;	/* uname(2) data from core file */
125*0Sstevel@tonic-gate 	prcred_t *core_cred;	/* process credential from core file */
126*0Sstevel@tonic-gate 	core_content_t core_content;	/* content dumped to core file */
127*0Sstevel@tonic-gate 	prpriv_t *core_priv;	/* process privileges from core file */
128*0Sstevel@tonic-gate 	size_t core_priv_size;	/* size of the privileges */
129*0Sstevel@tonic-gate 	void *core_privinfo;	/* system privileges info from core file */
130*0Sstevel@tonic-gate 	priv_impl_info_t *core_ppii;	/* NOTE entry for core_privinfo */
131*0Sstevel@tonic-gate 	char *core_zonename;	/* zone name from core file */
132*0Sstevel@tonic-gate #if defined(__i386) || defined(__amd64)
133*0Sstevel@tonic-gate 	struct ssd *core_ldt;	/* LDT entries from core file */
134*0Sstevel@tonic-gate 	uint_t core_nldt;	/* number of LDT entries in core file */
135*0Sstevel@tonic-gate #endif
136*0Sstevel@tonic-gate } core_info_t;
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate typedef struct elf_file {	/* convenience for managing ELF files */
139*0Sstevel@tonic-gate 	GElf_Ehdr e_hdr;	/* ELF file header information */
140*0Sstevel@tonic-gate 	Elf *e_elf;		/* ELF library handle */
141*0Sstevel@tonic-gate 	int e_fd;		/* file descriptor */
142*0Sstevel@tonic-gate } elf_file_t;
143*0Sstevel@tonic-gate 
144*0Sstevel@tonic-gate typedef struct ps_rwops {	/* ops vector for Pread() and Pwrite() */
145*0Sstevel@tonic-gate 	ssize_t (*p_pread)(struct ps_prochandle *,
146*0Sstevel@tonic-gate 	    void *, size_t, uintptr_t);
147*0Sstevel@tonic-gate 	ssize_t (*p_pwrite)(struct ps_prochandle *,
148*0Sstevel@tonic-gate 	    const void *, size_t, uintptr_t);
149*0Sstevel@tonic-gate } ps_rwops_t;
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate #define	HASHSIZE		1024	/* hash table size, power of 2 */
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate struct ps_prochandle {
154*0Sstevel@tonic-gate 	struct ps_lwphandle **hashtab;	/* hash table for LWPs (Lgrab()) */
155*0Sstevel@tonic-gate 	mutex_t	proc_lock;	/* protects hash table; serializes Lgrab() */
156*0Sstevel@tonic-gate 	pstatus_t orig_status;	/* remembered status on Pgrab() */
157*0Sstevel@tonic-gate 	pstatus_t status;	/* status when stopped */
158*0Sstevel@tonic-gate 	psinfo_t psinfo;	/* psinfo_t from last Ppsinfo() request */
159*0Sstevel@tonic-gate 	uintptr_t sysaddr;	/* address of most recent syscall instruction */
160*0Sstevel@tonic-gate 	pid_t	pid;		/* process-ID */
161*0Sstevel@tonic-gate 	int	state;		/* state of the process, see "libproc.h" */
162*0Sstevel@tonic-gate 	uint_t	flags;		/* see defines below */
163*0Sstevel@tonic-gate 	uint_t	agentcnt;	/* Pcreate_agent()/Pdestroy_agent() ref count */
164*0Sstevel@tonic-gate 	int	asfd;		/* /proc/<pid>/as filedescriptor */
165*0Sstevel@tonic-gate 	int	ctlfd;		/* /proc/<pid>/ctl filedescriptor */
166*0Sstevel@tonic-gate 	int	statfd;		/* /proc/<pid>/status filedescriptor */
167*0Sstevel@tonic-gate 	int	agentctlfd;	/* /proc/<pid>/lwp/agent/ctl */
168*0Sstevel@tonic-gate 	int	agentstatfd;	/* /proc/<pid>/lwp/agent/status */
169*0Sstevel@tonic-gate 	int	info_valid;	/* if zero, map and file info need updating */
170*0Sstevel@tonic-gate 	map_info_t *mappings;	/* cached process mappings */
171*0Sstevel@tonic-gate 	size_t	map_count;	/* number of mappings */
172*0Sstevel@tonic-gate 	size_t	map_alloc;	/* number of mappings allocated */
173*0Sstevel@tonic-gate 	uint_t	num_files;	/* number of file elements in file_info */
174*0Sstevel@tonic-gate 	list_t	file_head;	/* head of mapped files w/ symbol table info */
175*0Sstevel@tonic-gate 	char	*execname;	/* name of the executable file */
176*0Sstevel@tonic-gate 	auxv_t	*auxv;		/* the process's aux vector */
177*0Sstevel@tonic-gate 	int	nauxv;		/* number of aux vector entries */
178*0Sstevel@tonic-gate 	rd_agent_t *rap;	/* cookie for rtld_db */
179*0Sstevel@tonic-gate 	map_info_t *map_exec;	/* the mapping for the executable file */
180*0Sstevel@tonic-gate 	map_info_t *map_ldso;	/* the mapping for ld.so.1 */
181*0Sstevel@tonic-gate 	const ps_rwops_t *ops;	/* pointer to ops-vector for read and write */
182*0Sstevel@tonic-gate 	core_info_t *core;	/* information specific to core (if PS_DEAD) */
183*0Sstevel@tonic-gate 	uintptr_t *ucaddrs;	/* ucontext-list addresses */
184*0Sstevel@tonic-gate 	uint_t	ucnelems;	/* number of elements in the ucaddrs list */
185*0Sstevel@tonic-gate };
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate /* flags */
188*0Sstevel@tonic-gate #define	CREATED		0x01	/* process was created by Pcreate() */
189*0Sstevel@tonic-gate #define	SETSIG		0x02	/* set signal trace mask before continuing */
190*0Sstevel@tonic-gate #define	SETFAULT	0x04	/* set fault trace mask before continuing */
191*0Sstevel@tonic-gate #define	SETENTRY	0x08	/* set sysentry trace mask before continuing */
192*0Sstevel@tonic-gate #define	SETEXIT		0x10	/* set sysexit trace mask before continuing */
193*0Sstevel@tonic-gate #define	SETHOLD		0x20	/* set signal hold mask before continuing */
194*0Sstevel@tonic-gate #define	SETREGS		0x40	/* set registers before continuing */
195*0Sstevel@tonic-gate 
196*0Sstevel@tonic-gate struct ps_lwphandle {
197*0Sstevel@tonic-gate 	struct ps_prochandle *lwp_proc;	/* process to which this lwp belongs */
198*0Sstevel@tonic-gate 	struct ps_lwphandle *lwp_hash;	/* hash table linked list */
199*0Sstevel@tonic-gate 	lwpstatus_t	lwp_status;	/* status when stopped */
200*0Sstevel@tonic-gate 	lwpsinfo_t	lwp_psinfo;	/* lwpsinfo_t from last Lpsinfo() */
201*0Sstevel@tonic-gate 	lwpid_t		lwp_id;		/* lwp identifier */
202*0Sstevel@tonic-gate 	int		lwp_state;	/* state of the lwp, see "libproc.h" */
203*0Sstevel@tonic-gate 	uint_t		lwp_flags;	/* SETHOLD and/or SETREGS */
204*0Sstevel@tonic-gate 	int		lwp_ctlfd;	/* /proc/<pid>/lwp/<lwpid>/lwpctl */
205*0Sstevel@tonic-gate 	int		lwp_statfd;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus */
206*0Sstevel@tonic-gate };
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate /*
209*0Sstevel@tonic-gate  * Implementation functions in the process control library.
210*0Sstevel@tonic-gate  * These are not exported to clients of the library.
211*0Sstevel@tonic-gate  */
212*0Sstevel@tonic-gate extern	void	prldump(const char *, lwpstatus_t *);
213*0Sstevel@tonic-gate extern	int	dupfd(int, int);
214*0Sstevel@tonic-gate extern	int	set_minfd(void);
215*0Sstevel@tonic-gate extern	int	Pscantext(struct ps_prochandle *);
216*0Sstevel@tonic-gate extern	void	Pinitsym(struct ps_prochandle *);
217*0Sstevel@tonic-gate extern	void	Preadauxvec(struct ps_prochandle *);
218*0Sstevel@tonic-gate extern	void	optimize_symtab(sym_tbl_t *);
219*0Sstevel@tonic-gate extern	void	Pbuild_file_symtab(struct ps_prochandle *, file_info_t *);
220*0Sstevel@tonic-gate extern	ctf_file_t *Pbuild_file_ctf(struct ps_prochandle *, file_info_t *);
221*0Sstevel@tonic-gate extern	map_info_t *Paddr2mptr(struct ps_prochandle *, uintptr_t);
222*0Sstevel@tonic-gate extern	char 	*Pfindexec(struct ps_prochandle *, const char *,
223*0Sstevel@tonic-gate 	int (*)(const char *, void *), void *);
224*0Sstevel@tonic-gate extern	int	getlwpstatus(struct ps_prochandle *, lwpid_t, lwpstatus_t *);
225*0Sstevel@tonic-gate int	Pstopstatus(struct ps_prochandle *, long, uint32_t);
226*0Sstevel@tonic-gate 
227*0Sstevel@tonic-gate extern	int	Padd_mapping(struct ps_prochandle *, off64_t, file_info_t *,
228*0Sstevel@tonic-gate     prmap_t *);
229*0Sstevel@tonic-gate extern	void	Psort_mappings(struct ps_prochandle *);
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate /*
232*0Sstevel@tonic-gate  * Architecture-dependent definition of the breakpoint instruction.
233*0Sstevel@tonic-gate  */
234*0Sstevel@tonic-gate #if defined(sparc) || defined(__sparc)
235*0Sstevel@tonic-gate #define	BPT	((instr_t)0x91d02001)
236*0Sstevel@tonic-gate #elif defined(__i386) || defined(__amd64)
237*0Sstevel@tonic-gate #define	BPT	((instr_t)0xcc)
238*0Sstevel@tonic-gate #endif
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate /*
241*0Sstevel@tonic-gate  * Simple convenience.
242*0Sstevel@tonic-gate  */
243*0Sstevel@tonic-gate #define	TRUE	1
244*0Sstevel@tonic-gate #define	FALSE	0
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate #ifdef	__cplusplus
247*0Sstevel@tonic-gate }
248*0Sstevel@tonic-gate #endif
249*0Sstevel@tonic-gate 
250*0Sstevel@tonic-gate #endif	/* _PCONTROL_H */
251