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 2006 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Routines for manipulating the kmdb-specific aspects of dmods.
33 #include <sys/param.h>
35 #include <mdb/mdb_target_impl.h>
36 #include <kmdb/kmdb_module.h>
37 #include <mdb/mdb_debug.h>
38 #include <mdb/mdb_err.h>
41 typedef struct kmod_symarg
{
42 mdb_tgt_sym_f
*sym_cb
; /* Caller's callback function */
43 void *sym_data
; /* Callback function argument */
44 uint_t sym_type
; /* Symbol type/binding filter */
45 mdb_syminfo_t sym_info
; /* Symbol id and table id */
46 const char *sym_obj
; /* Containing object */
50 kmdb_module_path_set(const char **path
, size_t pathlen
)
54 wr
= mdb_zalloc(sizeof (kmdb_wr_path_t
), UM_SLEEP
);
55 wr
->dpth_node
.wn_task
= WNTASK_DMOD_PATH_CHANGE
;
56 wr
->dpth_path
= mdb_path_dup(path
, pathlen
, &wr
->dpth_pathlen
);
58 kmdb_wr_driver_notify(wr
);
62 kmdb_module_path_ack(kmdb_wr_path_t
*dpth
)
64 if (dpth
->dpth_path
!= NULL
)
65 mdb_path_free(dpth
->dpth_path
, dpth
->dpth_pathlen
);
66 mdb_free(dpth
, sizeof (kmdb_wr_path_t
));
69 static kmdb_modctl_t
*
70 kmdb_module_lookup_loaded(const char *name
)
75 if ((v
= mdb_nv_lookup(&mdb
.m_dmodctl
, name
)) == NULL
)
78 kmc
= MDB_NV_COOKIE(v
);
79 if (kmc
->kmc_state
!= KMDB_MC_STATE_LOADED
)
86 * Given an address, try to match it up with a dmod symbol.
89 kmdb_module_lookup_by_addr(uintptr_t addr
, uint_t flags
, char *buf
,
90 size_t nbytes
, GElf_Sym
*symp
, mdb_syminfo_t
*sip
)
92 kmdb_modctl_t
*sym_kmc
= NULL
;
98 mdb_nv_rewind(&mdb
.m_dmodctl
);
99 while ((v
= mdb_nv_advance(&mdb
.m_dmodctl
)) != NULL
) {
100 kmdb_modctl_t
*kmc
= MDB_NV_COOKIE(v
);
102 if (kmc
->kmc_state
!= KMDB_MC_STATE_LOADED
)
105 if (mdb_gelf_symtab_lookup_by_addr(kmc
->kmc_symtab
, addr
, flags
,
106 buf
, nbytes
, symp
, &sip
->sym_id
) != 0 ||
110 if (flags
& MDB_TGT_SYM_EXACT
) {
116 * If this is the first match we've found, or if this symbol is
117 * closer to the specified address than the last one we found,
120 if (sym_kmc
== NULL
|| mdb_gelf_sym_closer(symp
, &sym
, addr
)) {
128 return (set_errno(EMDB_NOSYMADDR
));
135 * Once we've found something, copy the final name into the caller's
136 * buffer, prefixed with a marker identifying this as a dmod symbol.
139 name
= mdb_gelf_sym_name(sym_kmc
->kmc_symtab
, symp
);
141 (void) mdb_snprintf(buf
, nbytes
, "DMOD`%s`%s",
142 sym_kmc
->kmc_modname
, name
);
144 sip
->sym_table
= MDB_TGT_SYMTAB
;
150 * Locate a given dmod symbol
153 kmdb_module_lookup_by_name(const char *obj
, const char *name
, GElf_Sym
*symp
,
158 if ((kmc
= kmdb_module_lookup_loaded(obj
)) == NULL
)
159 return (set_errno(EMDB_NOSYMADDR
));
161 if (mdb_gelf_symtab_lookup_by_name(kmc
->kmc_symtab
, name
,
162 symp
, &sip
->sym_id
) == 0) {
163 sip
->sym_table
= MDB_TGT_SYMTAB
;
167 return (set_errno(EMDB_NOSYM
));
171 kmdb_module_addr_to_ctf(uintptr_t addr
)
175 mdb_nv_rewind(&mdb
.m_dmodctl
);
176 while ((v
= mdb_nv_advance(&mdb
.m_dmodctl
)) != NULL
) {
177 kmdb_modctl_t
*kmc
= MDB_NV_COOKIE(v
);
180 if (kmc
->kmc_state
!= KMDB_MC_STATE_LOADED
)
183 mp
= kmc
->kmc_modctl
->mod_mp
;
184 if (addr
- (uintptr_t)mp
->text
< mp
->text_size
||
185 addr
- (uintptr_t)mp
->data
< mp
->data_size
||
186 addr
- mp
->bss
< mp
->bss_size
) {
187 ctf_file_t
*ctfp
= kmc
->kmc_mod
->mod_ctfp
;
190 (void) set_errno(EMDB_NOCTF
);
198 (void) set_errno(EMDB_NOMAP
);
203 kmdb_module_name_to_ctf(const char *obj
)
208 if ((kmc
= kmdb_module_lookup_loaded(obj
)) == NULL
) {
209 (void) set_errno(EMDB_NOOBJ
);
213 if ((ctfp
= kmc
->kmc_mod
->mod_ctfp
) == NULL
) {
214 (void) set_errno(EMDB_NOCTF
);
222 kmdb_module_symtab_func(void *data
, const GElf_Sym
*sym
, const char *name
,
225 kmod_symarg_t
*arg
= data
;
227 if (mdb_tgt_sym_match(sym
, arg
->sym_type
)) {
228 arg
->sym_info
.sym_id
= id
;
230 return (arg
->sym_cb(arg
->sym_data
, sym
, name
, &arg
->sym_info
,
238 kmdb_module_symbol_iter(const char *obj
, uint_t type
, mdb_tgt_sym_f
*cb
,
245 if ((v
= mdb_nv_lookup(&mdb
.m_dmodctl
, obj
)) == NULL
)
246 return (set_errno(EMDB_NOMOD
));
248 kmc
= MDB_NV_COOKIE(v
);
250 if (kmc
->kmc_state
!= KMDB_MC_STATE_LOADED
)
251 return (set_errno(EMDB_NOMOD
));
256 arg
.sym_info
.sym_table
= kmc
->kmc_symtab
->gst_tabid
;
259 mdb_gelf_symtab_iter(kmc
->kmc_symtab
, kmdb_module_symtab_func
, &arg
);