4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
32 #include <proc_service.h>
38 #include <sys/param.h>
41 * Mutex to protect global data
43 mutex_t glob_mutex
= DEFAULTMUTEX
;
44 int rtld_db_version
= RD_VERSION1
;
45 int rtld_db_logging
= 0;
46 char rtld_db_helper_path
[MAXPATHLEN
];
50 rd_log(const int on_off
)
52 (void) mutex_lock(&glob_mutex
);
53 rtld_db_logging
= on_off
;
54 (void) mutex_unlock(&glob_mutex
);
55 LOG(ps_plog(MSG_ORIG(MSG_DB_LOGENABLE
)));
61 * The following have been added as the versions of librtld_db
68 * o added support for the use of the AT_SUN_LDBASE auxvector
69 * to find the initialial debugging (r_debug) structures
71 * o added the rl_dynamic field to rd_loadobj_t
72 * o added the RD_FLG_MEM_OBJECT to be used with the
73 * rl_dynamic->rl_flags field.
76 * o added the following fields/flags to the rd_plt_info_t
78 * pi_baddr - bound address of PLT (if bound)
79 * pi_flags - flag field
80 * RD_FLG_PI_PLTBOUND (flag for pi_flags)
81 * if set - the PLT is bound and pi_baddr
82 * is filled in with the destination of the PLT.
85 * o added the following field to the rd_loadobj_t structure:
86 * rl_tlsmodid - module ID for TLS references
91 if ((version
< RD_VERSION1
) ||
92 (version
> RD_VERSION
))
94 rtld_db_version
= version
;
95 LOG(ps_plog(MSG_ORIG(MSG_DB_RDINIT
), rtld_db_version
));
101 rd_ctl(int cmd
, void *arg
)
103 if (cmd
!= RD_CTL_SET_HELPPATH
|| arg
== NULL
||
104 strlen((char *)arg
) >= MAXPATHLEN
)
107 (void) strcpy(rtld_db_helper_path
, (char *)arg
);
113 rd_get_dyns(rd_agent_t
*rap
, psaddr_t addr
, void **dynpp
, size_t *dynpp_sz
)
115 if (rap
->rd_helper
.rh_ops
!= NULL
)
116 return (rap
->rd_helper
.rh_ops
->rho_get_dyns(
117 rap
->rd_helper
.rh_data
, addr
, dynpp
, dynpp_sz
));
120 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
121 return (_rd_get_dyns64(rap
,
122 addr
, (Elf64_Dyn
**)dynpp
, dynpp_sz
));
125 return (_rd_get_dyns32(rap
,
126 addr
, (Dyn
**)dynpp
, dynpp_sz
));
130 rd_reset(struct rd_agent
*rap
)
140 * Determine if client is 32-bit or 64-bit.
142 if (ps_pdmodel(rap
->rd_psp
, &rap
->rd_dmodel
) != PS_OK
) {
143 LOG(ps_plog(MSG_ORIG(MSG_DB_DMLOOKFAIL
)));
148 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
149 err
= _rd_reset64(rap
);
152 err
= _rd_reset32(rap
);
160 rd_new(struct ps_prochandle
*php
)
164 LOG(ps_plog(MSG_ORIG(MSG_DB_RDNEW
), php
));
165 if ((rap
= (rd_agent_t
*)calloc(sizeof (rd_agent_t
), 1)) == NULL
)
169 (void) mutex_init(&rap
->rd_mutex
, USYNC_THREAD
, 0);
170 if (rd_reset(rap
) != RD_OK
) {
171 if (rap
->rd_helper
.rh_dlhandle
!= NULL
) {
172 rap
->rd_helper
.rh_ops
->rho_fini(rap
->rd_helper
.rh_data
);
173 (void) dlclose(rap
->rd_helper
.rh_dlhandle
);
176 LOG(ps_plog(MSG_ORIG(MSG_DB_RESETFAIL
)));
177 return ((rd_agent_t
*)0);
185 rd_delete(rd_agent_t
*rap
)
187 LOG(ps_plog(MSG_ORIG(MSG_DB_RDDELETE
), rap
));
188 if (rap
->rd_helper
.rh_dlhandle
!= NULL
) {
189 rap
->rd_helper
.rh_ops
->rho_fini(rap
->rd_helper
.rh_data
);
190 (void) dlclose(rap
->rd_helper
.rh_dlhandle
);
197 rd_loadobj_iter(rd_agent_t
*rap
, rl_iter_f
*cb
, void *client_data
)
204 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
205 err
= _rd_loadobj_iter64(rap
, cb
, client_data
);
208 err
= _rd_loadobj_iter32(rap
, cb
, client_data
);
216 rd_plt_resolution(rd_agent_t
*rap
, psaddr_t pc
, lwpid_t lwpid
,
217 psaddr_t pltbase
, rd_plt_info_t
*rpi
)
222 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
223 err
= plt64_resolution(rap
, pc
, lwpid
, pltbase
,
227 err
= plt32_resolution(rap
, pc
, lwpid
, pltbase
,
234 rd_event_addr(rd_agent_t
*rap
, rd_event_e num
, rd_notify_t
*np
)
243 np
->type
= RD_NOTIFY_BPT
;
244 np
->u
.bptaddr
= rap
->rd_preinit
;
247 np
->type
= RD_NOTIFY_BPT
;
248 np
->u
.bptaddr
= rap
->rd_postinit
;
251 np
->type
= RD_NOTIFY_BPT
;
252 np
->u
.bptaddr
= rap
->rd_dlact
;
255 LOG(ps_plog(MSG_ORIG(MSG_DB_UNEXPEVENT
), num
));
260 LOG(ps_plog(MSG_ORIG(MSG_DB_RDEVENTADDR
), num
,
261 EC_ADDR(np
->u
.bptaddr
)));
271 rd_event_enable(rd_agent_t
*rap
, int onoff
)
278 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
279 err
= _rd_event_enable64(rap
, onoff
);
282 err
= _rd_event_enable32(rap
, onoff
);
290 rd_event_getmsg(rd_agent_t
*rap
, rd_event_msg_t
*emsg
)
297 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
298 err
= _rd_event_getmsg64(rap
, emsg
);
301 err
= _rd_event_getmsg32(rap
, emsg
);
309 rd_binder_exit_addr(struct rd_agent
*rap
, const char *bname
, psaddr_t
*beaddr
)
313 if (rap
->rd_tbinder
) {
314 *beaddr
= rap
->rd_tbinder
;
317 if (ps_pglobal_sym(rap
->rd_psp
, PS_OBJ_LDSO
, bname
, &sym
) != PS_OK
) {
318 LOG(ps_plog(MSG_ORIG(MSG_DB_UNFNDSYM
),
323 rap
->rd_tbinder
= *beaddr
= sym
.st_value
+ sym
.st_size
- M_BIND_ADJ
;
330 rd_objpad_enable(struct rd_agent
*rap
, size_t padsize
)
337 if (rap
->rd_dmodel
== PR_MODEL_LP64
)
338 err
= _rd_objpad_enable64(rap
, padsize
);
341 err
= _rd_objpad_enable32(rap
, padsize
);
349 rd_errstr(rd_err_e rderr
)
352 * Convert an 'rd_err_e' to a string
356 return ((char *)MSG_ORIG(MSG_ER_OK
));
358 return ((char *)MSG_ORIG(MSG_ER_ERR
));
360 return ((char *)MSG_ORIG(MSG_ER_DBERR
));
362 return ((char *)MSG_ORIG(MSG_ER_NOCAPAB
));
364 return ((char *)MSG_ORIG(MSG_ER_NODYNAM
));
366 return ((char *)MSG_ORIG(MSG_ER_NOBASE
));
368 return ((char *)MSG_ORIG(MSG_ER_NOMAPS
));
370 return ((char *)MSG_ORIG(MSG_ER_DEFAULT
));