1*98c080d5SRod Evans /*
2*98c080d5SRod Evans  * CDDL HEADER START
3*98c080d5SRod Evans  *
4*98c080d5SRod Evans  * The contents of this file are subject to the terms of the
5*98c080d5SRod Evans  * Common Development and Distribution License (the "License").
6*98c080d5SRod Evans  * You may not use this file except in compliance with the License.
7*98c080d5SRod Evans  *
8*98c080d5SRod Evans  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*98c080d5SRod Evans  * or http://www.opensolaris.org/os/licensing.
10*98c080d5SRod Evans  * See the License for the specific language governing permissions
11*98c080d5SRod Evans  * and limitations under the License.
12*98c080d5SRod Evans  *
13*98c080d5SRod Evans  * When distributing Covered Code, include this CDDL HEADER in each
14*98c080d5SRod Evans  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*98c080d5SRod Evans  * If applicable, add the following below this CDDL HEADER, with the
16*98c080d5SRod Evans  * fields enclosed by brackets "[]" replaced with your own identifying
17*98c080d5SRod Evans  * information: Portions Copyright [yyyy] [name of copyright owner]
18*98c080d5SRod Evans  *
19*98c080d5SRod Evans  * CDDL HEADER END
20*98c080d5SRod Evans  */
21*98c080d5SRod Evans 
22*98c080d5SRod Evans /*
23*98c080d5SRod Evans  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
24*98c080d5SRod Evans  * Use is subject to license terms.
25*98c080d5SRod Evans  */
26*98c080d5SRod Evans 
27*98c080d5SRod Evans #include	"msg.h"
28*98c080d5SRod Evans #include	"_debug.h"
29*98c080d5SRod Evans #include	"libld.h"
30*98c080d5SRod Evans 
31*98c080d5SRod Evans void
Dbg_dl_iphdr_enter(Rt_map * clmp,u_longlong_t cnt_map,u_longlong_t cnt_unmap)32*98c080d5SRod Evans Dbg_dl_iphdr_enter(Rt_map *clmp, u_longlong_t cnt_map, u_longlong_t cnt_unmap)
33*98c080d5SRod Evans {
34*98c080d5SRod Evans 	Lm_list	*lml = LIST(clmp);
35*98c080d5SRod Evans 
36*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
37*98c080d5SRod Evans 		return;
38*98c080d5SRod Evans 
39*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
40*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_ENTER), NAME(clmp));
41*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNT), cnt_map, cnt_unmap);
42*98c080d5SRod Evans }
43*98c080d5SRod Evans 
44*98c080d5SRod Evans void
Dbg_dl_iphdr_callback(Lm_list * lml,struct dl_phdr_info * info)45*98c080d5SRod Evans Dbg_dl_iphdr_callback(Lm_list *lml, struct dl_phdr_info *info)
46*98c080d5SRod Evans {
47*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
48*98c080d5SRod Evans 		return;
49*98c080d5SRod Evans 
50*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_CALLBACK));
51*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_NAME), info->dlpi_name);
52*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_ADDR), EC_ADDR(info->dlpi_addr));
53*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_PHDR),
54*98c080d5SRod Evans 	    EC_ADDR(CAST_PTRINT(Addr, info->dlpi_phdr)),
55*98c080d5SRod Evans 	    EC_WORD(info->dlpi_phnum));
56*98c080d5SRod Evans }
57*98c080d5SRod Evans 
58*98c080d5SRod Evans void
Dbg_dl_iphdr_mapchange(Lm_list * lml,u_longlong_t cnt_map,u_longlong_t cnt_unmap)59*98c080d5SRod Evans Dbg_dl_iphdr_mapchange(Lm_list *lml, u_longlong_t cnt_map,
60*98c080d5SRod Evans     u_longlong_t cnt_unmap)
61*98c080d5SRod Evans {
62*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
63*98c080d5SRod Evans 		return;
64*98c080d5SRod Evans 
65*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNG));
66*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_MAPCNT), cnt_map, cnt_unmap);
67*98c080d5SRod Evans }
68*98c080d5SRod Evans 
69*98c080d5SRod Evans void
Dbg_dl_iphdr_unmap_ret(Lm_list * lml)70*98c080d5SRod Evans Dbg_dl_iphdr_unmap_ret(Lm_list *lml)
71*98c080d5SRod Evans {
72*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
73*98c080d5SRod Evans 		return;
74*98c080d5SRod Evans 
75*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_IPHDR_UNMAP));
76*98c080d5SRod Evans }
77*98c080d5SRod Evans 
78*98c080d5SRod Evans void
Dbg_dl_dlopen(Rt_map * clmp,const char * name,int * in_nfavl,int mode)79*98c080d5SRod Evans Dbg_dl_dlopen(Rt_map *clmp, const char *name, int *in_nfavl, int mode)
80*98c080d5SRod Evans {
81*98c080d5SRod Evans 	Conv_dl_mode_buf_t	dl_mode_buf;
82*98c080d5SRod Evans 	Lm_list			*lml = LIST(clmp);
83*98c080d5SRod Evans 	const char		*retry;
84*98c080d5SRod Evans 
85*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL))
86*98c080d5SRod Evans 		return;
87*98c080d5SRod Evans 
88*98c080d5SRod Evans 	/*
89*98c080d5SRod Evans 	 * The core functionality of dlopen() can be called twice.  The first
90*98c080d5SRod Evans 	 * attempt can be affected by path names that exist in the "not-found"
91*98c080d5SRod Evans 	 * AVL tree.  Should a "not-found" path name be found, a second attempt
92*98c080d5SRod Evans 	 * is made to locate the required file (in_nfavl is NULL).  This fall-
93*98c080d5SRod Evans 	 * back provides for file system changes while a process executes.
94*98c080d5SRod Evans 	 */
95*98c080d5SRod Evans 	if (in_nfavl)
96*98c080d5SRod Evans 		retry = MSG_ORIG(MSG_STR_EMPTY);
97*98c080d5SRod Evans 	else
98*98c080d5SRod Evans 		retry = MSG_INTL(MSG_STR_RETRY);
99*98c080d5SRod Evans 
100*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
101*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLOPEN), name, NAME(clmp), retry,
102*98c080d5SRod Evans 	    conv_dl_mode(mode, 0, &dl_mode_buf));
103*98c080d5SRod Evans }
104*98c080d5SRod Evans 
105*98c080d5SRod Evans void
Dbg_dl_dlclose(Rt_map * clmp,const char * name,int flag)106*98c080d5SRod Evans Dbg_dl_dlclose(Rt_map *clmp, const char *name, int flag)
107*98c080d5SRod Evans {
108*98c080d5SRod Evans 	const char	*str;
109*98c080d5SRod Evans 	Lm_list		*lml = LIST(clmp);
110*98c080d5SRod Evans 
111*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL))
112*98c080d5SRod Evans 		return;
113*98c080d5SRod Evans 
114*98c080d5SRod Evans 	if (flag == DBG_DLCLOSE_IGNORE)
115*98c080d5SRod Evans 		str = MSG_INTL(MSG_STR_IGNORE);
116*98c080d5SRod Evans 	else
117*98c080d5SRod Evans 		str = MSG_ORIG(MSG_STR_EMPTY);
118*98c080d5SRod Evans 
119*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
120*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLCLOSE), name, NAME(clmp), str);
121*98c080d5SRod Evans }
122*98c080d5SRod Evans 
123*98c080d5SRod Evans void
Dbg_dl_dldump(Rt_map * clmp,const char * ipath,const char * opath,int flags)124*98c080d5SRod Evans Dbg_dl_dldump(Rt_map *clmp, const char *ipath, const char *opath, int flags)
125*98c080d5SRod Evans {
126*98c080d5SRod Evans 	Conv_dl_flag_buf_t	dl_flag_buf;
127*98c080d5SRod Evans 	Lm_list			*lml = LIST(clmp);
128*98c080d5SRod Evans 
129*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_FILES | DBG_C_DL))
130*98c080d5SRod Evans 		return;
131*98c080d5SRod Evans 
132*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
133*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLDUMP), ipath, NAME(clmp),
134*98c080d5SRod Evans 	    opath ? opath : MSG_INTL(MSG_STR_NULL),
135*98c080d5SRod Evans 	    conv_dl_flag(flags, 0, &dl_flag_buf));
136*98c080d5SRod Evans }
137*98c080d5SRod Evans 
138*98c080d5SRod Evans void
Dbg_dl_dlerror(Rt_map * clmp,const char * str)139*98c080d5SRod Evans Dbg_dl_dlerror(Rt_map *clmp, const char *str)
140*98c080d5SRod Evans {
141*98c080d5SRod Evans 	Lm_list	*lml = LIST(clmp);
142*98c080d5SRod Evans 
143*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
144*98c080d5SRod Evans 		return;
145*98c080d5SRod Evans 
146*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
147*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLERROR), NAME(clmp),
148*98c080d5SRod Evans 	    str ? str : MSG_INTL(MSG_STR_NULL));
149*98c080d5SRod Evans }
150*98c080d5SRod Evans 
151*98c080d5SRod Evans void
Dbg_dl_dladdr(Rt_map * clmp,void * addr)152*98c080d5SRod Evans Dbg_dl_dladdr(Rt_map *clmp, void *addr)
153*98c080d5SRod Evans {
154*98c080d5SRod Evans 	Lm_list	*lml = LIST(clmp);
155*98c080d5SRod Evans 
156*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
157*98c080d5SRod Evans 		return;
158*98c080d5SRod Evans 
159*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
160*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLADDR), NAME(clmp), EC_NATPTR(addr));
161*98c080d5SRod Evans }
162*98c080d5SRod Evans 
163*98c080d5SRod Evans void
Dbg_dl_dlsym(Rt_map * clmp,const char * sym,int * in_nfavl,const char * next,int type)164*98c080d5SRod Evans Dbg_dl_dlsym(Rt_map *clmp, const char *sym, int *in_nfavl, const char *next,
165*98c080d5SRod Evans     int type)
166*98c080d5SRod Evans {
167*98c080d5SRod Evans 	const char	*str, *retry, *from = NAME(clmp);
168*98c080d5SRod Evans 	Lm_list		*lml = LIST(clmp);
169*98c080d5SRod Evans 
170*98c080d5SRod Evans 	static const Msg	dlsym_msg[DBG_DLSYM_NUM] = {
171*98c080d5SRod Evans 		MSG_STR_EMPTY,		/* MSG_ORIG(MSG_STR_EMPTY) */
172*98c080d5SRod Evans 		MSG_DLSYM_NEXT,		/* MSG_ORIG(MSG_DLSYM_NEXT) */
173*98c080d5SRod Evans 		MSG_DLSYM_DEFAULT,	/* MSG_ORIG(MSG_DLSYM_DEFAULT) */
174*98c080d5SRod Evans 		MSG_DLSYM_SELF,		/* MSG_ORIG(MSG_DLSYM_SELF) */
175*98c080d5SRod Evans 		MSG_DLSYM_PROBE,	/* MSG_ORIG(MSG_DLSYM_PROBE) */
176*98c080d5SRod Evans 		MSG_DLSYM_SINGLETON	/* MSG_ORIG(MSG_DLSYM_SINGLETON) */
177*98c080d5SRod Evans 	};
178*98c080d5SRod Evans #if	DBG_DLSYM_NUM != (DBG_DLSYM_SINGLETON + 1)
179*98c080d5SRod Evans #error	DBG_DLSYM_NUM has grown
180*98c080d5SRod Evans #endif
181*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_SYMBOLS | DBG_C_DL))
182*98c080d5SRod Evans 		return;
183*98c080d5SRod Evans 
184*98c080d5SRod Evans 	/*
185*98c080d5SRod Evans 	 * The core functionality of dlsym() can be called twice.  The first
186*98c080d5SRod Evans 	 * attempt can be affected by path names that exist in the "not-found"
187*98c080d5SRod Evans 	 * AVL tree.  Should a "not-found" path name be found, a second attempt
188*98c080d5SRod Evans 	 * is made to locate the required file (in_nfavl is NULL).  This fall-
189*98c080d5SRod Evans 	 * back provides for file system changes while a process executes.
190*98c080d5SRod Evans 	 */
191*98c080d5SRod Evans 	if (in_nfavl)
192*98c080d5SRod Evans 		retry = MSG_ORIG(MSG_STR_EMPTY);
193*98c080d5SRod Evans 	else
194*98c080d5SRod Evans 		retry = MSG_INTL(MSG_STR_RETRY);
195*98c080d5SRod Evans 
196*98c080d5SRod Evans 	if (type >= DBG_DLSYM_NUM)
197*98c080d5SRod Evans 		type = 0;
198*98c080d5SRod Evans 	str = MSG_ORIG(dlsym_msg[type]);
199*98c080d5SRod Evans 
200*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
201*98c080d5SRod Evans 	if (next == 0)
202*98c080d5SRod Evans 		dbg_print(lml, MSG_INTL(MSG_DLSYM_1), Dbg_demangle_name(sym),
203*98c080d5SRod Evans 		    from, retry, str);
204*98c080d5SRod Evans 	else
205*98c080d5SRod Evans 		dbg_print(lml, MSG_INTL(MSG_DLSYM_2), Dbg_demangle_name(sym),
206*98c080d5SRod Evans 		    from, next, retry, str);
207*98c080d5SRod Evans }
208*98c080d5SRod Evans 
209*98c080d5SRod Evans void
Dbg_dl_dlinfo(Rt_map * clmp,const char * name,int request,void * addr)210*98c080d5SRod Evans Dbg_dl_dlinfo(Rt_map *clmp, const char *name, int request, void *addr)
211*98c080d5SRod Evans {
212*98c080d5SRod Evans 	Lm_list	*lml = LIST(clmp);
213*98c080d5SRod Evans 
214*98c080d5SRod Evans 	if (DBG_NOTCLASS(DBG_C_DL))
215*98c080d5SRod Evans 		return;
216*98c080d5SRod Evans 
217*98c080d5SRod Evans 	Dbg_util_nl(lml, DBG_NL_STD);
218*98c080d5SRod Evans 	dbg_print(lml, MSG_INTL(MSG_DL_DLINFO), NAME(clmp), name,
219*98c080d5SRod Evans 	    conv_dl_info(request), EC_NATPTR(addr));
220*98c080d5SRod Evans }
221