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 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * The KDI, or kernel/debugger interface, is used to allow the kernel and the
30 * debugger to communicate. These communications take two forms:
32 * 1. kernel to debugger. Interfaces of this type are used by the kernel to
33 * inform the debugger of changes in the state of the system that need to
34 * be noted by the debugger. For example, the kernel uses one of these
35 * interfaces to tell debugger that the set of currently-loaded modules
38 * 2. debugger to kernel. Interfaces of this type are used by the debugger
39 * to extract information from the kernel that would otherwise be difficult
40 * to get, or to perform services that are specific to the machine being
41 * used. An example of the former is the module iterator, which is needed
42 * to allow symbol resolution, but which needs to resolve symbols prior
43 * to the iteration. The latter class include machine-specific or
44 * cpu-type-specific functions, such as the I-cache flusher. By directly
45 * using the kernel versions of these functions, we avoid the need to
46 * include multiple versions of each function - one per cpu and/or machine -
50 #include <sys/kdi_impl.h>
52 #include <kmdb/kmdb_kdi.h>
53 #include <kmdb/kmdb_dpi.h>
54 #include <kmdb/kmdb_kvm.h>
55 #include <kmdb/kmdb_promif.h>
56 #include <mdb/mdb_debug.h>
57 #include <mdb/mdb_err.h>
60 static int kdi_unload_request
;
62 typedef struct mod_interp_data
{
63 int (*mid_usercb
)(struct modctl
*, void *);
69 static kmdb_auxv_t
*kdi_auxv
;
72 kmdb_kdi_mods_changed(void)
74 return (mdb
.m_kdi
->kdi_mods_changed());
78 kmdb_kdi_mod_interp(struct modctl
*mp
, void *arg
)
80 mod_interp_data_t
*mid
= arg
;
83 kmdb_dpi_restore_fault_hdlr(mid
->mid_oldpcb
);
84 rc
= mid
->mid_usercb(mp
, mid
->mid_userarg
);
85 mid
->mid_oldpcb
= kmdb_dpi_set_fault_hdlr(&mid
->mid_pcb
);
91 * We need to protect ourselves against any problems that may occur while
92 * executing the module iterator, currently located in krtld. If, for
93 * example, one of the next pointers in the module list points to an invalid
94 * address, we don't want kmdb to explode. As such, we protect ourselves
95 * with the DPI fault-protection routines. We don't want our fault-protection
96 * callback to protect the callback that the kmdb consumer provided, so we
97 * provide our own interposition callback that removes our fault-protector
98 * before invoking the user's callback.
101 kmdb_kdi_mod_iter(int (*cb
)(struct modctl
*, void *), void *arg
)
103 mod_interp_data_t mid
;
106 if (setjmp(mid
.mid_pcb
) != 0) {
107 /* We took a fault while iterating through the modules */
108 kmdb_dpi_restore_fault_hdlr(mid
.mid_oldpcb
);
113 mid
.mid_userarg
= arg
;
114 mid
.mid_oldpcb
= kmdb_dpi_set_fault_hdlr(&mid
.mid_pcb
);
116 rc
= mdb
.m_kdi
->kdi_mod_iter(kmdb_kdi_mod_interp
, &mid
);
118 kmdb_dpi_restore_fault_hdlr(mid
.mid_oldpcb
);
124 kmdb_kdi_mod_isloaded(struct modctl
*modp
)
126 return (mdb
.m_kdi
->kdi_mod_isloaded(modp
));
130 kmdb_kdi_mod_haschanged(struct modctl
*mc1
, struct module
*mp1
,
131 struct modctl
*mc2
, struct module
*mp2
)
133 return (mdb
.m_kdi
->kdi_mod_haschanged(mc1
, mp1
, mc2
, mp2
));
137 kdi_prw(void *buf
, size_t nbytes
, physaddr_t addr
, int (*rw
)(caddr_t
, size_t,
138 physaddr_t
, size_t *))
143 kmdb_dpi_flush_slave_caches();
144 if ((rc
= rw(buf
, nbytes
, addr
, &sz
)) != 0)
145 return (set_errno(rc
));
151 kmdb_kdi_pread(void *buf
, size_t nbytes
, physaddr_t addr
)
153 return (kdi_prw(buf
, nbytes
, addr
, mdb
.m_kdi
->kdi_pread
));
157 kmdb_kdi_pwrite(void *buf
, size_t nbytes
, physaddr_t addr
)
159 return (kdi_prw(buf
, nbytes
, addr
, mdb
.m_kdi
->kdi_pwrite
));
163 kmdb_kdi_flush_caches(void)
165 mdb
.m_kdi
->kdi_flush_caches();
169 kmdb_kdi_get_unload_request(void)
171 return (kdi_unload_request
);
175 kmdb_kdi_set_unload_request(void)
177 kdi_unload_request
= 1;
181 kmdb_kdi_get_flags(void)
185 if (mdb
.m_flags
& MDB_FL_NOCTF
)
186 flags
|= KMDB_KDI_FL_NOCTF
;
187 if (mdb
.m_flags
& MDB_FL_NOMODS
)
188 flags
|= KMDB_KDI_FL_NOMODS
;
194 kmdb_kdi_range_is_nontoxic(uintptr_t va
, size_t sz
, int write
)
196 return (mdb
.m_kdi
->kdi_range_is_nontoxic(va
, sz
, write
));
200 kmdb_kdi_system_claim(void)
202 (void) kmdb_dpi_call((uintptr_t)mdb
.m_kdi
->kdi_system_claim
, 0, NULL
);
203 kmdb_prom_debugger_entry();
207 kmdb_kdi_system_release(void)
209 kmdb_prom_debugger_exit();
211 if (mdb
.m_kdi
->kdi_system_release
!= NULL
) {
212 (void) kmdb_dpi_call((uintptr_t)mdb
.m_kdi
->kdi_system_release
,
217 struct cons_polledio
*
218 kmdb_kdi_get_polled_io(void)
220 return (mdb
.m_kdi
->kdi_get_polled_io());
224 kmdb_kdi_kmdb_enter(void)
226 mdb
.m_kdi
->kdi_kmdb_enter();
230 kmdb_kdi_vtop(uintptr_t va
, physaddr_t
*pap
)
232 jmp_buf pcb
, *oldpcb
;
235 if (setjmp(pcb
) == 0) {
238 oldpcb
= kmdb_dpi_set_fault_hdlr(&pcb
);
240 if ((err
= mdb
.m_kdi
->kdi_vtop(va
, pap
)) != 0)
241 rc
= set_errno(err
== ENOENT
? EMDB_NOMAP
: err
);
243 /* We faulted during the translation */
244 rc
= set_errno(EMDB_NOMAP
);
247 kmdb_dpi_restore_fault_hdlr(oldpcb
);
253 kmdb_kdi_dtrace_get_state(void)
255 return (mdb
.m_kdi
->kdi_dtrace_get_state());
259 kmdb_kdi_dtrace_set(int state
)
263 if ((err
= mdb
.m_kdi
->kdi_dtrace_set(state
)) != 0)
264 return (set_errno(err
));
270 * This function is to be called only during kmdb initialization, as it
271 * uses the running kernel for symbol translation facilities.
274 kmdb_kdi_lookup_by_name(char *modname
, char *symname
)
276 ASSERT(kmdb_dpi_get_state(NULL
) == DPI_STATE_INIT
);
278 return (kdi_auxv
->kav_lookup_by_name(modname
, symname
));
282 kmdb_kdi_init(kdi_t
*kdi
, kmdb_auxv_t
*kav
)
285 mdb
.m_pagesize
= kav
->kav_pagesize
;
287 kdi_unload_request
= 0;
291 kmdb_kdi_init_isadep(kdi
, kav
);
295 kmdb_kdi_end_init(void)