xref: /illumos-gate/usr/src/lib/libproc/common/Pcontrol.h (revision 9164a50bf932130cbb5097a16f6986873ce0e6e5)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /*
26  * Copyright 2012 DEY Storage Systems, Inc.  All rights reserved.
27  * Copyright (c) 2013 by Delphix. All rights reserved.
28  * Copyright 2018 Joyent, Inc.
29  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
30  * Copyright 2024 Oxide Computer Company
31  */
32 
33 #ifndef	_PCONTROL_H
34 #define	_PCONTROL_H
35 
36 /*
37  * Implemention-specific include file for libproc process management.
38  * This is not to be seen by the clients of libproc.
39  */
40 
41 #include <stdio.h>
42 #include <gelf.h>
43 #include <synch.h>
44 #include <procfs.h>
45 #include <rtld_db.h>
46 #include <libproc.h>
47 #include <libctf.h>
48 #include <limits.h>
49 #include <libproc.h>
50 #include <thread.h>
51 #include <sys/secflags.h>
52 #include <sys/list.h>
53 
54 #ifdef	__cplusplus
55 extern "C" {
56 #endif
57 
58 #include "Putil.h"
59 
60 /*
61  * Definitions of the process control structures, internal to libproc.
62  * These may change without affecting clients of libproc.
63  */
64 
65 /*
66  * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which
67  * we wish to treat as a single logical symbol table. In this logical table,
68  * the data from the auxiliary table preceeds that from the primary. Symbol
69  * indices start at [0], which is the first item in the auxiliary table
70  * if there is one. The sole purpose for this is so that we can treat the
71  * combination of .SUNW_ldynsym and .dynsym sections as a logically single
72  * entity without having to violate the public interface to libelf.
73  *
74  * Both tables must share the same string table section.
75  *
76  * The symtab_getsym() function serves as a gelf_getsym() replacement
77  * that is aware of the two tables and makes them look like a single table
78  * to the caller.
79  *
80  */
81 typedef struct sym_tbl {	/* symbol table */
82 	Elf_Data *sym_data_pri;	/* primary table */
83 	Elf_Data *sym_data_aux;	/* auxiliary table */
84 	size_t	sym_symn_aux;	/* number of entries in auxiliary table */
85 	size_t	sym_symn;	/* total number of entries in both tables */
86 	char	*sym_strs;	/* ptr to strings */
87 	size_t	sym_strsz;	/* size of string table */
88 	GElf_Shdr sym_hdr_pri;	/* primary symbol table section header */
89 	GElf_Shdr sym_hdr_aux;	/* auxiliary symbol table section header */
90 	GElf_Shdr sym_strhdr;	/* string table section header */
91 	Elf	*sym_elf;	/* faked-up ELF handle from core file */
92 	void	*sym_elfmem;	/* data for faked-up ELF handle */
93 	uint_t	*sym_byname;	/* symbols sorted by name */
94 	uint_t	*sym_byaddr;	/* symbols sorted by addr */
95 	size_t	sym_count;	/* number of symbols in each sorted list */
96 } sym_tbl_t;
97 
98 typedef struct file_info {	/* symbol information for a mapped file */
99 	list_node_t file_list;	/* linked list */
100 	char	file_pname[PATH_MAX];	/* name from prmap_t */
101 	struct map_info *file_map;	/* primary (text) mapping */
102 	int	file_ref;	/* references from map_info_t structures */
103 	int	file_fd;	/* file descriptor for the mapped file */
104 	int	file_dbgfile;	/* file descriptor for the debug file */
105 	int	file_init;	/* 0: initialization yet to be performed */
106 	GElf_Half file_etype;	/* ELF e_type from ehdr */
107 	GElf_Half file_class;	/* ELF e_ident[EI_CLASS] from ehdr */
108 	rd_loadobj_t *file_lo;	/* load object structure from rtld_db */
109 	char	*file_lname;	/* load object name from rtld_db */
110 	char	*file_lbase;	/* pointer to basename of file_lname */
111 	char	*file_rname;	/* resolved on-disk object pathname */
112 	char	*file_rbase;	/* pointer to basename of file_rname */
113 	Elf	*file_elf;	/* ELF handle so we can close */
114 	Elf	*file_dbgelf;	/* Debug ELF handle so we can close */
115 	void	*file_elfmem;	/* data for faked-up ELF handle */
116 	sym_tbl_t file_symtab;	/* symbol table */
117 	sym_tbl_t file_dynsym;	/* dynamic symbol table */
118 	uintptr_t file_dyn_base;	/* load address for ET_DYN files */
119 	uintptr_t file_plt_base;	/* base address for PLT */
120 	size_t	file_plt_size;	/* size of PLT region */
121 	uintptr_t file_jmp_rel;	/* base address of PLT relocations */
122 	uintptr_t file_ctf_off;	/* offset of CTF data in object file */
123 	size_t	file_ctf_size;	/* size of CTF data in object file */
124 	int	file_ctf_dyn;	/* does the CTF data reference the dynsym */
125 	void	*file_ctf_buf;	/* CTF data for this file */
126 	ctf_file_t *file_ctfp;	/* CTF container for this file */
127 	char	*file_shstrs;	/* section header string table */
128 	size_t	file_shstrsz;	/* section header string table size */
129 	uintptr_t *file_saddrs; /* section header addresses */
130 	uint_t  file_nsaddrs;   /* number of section header addresses */
131 } file_info_t;
132 
133 typedef struct map_info {	/* description of an address space mapping */
134 	prmap_t	map_pmap;	/* /proc description of this mapping */
135 	file_info_t *map_file;	/* pointer into list of mapped files */
136 	off64_t map_offset;	/* offset into core file (if core) */
137 	int map_relocate;	/* associated file_map needs to be relocated */
138 } map_info_t;
139 
140 typedef struct lwp_info {	/* per-lwp information from core file */
141 	list_node_t lwp_list;	/* linked list */
142 	lwpid_t	lwp_id;		/* lwp identifier */
143 	lwpsinfo_t lwp_psinfo;	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo data */
144 	lwpstatus_t lwp_status;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus data */
145 	char lwp_name[THREAD_NAME_MAX];
146 	prxregset_t *lwp_xregs;	/* /proc/<pid>/lwp/<lwpid>/xregs data */
147 	size_t lwp_xregsize;
148 #if defined(sparc) || defined(__sparc)
149 	gwindows_t *lwp_gwins;	/* /proc/<pid>/lwp/<lwpid>/gwindows data */
150 	int64_t *lwp_asrs;	/* /proc/<pid>/lwp/<lwpid>/asrs data */
151 #endif
152 } lwp_info_t;
153 
154 typedef struct fd_info {
155 	list_node_t fd_list;	/* linked list */
156 	prfdinfo_t *fd_info;	/* fd info */
157 } fd_info_t;
158 
159 typedef struct core_info {	/* information specific to core files */
160 	char core_dmodel;	/* data model for core file */
161 	char core_osabi;	/* ELF OS ABI */
162 	int core_errno;		/* error during initialization if != 0 */
163 	list_t core_lwp_head;	/* head of list of lwp info */
164 	lwp_info_t *core_lwp;	/* current lwp information */
165 	off64_t core_size;	/* size of core file in bytes */
166 	char *core_platform;	/* platform string from core file */
167 	struct utsname *core_uts;	/* uname(2) data from core file */
168 	prcred_t *core_cred;	/* process credential from core file */
169 	core_content_t core_content;	/* content dumped to core file */
170 	prpriv_t *core_priv;	/* process privileges from core file */
171 	size_t core_priv_size;	/* size of the privileges */
172 	void *core_privinfo;	/* system privileges info from core file */
173 	priv_impl_info_t *core_ppii;	/* NOTE entry for core_privinfo */
174 	char *core_zonename;	/* zone name from core file */
175 	prsecflags_t *core_secflags; /* secflags from core file */
176 	prupanic_t *core_upanic; /* upanic from core file */
177 	prcwd_t *core_cwd;	/* cwd from core file */
178 #if defined(__i386) || defined(__amd64)
179 	struct ssd *core_ldt;	/* LDT entries from core file */
180 	uint_t core_nldt;	/* number of LDT entries in core file */
181 #endif
182 } core_info_t;
183 
184 typedef struct elf_file_header { /* extended ELF header */
185 	unsigned char e_ident[EI_NIDENT];
186 	Elf64_Half e_type;
187 	Elf64_Half e_machine;
188 	Elf64_Word e_version;
189 	Elf64_Addr e_entry;
190 	Elf64_Off e_phoff;
191 	Elf64_Off e_shoff;
192 	Elf64_Word e_flags;
193 	Elf64_Half e_ehsize;
194 	Elf64_Half e_phentsize;
195 	Elf64_Half e_shentsize;
196 	Elf64_Word e_phnum;	/* phdr count extended to 32 bits */
197 	Elf64_Word e_shnum;	/* shdr count extended to 32 bits */
198 	Elf64_Word e_shstrndx;	/* shdr string index extended to 32 bits */
199 } elf_file_header_t;
200 
201 typedef struct elf_file {	/* convenience for managing ELF files */
202 	elf_file_header_t e_hdr; /* Extended ELF header */
203 	Elf *e_elf;		/* ELF library handle */
204 	int e_fd;		/* file descriptor */
205 } elf_file_t;
206 
207 #define	HASHSIZE		1024	/* hash table size, power of 2 */
208 
209 struct ps_prochandle {
210 	struct ps_lwphandle **hashtab;	/* hash table for LWPs (Lgrab()) */
211 	mutex_t	proc_lock;	/* protects hash table; serializes Lgrab() */
212 	pstatus_t orig_status;	/* remembered status on Pgrab() */
213 	pstatus_t status;	/* status when stopped */
214 	psinfo_t psinfo;	/* psinfo_t from last Ppsinfo() request */
215 	uintptr_t sysaddr;	/* address of most recent syscall instruction */
216 	pid_t	pid;		/* process-ID */
217 	int	state;		/* state of the process, see "libproc.h" */
218 	uint_t	flags;		/* see defines below */
219 	uint_t	agentcnt;	/* Pcreate_agent()/Pdestroy_agent() ref count */
220 	int	asfd;		/* /proc/<pid>/as filedescriptor */
221 	int	ctlfd;		/* /proc/<pid>/ctl filedescriptor */
222 	int	statfd;		/* /proc/<pid>/status filedescriptor */
223 	int	agentctlfd;	/* /proc/<pid>/lwp/agent/ctl */
224 	int	agentstatfd;	/* /proc/<pid>/lwp/agent/status */
225 	int	info_valid;	/* if zero, map and file info need updating */
226 	map_info_t *mappings;	/* cached process mappings */
227 	size_t	map_count;	/* number of mappings */
228 	size_t	map_alloc;	/* number of mappings allocated */
229 	uint_t	num_files;	/* number of file elements in file_info */
230 	list_t	file_head;	/* head of mapped files w/ symbol table info */
231 	char	*execname;	/* name of the executable file */
232 	auxv_t	*auxv;		/* the process's aux vector */
233 	int	nauxv;		/* number of aux vector entries */
234 	rd_agent_t *rap;	/* cookie for rtld_db */
235 	map_info_t *map_exec;	/* the mapping for the executable file */
236 	map_info_t *map_ldso;	/* the mapping for ld.so.1 */
237 	ps_ops_t ops;		/* ops-vector */
238 	uintptr_t *ucaddrs;	/* ucontext-list addresses */
239 	uint_t	ucnelems;	/* number of elements in the ucaddrs list */
240 	char	*zoneroot;	/* cached path to zone root */
241 	list_t	fd_head;	/* head of file desc info list */
242 	uintptr_t map_missing;	/* first missing mapping in core due to sig */
243 	siginfo_t killinfo;	/* signal that interrupted core dump */
244 	psinfo_t spymaster;	/* agent LWP's spymaster, if any */
245 	void *data;		/* private data */
246 };
247 
248 /* flags */
249 #define	CREATED		0x01	/* process was created by Pcreate() */
250 #define	SETSIG		0x02	/* set signal trace mask before continuing */
251 #define	SETFAULT	0x04	/* set fault trace mask before continuing */
252 #define	SETENTRY	0x08	/* set sysentry trace mask before continuing */
253 #define	SETEXIT		0x10	/* set sysexit trace mask before continuing */
254 #define	SETHOLD		0x20	/* set signal hold mask before continuing */
255 #define	SETREGS		0x40	/* set registers before continuing */
256 #define	INCORE		0x80	/* use in-core data to build symbol tables */
257 
258 struct ps_lwphandle {
259 	struct ps_prochandle *lwp_proc;	/* process to which this lwp belongs */
260 	struct ps_lwphandle *lwp_hash;	/* hash table linked list */
261 	lwpstatus_t	lwp_status;	/* status when stopped */
262 	lwpsinfo_t	lwp_psinfo;	/* lwpsinfo_t from last Lpsinfo() */
263 	lwpid_t		lwp_id;		/* lwp identifier */
264 	int		lwp_state;	/* state of the lwp, see "libproc.h" */
265 	uint_t		lwp_flags;	/* SETHOLD and/or SETREGS */
266 	int		lwp_ctlfd;	/* /proc/<pid>/lwp/<lwpid>/lwpctl */
267 	int		lwp_statfd;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus */
268 };
269 
270 /*
271  * Implementation functions in the process control library.
272  * These are not exported to clients of the library.
273  */
274 extern	void	prldump(const char *, lwpstatus_t *);
275 extern	int	dupfd(int, int);
276 extern	int	set_minfd(void);
277 extern	int	Pscantext(struct ps_prochandle *);
278 extern	void	Pinitsym(struct ps_prochandle *);
279 extern	void	Pinitfd(struct ps_prochandle *);
280 extern	void	Preadauxvec(struct ps_prochandle *);
281 extern	void	optimize_symtab(sym_tbl_t *);
282 extern	void	Pbuild_file_symtab(struct ps_prochandle *, file_info_t *);
283 extern	ctf_file_t *Pbuild_file_ctf(struct ps_prochandle *, file_info_t *);
284 extern	map_info_t *Paddr2mptr(struct ps_prochandle *, uintptr_t);
285 extern	char	*Pfindexec(struct ps_prochandle *, const char *,
286 	int (*)(const char *, void *), void *);
287 extern	int	getlwpstatus(struct ps_prochandle *, lwpid_t, lwpstatus_t *);
288 int	Pstopstatus(struct ps_prochandle *, long, uint32_t);
289 extern	file_info_t *file_info_new(struct ps_prochandle *, map_info_t *);
290 extern	char	*Plofspath(const char *, char *, size_t);
291 extern	char	*Pzoneroot(struct ps_prochandle *, char *, size_t);
292 extern	char	*Pzonepath(struct ps_prochandle *, const char *, char *,
293 	size_t);
294 extern	fd_info_t *Pfd2info(struct ps_prochandle *, int);
295 
296 extern	char	*Pfindmap(struct ps_prochandle *, map_info_t *, char *,
297 	size_t);
298 
299 extern	int	Padd_mapping(struct ps_prochandle *, off64_t, file_info_t *,
300     prmap_t *);
301 extern	void	Psort_mappings(struct ps_prochandle *);
302 extern	struct ps_lwphandle *Lfind(struct ps_prochandle *, lwpid_t);
303 extern	int	Lstopstatus(struct ps_lwphandle *, long, uint_t);
304 
305 extern char	procfs_path[PATH_MAX];
306 extern ssize_t	proc_get_cwd(pid_t, char *, size_t);
307 
308 /*
309  * Architecture-dependent definition of the breakpoint instruction.
310  */
311 #if defined(sparc) || defined(__sparc)
312 #define	BPT	((instr_t)0x91d02001)
313 #elif defined(__i386) || defined(__amd64)
314 #define	BPT	((instr_t)0xcc)
315 #endif
316 
317 /*
318  * Simple convenience.
319  */
320 #define	TRUE	1
321 #define	FALSE	0
322 
323 #ifdef	__cplusplus
324 }
325 #endif
326 
327 #endif	/* _PCONTROL_H */
328