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 */
93#if !defined(__APPLE__)
94    extern struct ps_prochandle *Pcreate(const char *, char *const *,
95                                         int *, char *, size_t);
96#else
97    extern struct ps_prochandle *Pcreate(const char *, char *const *,
98                                         int *, char *, size_t, cpu_type_t);
99#endif
100extern const char *Pcreate_error(int);
101
102extern struct ps_prochandle *Pgrab(pid_t, int, int *);
103extern const char *Pgrab_error(int);
104
105extern  int     Preopen(struct ps_prochandle *);
106extern  void    Prelease(struct ps_prochandle *, int);
107
108extern  int     Pstate(struct ps_prochandle *);
109extern  const pstatus_t *Pstatus(struct ps_prochandle *);
110extern	int		Psetrun(struct ps_prochandle *, int, int);
111extern  ssize_t Pread(struct ps_prochandle *, void *, size_t, mach_vm_address_t);
112extern  int     Psetbkpt(struct ps_prochandle *, uintptr_t, ulong_t *);
113extern  int     Pdelbkpt(struct ps_prochandle *, uintptr_t, ulong_t);
114extern	int		Pxecbkpt(struct ps_prochandle *, ulong_t);
115extern  int     Psetflags(struct ps_prochandle *, long);
116extern  int     Punsetflags(struct ps_prochandle *, long);
117
118/*
119 * Function prototypes for system calls forced on the victim process.
120 */
121extern  int     pr_open(struct ps_prochandle *, const char *, int, mode_t);
122extern  int     pr_close(struct ps_prochandle *, int);
123extern  int     pr_ioctl(struct ps_prochandle *, int, int, void *, size_t);
124
125/*
126 * Symbol table interfaces.
127 */
128
129/*
130 * Pseudo-names passed to Plookup_by_name() for well-known load objects.
131 * NOTE: It is required that PR_OBJ_EXEC and PR_OBJ_LDSO exactly match
132 * the definitions of PS_OBJ_EXEC and PS_OBJ_LDSO from <proc_service.h>.
133 */
134#define PR_OBJ_EXEC     ((const char *)0)       /* search the executable file */
135#define PR_OBJ_LDSO     ((const char *)1)       /* search ld.so.1 */
136#define PR_OBJ_EVERY    ((const char *)-1)      /* search every load object */
137
138/*
139 * Special Lmid_t passed to Plookup_by_lmid() to search all link maps.  The
140 * special values LM_ID_BASE and LM_ID_LDSO from <link.h> may also be used.
141 * If PR_OBJ_EXEC is used as the object name, the lmid must be PR_LMID_EVERY
142 * or LM_ID_BASE in order to return a match.  If PR_OBJ_LDSO is used as the
143 * object name, the lmid must be PR_LMID_EVERY or LM_ID_LDSO to return a match.
144 */
145#define PR_LMID_EVERY   ((Lmid_t)-1UL)          /* search every link map */
146
147/*
148 * 'object_name' is the name of a load object obtained from an
149 * iteration over the process's address space mappings (Pmapping_iter),
150 * or an iteration over the process's mapped objects (Pobject_iter),
151 * or else it is one of the special PR_OBJ_* values above.
152 */
153extern int Plookup_by_name(struct ps_prochandle *, const char *, const char *, GElf_Sym *);
154
155extern int Plookup_by_addr(struct ps_prochandle *, mach_vm_address_t, char *, size_t, GElf_Sym *);
156
157typedef struct prsyminfo {
158          const char      *prs_object;            /* object name */
159          const char      *prs_name;              /* symbol name */
160          Lmid_t          prs_lmid;               /* link map id */
161//        uint_t          prs_id;                 /* symbol id */
162//        uint_t          prs_table;              /* symbol table id */
163} prsyminfo_t;
164
165extern int Pxlookup_by_name(struct ps_prochandle *,
166    Lmid_t, const char *, const char *, GElf_Sym *, prsyminfo_t *);
167
168extern int Pxlookup_by_addr(struct ps_prochandle *,
169    mach_vm_address_t, char *, size_t, GElf_Sym *, prsyminfo_t *);
170
171typedef int proc_map_f(void *, const prmap_t *, const char *);
172
173extern int Pobject_iter(struct ps_prochandle *, proc_map_f *, void *);
174
175/*
176 * Apple NOTE: These differ from their solaris counterparts by taking a prmap_t pointer argument.
177 * This is to manage thread local storage of the prmap_t.
178 */
179extern const prmap_t *Paddr_to_map(struct ps_prochandle *, mach_vm_address_t, prmap_t*);
180extern const prmap_t *Pname_to_map(struct ps_prochandle *, const char *, prmap_t*);
181extern const prmap_t *Plmid_to_map(struct ps_prochandle *, Lmid_t, const char *, prmap_t*);
182
183extern char *Pobjname(struct ps_prochandle *, mach_vm_address_t, char *, size_t);
184extern int Plmid(struct ps_prochandle *, mach_vm_address_t, Lmid_t *);
185
186#if defined(__APPLE__)
187
188/*
189 * Apple only objc iteration interface.
190 */
191
192typedef int proc_objc_f(void *, const GElf_Sym *, const char *, const char *);
193extern int Pobjc_method_iter(struct ps_prochandle *, proc_objc_f* , void *);
194
195typedef void Phandler_func_t(void *);
196extern void Pactivityserver(struct ps_prochandle *, Phandler_func_t, void *);
197#endif
198
199/*
200 * Symbol table iteration interface.  The special lmid constants LM_ID_BASE,
201 * LM_ID_LDSO, and PR_LMID_EVERY may be used with Psymbol_iter_by_lmid.
202 */
203typedef int proc_sym_f(void *, const GElf_Sym *, const char *);
204
205extern int Psymbol_iter_by_addr(struct ps_prochandle *, const char *, int, int, proc_sym_f *, void *);
206
207/*
208 * 'which' selects which symbol table and can be one of the following.
209 */
210#define PR_SYMTAB       1
211#define PR_DYNSYM       2
212
213/*
214 * 'type' selects the symbols of interest by binding and type.  It is a bit-
215 * mask of one or more of the following flags, whose order MUST match the
216 * order of STB and STT constants in <sys/elf.h>.
217 */
218#define BIND_LOCAL      0x0001
219#define BIND_GLOBAL     0x0002
220#define BIND_WEAK       0x0004
221#define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK)
222#define TYPE_NOTYPE     0x0100
223#define TYPE_OBJECT     0x0200
224#define TYPE_FUNC       0x0400
225#define TYPE_SECTION    0x0800
226#define TYPE_FILE       0x1000
227#define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|TYPE_FILE)
228
229/*
230 * This returns the rtld_db agent handle for the process.
231 * The handle will become invalid at the next successful exec() and
232 * must not be used beyond that point (see Preset_maps(), below).
233 */
234extern rd_agent_t *Prd_agent(struct ps_prochandle *);
235
236/*
237 * This should be called when an RD_DLACTIVITY event with the
238 * RD_CONSISTENT state occurs via librtld_db's event mechanism.
239 * This makes libproc's address space mappings and symbol tables current.
240 * The variant Pupdate_syms() can be used to preload all symbol tables as well.
241 */
242extern void Pupdate_maps(struct ps_prochandle *);
243extern void Pupdate_syms(struct ps_prochandle *);
244
245/*
246 * This must be called after the victim process performs a successful
247 * exec() if any of the symbol table interface functions have been called
248 * prior to that point.  This is essential because an exec() invalidates
249 * all previous symbol table and address space mapping information.
250 * It is always safe to call, but if it is called other than after an
251 * exec() by the victim process it just causes unnecessary overhead.
252 *
253 * The rtld_db agent handle obtained from a previous call to Prd_agent() is
254 * made invalid by Preset_maps() and Prd_agent() must be called again to get
255 * the new handle.
256 */
257extern void Preset_maps(struct ps_prochandle *);
258
259/*
260 * Given an address, Ppltdest() determines if this is part of a PLT, and if
261 * so returns a pointer to the symbol name that will be used for resolution.
262 * If the specified address is not part of a PLT, the function returns NULL.
263 */
264extern const char *Ppltdest(struct ps_prochandle *, mach_vm_address_t);
265
266/*
267 * We have a hideous three thread of control system.
268 *
269 * There is the main dtrace thread, the per-proc control thread, and the per symbolicator notification thread.
270 * The symbolicator notification thread and main thread may queue events for processing by the control thread.
271 * Pcreate_sync_proc_activity will not return until the control thread has processed the activity.
272 */
273extern void Pcreate_async_proc_activity(struct ps_prochandle*, rd_event_e);
274extern void Pcreate_sync_proc_activity(struct ps_prochandle*, rd_event_e);
275
276extern void* Pdequeue_proc_activity(struct ps_prochandle*);
277extern void Pdestroy_proc_activity(void*);
278
279#ifdef  __cplusplus
280}
281#endif
282
283#endif  /* _LIBPROC_H */
284