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, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24 * Use is subject to license terms.
25 */
26
27#ifndef _LIBPROC_H
28#define _LIBPROC_H
29
30/* #pragma ident   "@(#)libproc.h  1.46    05/06/08 SMI" */
31
32#include "rtld_db.h"
33#include <string.h>
34#include <sys/utsname.h>
35#include "bitmap.h"
36#include <dlfcn.h>
37
38#include "gelf.h"
39#include "procfs.h"
40
41#ifdef	__cplusplus
42extern "C" {
43#endif
44
45/* From Sun's link.h */
46#define LM_ID_BASE              0x00
47
48/*
49 * APPLE NOTE: This is a cut down copy of Sun's libproc.h. KEEP IT IN ORDER!
50 * We want to be able to diff this file against newer versions of libproc.h
51 * and see where changes have been made.
52 */
53
54/*
55 * Opaque structure tag reference to a process control structure.
56 * Clients of libproc cannot look inside the process control structure.
57 * The implementation of struct ps_prochandle can change w/o affecting clients.
58 */
59struct ps_prochandle;
60
61/* State values returned by Pstate() */
62#define PS_RUN          1       /* process is running */
63#define PS_STOP         2       /* process is stopped */
64#define PS_LOST         3       /* process is lost to control (EAGAIN) */
65#define PS_UNDEAD       4       /* process is terminated (zombie) */
66#define PS_DEAD         5       /* process is terminated (core file) */
67#define PS_IDLE         6       /* process has not been run */
68
69/* Flags accepted by Pgrab() */
70#define PGRAB_RETAIN    0x01    /* Retain tracing flags, else clear flags */
71#define PGRAB_FORCE     0x02    /* Open the process w/o O_EXCL */
72#define PGRAB_RDONLY    0x04    /* Open the process or core w/ O_RDONLY */
73#define PGRAB_NOSTOP    0x08    /* Open the process but do not stop it */
74
75/* Error codes from Pcreate() */
76#define C_STRANGE       -1      /* Unanticipated error, errno is meaningful */
77#define C_FORK          1       /* Unable to fork */
78#define C_PERM          2       /* No permission (file set-id or unreadable) */
79#define C_NOEXEC        3       /* Cannot execute file */
80#define C_INTR          4       /* Interrupt received while creating */
81#define C_LP64          5       /* Program is _LP64, self is _ILP32 */
82#define C_NOENT         6       /* Cannot find executable file */
83
84/* Flags accepted by Prelease */
85#define PRELEASE_CLEAR  0x10    /* Clear all tracing flags */
86#define PRELEASE_RETAIN 0x20    /* Retain final tracing flags */
87#define PRELEASE_HANG   0x40    /* Leave the process stopped */
88#define PRELEASE_KILL   0x80    /* Terminate the process */
89
90/*
91 * Function prototypes for routines in the process control package.
92 */
93extern struct ps_prochandle *Pcreate(const char *, char *const *,
94                                     int *, char *, size_t, cpu_type_t);
95extern const char *Pcreate_error(int);
96
97extern struct ps_prochandle *Pgrab(pid_t, int, int *);
98extern const char *Pgrab_error(int);
99
100extern  int     Preopen(struct ps_prochandle *);
101extern  void    Prelease(struct ps_prochandle *, int);
102
103extern  int     Pstate(struct ps_prochandle *);
104extern  const pstatus_t *Pstatus(struct ps_prochandle *);
105extern	int		Psetrun(struct ps_prochandle *, int, int);
106extern  ssize_t Pread(struct ps_prochandle *, void *, size_t, mach_vm_address_t);
107extern  int     Psetbkpt(struct ps_prochandle *, uintptr_t, ulong_t *);
108extern  int     Pdelbkpt(struct ps_prochandle *, uintptr_t, ulong_t);
109extern	int		Pxecbkpt(struct ps_prochandle *, ulong_t);
110extern  int     Psetflags(struct ps_prochandle *, long);
111extern  int     Punsetflags(struct ps_prochandle *, long);
112
113/*
114 * Function prototypes for system calls forced on the victim process.
115 */
116extern  int     pr_open(struct ps_prochandle *, const char *, int, mode_t);
117extern  int     pr_close(struct ps_prochandle *, int);
118extern  int     pr_ioctl(struct ps_prochandle *, int, int, void *, size_t);
119
120/*
121 * Symbol table interfaces.
122 */
123
124/*
125 * Pseudo-names passed to Plookup_by_name() for well-known load objects.
126 * NOTE: It is required that PR_OBJ_EXEC and PR_OBJ_LDSO exactly match
127 * the definitions of PS_OBJ_EXEC and PS_OBJ_LDSO from <proc_service.h>.
128 */
129#define PR_OBJ_EXEC     ((const char *)0)       /* search the executable file */
130#define PR_OBJ_LDSO     ((const char *)1)       /* search ld.so.1 */
131#define PR_OBJ_EVERY    ((const char *)-1)      /* search every load object */
132
133/*
134 * Special Lmid_t passed to Plookup_by_lmid() to search all link maps.  The
135 * special values LM_ID_BASE and LM_ID_LDSO from <link.h> may also be used.
136 * If PR_OBJ_EXEC is used as the object name, the lmid must be PR_LMID_EVERY
137 * or LM_ID_BASE in order to return a match.  If PR_OBJ_LDSO is used as the
138 * object name, the lmid must be PR_LMID_EVERY or LM_ID_LDSO to return a match.
139 */
140#define PR_LMID_EVERY   ((Lmid_t)-1UL)          /* search every link map */
141
142/*
143 * 'object_name' is the name of a load object obtained from an
144 * iteration over the process's address space mappings (Pmapping_iter),
145 * or an iteration over the process's mapped objects (Pobject_iter),
146 * or else it is one of the special PR_OBJ_* values above.
147 */
148extern int Plookup_by_name(struct ps_prochandle *, const char *, const char *, GElf_Sym *);
149
150extern int Plookup_by_addr(struct ps_prochandle *, mach_vm_address_t, char *, size_t, GElf_Sym *);
151
152typedef struct prsyminfo {
153          const char      *prs_object;            /* object name */
154          const char      *prs_name;              /* symbol name */
155          Lmid_t          prs_lmid;               /* link map id */
156//        uint_t          prs_id;                 /* symbol id */
157//        uint_t          prs_table;              /* symbol table id */
158} prsyminfo_t;
159
160extern int Pxlookup_by_name(struct ps_prochandle *,
161    Lmid_t, const char *, const char *, GElf_Sym *, prsyminfo_t *);
162
163extern int Pxlookup_by_addr(struct ps_prochandle *,
164    mach_vm_address_t, char *, size_t, GElf_Sym *, prsyminfo_t *);
165
166typedef int proc_map_f(void *, const prmap_t *, const char *);
167
168extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
169
170/*
171 * Apple NOTE: These differ from their solaris counterparts by taking a prmap_t pointer argument.
172 * This is to manage thread local storage of the prmap_t.
173 */
174extern const prmap_t *Paddr_to_map(struct ps_prochandle *, mach_vm_address_t, prmap_t*);
175extern const prmap_t *Pname_to_map(struct ps_prochandle *, const char *, prmap_t*);
176extern const prmap_t *Plmid_to_map(struct ps_prochandle *, Lmid_t, const char *, prmap_t*);
177
178extern char *Pobjname(struct ps_prochandle *, mach_vm_address_t, char *, size_t);
179extern int Plmid(struct ps_prochandle *, mach_vm_address_t, Lmid_t *);
180
181
182/*
183 * Apple only objc iteration interface.
184 */
185
186typedef int proc_objc_f(void *, const GElf_Sym *, const char *, const char *);
187extern int Pobjc_method_iter(struct ps_prochandle *, proc_objc_f* , void *);
188
189typedef void Phandler_func_t(void *);
190extern void Pactivityserver(struct ps_prochandle *, Phandler_func_t, void *);
191
192/*
193 * Symbol table iteration interface.  The special lmid constants LM_ID_BASE,
194 * LM_ID_LDSO, and PR_LMID_EVERY may be used with Psymbol_iter_by_lmid.
195 */
196typedef int proc_sym_f(void *, const GElf_Sym *, const char *);
197
198extern int Psymbol_iter_by_addr(struct ps_prochandle *, const char *, int, int, proc_sym_f *, void *);
199
200/*
201 * 'which' selects which symbol table and can be one of the following.
202 */
203#define PR_SYMTAB       1
204#define PR_DYNSYM       2
205
206/*
207 * 'type' selects the symbols of interest by binding and type.  It is a bit-
208 * mask of one or more of the following flags, whose order MUST match the
209 * order of STB and STT constants in <sys/elf.h>.
210 */
211#define BIND_LOCAL      0x0001
212#define BIND_GLOBAL     0x0002
213#define BIND_WEAK       0x0004
214#define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK)
215#define TYPE_NOTYPE     0x0100
216#define TYPE_OBJECT     0x0200
217#define TYPE_FUNC       0x0400
218#define TYPE_SECTION    0x0800
219#define TYPE_FILE       0x1000
220#define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|TYPE_FILE)
221
222/*
223 * This returns the rtld_db agent handle for the process.
224 * The handle will become invalid at the next successful exec() and
225 * must not be used beyond that point (see Preset_maps(), below).
226 */
227extern rd_agent_t *Prd_agent(struct ps_prochandle *);
228
229/*
230 * This should be called when an RD_DLACTIVITY event with the
231 * RD_CONSISTENT state occurs via librtld_db's event mechanism.
232 * This makes libproc's address space mappings and symbol tables current.
233 * The variant Pupdate_syms() can be used to preload all symbol tables as well.
234 */
235extern void Pupdate_maps(struct ps_prochandle *);
236extern void Pupdate_syms(struct ps_prochandle *);
237
238/*
239 * This must be called after the victim process performs a successful
240 * exec() if any of the symbol table interface functions have been called
241 * prior to that point.  This is essential because an exec() invalidates
242 * all previous symbol table and address space mapping information.
243 * It is always safe to call, but if it is called other than after an
244 * exec() by the victim process it just causes unnecessary overhead.
245 *
246 * The rtld_db agent handle obtained from a previous call to Prd_agent() is
247 * made invalid by Preset_maps() and Prd_agent() must be called again to get
248 * the new handle.
249 */
250extern void Preset_maps(struct ps_prochandle *);
251
252/*
253 * Given an address, Ppltdest() determines if this is part of a PLT, and if
254 * so returns a pointer to the symbol name that will be used for resolution.
255 * If the specified address is not part of a PLT, the function returns NULL.
256 */
257extern const char *Ppltdest(struct ps_prochandle *, mach_vm_address_t);
258
259/*
260 * We have a hideous three thread of control system.
261 *
262 * There is the main dtrace thread, the per-proc control thread, and the per symbolicator notification thread.
263 * The symbolicator notification thread and main thread may queue events for processing by the control thread.
264 * Pcreate_sync_proc_activity will not return until the control thread has processed the activity.
265 */
266extern void Pcreate_async_proc_activity(struct ps_prochandle*, rd_event_e);
267extern void Pcreate_sync_proc_activity(struct ps_prochandle*, rd_event_e);
268
269extern void* Pdequeue_proc_activity(struct ps_prochandle*);
270extern void Pdestroy_proc_activity(void*);
271
272#ifdef  __cplusplus
273}
274#endif
275
276#endif  /* _LIBPROC_H */
277