8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / mdb / common / kmdb / kmdb_module.c
blob094cbab6a6a92f038f386a02fcf2041c472f2cb9
1 /*
2 * CDDL HEADER START
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
7 * with the License.
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]
20 * CDDL HEADER END
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>
39 #include <mdb/mdb.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 */
47 } kmod_symarg_t;
49 void
50 kmdb_module_path_set(const char **path, size_t pathlen)
52 kmdb_wr_path_t *wr;
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);
61 void
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)
72 kmdb_modctl_t *kmc;
73 mdb_var_t *v;
75 if ((v = mdb_nv_lookup(&mdb.m_dmodctl, name)) == NULL)
76 return (NULL);
78 kmc = MDB_NV_COOKIE(v);
79 if (kmc->kmc_state != KMDB_MC_STATE_LOADED)
80 return (NULL);
82 return (kmc);
86 * Given an address, try to match it up with a dmod symbol.
88 int
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;
93 GElf_Sym sym;
94 uint_t symid;
95 mdb_var_t *v;
96 const char *name;
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)
103 continue;
105 if (mdb_gelf_symtab_lookup_by_addr(kmc->kmc_symtab, addr, flags,
106 buf, nbytes, symp, &sip->sym_id) != 0 ||
107 symp->st_value == 0)
108 continue;
110 if (flags & MDB_TGT_SYM_EXACT) {
111 sym_kmc = kmc;
112 goto found;
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,
118 * use it.
120 if (sym_kmc == NULL || mdb_gelf_sym_closer(symp, &sym, addr)) {
121 sym_kmc = kmc;
122 sym = *symp;
123 symid = sip->sym_id;
127 if (sym_kmc == NULL)
128 return (set_errno(EMDB_NOSYMADDR));
130 *symp = sym;
131 sip->sym_id = symid;
133 found:
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.
138 if (buf != NULL) {
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;
146 return (0);
150 * Locate a given dmod symbol
153 kmdb_module_lookup_by_name(const char *obj, const char *name, GElf_Sym *symp,
154 mdb_syminfo_t *sip)
156 kmdb_modctl_t *kmc;
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;
164 return (0);
167 return (set_errno(EMDB_NOSYM));
170 ctf_file_t *
171 kmdb_module_addr_to_ctf(uintptr_t addr)
173 mdb_var_t *v;
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);
178 struct module *mp;
180 if (kmc->kmc_state != KMDB_MC_STATE_LOADED)
181 continue;
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;
189 if (ctfp == NULL) {
190 (void) set_errno(EMDB_NOCTF);
191 return (NULL);
194 return (ctfp);
198 (void) set_errno(EMDB_NOMAP);
199 return (NULL);
202 ctf_file_t *
203 kmdb_module_name_to_ctf(const char *obj)
205 kmdb_modctl_t *kmc;
206 ctf_file_t *ctfp;
208 if ((kmc = kmdb_module_lookup_loaded(obj)) == NULL) {
209 (void) set_errno(EMDB_NOOBJ);
210 return (NULL);
213 if ((ctfp = kmc->kmc_mod->mod_ctfp) == NULL) {
214 (void) set_errno(EMDB_NOCTF);
215 return (NULL);
218 return (ctfp);
221 static int
222 kmdb_module_symtab_func(void *data, const GElf_Sym *sym, const char *name,
223 uint_t id)
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,
231 arg->sym_obj));
234 return (0);
238 kmdb_module_symbol_iter(const char *obj, uint_t type, mdb_tgt_sym_f *cb,
239 void *p)
241 kmdb_modctl_t *kmc;
242 kmod_symarg_t arg;
243 mdb_var_t *v;
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));
253 arg.sym_cb = cb;
254 arg.sym_data = p;
255 arg.sym_type = type;
256 arg.sym_info.sym_table = kmc->kmc_symtab->gst_tabid;
257 arg.sym_obj = obj;
259 mdb_gelf_symtab_iter(kmc->kmc_symtab, kmdb_module_symtab_func, &arg);
261 return (0);