1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 1994, by Sun Microsytems, Inc. 24*0Sstevel@tonic-gate */ 25*0Sstevel@tonic-gate 26*0Sstevel@tonic-gate #ifndef _TNFCTL_INT_H 27*0Sstevel@tonic-gate #define _TNFCTL_INT_H 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate /* 32*0Sstevel@tonic-gate * Interfaces private to libtnfctl 33*0Sstevel@tonic-gate * layout of tnfctl handle structure 34*0Sstevel@tonic-gate * layout of probe handle structure 35*0Sstevel@tonic-gate * other misc. interfaces used across source files 36*0Sstevel@tonic-gate */ 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #ifdef __cplusplus 39*0Sstevel@tonic-gate extern "C" { 40*0Sstevel@tonic-gate #endif 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate #include "tnfctl.h" 43*0Sstevel@tonic-gate #include <sys/types.h> 44*0Sstevel@tonic-gate #include <gelf.h> 45*0Sstevel@tonic-gate #include <libelf.h> 46*0Sstevel@tonic-gate #include "prb_proc.h" 47*0Sstevel@tonic-gate /* for warlock (lock_lint) static lock checking */ 48*0Sstevel@tonic-gate #include <note.h> 49*0Sstevel@tonic-gate #include <thread.h> 50*0Sstevel@tonic-gate #include <synch.h> 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate /* 53*0Sstevel@tonic-gate * This bogus structure is our way of getting around the fact that 54*0Sstevel@tonic-gate * warlock does not handle recursive locks (warlock does not complain 55*0Sstevel@tonic-gate * when anonymous locks, such as warlock_kludge->lmap_lock, are 56*0Sstevel@tonic-gate * multiply locked). 57*0Sstevel@tonic-gate */ 58*0Sstevel@tonic-gate #if defined(__lock_lint) 59*0Sstevel@tonic-gate struct warlock { 60*0Sstevel@tonic-gate mutex_t lmap_lock; 61*0Sstevel@tonic-gate } *warlock_kludge; 62*0Sstevel@tonic-gate #endif 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* 65*0Sstevel@tonic-gate * global variables used for INTERNAL_MODE synchronization with 66*0Sstevel@tonic-gate * dlopen's and dlclose's on another thread. 67*0Sstevel@tonic-gate */ 68*0Sstevel@tonic-gate extern mutex_t _tnfctl_lmap_lock; 69*0Sstevel@tonic-gate extern boolean_t _tnfctl_libs_changed; 70*0Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, _tnfctl_libs_changed)) 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate /* Project private interface - function name in target */ 73*0Sstevel@tonic-gate #define TRACE_END_FUNC "tnf_trace_end" 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate /* All tnfctl handles are in one of the following 4 modes */ 76*0Sstevel@tonic-gate enum proc_mode { 77*0Sstevel@tonic-gate KERNEL_MODE, /* kernel tracing */ 78*0Sstevel@tonic-gate DIRECT_MODE, /* tracing another process (exec or attach) */ 79*0Sstevel@tonic-gate INDIRECT_MODE, /* client provides /proc functions */ 80*0Sstevel@tonic-gate INTERNAL_MODE /* tracing probes in the same process */ 81*0Sstevel@tonic-gate }; 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate typedef struct prbctlref prbctlref_t; 84*0Sstevel@tonic-gate typedef struct objlist objlist_t; 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate /* per probe state - transient - freed on dlclose() */ 87*0Sstevel@tonic-gate struct prbctlref { 88*0Sstevel@tonic-gate uintptr_t addr; /* probe address in target */ 89*0Sstevel@tonic-gate objlist_t *obj; /* obj that this probe is in */ 90*0Sstevel@tonic-gate ulong_t probe_id; /* assigned id */ 91*0Sstevel@tonic-gate char *attr_string; 92*0Sstevel@tonic-gate tnf_probe_control_t wrkprbctl; /* probe struct from target */ 93*0Sstevel@tonic-gate tnfctl_probe_t *probe_handle; /* handle visible to client */ 94*0Sstevel@tonic-gate }; 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("one thread per handle", prbctlref)) 97*0Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, prbctlref::{addr obj})) 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate /* per object state */ 100*0Sstevel@tonic-gate struct objlist { 101*0Sstevel@tonic-gate boolean_t new_probe; /* relative to last library change */ 102*0Sstevel@tonic-gate boolean_t new; /* relative to last sync with linker */ 103*0Sstevel@tonic-gate boolean_t old; /* relative to last sync with linker */ 104*0Sstevel@tonic-gate char * objname; 105*0Sstevel@tonic-gate uintptr_t baseaddr; 106*0Sstevel@tonic-gate int objfd; 107*0Sstevel@tonic-gate uint_t min_probe_num; /* first probe id in object */ 108*0Sstevel@tonic-gate uint_t probecnt; /* number of probes in object */ 109*0Sstevel@tonic-gate prbctlref_t *probes; /* pointer to an array of probes */ 110*0Sstevel@tonic-gate objlist_t *next; 111*0Sstevel@tonic-gate }; 112*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("one thread per handle", objlist)) 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate /* per probe state that is freed only on tnfctl_close() */ 115*0Sstevel@tonic-gate struct tnfctl_probe_handle { 116*0Sstevel@tonic-gate boolean_t valid; 117*0Sstevel@tonic-gate prbctlref_t *probe_p; 118*0Sstevel@tonic-gate void *client_registered_data; 119*0Sstevel@tonic-gate struct tnfctl_probe_handle *next; 120*0Sstevel@tonic-gate }; 121*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("one thread per handle", tnfctl_probe_handle)) 122*0Sstevel@tonic-gate 123*0Sstevel@tonic-gate /* 124*0Sstevel@tonic-gate * state saved per tnfctl handle 125*0Sstevel@tonic-gate */ 126*0Sstevel@tonic-gate struct tnfctl_handle { 127*0Sstevel@tonic-gate void *proc_p; /* proc handle */ 128*0Sstevel@tonic-gate int kfd; /* kernel handle */ 129*0Sstevel@tonic-gate pid_t targ_pid; /* pid of target */ 130*0Sstevel@tonic-gate enum proc_mode mode; /* mode of handle */ 131*0Sstevel@tonic-gate /* tracing info */ 132*0Sstevel@tonic-gate const char *trace_file_name; 133*0Sstevel@tonic-gate int trace_buf_size; 134*0Sstevel@tonic-gate int trace_min_size; 135*0Sstevel@tonic-gate tnfctl_bufstate_t trace_buf_state; 136*0Sstevel@tonic-gate boolean_t trace_state; 137*0Sstevel@tonic-gate boolean_t kpidfilter_state; 138*0Sstevel@tonic-gate boolean_t called_exit; 139*0Sstevel@tonic-gate /* addresses of functions in target */ 140*0Sstevel@tonic-gate uintptr_t testfunc; 141*0Sstevel@tonic-gate uintptr_t allocfunc; 142*0Sstevel@tonic-gate uintptr_t commitfunc; 143*0Sstevel@tonic-gate uintptr_t endfunc; 144*0Sstevel@tonic-gate uintptr_t rollbackfunc; 145*0Sstevel@tonic-gate uintptr_t probelist_head; 146*0Sstevel@tonic-gate uintptr_t probelist_valid; 147*0Sstevel@tonic-gate uintptr_t trace_error; 148*0Sstevel@tonic-gate uintptr_t memseg_p; 149*0Sstevel@tonic-gate uintptr_t nonthread_test; 150*0Sstevel@tonic-gate uintptr_t thread_test; 151*0Sstevel@tonic-gate uintptr_t thread_sync; 152*0Sstevel@tonic-gate boolean_t mt_target; 153*0Sstevel@tonic-gate uint_t num_probes; /* number of probes in target */ 154*0Sstevel@tonic-gate tnfctl_probe_t *probe_handle_list_head; 155*0Sstevel@tonic-gate /* object info */ 156*0Sstevel@tonic-gate boolean_t in_objlist; /* _tnfctl_lmap_lock reentrancy check */ 157*0Sstevel@tonic-gate objlist_t *objlist; 158*0Sstevel@tonic-gate /* combination info */ 159*0Sstevel@tonic-gate void *buildroot; /* root of built combinations */ 160*0Sstevel@tonic-gate void *decoderoot; /* root of decoded combinations */ 161*0Sstevel@tonic-gate /* per probe create/destroy functions */ 162*0Sstevel@tonic-gate void *(*create_func)(tnfctl_handle_t *, tnfctl_probe_t *); 163*0Sstevel@tonic-gate void (*destroy_func)(void *); 164*0Sstevel@tonic-gate /* functions to inspect target process */ 165*0Sstevel@tonic-gate int (*p_read)(void *prochandle, uintptr_t addr, void *buf, size_t size); 166*0Sstevel@tonic-gate int (*p_write)(void *prochandle, uintptr_t addr, 167*0Sstevel@tonic-gate void *buf, size_t size); 168*0Sstevel@tonic-gate int (*p_obj_iter)(void *prochandle, tnfctl_ind_obj_f *func, 169*0Sstevel@tonic-gate void *client_data); 170*0Sstevel@tonic-gate pid_t (*p_getpid)(void *prochandle); 171*0Sstevel@tonic-gate }; 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("one thread per handle", tnfctl_handle)) 174*0Sstevel@tonic-gate NOTE(MUTEX_PROTECTS_DATA(warlock::lmap_lock, tnfctl_handle::objlist)) 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate typedef enum comb_op { 177*0Sstevel@tonic-gate PRB_COMB_CHAIN = 0, /* call the down, then the next */ 178*0Sstevel@tonic-gate PRB_COMB_COUNT = 1 /* how many? */ 179*0Sstevel@tonic-gate } comb_op_t; 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate enum event_op_t { 182*0Sstevel@tonic-gate EVT_NONE, 183*0Sstevel@tonic-gate EVT_OPEN, 184*0Sstevel@tonic-gate EVT_CLOSE 185*0Sstevel@tonic-gate }; 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate /* 189*0Sstevel@tonic-gate * interfaces to search for symbols or to search for relocations 190*0Sstevel@tonic-gate * in an elf file 191*0Sstevel@tonic-gate */ 192*0Sstevel@tonic-gate typedef struct tnfctl_elf_search tnfctl_elf_search_t; 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate /* prototype for callback for traversing an elf section */ 195*0Sstevel@tonic-gate typedef tnfctl_errcode_t 196*0Sstevel@tonic-gate (*tnfctl_traverse_section_func_t) (Elf * elf, char *strs, Elf_Scn * scn, 197*0Sstevel@tonic-gate GElf_Shdr * shdr, Elf_Data * data, uintptr_t baseaddr, 198*0Sstevel@tonic-gate tnfctl_elf_search_t * search_info); 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate /* prototype for callback for traversing records in an elf section */ 201*0Sstevel@tonic-gate typedef tnfctl_errcode_t 202*0Sstevel@tonic-gate (*tnfctl_record_func_t) (char *name, uintptr_t addr, void *entry, 203*0Sstevel@tonic-gate tnfctl_elf_search_t * search_info); 204*0Sstevel@tonic-gate 205*0Sstevel@tonic-gate struct tnfctl_elf_search { 206*0Sstevel@tonic-gate tnfctl_traverse_section_func_t section_func; 207*0Sstevel@tonic-gate void *section_data; 208*0Sstevel@tonic-gate tnfctl_record_func_t record_func; 209*0Sstevel@tonic-gate void *record_data; 210*0Sstevel@tonic-gate }; 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate /* traverse all the sections in an object */ 213*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_traverse_object(int objfd, uintptr_t addr, 214*0Sstevel@tonic-gate tnfctl_elf_search_t *search_info_p); 215*0Sstevel@tonic-gate /* search a .rela section */ 216*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_traverse_rela(Elf * elf, char *strs, Elf_Scn * rel_scn, 217*0Sstevel@tonic-gate GElf_Shdr * rel_shdr, Elf_Data * rel_data, uintptr_t baseaddr, 218*0Sstevel@tonic-gate tnfctl_elf_search_t * search_info_p); 219*0Sstevel@tonic-gate /* search a .dynsym section */ 220*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_traverse_dynsym(Elf * elf, char *elfstrs, 221*0Sstevel@tonic-gate Elf_Scn * scn, GElf_Shdr * shdr, Elf_Data * data, uintptr_t baseaddr, 222*0Sstevel@tonic-gate tnfctl_elf_search_t * search_info_p); 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate /* prototype of callback for internal probe traversal function */ 225*0Sstevel@tonic-gate typedef tnfctl_errcode_t 226*0Sstevel@tonic-gate (*_tnfctl_traverse_probe_func_t)(tnfctl_handle_t *, prbctlref_t *, void *); 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate /* sync up list of objects with that of the linker */ 229*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_lmap_update(tnfctl_handle_t *hndl, boolean_t *lmap_ok, 230*0Sstevel@tonic-gate enum event_op_t *evt); 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate /* sync up list of objects and probes */ 233*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_refresh_process(tnfctl_handle_t *, boolean_t *, 234*0Sstevel@tonic-gate enum event_op_t *); 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_set_state(tnfctl_handle_t *hndl); 237*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_create_tracefile(tnfctl_handle_t *hndl, 238*0Sstevel@tonic-gate const char *trace_file_name, uint_t trace_file_size); 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate /* probe interfaces */ 241*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_find_all_probes(tnfctl_handle_t *hndl); 242*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_probes_traverse(tnfctl_handle_t *hndl, 243*0Sstevel@tonic-gate _tnfctl_traverse_probe_func_t func_p, void *calldata_p); 244*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_flush_a_probe(tnfctl_handle_t *hndl, 245*0Sstevel@tonic-gate prbctlref_t *ref_p, size_t offset, size_t size); 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate /* combination interfaces */ 248*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_comb_build(tnfctl_handle_t *hndl, comb_op_t op, 249*0Sstevel@tonic-gate uintptr_t down, uintptr_t next, uintptr_t *comb_p); 250*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_comb_decode(tnfctl_handle_t *hndl, uintptr_t addr, 251*0Sstevel@tonic-gate char ***func_names, uintptr_t **func_addrs); 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate /* allocate memory in target process */ 254*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_targmem_alloc(tnfctl_handle_t *hndl, size_t size, 255*0Sstevel@tonic-gate uintptr_t *addr_p); 256*0Sstevel@tonic-gate 257*0Sstevel@tonic-gate /* inprocess "plug ins" for functions in tnfctl_handle_t structure */ 258*0Sstevel@tonic-gate int _tnfctl_read_targ(void *proc_p, uintptr_t addr, void *buf, size_t size); 259*0Sstevel@tonic-gate int _tnfctl_write_targ(void *proc_p, uintptr_t addr, void *buf, size_t size); 260*0Sstevel@tonic-gate int _tnfctl_loadobj_iter(void *proc_p, tnfctl_ind_obj_f *func, 261*0Sstevel@tonic-gate void *client_data); 262*0Sstevel@tonic-gate pid_t _tnfctl_pid_get(void *proc_p); 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate /* read a string from the target process */ 265*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_readstr_targ(tnfctl_handle_t *hndl, uintptr_t addr, 266*0Sstevel@tonic-gate char **outstr_pp); 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate /* symbol searching interfaces */ 269*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_sym_find_in_obj(int objfd, uintptr_t baseaddr, 270*0Sstevel@tonic-gate const char *symname, uintptr_t *symaddr); 271*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_sym_obj_find(tnfctl_handle_t *hndl, 272*0Sstevel@tonic-gate const char *lib_base_name, const char *symname, uintptr_t *symaddr); 273*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_sym_find(tnfctl_handle_t *hndl, const char *symname, 274*0Sstevel@tonic-gate uintptr_t *symaddr); 275*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_sym_findname(tnfctl_handle_t *hndl, uintptr_t symaddr, 276*0Sstevel@tonic-gate char **symname); 277*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_elf_dbgent(tnfctl_handle_t *hndl, 278*0Sstevel@tonic-gate uintptr_t * entaddr_p); 279*0Sstevel@tonic-gate 280*0Sstevel@tonic-gate /* free objs and probes */ 281*0Sstevel@tonic-gate void _tnfctl_free_objs_and_probes(tnfctl_handle_t *); 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* locking interfaces */ 284*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_lock_libs(tnfctl_handle_t *hndl, 285*0Sstevel@tonic-gate boolean_t *release_lock); 286*0Sstevel@tonic-gate void _tnfctl_unlock_libs(tnfctl_handle_t *hndl, boolean_t release_lock); 287*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_sync_lib_list(tnfctl_handle_t *hndl); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate /* 290*0Sstevel@tonic-gate * BugID 1253419 291*0Sstevel@tonic-gate * The flags that indicate if in/external trace control is active. 292*0Sstevel@tonic-gate * Used to prevent simultaneous internal and external probe control. 293*0Sstevel@tonic-gate * For external control keep pid of traced process to handle case 294*0Sstevel@tonic-gate * where process forks. (child is not under external control) 295*0Sstevel@tonic-gate */ 296*0Sstevel@tonic-gate #define TNFCTL_INTERNAL_TRACEFLAG "_tnfctl_internal_tracing_flag" 297*0Sstevel@tonic-gate #define TNFCTL_EXTERNAL_TRACEDPID "_tnfctl_externally_traced_pid" 298*0Sstevel@tonic-gate extern boolean_t _tnfctl_internal_tracing_flag; 299*0Sstevel@tonic-gate extern pid_t _tnfctl_externally_traced_pid; 300*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_internal_getlock(void); 301*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_external_getlock(tnfctl_handle_t *hndl); 302*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_internal_releaselock(void); 303*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_external_releaselock(tnfctl_handle_t *hndl); 304*0Sstevel@tonic-gate 305*0Sstevel@tonic-gate /* error mapping functions */ 306*0Sstevel@tonic-gate tnfctl_errcode_t _tnfctl_map_to_errcode(prb_status_t prbstat); 307*0Sstevel@tonic-gate tnfctl_errcode_t tnfctl_status_map(int); 308*0Sstevel@tonic-gate 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate /* 311*0Sstevel@tonic-gate * LOCK is the macro to lock down the library list so that a dlopen or 312*0Sstevel@tonic-gate * dlclose by another thread will block waiting for the lock to be released. 313*0Sstevel@tonic-gate * 314*0Sstevel@tonic-gate * LOCK_SYNC does the same as LOCK + it syncs up libtnfctl's cache of 315*0Sstevel@tonic-gate * libraries in target process with that of what the run time linker maintains. 316*0Sstevel@tonic-gate * 317*0Sstevel@tonic-gate * These macros do conditional locking because they are needed only by 318*0Sstevel@tonic-gate * INTERNAL_MODE clients. There are 2 versions of these macros so that 319*0Sstevel@tonic-gate * lock_lint won't have to see the conditional locking. 320*0Sstevel@tonic-gate * CAUTION: Be aware that these macros have a return() embedded in them. 321*0Sstevel@tonic-gate */ 322*0Sstevel@tonic-gate #ifdef __lock_lint 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate #define LOCK(hndl, stat, release) (void) _tnfctl_lock_libs(hndl, &release) 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate #define LOCK_SYNC(hndl, stat, release) \ 327*0Sstevel@tonic-gate (void) _tnfctl_lock_libs(hndl, &release); \ 328*0Sstevel@tonic-gate (void) _tnfctl_sync_lib_list(hndl) 329*0Sstevel@tonic-gate 330*0Sstevel@tonic-gate #define UNLOCK(hndl, release) _tnfctl_unlock_libs(hndl, release) 331*0Sstevel@tonic-gate 332*0Sstevel@tonic-gate #else 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate #define LOCK(hndl, stat, release) \ 335*0Sstevel@tonic-gate if (hndl->mode == INTERNAL_MODE) { \ 336*0Sstevel@tonic-gate stat = _tnfctl_lock_libs(hndl, &release); \ 337*0Sstevel@tonic-gate if (stat) \ 338*0Sstevel@tonic-gate return (stat); \ 339*0Sstevel@tonic-gate } \ 340*0Sstevel@tonic-gate else 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate #define LOCK_SYNC(hndl, stat, release) \ 343*0Sstevel@tonic-gate if (hndl->mode == INTERNAL_MODE) { \ 344*0Sstevel@tonic-gate stat = _tnfctl_lock_libs(hndl, &release); \ 345*0Sstevel@tonic-gate if (stat) \ 346*0Sstevel@tonic-gate return (stat); \ 347*0Sstevel@tonic-gate stat = _tnfctl_sync_lib_list(hndl); \ 348*0Sstevel@tonic-gate if (stat) { \ 349*0Sstevel@tonic-gate _tnfctl_unlock_libs(hndl, release); \ 350*0Sstevel@tonic-gate return (stat); \ 351*0Sstevel@tonic-gate } \ 352*0Sstevel@tonic-gate } \ 353*0Sstevel@tonic-gate else 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate #define UNLOCK(hndl, release) \ 356*0Sstevel@tonic-gate if (hndl->mode == INTERNAL_MODE) \ 357*0Sstevel@tonic-gate _tnfctl_unlock_libs(hndl, release_lock); \ 358*0Sstevel@tonic-gate else 359*0Sstevel@tonic-gate 360*0Sstevel@tonic-gate #endif 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate #ifdef __cplusplus 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate #endif 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate #endif /* _TNFCTL_INT_H */ 367