xref: /titanic_41/usr/src/lib/libtnfctl/sym.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1994, by Sun Microsytems, Inc.
24*7c478bd9Sstevel@tonic-gate  */
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*7c478bd9Sstevel@tonic-gate 
28*7c478bd9Sstevel@tonic-gate /*
29*7c478bd9Sstevel@tonic-gate  * Routines that
30*7c478bd9Sstevel@tonic-gate  *	- return an address for a symbol name
31*7c478bd9Sstevel@tonic-gate  *	- return a symbol name for an address
32*7c478bd9Sstevel@tonic-gate  */
33*7c478bd9Sstevel@tonic-gate 
34*7c478bd9Sstevel@tonic-gate #ifndef DEBUG
35*7c478bd9Sstevel@tonic-gate #define	NDEBUG	1
36*7c478bd9Sstevel@tonic-gate #endif
37*7c478bd9Sstevel@tonic-gate 
38*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
39*7c478bd9Sstevel@tonic-gate #include <unistd.h>
40*7c478bd9Sstevel@tonic-gate #include <string.h>
41*7c478bd9Sstevel@tonic-gate #include <errno.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/procfs.h>
43*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
44*7c478bd9Sstevel@tonic-gate #include <assert.h>
45*7c478bd9Sstevel@tonic-gate #include <note.h>
46*7c478bd9Sstevel@tonic-gate 
47*7c478bd9Sstevel@tonic-gate #include "tnfctl_int.h"
48*7c478bd9Sstevel@tonic-gate #include "dbg.h"
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate 
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * Typedefs
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate typedef struct sym_args {
56*7c478bd9Sstevel@tonic-gate 	char		*sa_name;
57*7c478bd9Sstevel@tonic-gate 	uintptr_t	sa_addr;
58*7c478bd9Sstevel@tonic-gate } sym_args_t;
59*7c478bd9Sstevel@tonic-gate NOTE(SCHEME_PROTECTS_DATA("always automatic", sym_args))
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate  * Declarations
63*7c478bd9Sstevel@tonic-gate  */
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t sym_findname_in_obj(int objfd, uintptr_t baseaddr,
66*7c478bd9Sstevel@tonic-gate 	uintptr_t symaddr, char **symname);
67*7c478bd9Sstevel@tonic-gate 
68*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t sym_match(char *name, uintptr_t addr, void *sym_entry,
69*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t *search_info_p);
70*7c478bd9Sstevel@tonic-gate 
71*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t sym_matchname(char *name, uintptr_t addr,
72*7c478bd9Sstevel@tonic-gate 	void *sym_entry,
73*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t *search_info_p);
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate 
76*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
77*7c478bd9Sstevel@tonic-gate /* ----------------------- Public Functions ----------------------- */
78*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
79*7c478bd9Sstevel@tonic-gate 
80*7c478bd9Sstevel@tonic-gate /*
81*7c478bd9Sstevel@tonic-gate  * _tnfctl_sym_find_in_obj() - determines the virtual address of the supplied
82*7c478bd9Sstevel@tonic-gate  * symbol in the object file specified by fd.
83*7c478bd9Sstevel@tonic-gate  */
84*7c478bd9Sstevel@tonic-gate tnfctl_errcode_t
_tnfctl_sym_find_in_obj(int objfd,uintptr_t baseaddr,const char * symname,uintptr_t * symaddr)85*7c478bd9Sstevel@tonic-gate _tnfctl_sym_find_in_obj(int objfd, uintptr_t baseaddr, const char *symname,
86*7c478bd9Sstevel@tonic-gate 		uintptr_t *symaddr)
87*7c478bd9Sstevel@tonic-gate {
88*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	prexstat = TNFCTL_ERR_NONE;
89*7c478bd9Sstevel@tonic-gate 	sym_args_t		symargs;
90*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t	search_info;
91*7c478bd9Sstevel@tonic-gate 
92*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_1(_tnfctl_sym_find_in_obj_1, "libtnfctl",
93*7c478bd9Sstevel@tonic-gate 			"sunw%verbosity 3",
94*7c478bd9Sstevel@tonic-gate 			tnf_string, searching_for, symname);
95*7c478bd9Sstevel@tonic-gate 
96*7c478bd9Sstevel@tonic-gate 	symargs.sa_name = (char *) symname;
97*7c478bd9Sstevel@tonic-gate 	/* clear output argument in advance */
98*7c478bd9Sstevel@tonic-gate 	symargs.sa_addr = 0;
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate 	search_info.section_func = _tnfctl_traverse_dynsym;
101*7c478bd9Sstevel@tonic-gate 	search_info.record_func = sym_match;
102*7c478bd9Sstevel@tonic-gate 	search_info.record_data = &symargs;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate 	prexstat = _tnfctl_traverse_object(objfd, baseaddr, &search_info);
105*7c478bd9Sstevel@tonic-gate 	if (prexstat)
106*7c478bd9Sstevel@tonic-gate 		return (prexstat);
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	/* check if we found symbol address */
109*7c478bd9Sstevel@tonic-gate 	if (symargs.sa_addr == 0) {
110*7c478bd9Sstevel@tonic-gate 		return (TNFCTL_ERR_BADARG);
111*7c478bd9Sstevel@tonic-gate 	}
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate 	*symaddr = symargs.sa_addr;
114*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
115*7c478bd9Sstevel@tonic-gate }
116*7c478bd9Sstevel@tonic-gate 
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate /*
119*7c478bd9Sstevel@tonic-gate  * _tnfctl_sym_find() - determines the virtual address of the supplied symbol
120*7c478bd9Sstevel@tonic-gate  * in the process.
121*7c478bd9Sstevel@tonic-gate  */
122*7c478bd9Sstevel@tonic-gate tnfctl_errcode_t
_tnfctl_sym_find(tnfctl_handle_t * hndl,const char * symname,uintptr_t * symaddr)123*7c478bd9Sstevel@tonic-gate _tnfctl_sym_find(tnfctl_handle_t *hndl, const char *symname, uintptr_t *symaddr)
124*7c478bd9Sstevel@tonic-gate {
125*7c478bd9Sstevel@tonic-gate 	boolean_t	release_lock;
126*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	prexstat = TNFCTL_ERR_NONE;
127*7c478bd9Sstevel@tonic-gate 	objlist_t	*obj;
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_1(_tnfctl_sym_find_start, "libtnfctl",
130*7c478bd9Sstevel@tonic-gate 			"start _tnfctl_sym_find; sunw%verbosity 3",
131*7c478bd9Sstevel@tonic-gate 			tnf_string, searching_for, symname);
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 	/*LINTED statement has no consequent: else*/
134*7c478bd9Sstevel@tonic-gate 	LOCK(hndl, prexstat, release_lock);
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 	/* for every object in list, search for symbol */
137*7c478bd9Sstevel@tonic-gate 	for (obj = hndl->objlist; obj; obj = obj->next) {
138*7c478bd9Sstevel@tonic-gate 		if (obj->old == B_TRUE)
139*7c478bd9Sstevel@tonic-gate 			continue;	/* don't examine dlclose'd libs */
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 		/* return value of TNFCTL_ERR_BADARG means symbol not found */
142*7c478bd9Sstevel@tonic-gate 		prexstat = _tnfctl_sym_find_in_obj(obj->objfd,
143*7c478bd9Sstevel@tonic-gate 			obj->baseaddr, symname, symaddr);
144*7c478bd9Sstevel@tonic-gate 		if (prexstat == TNFCTL_ERR_NONE)
145*7c478bd9Sstevel@tonic-gate 			/* symbol found */
146*7c478bd9Sstevel@tonic-gate 			break;
147*7c478bd9Sstevel@tonic-gate 		else if (prexstat != TNFCTL_ERR_BADARG)
148*7c478bd9Sstevel@tonic-gate 			/* error condition */
149*7c478bd9Sstevel@tonic-gate 			break;
150*7c478bd9Sstevel@tonic-gate 		/* continue loop on TNFCTL_ERR_BADARG */
151*7c478bd9Sstevel@tonic-gate 	}
152*7c478bd9Sstevel@tonic-gate 
153*7c478bd9Sstevel@tonic-gate 	/*LINTED statement has no consequent: else*/
154*7c478bd9Sstevel@tonic-gate 	UNLOCK(hndl, release_lock);
155*7c478bd9Sstevel@tonic-gate 
156*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_0(_tnfctl_sym_find_end, "libtnfctl",
157*7c478bd9Sstevel@tonic-gate 			"end _tnfctl_sym_find; sunw%verbosity 3");
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate 	return (prexstat);
160*7c478bd9Sstevel@tonic-gate }
161*7c478bd9Sstevel@tonic-gate 
162*7c478bd9Sstevel@tonic-gate /*
163*7c478bd9Sstevel@tonic-gate  * _tnfctl_sym_obj_find() - determines the virtual address of the supplied
164*7c478bd9Sstevel@tonic-gate  *	symbol in the object specified by base name
165*7c478bd9Sstevel@tonic-gate  */
166*7c478bd9Sstevel@tonic-gate tnfctl_errcode_t
_tnfctl_sym_obj_find(tnfctl_handle_t * hndl,const char * lib_base_name,const char * symname,uintptr_t * symaddr)167*7c478bd9Sstevel@tonic-gate _tnfctl_sym_obj_find(tnfctl_handle_t *hndl, const char *lib_base_name,
168*7c478bd9Sstevel@tonic-gate 	const char *symname, uintptr_t *symaddr)
169*7c478bd9Sstevel@tonic-gate {
170*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	prexstat = TNFCTL_ERR_NONE;
171*7c478bd9Sstevel@tonic-gate 	objlist_t	*obj, *found_obj;
172*7c478bd9Sstevel@tonic-gate 	const char *str_ptr;
173*7c478bd9Sstevel@tonic-gate 
174*7c478bd9Sstevel@tonic-gate 	assert((hndl->mode == INTERNAL_MODE) ?
175*7c478bd9Sstevel@tonic-gate 		(MUTEX_HELD(&_tnfctl_lmap_lock)) : 1);
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_1(_tnfctl_sym_obj_find_start, "libtnfctl",
178*7c478bd9Sstevel@tonic-gate 			"start _tnfctl_sym_obj_find; sunw%verbosity 3",
179*7c478bd9Sstevel@tonic-gate 			tnf_string, searching_for, symname);
180*7c478bd9Sstevel@tonic-gate 
181*7c478bd9Sstevel@tonic-gate 	found_obj = NULL;
182*7c478bd9Sstevel@tonic-gate 	/* for every object in list ... */
183*7c478bd9Sstevel@tonic-gate 	for (obj = hndl->objlist; obj; obj = obj->next) {
184*7c478bd9Sstevel@tonic-gate 		if (obj->old == B_TRUE)
185*7c478bd9Sstevel@tonic-gate 			continue;	/* don't examine dlclose'd libs */
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 		if (obj->objname == NULL)
188*7c478bd9Sstevel@tonic-gate 			continue;
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 		/* find the last occurrence of / in the name */
191*7c478bd9Sstevel@tonic-gate 		str_ptr = strrchr(obj->objname, '/');
192*7c478bd9Sstevel@tonic-gate 		if (str_ptr == NULL) {
193*7c478bd9Sstevel@tonic-gate 			str_ptr = obj->objname;
194*7c478bd9Sstevel@tonic-gate 		} else {
195*7c478bd9Sstevel@tonic-gate 			str_ptr++;	/* bump up past '/' */
196*7c478bd9Sstevel@tonic-gate 		}
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 		/* XXX - use strcoll ? */
199*7c478bd9Sstevel@tonic-gate 		if (strcmp(str_ptr, lib_base_name) == 0) {
200*7c478bd9Sstevel@tonic-gate 			found_obj = obj;
201*7c478bd9Sstevel@tonic-gate 			break;
202*7c478bd9Sstevel@tonic-gate 		}
203*7c478bd9Sstevel@tonic-gate 	}
204*7c478bd9Sstevel@tonic-gate 	/* return value of TNFCTL_ERR_BADARG means symbol not found */
205*7c478bd9Sstevel@tonic-gate 	if (found_obj == NULL)
206*7c478bd9Sstevel@tonic-gate 		return (TNFCTL_ERR_BADARG);
207*7c478bd9Sstevel@tonic-gate 
208*7c478bd9Sstevel@tonic-gate 	prexstat = _tnfctl_sym_find_in_obj(found_obj->objfd,
209*7c478bd9Sstevel@tonic-gate 			found_obj->baseaddr, symname, symaddr);
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_0(_tnfctl_sym_obj_find_end, "libtnfctl",
212*7c478bd9Sstevel@tonic-gate 			"end _tnfctl_sym_obj_find; sunw%verbosity 3");
213*7c478bd9Sstevel@tonic-gate 
214*7c478bd9Sstevel@tonic-gate 	return (prexstat);
215*7c478bd9Sstevel@tonic-gate }
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate /*
218*7c478bd9Sstevel@tonic-gate  * _tnfctl_sym_findname() - determines the name of a function from its address.
219*7c478bd9Sstevel@tonic-gate  */
220*7c478bd9Sstevel@tonic-gate tnfctl_errcode_t
_tnfctl_sym_findname(tnfctl_handle_t * hndl,uintptr_t symaddr,char ** symname)221*7c478bd9Sstevel@tonic-gate _tnfctl_sym_findname(tnfctl_handle_t *hndl, uintptr_t symaddr,
222*7c478bd9Sstevel@tonic-gate 	char **symname)
223*7c478bd9Sstevel@tonic-gate {
224*7c478bd9Sstevel@tonic-gate 	boolean_t	release_lock;
225*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	prexstat = TNFCTL_ERR_NONE;
226*7c478bd9Sstevel@tonic-gate 	objlist_t	*obj;
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_1(_tnfctl_sym_findname_start, "libtnfctl",
229*7c478bd9Sstevel@tonic-gate 			"start _tnfctl_sym_findname; sunw%verbosity 3",
230*7c478bd9Sstevel@tonic-gate 			tnf_opaque, searching_for, symaddr);
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate 	/*LINTED statement has no consequent: else*/
233*7c478bd9Sstevel@tonic-gate 	LOCK(hndl, prexstat, release_lock);
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	/* for every object in list, search for name */
236*7c478bd9Sstevel@tonic-gate 	for (obj = hndl->objlist; obj; obj = obj->next) {
237*7c478bd9Sstevel@tonic-gate 		if (obj->old == B_TRUE)
238*7c478bd9Sstevel@tonic-gate 			continue;	/* don't examine dlclose'd libs */
239*7c478bd9Sstevel@tonic-gate 		/* return value of TNFCTL_ERR_BADARG means symbol not found */
240*7c478bd9Sstevel@tonic-gate 		prexstat = sym_findname_in_obj(obj->objfd,
241*7c478bd9Sstevel@tonic-gate 			obj->baseaddr, symaddr, symname);
242*7c478bd9Sstevel@tonic-gate 		if (prexstat == TNFCTL_ERR_NONE)
243*7c478bd9Sstevel@tonic-gate 			/* symbol found */
244*7c478bd9Sstevel@tonic-gate 			break;
245*7c478bd9Sstevel@tonic-gate 		else if (prexstat != TNFCTL_ERR_BADARG)
246*7c478bd9Sstevel@tonic-gate 			/* error condition */
247*7c478bd9Sstevel@tonic-gate 			break;
248*7c478bd9Sstevel@tonic-gate 		/* continue loop on TNFCTL_ERR_BADARG */
249*7c478bd9Sstevel@tonic-gate 	}
250*7c478bd9Sstevel@tonic-gate 
251*7c478bd9Sstevel@tonic-gate 	/*LINTED statement has no consequent: else*/
252*7c478bd9Sstevel@tonic-gate 	UNLOCK(hndl, release_lock);
253*7c478bd9Sstevel@tonic-gate 
254*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_0(_tnfctl_sym_findname_end, "libtnfctl",
255*7c478bd9Sstevel@tonic-gate 			"end _tnfctl_sym_findname; sunw%verbosity 3");
256*7c478bd9Sstevel@tonic-gate 
257*7c478bd9Sstevel@tonic-gate 	return (prexstat);
258*7c478bd9Sstevel@tonic-gate }
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 
261*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
262*7c478bd9Sstevel@tonic-gate /* ----------------------- Private Functions ---------------------- */
263*7c478bd9Sstevel@tonic-gate /* ---------------------------------------------------------------- */
264*7c478bd9Sstevel@tonic-gate 
265*7c478bd9Sstevel@tonic-gate /*
266*7c478bd9Sstevel@tonic-gate  * sym_findname_in_obj() - determines the name of the supplied
267*7c478bd9Sstevel@tonic-gate  * address in the specified object file.
268*7c478bd9Sstevel@tonic-gate  */
269*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t
sym_findname_in_obj(int objfd,uintptr_t baseaddr,uintptr_t symaddr,char ** symname)270*7c478bd9Sstevel@tonic-gate sym_findname_in_obj(int objfd, uintptr_t baseaddr, uintptr_t symaddr,
271*7c478bd9Sstevel@tonic-gate 	char **symname)
272*7c478bd9Sstevel@tonic-gate {
273*7c478bd9Sstevel@tonic-gate 	tnfctl_errcode_t	prexstat = TNFCTL_ERR_NONE;
274*7c478bd9Sstevel@tonic-gate 	sym_args_t	symargs;
275*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t	search_info;
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 	DBG_TNF_PROBE_1(sym_findname_in_obj_1, "libtnfctl",
278*7c478bd9Sstevel@tonic-gate 			"sunw%verbosity 3",
279*7c478bd9Sstevel@tonic-gate 			tnf_opaque, searching_for, symaddr);
280*7c478bd9Sstevel@tonic-gate 
281*7c478bd9Sstevel@tonic-gate 	/* clear output argument in advance */
282*7c478bd9Sstevel@tonic-gate 	symargs.sa_name = NULL;
283*7c478bd9Sstevel@tonic-gate 	symargs.sa_addr = symaddr;
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	search_info.section_func = _tnfctl_traverse_dynsym;
286*7c478bd9Sstevel@tonic-gate 	search_info.record_func = sym_matchname;
287*7c478bd9Sstevel@tonic-gate 	search_info.record_data = &symargs;
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate 	prexstat = _tnfctl_traverse_object(objfd, baseaddr, &search_info);
290*7c478bd9Sstevel@tonic-gate 	if (prexstat)
291*7c478bd9Sstevel@tonic-gate 		return (prexstat);
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 	/* check if we found symbol address */
294*7c478bd9Sstevel@tonic-gate 	if (symargs.sa_name == NULL) {
295*7c478bd9Sstevel@tonic-gate 		return (TNFCTL_ERR_BADARG);
296*7c478bd9Sstevel@tonic-gate 	}
297*7c478bd9Sstevel@tonic-gate 
298*7c478bd9Sstevel@tonic-gate 	*symname = symargs.sa_name;
299*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
300*7c478bd9Sstevel@tonic-gate }
301*7c478bd9Sstevel@tonic-gate 
302*7c478bd9Sstevel@tonic-gate /*
303*7c478bd9Sstevel@tonic-gate  * sym_match() - function to be called on each symbol in a dynsym section.
304*7c478bd9Sstevel@tonic-gate  *		Used to find the address of a symbol.
305*7c478bd9Sstevel@tonic-gate  */
306*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t
sym_match(char * name,uintptr_t addr,void * sym_entry,tnfctl_elf_search_t * search_info_p)307*7c478bd9Sstevel@tonic-gate sym_match(char *name, uintptr_t addr, void *sym_entry,
308*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t *search_info_p)
309*7c478bd9Sstevel@tonic-gate {
310*7c478bd9Sstevel@tonic-gate 	sym_args_t	*symargs_p = (sym_args_t *) search_info_p->record_data;
311*7c478bd9Sstevel@tonic-gate 	Elf3264_Sym	*sym = (Elf3264_Sym *) sym_entry;
312*7c478bd9Sstevel@tonic-gate #if 0
313*7c478bd9Sstevel@tonic-gate 	printf("enter sym_match: \n");
314*7c478bd9Sstevel@tonic-gate 	if (symargs_p->sa_name != 0)
315*7c478bd9Sstevel@tonic-gate 		printf("(symargs_p->sa_name) = %s\n", symargs_p->sa_name);
316*7c478bd9Sstevel@tonic-gate 	else
317*7c478bd9Sstevel@tonic-gate 		printf("symargs_p->sa_name = 0\n");
318*7c478bd9Sstevel@tonic-gate 	if (name != 0)
319*7c478bd9Sstevel@tonic-gate 		printf("(name) = %s\n", name);
320*7c478bd9Sstevel@tonic-gate 	else
321*7c478bd9Sstevel@tonic-gate 		printf("name = 0\n");
322*7c478bd9Sstevel@tonic-gate #endif
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate #ifdef VERYVERBOSE
325*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "sym_match: checking \"%s\"\n", name);
326*7c478bd9Sstevel@tonic-gate #endif
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 	if ((sym->st_shndx != SHN_UNDEF) &&
329*7c478bd9Sstevel@tonic-gate 			(strcmp(name, symargs_p->sa_name) == 0)) {
330*7c478bd9Sstevel@tonic-gate 
331*7c478bd9Sstevel@tonic-gate 		DBG_TNF_PROBE_2(sym_match_1, "libtnfctl",
332*7c478bd9Sstevel@tonic-gate 			"sunw%verbosity 2; sunw%debug '\tMatched Symbol'",
333*7c478bd9Sstevel@tonic-gate 			tnf_string, symbol, name,
334*7c478bd9Sstevel@tonic-gate 			tnf_opaque, address_found, addr);
335*7c478bd9Sstevel@tonic-gate 
336*7c478bd9Sstevel@tonic-gate 		symargs_p->sa_addr = addr;
337*7c478bd9Sstevel@tonic-gate 	}
338*7c478bd9Sstevel@tonic-gate #if 0
339*7c478bd9Sstevel@tonic-gate 	printf("leaving sym_match\n");
340*7c478bd9Sstevel@tonic-gate #endif
341*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
342*7c478bd9Sstevel@tonic-gate }
343*7c478bd9Sstevel@tonic-gate 
344*7c478bd9Sstevel@tonic-gate 
345*7c478bd9Sstevel@tonic-gate /*
346*7c478bd9Sstevel@tonic-gate  * sym_matchname() - function to be called on each symbol in a dynsym
347*7c478bd9Sstevel@tonic-gate  * section. Used to find the name of a symbol whose address is known.
348*7c478bd9Sstevel@tonic-gate  */
349*7c478bd9Sstevel@tonic-gate static tnfctl_errcode_t
sym_matchname(char * name,uintptr_t addr,void * sym_entry,tnfctl_elf_search_t * search_info_p)350*7c478bd9Sstevel@tonic-gate sym_matchname(char *name, uintptr_t addr, void *sym_entry,
351*7c478bd9Sstevel@tonic-gate 	tnfctl_elf_search_t * search_info_p)
352*7c478bd9Sstevel@tonic-gate {
353*7c478bd9Sstevel@tonic-gate 	sym_args_t	*symargs_p = (sym_args_t *) search_info_p->record_data;
354*7c478bd9Sstevel@tonic-gate 	Elf3264_Sym	*sym = (Elf3264_Sym *) sym_entry;
355*7c478bd9Sstevel@tonic-gate 
356*7c478bd9Sstevel@tonic-gate #ifdef VERYVERBOSE
357*7c478bd9Sstevel@tonic-gate 	(void) fprintf(stderr, "sym_matchname: checking \"%s\"\n", name);
358*7c478bd9Sstevel@tonic-gate #endif
359*7c478bd9Sstevel@tonic-gate 
360*7c478bd9Sstevel@tonic-gate 	if ((sym->st_shndx != SHN_UNDEF) &&
361*7c478bd9Sstevel@tonic-gate 			symargs_p->sa_addr == addr) {
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 		DBG_TNF_PROBE_2(sym_matchname_1, "libtnfctl",
364*7c478bd9Sstevel@tonic-gate 			"sunw%verbosity 2; sunw%debug '\tMatched Name'",
365*7c478bd9Sstevel@tonic-gate 			tnf_string, symbol_found, name,
366*7c478bd9Sstevel@tonic-gate 			tnf_opaque, address, addr);
367*7c478bd9Sstevel@tonic-gate 
368*7c478bd9Sstevel@tonic-gate 		symargs_p->sa_name = strdup(name);
369*7c478bd9Sstevel@tonic-gate 	}
370*7c478bd9Sstevel@tonic-gate 
371*7c478bd9Sstevel@tonic-gate 	return (TNFCTL_ERR_NONE);
372*7c478bd9Sstevel@tonic-gate }
373