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#ifndef	_PCONTROL_H
27#define	_PCONTROL_H
28
29/*
30 * Implemention-specific include file for libproc process management.
31 * This is not to be seen by the clients of libproc.
32 */
33
34#include <stdio.h>
35#include <gelf.h>
36#include <synch.h>
37#include <procfs.h>
38#include <rtld_db.h>
39#include <libproc.h>
40#include <libctf.h>
41#include <limits.h>
42
43#ifdef	__cplusplus
44extern "C" {
45#endif
46
47#include "Putil.h"
48
49/*
50 * Definitions of the process control structures, internal to libproc.
51 * These may change without affecting clients of libproc.
52 */
53
54/*
55 * sym_tbl_t contains a primary and an (optional) auxiliary symbol table, which
56 * we wish to treat as a single logical symbol table. In this logical table,
57 * the data from the auxiliary table preceeds that from the primary. Symbol
58 * indices start at [0], which is the first item in the auxiliary table
59 * if there is one. The sole purpose for this is so that we can treat the
60 * combination of .SUNW_ldynsym and .dynsym sections as a logically single
61 * entity without having to violate the public interface to libelf.
62 *
63 * Both tables must share the same string table section.
64 *
65 * The symtab_getsym() function serves as a gelf_getsym() replacement
66 * that is aware of the two tables and makes them look like a single table
67 * to the caller.
68 *
69 */
70typedef struct sym_tbl {	/* symbol table */
71	Elf_Data *sym_data_pri;	/* primary table */
72	Elf_Data *sym_data_aux;	/* auxiliary table */
73	size_t	sym_symn_aux;	/* number of entries in auxiliary table */
74	size_t	sym_symn;	/* total number of entries in both tables */
75	char	*sym_strs;	/* ptr to strings */
76	size_t	sym_strsz;	/* size of string table */
77	GElf_Shdr sym_hdr_pri;	/* primary symbol table section header */
78	GElf_Shdr sym_hdr_aux;	/* auxiliary symbol table section header */
79	GElf_Shdr sym_strhdr;	/* string table section header */
80	Elf	*sym_elf;	/* faked-up ELF handle from core file */
81	void	*sym_elfmem;	/* data for faked-up ELF handle */
82	uint_t	*sym_byname;	/* symbols sorted by name */
83	uint_t	*sym_byaddr;	/* symbols sorted by addr */
84	size_t	sym_count;	/* number of symbols in each sorted list */
85} sym_tbl_t;
86
87typedef struct file_info {	/* symbol information for a mapped file */
88	plist_t	file_list;	/* linked list */
89	char	file_pname[PRMAPSZ];	/* name from prmap_t */
90	struct map_info *file_map;	/* primary (text) mapping */
91	int	file_ref;	/* references from map_info_t structures */
92	int	file_fd;	/* file descriptor for the mapped file */
93	int	file_init;	/* 0: initialization yet to be performed */
94	GElf_Half file_etype;	/* ELF e_type from ehdr */
95	GElf_Half file_class;	/* ELF e_ident[EI_CLASS] from ehdr */
96	rd_loadobj_t *file_lo;	/* load object structure from rtld_db */
97	char	*file_lname;	/* load object name from rtld_db */
98	char	*file_lbase;	/* pointer to basename of file_lname */
99	char	*file_rname;	/* resolved on-disk object pathname */
100	char	*file_rbase;	/* pointer to basename of file_rname */
101	Elf	*file_elf;	/* ELF handle so we can close */
102	void	*file_elfmem;	/* data for faked-up ELF handle */
103	sym_tbl_t file_symtab;	/* symbol table */
104	sym_tbl_t file_dynsym;	/* dynamic symbol table */
105	uintptr_t file_dyn_base;	/* load address for ET_DYN files */
106	uintptr_t file_plt_base;	/* base address for PLT */
107	size_t	file_plt_size;	/* size of PLT region */
108	uintptr_t file_jmp_rel;	/* base address of PLT relocations */
109	uintptr_t file_ctf_off;	/* offset of CTF data in object file */
110	size_t	file_ctf_size;	/* size of CTF data in object file */
111	int	file_ctf_dyn;	/* does the CTF data reference the dynsym */
112	void	*file_ctf_buf;	/* CTF data for this file */
113	ctf_file_t *file_ctfp;	/* CTF container for this file */
114	char	*file_shstrs;	/* section header string table */
115	size_t	file_shstrsz;	/* section header string table size */
116	uintptr_t *file_saddrs; /* section header addresses */
117	uint_t  file_nsaddrs;   /* number of section header addresses */
118} file_info_t;
119
120typedef struct map_info {	/* description of an address space mapping */
121	prmap_t	map_pmap;	/* /proc description of this mapping */
122	file_info_t *map_file;	/* pointer into list of mapped files */
123	off64_t map_offset;	/* offset into core file (if core) */
124	int map_relocate;	/* associated file_map needs to be relocated */
125} map_info_t;
126
127typedef struct lwp_info {	/* per-lwp information from core file */
128	plist_t	lwp_list;	/* linked list */
129	lwpid_t	lwp_id;		/* lwp identifier */
130	lwpsinfo_t lwp_psinfo;	/* /proc/<pid>/lwp/<lwpid>/lwpsinfo data */
131	lwpstatus_t lwp_status;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus data */
132#if defined(sparc) || defined(__sparc)
133	gwindows_t *lwp_gwins;	/* /proc/<pid>/lwp/<lwpid>/gwindows data */
134	prxregset_t *lwp_xregs;	/* /proc/<pid>/lwp/<lwpid>/xregs data */
135	int64_t *lwp_asrs;	/* /proc/<pid>/lwp/<lwpid>/asrs data */
136#endif
137} lwp_info_t;
138
139typedef struct core_info {	/* information specific to core files */
140	char core_dmodel;	/* data model for core file */
141	int core_errno;		/* error during initialization if != 0 */
142	plist_t core_lwp_head;	/* head of list of lwp info */
143	lwp_info_t *core_lwp;	/* current lwp information */
144	uint_t core_nlwp;	/* number of lwp's in list */
145	off64_t core_size;	/* size of core file in bytes */
146	char *core_platform;	/* platform string from core file */
147	struct utsname *core_uts;	/* uname(2) data from core file */
148	prcred_t *core_cred;	/* process credential from core file */
149	core_content_t core_content;	/* content dumped to core file */
150	prpriv_t *core_priv;	/* process privileges from core file */
151	size_t core_priv_size;	/* size of the privileges */
152	void *core_privinfo;	/* system privileges info from core file */
153	priv_impl_info_t *core_ppii;	/* NOTE entry for core_privinfo */
154	char *core_zonename;	/* zone name from core file */
155#if defined(__i386) || defined(__amd64)
156	struct ssd *core_ldt;	/* LDT entries from core file */
157	uint_t core_nldt;	/* number of LDT entries in core file */
158#endif
159} core_info_t;
160
161typedef struct elf_file_header { /* extended ELF header */
162	unsigned char e_ident[EI_NIDENT];
163	Elf64_Half e_type;
164	Elf64_Half e_machine;
165	Elf64_Word e_version;
166	Elf64_Addr e_entry;
167	Elf64_Off e_phoff;
168	Elf64_Off e_shoff;
169	Elf64_Word e_flags;
170	Elf64_Half e_ehsize;
171	Elf64_Half e_phentsize;
172	Elf64_Half e_shentsize;
173	Elf64_Word e_phnum;	/* phdr count extended to 32 bits */
174	Elf64_Word e_shnum;	/* shdr count extended to 32 bits */
175	Elf64_Word e_shstrndx;	/* shdr string index extended to 32 bits */
176} elf_file_header_t;
177
178typedef struct elf_file {	/* convenience for managing ELF files */
179	elf_file_header_t e_hdr; /* Extended ELF header */
180	Elf *e_elf;		/* ELF library handle */
181	int e_fd;		/* file descriptor */
182} elf_file_t;
183
184typedef struct ps_rwops {	/* ops vector for Pread() and Pwrite() */
185	ssize_t (*p_pread)(struct ps_prochandle *,
186	    void *, size_t, uintptr_t);
187	ssize_t (*p_pwrite)(struct ps_prochandle *,
188	    const void *, size_t, uintptr_t);
189} ps_rwops_t;
190
191#define	HASHSIZE		1024	/* hash table size, power of 2 */
192
193struct ps_prochandle {
194	struct ps_lwphandle **hashtab;	/* hash table for LWPs (Lgrab()) */
195	mutex_t	proc_lock;	/* protects hash table; serializes Lgrab() */
196	pstatus_t orig_status;	/* remembered status on Pgrab() */
197	pstatus_t status;	/* status when stopped */
198	psinfo_t psinfo;	/* psinfo_t from last Ppsinfo() request */
199	uintptr_t sysaddr;	/* address of most recent syscall instruction */
200	pid_t	pid;		/* process-ID */
201	int	state;		/* state of the process, see "libproc.h" */
202	uint_t	flags;		/* see defines below */
203	uint_t	agentcnt;	/* Pcreate_agent()/Pdestroy_agent() ref count */
204	int	asfd;		/* /proc/<pid>/as filedescriptor */
205	int	ctlfd;		/* /proc/<pid>/ctl filedescriptor */
206	int	statfd;		/* /proc/<pid>/status filedescriptor */
207	int	agentctlfd;	/* /proc/<pid>/lwp/agent/ctl */
208	int	agentstatfd;	/* /proc/<pid>/lwp/agent/status */
209	int	info_valid;	/* if zero, map and file info need updating */
210	map_info_t *mappings;	/* cached process mappings */
211	size_t	map_count;	/* number of mappings */
212	size_t	map_alloc;	/* number of mappings allocated */
213	uint_t	num_files;	/* number of file elements in file_info */
214	plist_t	file_head;	/* head of mapped files w/ symbol table info */
215	char	*execname;	/* name of the executable file */
216	auxv_t	*auxv;		/* the process's aux vector */
217	int	nauxv;		/* number of aux vector entries */
218	rd_agent_t *rap;	/* cookie for rtld_db */
219	map_info_t *map_exec;	/* the mapping for the executable file */
220	map_info_t *map_ldso;	/* the mapping for ld.so.1 */
221	const ps_rwops_t *ops;	/* pointer to ops-vector for read and write */
222	core_info_t *core;	/* information specific to core (if PS_DEAD) */
223	uintptr_t *ucaddrs;	/* ucontext-list addresses */
224	uint_t	ucnelems;	/* number of elements in the ucaddrs list */
225	char	*zoneroot;	/* cached path to zone root */
226};
227
228/* flags */
229#define	CREATED		0x01	/* process was created by Pcreate() */
230#define	SETSIG		0x02	/* set signal trace mask before continuing */
231#define	SETFAULT	0x04	/* set fault trace mask before continuing */
232#define	SETENTRY	0x08	/* set sysentry trace mask before continuing */
233#define	SETEXIT		0x10	/* set sysexit trace mask before continuing */
234#define	SETHOLD		0x20	/* set signal hold mask before continuing */
235#define	SETREGS		0x40	/* set registers before continuing */
236
237struct ps_lwphandle {
238	struct ps_prochandle *lwp_proc;	/* process to which this lwp belongs */
239	struct ps_lwphandle *lwp_hash;	/* hash table linked list */
240	lwpstatus_t	lwp_status;	/* status when stopped */
241	lwpsinfo_t	lwp_psinfo;	/* lwpsinfo_t from last Lpsinfo() */
242	lwpid_t		lwp_id;		/* lwp identifier */
243	int		lwp_state;	/* state of the lwp, see "libproc.h" */
244	uint_t		lwp_flags;	/* SETHOLD and/or SETREGS */
245	int		lwp_ctlfd;	/* /proc/<pid>/lwp/<lwpid>/lwpctl */
246	int		lwp_statfd;	/* /proc/<pid>/lwp/<lwpid>/lwpstatus */
247};
248
249/*
250 * Implementation functions in the process control library.
251 * These are not exported to clients of the library.
252 */
253extern	void	prldump(const char *, lwpstatus_t *);
254extern	int	dupfd(int, int);
255extern	int	set_minfd(void);
256extern	int	Pscantext(struct ps_prochandle *);
257extern	void	Pinitsym(struct ps_prochandle *);
258extern	void	Preadauxvec(struct ps_prochandle *);
259extern	void	optimize_symtab(sym_tbl_t *);
260extern	void	Pbuild_file_symtab(struct ps_prochandle *, file_info_t *);
261extern	ctf_file_t *Pbuild_file_ctf(struct ps_prochandle *, file_info_t *);
262extern	map_info_t *Paddr2mptr(struct ps_prochandle *, uintptr_t);
263extern	char 	*Pfindexec(struct ps_prochandle *, const char *,
264	int (*)(const char *, void *), void *);
265extern	int	getlwpstatus(struct ps_prochandle *, lwpid_t, lwpstatus_t *);
266int	Pstopstatus(struct ps_prochandle *, long, uint32_t);
267extern	file_info_t *file_info_new(struct ps_prochandle *, map_info_t *);
268extern	char	*Plofspath(const char *, char *, size_t);
269extern	char	*Pzoneroot(struct ps_prochandle *, char *, size_t);
270extern	char	*Pzonepath(struct ps_prochandle *, const char *, char *,
271	size_t);
272extern	char	*Pfindmap(struct ps_prochandle *, map_info_t *, char *,
273	size_t);
274
275extern	int	Padd_mapping(struct ps_prochandle *, off64_t, file_info_t *,
276    prmap_t *);
277extern	void	Psort_mappings(struct ps_prochandle *);
278
279extern char	procfs_path[PATH_MAX];
280
281/*
282 * Architecture-dependent definition of the breakpoint instruction.
283 */
284#if defined(sparc) || defined(__sparc)
285#define	BPT	((instr_t)0x91d02001)
286#elif defined(__i386) || defined(__amd64)
287#define	BPT	((instr_t)0xcc)
288#endif
289
290/*
291 * Simple convenience.
292 */
293#define	TRUE	1
294#define	FALSE	0
295
296#ifdef	__cplusplus
297}
298#endif
299
300#endif	/* _PCONTROL_H */
301