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
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.
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]
23 * Copyright (c) 1994, by Sun Microsytems, Inc.
30 * Interfaces private to libtnfctl
31 * layout of tnfctl handle structure
32 * layout of probe handle structure
33 * other misc. interfaces used across source files
41 #include <sys/types.h>
49 * global variables used for INTERNAL_MODE synchronization with
50 * dlopen's and dlclose's on another thread.
52 extern mutex_t _tnfctl_lmap_lock
;
53 extern boolean_t _tnfctl_libs_changed
;
55 /* Project private interface - function name in target */
56 #define TRACE_END_FUNC "tnf_trace_end"
58 /* All tnfctl handles are in one of the following 4 modes */
60 KERNEL_MODE
, /* kernel tracing */
61 DIRECT_MODE
, /* tracing another process (exec or attach) */
62 INDIRECT_MODE
, /* client provides /proc functions */
63 INTERNAL_MODE
/* tracing probes in the same process */
66 typedef struct prbctlref prbctlref_t
;
67 typedef struct objlist objlist_t
;
69 /* per probe state - transient - freed on dlclose() */
71 uintptr_t addr
; /* probe address in target */
72 objlist_t
*obj
; /* obj that this probe is in */
73 ulong_t probe_id
; /* assigned id */
75 tnf_probe_control_t wrkprbctl
; /* probe struct from target */
76 tnfctl_probe_t
*probe_handle
; /* handle visible to client */
79 /* per object state */
81 boolean_t new_probe
; /* relative to last library change */
82 boolean_t
new; /* relative to last sync with linker */
83 boolean_t old
; /* relative to last sync with linker */
87 uint_t min_probe_num
; /* first probe id in object */
88 uint_t probecnt
; /* number of probes in object */
89 prbctlref_t
*probes
; /* pointer to an array of probes */
93 /* per probe state that is freed only on tnfctl_close() */
94 struct tnfctl_probe_handle
{
97 void *client_registered_data
;
98 struct tnfctl_probe_handle
*next
;
102 * state saved per tnfctl handle
104 struct tnfctl_handle
{
105 void *proc_p
; /* proc handle */
106 int kfd
; /* kernel handle */
107 pid_t targ_pid
; /* pid of target */
108 enum proc_mode mode
; /* mode of handle */
110 const char *trace_file_name
;
113 tnfctl_bufstate_t trace_buf_state
;
114 boolean_t trace_state
;
115 boolean_t kpidfilter_state
;
116 boolean_t called_exit
;
117 /* addresses of functions in target */
120 uintptr_t commitfunc
;
122 uintptr_t rollbackfunc
;
123 uintptr_t probelist_head
;
124 uintptr_t probelist_valid
;
125 uintptr_t trace_error
;
127 uintptr_t nonthread_test
;
128 uintptr_t thread_test
;
129 uintptr_t thread_sync
;
131 uint_t num_probes
; /* number of probes in target */
132 tnfctl_probe_t
*probe_handle_list_head
;
134 boolean_t in_objlist
; /* _tnfctl_lmap_lock reentrancy check */
136 /* combination info */
137 void *buildroot
; /* root of built combinations */
138 void *decoderoot
; /* root of decoded combinations */
139 /* per probe create/destroy functions */
140 void *(*create_func
)(tnfctl_handle_t
*, tnfctl_probe_t
*);
141 void (*destroy_func
)(void *);
142 /* functions to inspect target process */
143 int (*p_read
)(void *prochandle
, uintptr_t addr
, void *buf
, size_t size
);
144 int (*p_write
)(void *prochandle
, uintptr_t addr
,
145 void *buf
, size_t size
);
146 int (*p_obj_iter
)(void *prochandle
, tnfctl_ind_obj_f
*func
,
148 pid_t (*p_getpid
)(void *prochandle
);
151 typedef enum comb_op
{
152 PRB_COMB_CHAIN
= 0, /* call the down, then the next */
153 PRB_COMB_COUNT
= 1 /* how many? */
164 * interfaces to search for symbols or to search for relocations
167 typedef struct tnfctl_elf_search tnfctl_elf_search_t
;
169 /* prototype for callback for traversing an elf section */
170 typedef tnfctl_errcode_t
171 (*tnfctl_traverse_section_func_t
) (Elf
* elf
, char *strs
, Elf_Scn
* scn
,
172 GElf_Shdr
* shdr
, Elf_Data
* data
, uintptr_t baseaddr
,
173 tnfctl_elf_search_t
* search_info
);
175 /* prototype for callback for traversing records in an elf section */
176 typedef tnfctl_errcode_t
177 (*tnfctl_record_func_t
) (char *name
, uintptr_t addr
, void *entry
,
178 tnfctl_elf_search_t
* search_info
);
180 struct tnfctl_elf_search
{
181 tnfctl_traverse_section_func_t section_func
;
183 tnfctl_record_func_t record_func
;
187 /* traverse all the sections in an object */
188 tnfctl_errcode_t
_tnfctl_traverse_object(int objfd
, uintptr_t addr
,
189 tnfctl_elf_search_t
*search_info_p
);
190 /* search a .rela section */
191 tnfctl_errcode_t
_tnfctl_traverse_rela(Elf
* elf
, char *strs
, Elf_Scn
* rel_scn
,
192 GElf_Shdr
* rel_shdr
, Elf_Data
* rel_data
, uintptr_t baseaddr
,
193 tnfctl_elf_search_t
* search_info_p
);
194 /* search a .dynsym section */
195 tnfctl_errcode_t
_tnfctl_traverse_dynsym(Elf
* elf
, char *elfstrs
,
196 Elf_Scn
* scn
, GElf_Shdr
* shdr
, Elf_Data
* data
, uintptr_t baseaddr
,
197 tnfctl_elf_search_t
* search_info_p
);
199 /* prototype of callback for internal probe traversal function */
200 typedef tnfctl_errcode_t
201 (*_tnfctl_traverse_probe_func_t
)(tnfctl_handle_t
*, prbctlref_t
*, void *);
203 /* sync up list of objects with that of the linker */
204 tnfctl_errcode_t
_tnfctl_lmap_update(tnfctl_handle_t
*hndl
, boolean_t
*lmap_ok
,
205 enum event_op_t
*evt
);
207 /* sync up list of objects and probes */
208 tnfctl_errcode_t
_tnfctl_refresh_process(tnfctl_handle_t
*, boolean_t
*,
211 tnfctl_errcode_t
_tnfctl_set_state(tnfctl_handle_t
*hndl
);
212 tnfctl_errcode_t
_tnfctl_create_tracefile(tnfctl_handle_t
*hndl
,
213 const char *trace_file_name
, uint_t trace_file_size
);
215 /* probe interfaces */
216 tnfctl_errcode_t
_tnfctl_find_all_probes(tnfctl_handle_t
*hndl
);
217 tnfctl_errcode_t
_tnfctl_probes_traverse(tnfctl_handle_t
*hndl
,
218 _tnfctl_traverse_probe_func_t func_p
, void *calldata_p
);
219 tnfctl_errcode_t
_tnfctl_flush_a_probe(tnfctl_handle_t
*hndl
,
220 prbctlref_t
*ref_p
, size_t offset
, size_t size
);
222 /* combination interfaces */
223 tnfctl_errcode_t
_tnfctl_comb_build(tnfctl_handle_t
*hndl
, comb_op_t op
,
224 uintptr_t down
, uintptr_t next
, uintptr_t *comb_p
);
225 tnfctl_errcode_t
_tnfctl_comb_decode(tnfctl_handle_t
*hndl
, uintptr_t addr
,
226 char ***func_names
, uintptr_t **func_addrs
);
228 /* allocate memory in target process */
229 tnfctl_errcode_t
_tnfctl_targmem_alloc(tnfctl_handle_t
*hndl
, size_t size
,
232 /* inprocess "plug ins" for functions in tnfctl_handle_t structure */
233 int _tnfctl_read_targ(void *proc_p
, uintptr_t addr
, void *buf
, size_t size
);
234 int _tnfctl_write_targ(void *proc_p
, uintptr_t addr
, void *buf
, size_t size
);
235 int _tnfctl_loadobj_iter(void *proc_p
, tnfctl_ind_obj_f
*func
,
237 pid_t
_tnfctl_pid_get(void *proc_p
);
239 /* read a string from the target process */
240 tnfctl_errcode_t
_tnfctl_readstr_targ(tnfctl_handle_t
*hndl
, uintptr_t addr
,
243 /* symbol searching interfaces */
244 tnfctl_errcode_t
_tnfctl_sym_find_in_obj(int objfd
, uintptr_t baseaddr
,
245 const char *symname
, uintptr_t *symaddr
);
246 tnfctl_errcode_t
_tnfctl_sym_obj_find(tnfctl_handle_t
*hndl
,
247 const char *lib_base_name
, const char *symname
, uintptr_t *symaddr
);
248 tnfctl_errcode_t
_tnfctl_sym_find(tnfctl_handle_t
*hndl
, const char *symname
,
250 tnfctl_errcode_t
_tnfctl_sym_findname(tnfctl_handle_t
*hndl
, uintptr_t symaddr
,
252 tnfctl_errcode_t
_tnfctl_elf_dbgent(tnfctl_handle_t
*hndl
,
253 uintptr_t * entaddr_p
);
255 /* free objs and probes */
256 void _tnfctl_free_objs_and_probes(tnfctl_handle_t
*);
258 /* locking interfaces */
259 tnfctl_errcode_t
_tnfctl_lock_libs(tnfctl_handle_t
*hndl
,
260 boolean_t
*release_lock
);
261 void _tnfctl_unlock_libs(tnfctl_handle_t
*hndl
, boolean_t release_lock
);
262 tnfctl_errcode_t
_tnfctl_sync_lib_list(tnfctl_handle_t
*hndl
);
266 * The flags that indicate if in/external trace control is active.
267 * Used to prevent simultaneous internal and external probe control.
268 * For external control keep pid of traced process to handle case
269 * where process forks. (child is not under external control)
271 #define TNFCTL_INTERNAL_TRACEFLAG "_tnfctl_internal_tracing_flag"
272 #define TNFCTL_EXTERNAL_TRACEDPID "_tnfctl_externally_traced_pid"
273 extern boolean_t _tnfctl_internal_tracing_flag
;
274 extern pid_t _tnfctl_externally_traced_pid
;
275 tnfctl_errcode_t
_tnfctl_internal_getlock(void);
276 tnfctl_errcode_t
_tnfctl_external_getlock(tnfctl_handle_t
*hndl
);
277 tnfctl_errcode_t
_tnfctl_internal_releaselock(void);
278 tnfctl_errcode_t
_tnfctl_external_releaselock(tnfctl_handle_t
*hndl
);
280 /* error mapping functions */
281 tnfctl_errcode_t
_tnfctl_map_to_errcode(prb_status_t prbstat
);
282 tnfctl_errcode_t
tnfctl_status_map(int);
286 * LOCK is the macro to lock down the library list so that a dlopen or
287 * dlclose by another thread will block waiting for the lock to be released.
289 * LOCK_SYNC does the same as LOCK + it syncs up libtnfctl's cache of
290 * libraries in target process with that of what the run time linker maintains.
292 * These macros do conditional locking because they are needed only by
293 * INTERNAL_MODE clients. There are 2 versions of these macros so that
294 * lock_lint won't have to see the conditional locking.
295 * CAUTION: Be aware that these macros have a return() embedded in them.
297 #define LOCK(hndl, stat, release) \
298 if (hndl->mode == INTERNAL_MODE) { \
299 stat = _tnfctl_lock_libs(hndl, &release); \
305 #define LOCK_SYNC(hndl, stat, release) \
306 if (hndl->mode == INTERNAL_MODE) { \
307 stat = _tnfctl_lock_libs(hndl, &release); \
310 stat = _tnfctl_sync_lib_list(hndl); \
312 _tnfctl_unlock_libs(hndl, release); \
318 #define UNLOCK(hndl, release) \
319 if (hndl->mode == INTERNAL_MODE) \
320 _tnfctl_unlock_libs(hndl, release_lock); \
327 #endif /* _TNFCTL_INT_H */