Fri Oct 30 06:57:09 2020 UTC ()
Trailing whitespace


(skrll)
diff -r1.170 -r1.171 src/sys/ddb/db_command.c
diff -r1.38 -r1.39 src/sys/ddb/db_command.h
diff -r1.27 -r1.28 src/sys/ddb/db_input.c
diff -r1.12 -r1.13 src/sys/ddb/db_proc.c

cvs diff -r1.170 -r1.171 src/sys/ddb/db_command.c (switch to unified diff)

--- src/sys/ddb/db_command.c 2020/04/13 11:43:27 1.170
+++ src/sys/ddb/db_command.c 2020/10/30 06:57:08 1.171
@@ -1,1474 +1,1474 @@ @@ -1,1474 +1,1474 @@
1/* $NetBSD: db_command.c,v 1.170 2020/04/13 11:43:27 skrll Exp $ */ 1/* $NetBSD: db_command.c,v 1.171 2020/10/30 06:57:08 skrll Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2009, 2019 4 * Copyright (c) 1996, 1997, 1998, 1999, 2002, 2009, 2019
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Adam Hamsik, and by Andrew Doran. 9 * by Adam Hamsik, and by Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Mach Operating System 34 * Mach Operating System
35 * Copyright (c) 1991,1990 Carnegie Mellon University 35 * Copyright (c) 1991,1990 Carnegie Mellon University
36 * All Rights Reserved. 36 * All Rights Reserved.
37 * 37 *
38 * Permission to use, copy, modify and distribute this software and its 38 * Permission to use, copy, modify and distribute this software and its
39 * documentation is hereby granted, provided that both the copyright 39 * documentation is hereby granted, provided that both the copyright
40 * notice and this permission notice appear in all copies of the 40 * notice and this permission notice appear in all copies of the
41 * software, derivative works or modified versions, and any portions 41 * software, derivative works or modified versions, and any portions
42 * thereof, and that both notices appear in supporting documentation. 42 * thereof, and that both notices appear in supporting documentation.
43 * 43 *
44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 44 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 45 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
46 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 46 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
47 * 47 *
48 * Carnegie Mellon requests users of this software to return to 48 * Carnegie Mellon requests users of this software to return to
49 * 49 *
50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 50 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
51 * School of Computer Science 51 * School of Computer Science
52 * Carnegie Mellon University 52 * Carnegie Mellon University
53 * Pittsburgh PA 15213-3890 53 * Pittsburgh PA 15213-3890
54 * 54 *
55 * any improvements or extensions that they make and grant Carnegie the 55 * any improvements or extensions that they make and grant Carnegie the
56 * rights to redistribute these changes. 56 * rights to redistribute these changes.
57 */ 57 */
58 58
59/* 59/*
60 * Command dispatcher. 60 * Command dispatcher.
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.170 2020/04/13 11:43:27 skrll Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: db_command.c,v 1.171 2020/10/30 06:57:08 skrll Exp $");
65 65
66#ifdef _KERNEL_OPT 66#ifdef _KERNEL_OPT
67#include "opt_aio.h" 67#include "opt_aio.h"
68#include "opt_ddb.h" 68#include "opt_ddb.h"
69#include "opt_kgdb.h" 69#include "opt_kgdb.h"
70#include "opt_mqueue.h" 70#include "opt_mqueue.h"
71#include "opt_inet.h" 71#include "opt_inet.h"
72#include "opt_kernhist.h" 72#include "opt_kernhist.h"
73#include "opt_ddbparam.h" 73#include "opt_ddbparam.h"
74#include "opt_multiprocessor.h" 74#include "opt_multiprocessor.h"
75#endif 75#endif
76 76
77#include <sys/param.h> 77#include <sys/param.h>
78#include <sys/systm.h> 78#include <sys/systm.h>
79#include <sys/reboot.h> 79#include <sys/reboot.h>
80#include <sys/device.h> 80#include <sys/device.h>
81#include <sys/lwp.h> 81#include <sys/lwp.h>
82#include <sys/mbuf.h> 82#include <sys/mbuf.h>
83#include <sys/namei.h> 83#include <sys/namei.h>
84#include <sys/pool.h> 84#include <sys/pool.h>
85#include <sys/proc.h> 85#include <sys/proc.h>
86#include <sys/vnode.h> 86#include <sys/vnode.h>
87#include <sys/vmem.h> 87#include <sys/vmem.h>
88#include <sys/lockdebug.h> 88#include <sys/lockdebug.h>
89#include <sys/cpu.h> 89#include <sys/cpu.h>
90#include <sys/buf.h> 90#include <sys/buf.h>
91#include <sys/module.h> 91#include <sys/module.h>
92#include <sys/kernhist.h> 92#include <sys/kernhist.h>
93#include <sys/socketvar.h> 93#include <sys/socketvar.h>
94#include <sys/queue.h> 94#include <sys/queue.h>
95 95
96#include <dev/cons.h> 96#include <dev/cons.h>
97 97
98#include <ddb/ddb.h> 98#include <ddb/ddb.h>
99 99
100#include <uvm/uvm_extern.h> 100#include <uvm/uvm_extern.h>
101#include <uvm/uvm_ddb.h> 101#include <uvm/uvm_ddb.h>
102 102
103#include <net/route.h> 103#include <net/route.h>
104 104
105/* 105/*
106 * Results of command search. 106 * Results of command search.
107 */ 107 */
108#define CMD_EXACT 0 108#define CMD_EXACT 0
109#define CMD_PREFIX 1 109#define CMD_PREFIX 1
110#define CMD_NONE 2 110#define CMD_NONE 2
111#define CMD_AMBIGUOUS 3 111#define CMD_AMBIGUOUS 3
112 112
113/* 113/*
114 * Exported global variables 114 * Exported global variables
115 */ 115 */
116bool db_cmd_loop_done; 116bool db_cmd_loop_done;
117label_t *db_recover; 117label_t *db_recover;
118db_addr_t db_dot; 118db_addr_t db_dot;
119db_addr_t db_last_addr; 119db_addr_t db_last_addr;
120db_addr_t db_prev; 120db_addr_t db_prev;
121db_addr_t db_next; 121db_addr_t db_next;
122 122
123 123
124/* 124/*
125 * New DDB api for adding and removing commands uses three lists, because 125 * New DDB api for adding and removing commands uses three lists, because
126 * we use two types of commands 126 * we use two types of commands
127 * a) standard commands without subcommands -> reboot 127 * a) standard commands without subcommands -> reboot
128 * b) show commands which are subcommands of show command -> show aio_jobs 128 * b) show commands which are subcommands of show command -> show aio_jobs
129 * c) if defined machine specific commands 129 * c) if defined machine specific commands
130 * 130 *
131 * ddb_add_cmd, ddb_rem_cmd use type (DDB_SHOW_CMD||DDB_BASE_CMD)argument to 131 * ddb_add_cmd, ddb_rem_cmd use type (DDB_SHOW_CMD||DDB_BASE_CMD)argument to
132 * add them to representativ lists. 132 * add them to representativ lists.
133 */ 133 */
134 134
135static const struct db_command db_command_table[]; 135static const struct db_command db_command_table[];
136static const struct db_command db_show_cmds[]; 136static const struct db_command db_show_cmds[];
137 137
138#ifdef DB_MACHINE_COMMANDS 138#ifdef DB_MACHINE_COMMANDS
139/* arch/<arch>/<arch>/db_interface.c */ 139/* arch/<arch>/<arch>/db_interface.c */
140extern const struct db_command db_machine_command_table[]; 140extern const struct db_command db_machine_command_table[];
141#endif 141#endif
142 142
143/* the global queue of all command tables */ 143/* the global queue of all command tables */
144TAILQ_HEAD(db_cmd_tbl_en_head, db_cmd_tbl_en); 144TAILQ_HEAD(db_cmd_tbl_en_head, db_cmd_tbl_en);
145 145
146/* TAILQ entry used to register command tables */ 146/* TAILQ entry used to register command tables */
147struct db_cmd_tbl_en { 147struct db_cmd_tbl_en {
148 const struct db_command *db_cmd; /* cmd table */ 148 const struct db_command *db_cmd; /* cmd table */
149 TAILQ_ENTRY(db_cmd_tbl_en) db_cmd_next; 149 TAILQ_ENTRY(db_cmd_tbl_en) db_cmd_next;
150}; 150};
151 151
152/* head of base commands list */ 152/* head of base commands list */
153static struct db_cmd_tbl_en_head db_base_cmd_list = 153static struct db_cmd_tbl_en_head db_base_cmd_list =
154 TAILQ_HEAD_INITIALIZER(db_base_cmd_list); 154 TAILQ_HEAD_INITIALIZER(db_base_cmd_list);
155static struct db_cmd_tbl_en db_base_cmd_builtins = 155static struct db_cmd_tbl_en db_base_cmd_builtins =
156 { .db_cmd = db_command_table }; 156 { .db_cmd = db_command_table };
157 157
158/* head of show commands list */ 158/* head of show commands list */
159static struct db_cmd_tbl_en_head db_show_cmd_list = 159static struct db_cmd_tbl_en_head db_show_cmd_list =
160 TAILQ_HEAD_INITIALIZER(db_show_cmd_list); 160 TAILQ_HEAD_INITIALIZER(db_show_cmd_list);
161static struct db_cmd_tbl_en db_show_cmd_builtins = 161static struct db_cmd_tbl_en db_show_cmd_builtins =
162 { .db_cmd = db_show_cmds }; 162 { .db_cmd = db_show_cmds };
163 163
164/* head of machine commands list */ 164/* head of machine commands list */
165static struct db_cmd_tbl_en_head db_mach_cmd_list = 165static struct db_cmd_tbl_en_head db_mach_cmd_list =
166 TAILQ_HEAD_INITIALIZER(db_mach_cmd_list); 166 TAILQ_HEAD_INITIALIZER(db_mach_cmd_list);
167#ifdef DB_MACHINE_COMMANDS 167#ifdef DB_MACHINE_COMMANDS
168static struct db_cmd_tbl_en db_mach_cmd_builtins = 168static struct db_cmd_tbl_en db_mach_cmd_builtins =
169 { .db_cmd = db_machine_command_table }; 169 { .db_cmd = db_machine_command_table };
170#endif 170#endif
171 171
172/* 172/*
173 * if 'ed' style: 'dot' is set at start of last item printed, 173 * if 'ed' style: 'dot' is set at start of last item printed,
174 * and '+' points to next line. 174 * and '+' points to next line.
175 * Otherwise: 'dot' points to next item, '..' points to last. 175 * Otherwise: 'dot' points to next item, '..' points to last.
176 */ 176 */
177static bool db_ed_style = true; 177static bool db_ed_style = true;
178 178
179static void db_init_commands(void); 179static void db_init_commands(void);
180static int db_register_tbl_entry(uint8_t type, 180static int db_register_tbl_entry(uint8_t type,
181 struct db_cmd_tbl_en *list_ent); 181 struct db_cmd_tbl_en *list_ent);
182static void db_cmd_list(const struct db_cmd_tbl_en_head *); 182static void db_cmd_list(const struct db_cmd_tbl_en_head *);
183static int db_cmd_search(const char *, struct db_cmd_tbl_en_head *, 183static int db_cmd_search(const char *, struct db_cmd_tbl_en_head *,
184 const struct db_command **); 184 const struct db_command **);
185static int db_cmd_search_table(const char *, const struct db_command *, 185static int db_cmd_search_table(const char *, const struct db_command *,
186 const struct db_command **); 186 const struct db_command **);
187static void db_cmd_search_failed(char *, int); 187static void db_cmd_search_failed(char *, int);
188static const struct db_command *db_read_command(void); 188static const struct db_command *db_read_command(void);
189static void db_command(const struct db_command **); 189static void db_command(const struct db_command **);
190static void db_buf_print_cmd(db_expr_t, bool, db_expr_t, const char *); 190static void db_buf_print_cmd(db_expr_t, bool, db_expr_t, const char *);
191static void db_event_print_cmd(db_expr_t, bool, db_expr_t, const char *); 191static void db_event_print_cmd(db_expr_t, bool, db_expr_t, const char *);
192static void db_fncall(db_expr_t, bool, db_expr_t, const char *); 192static void db_fncall(db_expr_t, bool, db_expr_t, const char *);
193static void db_help_print_cmd(db_expr_t, bool, db_expr_t, const char *); 193static void db_help_print_cmd(db_expr_t, bool, db_expr_t, const char *);
194static void db_lock_print_cmd(db_expr_t, bool, db_expr_t, const char *); 194static void db_lock_print_cmd(db_expr_t, bool, db_expr_t, const char *);
195static void db_show_all_locks(db_expr_t, bool, db_expr_t, const char *); 195static void db_show_all_locks(db_expr_t, bool, db_expr_t, const char *);
196static void db_show_lockstats(db_expr_t, bool, db_expr_t, const char *); 196static void db_show_lockstats(db_expr_t, bool, db_expr_t, const char *);
197static void db_show_all_freelists(db_expr_t, bool, db_expr_t, const char *); 197static void db_show_all_freelists(db_expr_t, bool, db_expr_t, const char *);
198static void db_mount_print_cmd(db_expr_t, bool, db_expr_t, const char *); 198static void db_mount_print_cmd(db_expr_t, bool, db_expr_t, const char *);
199static void db_show_all_mount(db_expr_t, bool, db_expr_t, const char *); 199static void db_show_all_mount(db_expr_t, bool, db_expr_t, const char *);
200static void db_mbuf_print_cmd(db_expr_t, bool, db_expr_t, const char *); 200static void db_mbuf_print_cmd(db_expr_t, bool, db_expr_t, const char *);
201static void db_map_print_cmd(db_expr_t, bool, db_expr_t, const char *); 201static void db_map_print_cmd(db_expr_t, bool, db_expr_t, const char *);
202static void db_namecache_print_cmd(db_expr_t, bool, db_expr_t, 202static void db_namecache_print_cmd(db_expr_t, bool, db_expr_t,
203 const char *); 203 const char *);
204static void db_object_print_cmd(db_expr_t, bool, db_expr_t, const char *); 204static void db_object_print_cmd(db_expr_t, bool, db_expr_t, const char *);
205static void db_page_print_cmd(db_expr_t, bool, db_expr_t, const char *); 205static void db_page_print_cmd(db_expr_t, bool, db_expr_t, const char *);
206static void db_show_all_pages(db_expr_t, bool, db_expr_t, const char *); 206static void db_show_all_pages(db_expr_t, bool, db_expr_t, const char *);
207static void db_pool_print_cmd(db_expr_t, bool, db_expr_t, const char *); 207static void db_pool_print_cmd(db_expr_t, bool, db_expr_t, const char *);
208static void db_reboot_cmd(db_expr_t, bool, db_expr_t, const char *); 208static void db_reboot_cmd(db_expr_t, bool, db_expr_t, const char *);
209static void db_sifting_cmd(db_expr_t, bool, db_expr_t, const char *); 209static void db_sifting_cmd(db_expr_t, bool, db_expr_t, const char *);
210static void db_socket_print_cmd(db_expr_t, bool, db_expr_t, const char *); 210static void db_socket_print_cmd(db_expr_t, bool, db_expr_t, const char *);
211static void db_stack_trace_cmd(db_expr_t, bool, db_expr_t, const char *); 211static void db_stack_trace_cmd(db_expr_t, bool, db_expr_t, const char *);
212static void db_sync_cmd(db_expr_t, bool, db_expr_t, const char *); 212static void db_sync_cmd(db_expr_t, bool, db_expr_t, const char *);
213static void db_whatis_cmd(db_expr_t, bool, db_expr_t, const char *); 213static void db_whatis_cmd(db_expr_t, bool, db_expr_t, const char *);
214static void db_uvmexp_print_cmd(db_expr_t, bool, db_expr_t, const char *); 214static void db_uvmexp_print_cmd(db_expr_t, bool, db_expr_t, const char *);
215#ifdef KERNHIST 215#ifdef KERNHIST
216static void db_kernhist_print_cmd(db_expr_t, bool, db_expr_t, const char *); 216static void db_kernhist_print_cmd(db_expr_t, bool, db_expr_t, const char *);
217#endif 217#endif
218static void db_vnode_print_cmd(db_expr_t, bool, db_expr_t, const char *); 218static void db_vnode_print_cmd(db_expr_t, bool, db_expr_t, const char *);
219static void db_vnode_lock_print_cmd(db_expr_t, bool, db_expr_t, 219static void db_vnode_lock_print_cmd(db_expr_t, bool, db_expr_t,
220 const char *); 220 const char *);
221static void db_vmem_print_cmd(db_expr_t, bool, db_expr_t, const char *); 221static void db_vmem_print_cmd(db_expr_t, bool, db_expr_t, const char *);
222 222
223static const struct db_command db_show_cmds[] = { 223static const struct db_command db_show_cmds[] = {
224 /*added from all sub cmds*/ 224 /*added from all sub cmds*/
225 { DDB_ADD_CMD("callout", db_show_callout, 225 { DDB_ADD_CMD("callout", db_show_callout,
226 0 ,"List all used callout functions.",NULL,NULL) }, 226 0 ,"List all used callout functions.",NULL,NULL) },
227 { DDB_ADD_CMD("pages", db_show_all_pages, 227 { DDB_ADD_CMD("pages", db_show_all_pages,
228 0 ,"List all used memory pages.",NULL,NULL) }, 228 0 ,"List all used memory pages.",NULL,NULL) },
229 { DDB_ADD_CMD("proc", db_show_proc, 229 { DDB_ADD_CMD("proc", db_show_proc,
230 0 ,"Print process information.",NULL,NULL) }, 230 0 ,"Print process information.",NULL,NULL) },
231 { DDB_ADD_CMD("procs", db_show_all_procs, 231 { DDB_ADD_CMD("procs", db_show_all_procs,
232 0 ,"List all processes.",NULL,NULL) }, 232 0 ,"List all processes.",NULL,NULL) },
233 { DDB_ADD_CMD("pools", db_show_all_pools, 233 { DDB_ADD_CMD("pools", db_show_all_pools,
234 0 ,"Show all pools",NULL,NULL) }, 234 0 ,"Show all pools",NULL,NULL) },
235 { DDB_ADD_CMD("locks", db_show_all_locks, 235 { DDB_ADD_CMD("locks", db_show_all_locks,
236 0 ,"Show all held locks", "[/t]", NULL) }, 236 0 ,"Show all held locks", "[/t]", NULL) },
237 { DDB_ADD_CMD("mount", db_show_all_mount, 0, 237 { DDB_ADD_CMD("mount", db_show_all_mount, 0,
238 "Print all mount structures.", "[/f]", NULL) }, 238 "Print all mount structures.", "[/f]", NULL) },
239 { DDB_ADD_CMD("freelists", db_show_all_freelists, 239 { DDB_ADD_CMD("freelists", db_show_all_freelists,
240 0 ,"Show all freelists", NULL, NULL) }, 240 0 ,"Show all freelists", NULL, NULL) },
241#ifdef AIO 241#ifdef AIO
242 /*added from all sub cmds*/ 242 /*added from all sub cmds*/
243 { DDB_ADD_CMD("aio_jobs", db_show_aio_jobs, 0, 243 { DDB_ADD_CMD("aio_jobs", db_show_aio_jobs, 0,
244 "Show aio jobs",NULL,NULL) }, 244 "Show aio jobs",NULL,NULL) },
245#endif 245#endif
246 { DDB_ADD_CMD("all", NULL, 246 { DDB_ADD_CMD("all", NULL,
247 CS_COMPAT, NULL,NULL,NULL) }, 247 CS_COMPAT, NULL,NULL,NULL) },
248#if defined(INET) 248#if defined(INET)
249 { DDB_ADD_CMD("routes", db_show_routes, 0,NULL,NULL,NULL) }, 249 { DDB_ADD_CMD("routes", db_show_routes, 0,NULL,NULL,NULL) },
250#endif 250#endif
251#ifdef _KERNEL 251#ifdef _KERNEL
252 { DDB_ADD_CMD("breaks", db_listbreak_cmd, 0, 252 { DDB_ADD_CMD("breaks", db_listbreak_cmd, 0,
253 "Display all breaks.",NULL,NULL) }, 253 "Display all breaks.",NULL,NULL) },
254#endif 254#endif
255 { DDB_ADD_CMD("buf", db_buf_print_cmd, 0, 255 { DDB_ADD_CMD("buf", db_buf_print_cmd, 0,
256 "Print the struct buf at address.", "[/f] address",NULL) }, 256 "Print the struct buf at address.", "[/f] address",NULL) },
257 { DDB_ADD_CMD("devices", db_show_all_devices, 0,NULL,NULL,NULL) }, 257 { DDB_ADD_CMD("devices", db_show_all_devices, 0,NULL,NULL,NULL) },
258 { DDB_ADD_CMD("event", db_event_print_cmd, 0, 258 { DDB_ADD_CMD("event", db_event_print_cmd, 0,
259 "Print all the non-zero evcnt(9) event counters.", "[/fitm]",NULL) }, 259 "Print all the non-zero evcnt(9) event counters.", "[/fitm]",NULL) },
260 { DDB_ADD_CMD("files", db_show_files_cmd, 0, 260 { DDB_ADD_CMD("files", db_show_files_cmd, 0,
261 "Print the files open by process at address", 261 "Print the files open by process at address",
262 "[/f] address", NULL) }, 262 "[/f] address", NULL) },
263 { DDB_ADD_CMD("lock", db_lock_print_cmd, 0,NULL,NULL,NULL) }, 263 { DDB_ADD_CMD("lock", db_lock_print_cmd, 0,NULL,NULL,NULL) },
264 { DDB_ADD_CMD("lockstats", 264 { DDB_ADD_CMD("lockstats",
265 db_show_lockstats, 0, 265 db_show_lockstats, 0,
266 "Print statistics of locks", NULL, NULL) }, 266 "Print statistics of locks", NULL, NULL) },
267 { DDB_ADD_CMD("map", db_map_print_cmd, 0, 267 { DDB_ADD_CMD("map", db_map_print_cmd, 0,
268 "Print the vm_map at address.", "[/f] address",NULL) }, 268 "Print the vm_map at address.", "[/f] address",NULL) },
269 { DDB_ADD_CMD("socket", db_socket_print_cmd, 0,NULL,NULL,NULL) }, 269 { DDB_ADD_CMD("socket", db_socket_print_cmd, 0,NULL,NULL,NULL) },
270 { DDB_ADD_CMD("module", db_show_module_cmd, 0, 270 { DDB_ADD_CMD("module", db_show_module_cmd, 0,
271 "Print kernel modules", NULL, NULL) }, 271 "Print kernel modules", NULL, NULL) },
272 { DDB_ADD_CMD("mount", db_mount_print_cmd, 0, 272 { DDB_ADD_CMD("mount", db_mount_print_cmd, 0,
273 "Print the mount structure at address.", "[/f] address",NULL) }, 273 "Print the mount structure at address.", "[/f] address",NULL) },
274#ifdef MQUEUE 274#ifdef MQUEUE
275 { DDB_ADD_CMD("mqueue", db_show_mqueue_cmd, 0, 275 { DDB_ADD_CMD("mqueue", db_show_mqueue_cmd, 0,
276 "Print the message queues", NULL, NULL) }, 276 "Print the message queues", NULL, NULL) },
277#endif 277#endif
278 { DDB_ADD_CMD("mbuf", db_mbuf_print_cmd, 0,NULL,NULL, 278 { DDB_ADD_CMD("mbuf", db_mbuf_print_cmd, 0,NULL,NULL,
279 "-c prints all mbuf chains") }, 279 "-c prints all mbuf chains") },
280 { DDB_ADD_CMD("ncache", db_namecache_print_cmd, 0, 280 { DDB_ADD_CMD("ncache", db_namecache_print_cmd, 0,
281 "Dump the namecache list.", "address",NULL) }, 281 "Dump the namecache list.", "address",NULL) },
282 { DDB_ADD_CMD("object", db_object_print_cmd, 0, 282 { DDB_ADD_CMD("object", db_object_print_cmd, 0,
283 "Print the vm_object at address.", "[/f] address",NULL) }, 283 "Print the vm_object at address.", "[/f] address",NULL) },
284 { DDB_ADD_CMD("page", db_page_print_cmd, 0, 284 { DDB_ADD_CMD("page", db_page_print_cmd, 0,
285 "Print the vm_page at address.", "[/f] address",NULL) }, 285 "Print the vm_page at address.", "[/f] address",NULL) },
286 { DDB_ADD_CMD("panic", db_show_panic, 0, 286 { DDB_ADD_CMD("panic", db_show_panic, 0,
287 "Print the current panic string",NULL,NULL) }, 287 "Print the current panic string",NULL,NULL) },
288 { DDB_ADD_CMD("pool", db_pool_print_cmd, 0, 288 { DDB_ADD_CMD("pool", db_pool_print_cmd, 0,
289 "Print the pool at address.", "[/clp] address",NULL) }, 289 "Print the pool at address.", "[/clp] address",NULL) },
290 { DDB_ADD_CMD("registers", db_show_regs, 0, 290 { DDB_ADD_CMD("registers", db_show_regs, 0,
291 "Display the register set.", "[/u]",NULL) }, 291 "Display the register set.", "[/u]",NULL) },
292 { DDB_ADD_CMD("sched_qs", db_show_sched_qs, 0, 292 { DDB_ADD_CMD("sched_qs", db_show_sched_qs, 0,
293 "Print the state of the scheduler's run queues.", 293 "Print the state of the scheduler's run queues.",
294 NULL,NULL) }, 294 NULL,NULL) },
295 { DDB_ADD_CMD("uvmexp", db_uvmexp_print_cmd, 0, 295 { DDB_ADD_CMD("uvmexp", db_uvmexp_print_cmd, 0,
296 "Print a selection of UVM counters and statistics.", 296 "Print a selection of UVM counters and statistics.",
297 NULL,NULL) }, 297 NULL,NULL) },
298#ifdef KERNHIST 298#ifdef KERNHIST
299 { DDB_ADD_CMD("kernhist", db_kernhist_print_cmd, 0, 299 { DDB_ADD_CMD("kernhist", db_kernhist_print_cmd, 0,
300 "Print the UVM history logs.", 300 "Print the UVM history logs.",
301 NULL,NULL) }, 301 NULL,NULL) },
302#endif 302#endif
303 { DDB_ADD_CMD("vnode", db_vnode_print_cmd, 0, 303 { DDB_ADD_CMD("vnode", db_vnode_print_cmd, 0,
304 "Print the vnode at address.", "[/f] address",NULL) }, 304 "Print the vnode at address.", "[/f] address",NULL) },
305 { DDB_ADD_CMD("vnode_lock", db_vnode_lock_print_cmd, 0, 305 { DDB_ADD_CMD("vnode_lock", db_vnode_lock_print_cmd, 0,
306 "Print the vnode having that address as v_lock.", 306 "Print the vnode having that address as v_lock.",
307 "[/f] address",NULL) }, 307 "[/f] address",NULL) },
308 { DDB_ADD_CMD("vmem", db_vmem_print_cmd, 0, 308 { DDB_ADD_CMD("vmem", db_vmem_print_cmd, 0,
309 "Print the vmem usage.", "[/a] address", NULL) }, 309 "Print the vmem usage.", "[/a] address", NULL) },
310 { DDB_ADD_CMD("vmems", db_show_all_vmems, 0, 310 { DDB_ADD_CMD("vmems", db_show_all_vmems, 0,
311 "Show all vmems.", NULL, NULL) }, 311 "Show all vmems.", NULL, NULL) },
312#ifdef _KERNEL 312#ifdef _KERNEL
313 { DDB_ADD_CMD("watches", db_listwatch_cmd, 0, 313 { DDB_ADD_CMD("watches", db_listwatch_cmd, 0,
314 "Display all watchpoints.", NULL,NULL) }, 314 "Display all watchpoints.", NULL,NULL) },
315#endif 315#endif
316 { DDB_ADD_CMD(NULL, NULL, 0,NULL,NULL,NULL) } 316 { DDB_ADD_CMD(NULL, NULL, 0,NULL,NULL,NULL) }
317}; 317};
318 318
319static const struct db_command db_command_table[] = { 319static const struct db_command db_command_table[] = {
320 { DDB_ADD_CMD("b", db_breakpoint_cmd, 0, 320 { DDB_ADD_CMD("b", db_breakpoint_cmd, 0,
321 "Set a breakpoint at address", "[/u] address[,count].",NULL) }, 321 "Set a breakpoint at address", "[/u] address[,count].",NULL) },
322 { DDB_ADD_CMD("break", db_breakpoint_cmd, 0, 322 { DDB_ADD_CMD("break", db_breakpoint_cmd, 0,
323 "Set a breakpoint at address", "[/u] address[,count].",NULL) }, 323 "Set a breakpoint at address", "[/u] address[,count].",NULL) },
324 { DDB_ADD_CMD("bt", db_stack_trace_cmd, 0, 324 { DDB_ADD_CMD("bt", db_stack_trace_cmd, 0,
325 "Show backtrace.", "See help trace.",NULL) }, 325 "Show backtrace.", "See help trace.",NULL) },
326 { DDB_ADD_CMD("c", db_continue_cmd, 0, 326 { DDB_ADD_CMD("c", db_continue_cmd, 0,
327 "Continue execution.", "[/c]",NULL) }, 327 "Continue execution.", "[/c]",NULL) },
328 { DDB_ADD_CMD("call", db_fncall, CS_OWN, 328 { DDB_ADD_CMD("call", db_fncall, CS_OWN,
329 "Call the function", "address[(expression[,...])]",NULL) }, 329 "Call the function", "address[(expression[,...])]",NULL) },
330 { DDB_ADD_CMD("callout", db_show_callout, 0, NULL, 330 { DDB_ADD_CMD("callout", db_show_callout, 0, NULL,
331 NULL,NULL ) }, 331 NULL,NULL ) },
332 { DDB_ADD_CMD("continue", db_continue_cmd, 0, 332 { DDB_ADD_CMD("continue", db_continue_cmd, 0,
333 "Continue execution.", "[/c]",NULL) }, 333 "Continue execution.", "[/c]",NULL) },
334 { DDB_ADD_CMD("d", db_delete_cmd, 0, 334 { DDB_ADD_CMD("d", db_delete_cmd, 0,
335 "Delete a breakpoint.", "address | #number",NULL) }, 335 "Delete a breakpoint.", "address | #number",NULL) },
336 { DDB_ADD_CMD("delete", db_delete_cmd, 0, 336 { DDB_ADD_CMD("delete", db_delete_cmd, 0,
337 "Delete a breakpoint.", "address | #number",NULL) }, 337 "Delete a breakpoint.", "address | #number",NULL) },
338 { DDB_ADD_CMD("dmesg", db_dmesg, 0, 338 { DDB_ADD_CMD("dmesg", db_dmesg, 0,
339 "Show kernel message buffer.", "[count]",NULL) }, 339 "Show kernel message buffer.", "[count]",NULL) },
340 { DDB_ADD_CMD("dwatch", db_deletewatch_cmd, 0, 340 { DDB_ADD_CMD("dwatch", db_deletewatch_cmd, 0,
341 "Delete the watchpoint.", "address",NULL) }, 341 "Delete the watchpoint.", "address",NULL) },
342 { DDB_ADD_CMD("examine", db_examine_cmd, CS_SET_DOT, 342 { DDB_ADD_CMD("examine", db_examine_cmd, CS_SET_DOT,
343 "Display the address locations.", 343 "Display the address locations.",
344 "[/modifier] address[,count]",NULL) }, 344 "[/modifier] address[,count]",NULL) },
345 { DDB_ADD_CMD("exit", db_continue_cmd, 0, 345 { DDB_ADD_CMD("exit", db_continue_cmd, 0,
346 "Continue execution.", "[/c]",NULL) }, 346 "Continue execution.", "[/c]",NULL) },
347 { DDB_ADD_CMD("help", db_help_print_cmd, CS_OWN|CS_NOREPEAT, 347 { DDB_ADD_CMD("help", db_help_print_cmd, CS_OWN|CS_NOREPEAT,
348 "Display help about commands", 348 "Display help about commands",
349 "Use other commands as arguments.",NULL) }, 349 "Use other commands as arguments.",NULL) },
350 { DDB_ADD_CMD("kill", db_kill_proc, CS_OWN, 350 { DDB_ADD_CMD("kill", db_kill_proc, CS_OWN,
351 "Send a signal to the process","pid[,signal_number]", 351 "Send a signal to the process","pid[,signal_number]",
352 " pid:\t\t\tthe process id (may need 0t prefix for decimal)\n" 352 " pid:\t\t\tthe process id (may need 0t prefix for decimal)\n"
353 " signal_number:\tthe signal to send") }, 353 " signal_number:\tthe signal to send") },
354#ifdef KGDB 354#ifdef KGDB
355 { DDB_ADD_CMD("kgdb", db_kgdb_cmd, 0, NULL,NULL,NULL) }, 355 { DDB_ADD_CMD("kgdb", db_kgdb_cmd, 0, NULL,NULL,NULL) },
356#endif 356#endif
357 { DDB_ADD_CMD("machine",NULL,CS_MACH, 357 { DDB_ADD_CMD("machine",NULL,CS_MACH,
358 "Architecture specific functions.",NULL,NULL) }, 358 "Architecture specific functions.",NULL,NULL) },
359 { DDB_ADD_CMD("match", db_trace_until_matching_cmd,0, 359 { DDB_ADD_CMD("match", db_trace_until_matching_cmd,0,
360 "Stop at the matching return instruction.","See help next",NULL) }, 360 "Stop at the matching return instruction.","See help next",NULL) },
361 { DDB_ADD_CMD("next", db_trace_until_matching_cmd,0, 361 { DDB_ADD_CMD("next", db_trace_until_matching_cmd,0,
362 "Stop at the matching return instruction.","[/p]",NULL) }, 362 "Stop at the matching return instruction.","[/p]",NULL) },
363 { DDB_ADD_CMD("p", db_print_cmd, 0, 363 { DDB_ADD_CMD("p", db_print_cmd, 0,
364 "Print address according to the format.", 364 "Print address according to the format.",
365 "[/axzodurc] address [address ...]",NULL) }, 365 "[/axzodurc] address [address ...]",NULL) },
366 { DDB_ADD_CMD("print", db_print_cmd, 0, 366 { DDB_ADD_CMD("print", db_print_cmd, 0,
367 "Print address according to the format.", 367 "Print address according to the format.",
368 "[/axzodurc] address [address ...]",NULL) }, 368 "[/axzodurc] address [address ...]",NULL) },
369 { DDB_ADD_CMD("ps", db_show_all_procs, 0, 369 { DDB_ADD_CMD("ps", db_show_all_procs, 0,
370 "Print all processes.","See show all procs",NULL) }, 370 "Print all processes.","See show all procs",NULL) },
371 { DDB_ADD_CMD("quit", db_continue_cmd, 0, 371 { DDB_ADD_CMD("quit", db_continue_cmd, 0,
372 "Continue execution.", "[/c]",NULL) }, 372 "Continue execution.", "[/c]",NULL) },
373 { DDB_ADD_CMD("reboot", db_reboot_cmd, CS_OWN, 373 { DDB_ADD_CMD("reboot", db_reboot_cmd, CS_OWN,
374 "Reboot","0x1 RB_ASKNAME, 0x2 RB_SINGLE, 0x4 RB_NOSYNC, 0x8 RB_HALT," 374 "Reboot","0x1 RB_ASKNAME, 0x2 RB_SINGLE, 0x4 RB_NOSYNC, 0x8 RB_HALT,"
375 "0x40 RB_KDB, 0x100 RB_DUMP, 0x808 RB_POWERDOWN",NULL) }, 375 "0x40 RB_KDB, 0x100 RB_DUMP, 0x808 RB_POWERDOWN",NULL) },
376 { DDB_ADD_CMD("s", db_single_step_cmd, 0, 376 { DDB_ADD_CMD("s", db_single_step_cmd, 0,
377 "Single-step count times.","[/p] [,count]",NULL) }, 377 "Single-step count times.","[/p] [,count]",NULL) },
378 { DDB_ADD_CMD("search", db_search_cmd, CS_OWN|CS_SET_DOT, 378 { DDB_ADD_CMD("search", db_search_cmd, CS_OWN|CS_SET_DOT,
379 "Search memory from address for value.", 379 "Search memory from address for value.",
380 "[/bhl] address value [mask] [,count]",NULL) }, 380 "[/bhl] address value [mask] [,count]",NULL) },
381 { DDB_ADD_CMD("set", db_set_cmd, CS_OWN, 381 { DDB_ADD_CMD("set", db_set_cmd, CS_OWN,
382 "Set the named variable","$variable [=] expression",NULL) }, 382 "Set the named variable","$variable [=] expression",NULL) },
383 { DDB_ADD_CMD("show", NULL, CS_SHOW, 383 { DDB_ADD_CMD("show", NULL, CS_SHOW,
384 "Show kernel stats.", NULL,NULL) }, 384 "Show kernel stats.", NULL,NULL) },
385 { DDB_ADD_CMD("sifting", db_sifting_cmd, CS_OWN, 385 { DDB_ADD_CMD("sifting", db_sifting_cmd, CS_OWN,
386 "Search the symbol tables ","[/F] string",NULL) }, 386 "Search the symbol tables ","[/F] string",NULL) },
387 { DDB_ADD_CMD("step", db_single_step_cmd, 0, 387 { DDB_ADD_CMD("step", db_single_step_cmd, 0,
388 "Single-step count times.","[/p] [,count]",NULL) }, 388 "Single-step count times.","[/p] [,count]",NULL) },
389 { DDB_ADD_CMD("sync", db_sync_cmd, CS_OWN, 389 { DDB_ADD_CMD("sync", db_sync_cmd, CS_OWN,
390 "Force a crash dump, and then reboot.",NULL,NULL) }, 390 "Force a crash dump, and then reboot.",NULL,NULL) },
391 { DDB_ADD_CMD("trace", db_stack_trace_cmd, 0, 391 { DDB_ADD_CMD("trace", db_stack_trace_cmd, 0,
392 "Stack trace from frame-address.", 392 "Stack trace from frame-address.",
393 "[/u[l]] [frame-address][,count]",NULL) }, 393 "[/u[l]] [frame-address][,count]",NULL) },
394 { DDB_ADD_CMD("until", db_trace_until_call_cmd,0, 394 { DDB_ADD_CMD("until", db_trace_until_call_cmd,0,
395 "Stop at the next call or return instruction.","[/p]",NULL) }, 395 "Stop at the next call or return instruction.","[/p]",NULL) },
396 { DDB_ADD_CMD("w", db_write_cmd, CS_MORE|CS_SET_DOT, 396 { DDB_ADD_CMD("w", db_write_cmd, CS_MORE|CS_SET_DOT,
397 "Write the expressions at succeeding locations.", 397 "Write the expressions at succeeding locations.",
398 "[/bhl] address expression [expression ...]",NULL) }, 398 "[/bhl] address expression [expression ...]",NULL) },
399 { DDB_ADD_CMD("watch", db_watchpoint_cmd, CS_MORE, 399 { DDB_ADD_CMD("watch", db_watchpoint_cmd, CS_MORE,
400 "Set a watchpoint for a region. ","address[,size]",NULL) }, 400 "Set a watchpoint for a region. ","address[,size]",NULL) },
401 { DDB_ADD_CMD("whatis", db_whatis_cmd, 0, 401 { DDB_ADD_CMD("whatis", db_whatis_cmd, 0,
402 "Describe what an address is", "address", NULL) }, 402 "Describe what an address is", "address", NULL) },
403 { DDB_ADD_CMD("write", db_write_cmd, CS_MORE|CS_SET_DOT, 403 { DDB_ADD_CMD("write", db_write_cmd, CS_MORE|CS_SET_DOT,
404 "Write the expressions at succeeding locations.", 404 "Write the expressions at succeeding locations.",
405 "[/bhl] address expression [expression ...]",NULL) }, 405 "[/bhl] address expression [expression ...]",NULL) },
406 { DDB_ADD_CMD("x", db_examine_cmd, CS_SET_DOT, 406 { DDB_ADD_CMD("x", db_examine_cmd, CS_SET_DOT,
407 "Display the address locations.", 407 "Display the address locations.",
408 "[/modifier] address[,count]",NULL) }, 408 "[/modifier] address[,count]",NULL) },
409 { DDB_ADD_CMD(NULL, NULL, 0, NULL, NULL, NULL) } 409 { DDB_ADD_CMD(NULL, NULL, 0, NULL, NULL, NULL) }
410}; 410};
411 411
412static const struct db_command *db_last_command = NULL; 412static const struct db_command *db_last_command = NULL;
413#if defined(DDB_COMMANDONENTER) 413#if defined(DDB_COMMANDONENTER)
414char db_cmd_on_enter[DB_LINE_MAXLEN + 1] = ___STRING(DDB_COMMANDONENTER); 414char db_cmd_on_enter[DB_LINE_MAXLEN + 1] = ___STRING(DDB_COMMANDONENTER);
415#else /* defined(DDB_COMMANDONENTER) */ 415#else /* defined(DDB_COMMANDONENTER) */
416char db_cmd_on_enter[DB_LINE_MAXLEN + 1] = ""; 416char db_cmd_on_enter[DB_LINE_MAXLEN + 1] = "";
417#endif /* defined(DDB_COMMANDONENTER) */ 417#endif /* defined(DDB_COMMANDONENTER) */
418#define DB_LINE_SEP ';' 418#define DB_LINE_SEP ';'
419 419
420/* 420/*
421 * Execute commandlist after ddb start 421 * Execute commandlist after ddb start
422 * This function goes through the command list created from commands and ';' 422 * This function goes through the command list created from commands and ';'
423 */ 423 */
424static void 424static void
425db_execute_commandlist(const char *cmdlist) 425db_execute_commandlist(const char *cmdlist)
426{ 426{
427 const char *cmd = cmdlist; 427 const char *cmd = cmdlist;
428 const struct db_command *dummy = NULL; 428 const struct db_command *dummy = NULL;
429 429
430 while (*cmd != '\0') { 430 while (*cmd != '\0') {
431 const char *ep = cmd; 431 const char *ep = cmd;
432 432
433 while (*ep != '\0' && *ep != DB_LINE_SEP) { 433 while (*ep != '\0' && *ep != DB_LINE_SEP) {
434 ep++; 434 ep++;
435 } 435 }
436 db_set_line(cmd, ep); 436 db_set_line(cmd, ep);
437 db_command(&dummy); 437 db_command(&dummy);
438 cmd = ep; 438 cmd = ep;
439 if (*cmd == DB_LINE_SEP) { 439 if (*cmd == DB_LINE_SEP) {
440 cmd++; 440 cmd++;
441 } 441 }
442 } 442 }
443} 443}
444 444
445/* Initialize ddb command tables */ 445/* Initialize ddb command tables */
446void 446void
447db_init_commands(void) 447db_init_commands(void)
448{ 448{
449 static bool done = false; 449 static bool done = false;
450 450
451 if (done) return; 451 if (done) return;
452 done = true; 452 done = true;
453 453
454 /* register command tables */ 454 /* register command tables */
455 (void)db_register_tbl_entry(DDB_BASE_CMD, &db_base_cmd_builtins); 455 (void)db_register_tbl_entry(DDB_BASE_CMD, &db_base_cmd_builtins);
456#ifdef DB_MACHINE_COMMANDS 456#ifdef DB_MACHINE_COMMANDS
457 (void)db_register_tbl_entry(DDB_MACH_CMD, &db_mach_cmd_builtins); 457 (void)db_register_tbl_entry(DDB_MACH_CMD, &db_mach_cmd_builtins);
458#endif 458#endif
459 (void)db_register_tbl_entry(DDB_SHOW_CMD, &db_show_cmd_builtins); 459 (void)db_register_tbl_entry(DDB_SHOW_CMD, &db_show_cmd_builtins);
460} 460}
461 461
462 462
463/* 463/*
464 * Add command table to the specified list 464 * Add command table to the specified list
465 * Arg: 465 * Arg:
466 * int type specifies type of command table DDB_SHOW_CMD|DDB_BASE_CMD|DDB_MAC_CMD 466 * int type specifies type of command table DDB_SHOW_CMD|DDB_BASE_CMD|DDB_MAC_CMD
467 * *cmd_tbl poiter to static allocated db_command table 467 * *cmd_tbl poiter to static allocated db_command table
468 * 468 *
469 * Command table must be NULL terminated array of struct db_command 469 * Command table must be NULL terminated array of struct db_command
470 */ 470 */
471int 471int
472db_register_tbl(uint8_t type, const struct db_command *cmd_tbl) 472db_register_tbl(uint8_t type, const struct db_command *cmd_tbl)
473{ 473{
474 struct db_cmd_tbl_en *list_ent; 474 struct db_cmd_tbl_en *list_ent;
475  475
476 /* empty list - ignore */ 476 /* empty list - ignore */
477 if (cmd_tbl->name == 0) 477 if (cmd_tbl->name == 0)
478 return 0; 478 return 0;
479 479
480 /* force builtin commands to be registered first */ 480 /* force builtin commands to be registered first */
481 db_init_commands(); 481 db_init_commands();
482 482
483 /* now create a list entry for this table */ 483 /* now create a list entry for this table */
484 list_ent = db_zalloc(sizeof(*list_ent)); 484 list_ent = db_zalloc(sizeof(*list_ent));
485 if (list_ent == NULL) 485 if (list_ent == NULL)
486 return ENOMEM; 486 return ENOMEM;
487 list_ent->db_cmd=cmd_tbl; 487 list_ent->db_cmd=cmd_tbl;
488 488
489 /* and register it */ 489 /* and register it */
490 return db_register_tbl_entry(type, list_ent); 490 return db_register_tbl_entry(type, list_ent);
491} 491}
492 492
493static int 493static int
494db_register_tbl_entry(uint8_t type, struct db_cmd_tbl_en *list_ent) 494db_register_tbl_entry(uint8_t type, struct db_cmd_tbl_en *list_ent)
495{ 495{
496 struct db_cmd_tbl_en_head *list; 496 struct db_cmd_tbl_en_head *list;
497 497
498 switch(type) { 498 switch(type) {
499 case DDB_BASE_CMD: 499 case DDB_BASE_CMD:
500 list = &db_base_cmd_list; 500 list = &db_base_cmd_list;
501 break; 501 break;
502 case DDB_SHOW_CMD: 502 case DDB_SHOW_CMD:
503 list = &db_show_cmd_list; 503 list = &db_show_cmd_list;
504 break; 504 break;
505 case DDB_MACH_CMD: 505 case DDB_MACH_CMD:
506 list = &db_mach_cmd_list; 506 list = &db_mach_cmd_list;
507 break; 507 break;
508 default: 508 default:
509 return ENOENT; 509 return ENOENT;
510 } 510 }
511 511
512 TAILQ_INSERT_TAIL(list, list_ent, db_cmd_next); 512 TAILQ_INSERT_TAIL(list, list_ent, db_cmd_next);
513 513
514 return 0; 514 return 0;
515} 515}
516 516
517/* 517/*
518 * Remove command table specified with db_cmd address == cmd_tbl 518 * Remove command table specified with db_cmd address == cmd_tbl
519 */ 519 */
520int 520int
521db_unregister_tbl(uint8_t type,const struct db_command *cmd_tbl) 521db_unregister_tbl(uint8_t type,const struct db_command *cmd_tbl)
522{ 522{
523 struct db_cmd_tbl_en *list_ent; 523 struct db_cmd_tbl_en *list_ent;
524 struct db_cmd_tbl_en_head *list; 524 struct db_cmd_tbl_en_head *list;
525 525
526 /* find list on which the entry should live */ 526 /* find list on which the entry should live */
527 switch (type) { 527 switch (type) {
528 case DDB_BASE_CMD: 528 case DDB_BASE_CMD:
529 list=&db_base_cmd_list; 529 list=&db_base_cmd_list;
530 break; 530 break;
531 case DDB_SHOW_CMD: 531 case DDB_SHOW_CMD:
532 list=&db_show_cmd_list; 532 list=&db_show_cmd_list;
533 break; 533 break;
534 case DDB_MACH_CMD: 534 case DDB_MACH_CMD:
535 list=&db_mach_cmd_list; 535 list=&db_mach_cmd_list;
536 break; 536 break;
537 default: 537 default:
538 return EINVAL; 538 return EINVAL;
539 } 539 }
540 540
541 TAILQ_FOREACH (list_ent, list, db_cmd_next) { 541 TAILQ_FOREACH (list_ent, list, db_cmd_next) {
542 if (list_ent->db_cmd == cmd_tbl){ 542 if (list_ent->db_cmd == cmd_tbl){
543 TAILQ_REMOVE(list, 543 TAILQ_REMOVE(list,
544 list_ent, db_cmd_next); 544 list_ent, db_cmd_next);
545 db_free(list_ent, sizeof(*list_ent)); 545 db_free(list_ent, sizeof(*list_ent));
546 return 0; 546 return 0;
547 } 547 }
548 } 548 }
549 return ENOENT; 549 return ENOENT;
550} 550}
551 551
552#ifndef _KERNEL 552#ifndef _KERNEL
553#define cnpollc(c) __nothing 553#define cnpollc(c) __nothing
554#endif 554#endif
555 555
556/* 556/*
557 * This function is called via db_trap() or directly from 557 * This function is called via db_trap() or directly from
558 * machine trap code. 558 * machine trap code.
559 */ 559 */
560void 560void
561db_command_loop(void) 561db_command_loop(void)
562{ 562{
563 label_t db_jmpbuf; 563 label_t db_jmpbuf;
564 label_t *savejmp; 564 label_t *savejmp;
565 565
566 /* 566 /*
567 * Initialize 'prev' and 'next' to dot. 567 * Initialize 'prev' and 'next' to dot.
568 */ 568 */
569 db_prev = db_dot; 569 db_prev = db_dot;
570 db_next = db_dot; 570 db_next = db_dot;
571 571
572 db_cmd_loop_done = false; 572 db_cmd_loop_done = false;
573 573
574 /* Init default command tables add machine, base, 574 /* Init default command tables add machine, base,
575 show command tables to the list */ 575 show command tables to the list */
576 db_init_commands(); 576 db_init_commands();
577 577
578 /* save context for return from ddb */ 578 /* save context for return from ddb */
579 savejmp = db_recover; 579 savejmp = db_recover;
580 db_recover = &db_jmpbuf; 580 db_recover = &db_jmpbuf;
581 (void) setjmp(&db_jmpbuf); 581 (void) setjmp(&db_jmpbuf);
582 582
583 /* 583 /*
584 * Execute default ddb start commands only if this is the 584 * Execute default ddb start commands only if this is the
585 * first entry into DDB, in case the start commands fault 585 * first entry into DDB, in case the start commands fault
586 * and we recurse into here. 586 * and we recurse into here.
587 */ 587 */
588 if (!savejmp) 588 if (!savejmp)
589 db_execute_commandlist(db_cmd_on_enter); 589 db_execute_commandlist(db_cmd_on_enter);
590 590
591 (void) setjmp(&db_jmpbuf); 591 (void) setjmp(&db_jmpbuf);
592 while (!db_cmd_loop_done) { 592 while (!db_cmd_loop_done) {
593 if (db_print_position() != 0) 593 if (db_print_position() != 0)
594 db_printf("\n"); 594 db_printf("\n");
595 db_output_line = 0; 595 db_output_line = 0;
596 cnpollc(1); 596 cnpollc(1);
597 (void) db_read_line(); 597 (void) db_read_line();
598 cnpollc(0); 598 cnpollc(0);
599 db_command(&db_last_command); 599 db_command(&db_last_command);
600 } 600 }
601 601
602 db_recover = savejmp; 602 db_recover = savejmp;
603} 603}
604 604
605/* 605/*
606 * Search command table for command prefix 606 * Search command table for command prefix
607 */ 607 */
608static int 608static int
609db_cmd_search_table(const char *name, 609db_cmd_search_table(const char *name,
610 const struct db_command *table, 610 const struct db_command *table,
611 const struct db_command **cmdp) 611 const struct db_command **cmdp)
612{ 612{
613 613
614 const struct db_command *cmd; 614 const struct db_command *cmd;
615 int result; 615 int result;
616 616
617 result = CMD_NONE; 617 result = CMD_NONE;
618 *cmdp = NULL; 618 *cmdp = NULL;
619 619
620 for (cmd = table; cmd->name != 0; cmd++) { 620 for (cmd = table; cmd->name != 0; cmd++) {
621 const char *lp; 621 const char *lp;
622 const char *rp; 622 const char *rp;
623 623
624 lp = name; 624 lp = name;
625 rp = cmd->name; 625 rp = cmd->name;
626 while (*lp != '\0' && *lp == *rp) { 626 while (*lp != '\0' && *lp == *rp) {
627 rp++; 627 rp++;
628 lp++; 628 lp++;
629 } 629 }
630 630
631 if (*lp != '\0') /* mismatch or extra chars in name */ 631 if (*lp != '\0') /* mismatch or extra chars in name */
632 continue; 632 continue;
633 633
634 if (*rp == '\0') { /* exact match */ 634 if (*rp == '\0') { /* exact match */
635 *cmdp = cmd; 635 *cmdp = cmd;
636 return (CMD_EXACT); 636 return (CMD_EXACT);
637 } 637 }
638 638
639 /* prefix match: end of name, not end of command */ 639 /* prefix match: end of name, not end of command */
640 if (result == CMD_NONE) { 640 if (result == CMD_NONE) {
641 result = CMD_PREFIX; 641 result = CMD_PREFIX;
642 *cmdp = cmd; 642 *cmdp = cmd;
643 } 643 }
644 else if (result == CMD_PREFIX) { 644 else if (result == CMD_PREFIX) {
645 result = CMD_AMBIGUOUS; 645 result = CMD_AMBIGUOUS;
646 *cmdp = NULL; 646 *cmdp = NULL;
647 } 647 }
648 } 648 }
649 649
650 return (result); 650 return (result);
651} 651}
652 652
653 653
654/* 654/*
655 * Search list of command tables for command 655 * Search list of command tables for command
656 */ 656 */
657static int 657static int
658db_cmd_search(const char *name, 658db_cmd_search(const char *name,
659 struct db_cmd_tbl_en_head *list_head, 659 struct db_cmd_tbl_en_head *list_head,
660 const struct db_command **cmdp) 660 const struct db_command **cmdp)
661{ 661{
662 struct db_cmd_tbl_en *list_ent; 662 struct db_cmd_tbl_en *list_ent;
663 const struct db_command *found_command; 663 const struct db_command *found_command;
664 bool accept_prefix_match; 664 bool accept_prefix_match;
665 int result; 665 int result;
666 666
667 result = CMD_NONE; 667 result = CMD_NONE;
668 found_command = NULL; 668 found_command = NULL;
669 accept_prefix_match = true; 669 accept_prefix_match = true;
670 670
671 TAILQ_FOREACH(list_ent, list_head, db_cmd_next) { 671 TAILQ_FOREACH(list_ent, list_head, db_cmd_next) {
672 const struct db_command *cmd; 672 const struct db_command *cmd;
673 int found; 673 int found;
674 674
675 found = db_cmd_search_table(name, list_ent->db_cmd, &cmd); 675 found = db_cmd_search_table(name, list_ent->db_cmd, &cmd);
676 if (found == CMD_EXACT) { 676 if (found == CMD_EXACT) {
677 result = CMD_EXACT; 677 result = CMD_EXACT;
678 found_command = cmd; 678 found_command = cmd;
679 break; 679 break;
680 } 680 }
681 681
682 if (found == CMD_PREFIX) { 682 if (found == CMD_PREFIX) {
683 if (accept_prefix_match) { 683 if (accept_prefix_match) {
684 /* 684 /*
685 * Continue search, but note current result 685 * Continue search, but note current result
686 * in case we won't find anything else. 686 * in case we won't find anything else.
687 */ 687 */
688 accept_prefix_match = false; 688 accept_prefix_match = false;
689 result = CMD_PREFIX; 689 result = CMD_PREFIX;
690 found_command = cmd; 690 found_command = cmd;
691 } else { 691 } else {
692 /* 692 /*
693 * Watch out for globally ambiguous 693 * Watch out for globally ambiguous
694 * prefix match that is not locally 694 * prefix match that is not locally
695 * ambiguous - with one match in one 695 * ambiguous - with one match in one
696 * table and another match(es) in 696 * table and another match(es) in
697 * another table. 697 * another table.
698 */ 698 */
699 result = CMD_AMBIGUOUS; 699 result = CMD_AMBIGUOUS;
700 found_command = NULL; 700 found_command = NULL;
701 } 701 }
702 } 702 }
703 else if (found == CMD_AMBIGUOUS) { 703 else if (found == CMD_AMBIGUOUS) {
704 accept_prefix_match = false; 704 accept_prefix_match = false;
705 result = CMD_AMBIGUOUS; 705 result = CMD_AMBIGUOUS;
706 found_command = NULL; 706 found_command = NULL;
707 } 707 }
708 } 708 }
709 709
710 *cmdp = found_command; 710 *cmdp = found_command;
711 return result; 711 return result;
712} 712}
713 713
714static void 714static void
715db_cmd_search_failed(char *name, int search_result) 715db_cmd_search_failed(char *name, int search_result)
716{ 716{
717 if (search_result == CMD_NONE) 717 if (search_result == CMD_NONE)
718 db_printf("No such command: %s\n", name); 718 db_printf("No such command: %s\n", name);
719 else 719 else
720 db_printf("Ambiguous command: %s\n", name); 720 db_printf("Ambiguous command: %s\n", name);
721} 721}
722 722
723 723
724/* 724/*
725 * List commands to the console. 725 * List commands to the console.
726 */ 726 */
727static void 727static void
728db_cmd_list(const struct db_cmd_tbl_en_head *list) 728db_cmd_list(const struct db_cmd_tbl_en_head *list)
729{ 729{
730 730
731 struct db_cmd_tbl_en *list_ent; 731 struct db_cmd_tbl_en *list_ent;
732 const struct db_command *table; 732 const struct db_command *table;
733 size_t i, j, w, columns, lines, numcmds, width=0; 733 size_t i, j, w, columns, lines, numcmds, width=0;
734 const char *p; 734 const char *p;
735 735
736 TAILQ_FOREACH(list_ent,list,db_cmd_next) { 736 TAILQ_FOREACH(list_ent,list,db_cmd_next) {
737 table = list_ent->db_cmd; 737 table = list_ent->db_cmd;
738 for (i = 0; table[i].name != NULL; i++) { 738 for (i = 0; table[i].name != NULL; i++) {
739 w = strlen(table[i].name); 739 w = strlen(table[i].name);
740 if (w > width) 740 if (w > width)
741 width = w; 741 width = w;
742 } 742 }
743 } 743 }
744 744
745 width = DB_NEXT_TAB(width); 745 width = DB_NEXT_TAB(width);
746 746
747 columns = db_max_width / width; 747 columns = db_max_width / width;
748 if (columns == 0) 748 if (columns == 0)
749 columns = 1; 749 columns = 1;
750 750
751 TAILQ_FOREACH(list_ent,list,db_cmd_next) { 751 TAILQ_FOREACH(list_ent,list,db_cmd_next) {
752 table = list_ent->db_cmd; 752 table = list_ent->db_cmd;
753 753
754 for (numcmds = 0; table[numcmds].name != NULL; numcmds++) 754 for (numcmds = 0; table[numcmds].name != NULL; numcmds++)
755 ; 755 ;
756 lines = (numcmds + columns - 1) / columns; 756 lines = (numcmds + columns - 1) / columns;
757 757
758 for (i = 0; i < lines; i++) { 758 for (i = 0; i < lines; i++) {
759 for (j = 0; j < columns; j++) { 759 for (j = 0; j < columns; j++) {
760 p = table[j * lines + i].name; 760 p = table[j * lines + i].name;
761 if (p) 761 if (p)
762 db_printf("%s", p); 762 db_printf("%s", p);
763 if (j * lines + i + lines >= numcmds) { 763 if (j * lines + i + lines >= numcmds) {
764 db_putchar('\n'); 764 db_putchar('\n');
765 break; 765 break;
766 } 766 }
767 if (p) { 767 if (p) {
768 w = strlen(p); 768 w = strlen(p);
769 while (w < width) { 769 while (w < width) {
770 w = DB_NEXT_TAB(w); 770 w = DB_NEXT_TAB(w);
771 db_putchar('\t'); 771 db_putchar('\t');
772 } 772 }
773 } 773 }
774 } 774 }
775 } 775 }
776 } 776 }
777 return; 777 return;
778} 778}
779 779
780/* 780/*
781 * Read complete command with all subcommands, starting with current 781 * Read complete command with all subcommands, starting with current
782 * db_tok_string. If subcommand is missing, print the list of all 782 * db_tok_string. If subcommand is missing, print the list of all
783 * subcommands. If command/subcommand is not found, print an error 783 * subcommands. If command/subcommand is not found, print an error
784 * message. Returns pointer to "leaf" command or NULL. 784 * message. Returns pointer to "leaf" command or NULL.
785 */ 785 */
786static const struct db_command * 786static const struct db_command *
787db_read_command(void) 787db_read_command(void)
788{ 788{
789 const struct db_command *command; 789 const struct db_command *command;
790 struct db_cmd_tbl_en_head *list; 790 struct db_cmd_tbl_en_head *list;
791 int found; 791 int found;
792 int t; 792 int t;
793 793
794 list = &db_base_cmd_list; 794 list = &db_base_cmd_list;
795 do { 795 do {
796 found = db_cmd_search(db_tok_string, list, &command); 796 found = db_cmd_search(db_tok_string, list, &command);
797 if (command == NULL) { 797 if (command == NULL) {
798 db_cmd_search_failed(db_tok_string, found); 798 db_cmd_search_failed(db_tok_string, found);
799 db_flush_lex(); 799 db_flush_lex();
800 return NULL; 800 return NULL;
801 } 801 }
802 802
803 if (command->flag == CS_SHOW) 803 if (command->flag == CS_SHOW)
804 list = &db_show_cmd_list; 804 list = &db_show_cmd_list;
805 else if (command->flag == CS_MACH) 805 else if (command->flag == CS_MACH)
806 list = &db_mach_cmd_list; 806 list = &db_mach_cmd_list;
807 else if (command->flag == CS_COMPAT) 807 else if (command->flag == CS_COMPAT)
808 /* same list */; 808 /* same list */;
809 else 809 else
810 break; /* expect no more subcommands */ 810 break; /* expect no more subcommands */
811 811
812 t = db_read_token(); /* read subcommand */ 812 t = db_read_token(); /* read subcommand */
813 if (t != tIDENT) { 813 if (t != tIDENT) {
814 /* if none given - just print all of them */ 814 /* if none given - just print all of them */
815 db_cmd_list(list); 815 db_cmd_list(list);
816 db_flush_lex(); 816 db_flush_lex();
817 return NULL; 817 return NULL;
818 } 818 }
819 } while (list != NULL); 819 } while (list != NULL);
820 820
821 return command; 821 return command;
822} 822}
823 823
824/* 824/*
825 * Parse command line and execute apropriate function. 825 * Parse command line and execute apropriate function.
826 */ 826 */
827static void 827static void
828db_command(const struct db_command **last_cmdp) 828db_command(const struct db_command **last_cmdp)
829{ 829{
830 static db_expr_t last_count = 0; 830 static db_expr_t last_count = 0;
831 831
832 int t; 832 int t;
833 const struct db_command *command; 833 const struct db_command *command;
834 db_expr_t addr, count; 834 db_expr_t addr, count;
835 bool have_addr; 835 bool have_addr;
836 char modif[TOK_STRING_SIZE]; 836 char modif[TOK_STRING_SIZE];
837 837
838 command = NULL; 838 command = NULL;
839 have_addr = false; 839 have_addr = false;
840 count = -1; 840 count = -1;
841 841
842 t = db_read_token(); 842 t = db_read_token();
843 if ((t == tEOL) || (t == tCOMMA)) { 843 if ((t == tEOL) || (t == tCOMMA)) {
844 /* 844 /*
845 * An empty line repeats last command, at 'next'. 845 * An empty line repeats last command, at 'next'.
846 * Only a count repeats the last command with the new count. 846 * Only a count repeats the last command with the new count.
847 */ 847 */
848 command = *last_cmdp; 848 command = *last_cmdp;
849 849
850 if (!command) 850 if (!command)
851 return; 851 return;
852 852
853 addr = (db_expr_t)db_next; 853 addr = (db_expr_t)db_next;
854 if (t == tCOMMA) { 854 if (t == tCOMMA) {
855 if (!db_expression(&count)) { 855 if (!db_expression(&count)) {
856 db_printf("Count missing\n"); 856 db_printf("Count missing\n");
857 db_flush_lex(); 857 db_flush_lex();
858 return; 858 return;
859 } 859 }
860 } else 860 } else
861 count = last_count; 861 count = last_count;
862 modif[0] = '\0'; 862 modif[0] = '\0';
863 db_skip_to_eol(); 863 db_skip_to_eol();
864 864
865 } else if (t == tEXCL) { 865 } else if (t == tEXCL) {
866 db_fncall(0, 0, 0, NULL); 866 db_fncall(0, 0, 0, NULL);
867 return; 867 return;
868 868
869 } else if (t != tIDENT) { 869 } else if (t != tIDENT) {
870 db_printf("?\n"); 870 db_printf("?\n");
871 db_flush_lex(); 871 db_flush_lex();
872 return; 872 return;
873 873
874 } else { 874 } else {
875 875
876 command = db_read_command(); 876 command = db_read_command();
877 if (command == NULL) 877 if (command == NULL)
878 return; 878 return;
879 879
880 if ((command->flag & CS_OWN) == 0) { 880 if ((command->flag & CS_OWN) == 0) {
881 881
882 /* 882 /*
883 * Standard syntax: 883 * Standard syntax:
884 * command [/modifier] [addr] [,count] 884 * command [/modifier] [addr] [,count]
885 */ 885 */
886 t = db_read_token(); /* get modifier */ 886 t = db_read_token(); /* get modifier */
887 if (t == tSLASH) { 887 if (t == tSLASH) {
888 t = db_read_token(); 888 t = db_read_token();
889 if (t != tIDENT) { 889 if (t != tIDENT) {
890 db_printf("Bad modifier\n"); 890 db_printf("Bad modifier\n");
891 db_flush_lex(); 891 db_flush_lex();
892 return; 892 return;
893 } 893 }
894 /* save modifier */ 894 /* save modifier */
895 strlcpy(modif, db_tok_string, sizeof(modif)); 895 strlcpy(modif, db_tok_string, sizeof(modif));
896 896
897 } else { 897 } else {
898 db_unread_token(t); 898 db_unread_token(t);
899 modif[0] = '\0'; 899 modif[0] = '\0';
900 } 900 }
901 901
902 if (db_expression(&addr)) { /*get address*/ 902 if (db_expression(&addr)) { /*get address*/
903 db_dot = (db_addr_t) addr; 903 db_dot = (db_addr_t) addr;
904 db_last_addr = db_dot; 904 db_last_addr = db_dot;
905 have_addr = true; 905 have_addr = true;
906 } else { 906 } else {
907 addr = (db_expr_t) db_dot; 907 addr = (db_expr_t) db_dot;
908 } 908 }
909 909
910 t = db_read_token(); 910 t = db_read_token();
911 if (t == tCOMMA) { /*Get count*/ 911 if (t == tCOMMA) { /*Get count*/
912 if (!db_expression(&count)) { 912 if (!db_expression(&count)) {
913 db_printf("Count missing\n"); 913 db_printf("Count missing\n");
914 db_flush_lex(); 914 db_flush_lex();
915 return; 915 return;
916 } 916 }
917 } else { 917 } else {
918 db_unread_token(t); 918 db_unread_token(t);
919 } 919 }
920 if ((command->flag & CS_MORE) == 0) { 920 if ((command->flag & CS_MORE) == 0) {
921 db_skip_to_eol(); 921 db_skip_to_eol();
922 } 922 }
923 } 923 }
924 } 924 }
925 925
926 if (command != NULL && command->flag & CS_NOREPEAT) { 926 if (command != NULL && command->flag & CS_NOREPEAT) {
927 *last_cmdp = NULL; 927 *last_cmdp = NULL;
928 last_count = 0; 928 last_count = 0;
929 } else { 929 } else {
930 *last_cmdp = command; 930 *last_cmdp = command;
931 last_count = count; 931 last_count = count;
932 } 932 }
933 933
934 934
935 if (command != NULL) { 935 if (command != NULL) {
936 /* 936 /*
937 * Execute the command. 937 * Execute the command.
938 */ 938 */
939 if (command->fcn != NULL) 939 if (command->fcn != NULL)
940 (*command->fcn)(addr, have_addr, count, modif); 940 (*command->fcn)(addr, have_addr, count, modif);
941 941
942 if (command->flag & CS_SET_DOT) { 942 if (command->flag & CS_SET_DOT) {
943 /* 943 /*
944 * If command changes dot, set dot to 944 * If command changes dot, set dot to
945 * previous address displayed (if 'ed' style). 945 * previous address displayed (if 'ed' style).
946 */ 946 */
947 if (db_ed_style) 947 if (db_ed_style)
948 db_dot = db_prev; 948 db_dot = db_prev;
949 else 949 else
950 db_dot = db_next; 950 db_dot = db_next;
951 } else { 951 } else {
952 /* 952 /*
953 * If command does not change dot, 953 * If command does not change dot,
954 * set 'next' location to be the same. 954 * set 'next' location to be the same.
955 */ 955 */
956 db_next = db_dot; 956 db_next = db_dot;
957 } 957 }
958 } 958 }
959} 959}
960 960
961/* 961/*
962 * Print help for commands 962 * Print help for commands
963 */ 963 */
964static void 964static void
965db_help_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 965db_help_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
966const char *modif) 966const char *modif)
967{ 967{
968 const struct db_command *command; 968 const struct db_command *command;
969 int t; 969 int t;
970 970
971 t = db_read_token(); 971 t = db_read_token();
972 972
973 /* is there another command after the "help"? */ 973 /* is there another command after the "help"? */
974 if (t != tIDENT) { 974 if (t != tIDENT) {
975 /* print base commands */ 975 /* print base commands */
976 db_cmd_list(&db_base_cmd_list); 976 db_cmd_list(&db_base_cmd_list);
977 return; 977 return;
978 } 978 }
979 979
980 command = db_read_command(); 980 command = db_read_command();
981 if (command == NULL) 981 if (command == NULL)
982 return; 982 return;
983 983
984#ifdef DDB_VERBOSE_HELP 984#ifdef DDB_VERBOSE_HELP
985 db_printf("Command: %s\n", command->name); 985 db_printf("Command: %s\n", command->name);
986 if (command->cmd_descr != NULL) 986 if (command->cmd_descr != NULL)
987 db_printf(" Description: %s\n", command->cmd_descr); 987 db_printf(" Description: %s\n", command->cmd_descr);
988 if (command->cmd_arg != NULL) 988 if (command->cmd_arg != NULL)
989 db_printf(" Arguments: %s\n", command->cmd_arg); 989 db_printf(" Arguments: %s\n", command->cmd_arg);
990 if (command->cmd_arg_help != NULL) 990 if (command->cmd_arg_help != NULL)
991 db_printf(" Arguments description:\n%s\n", 991 db_printf(" Arguments description:\n%s\n",
992 command->cmd_arg_help); 992 command->cmd_arg_help);
993 if ((command->cmd_arg == NULL) && (command->cmd_descr == NULL)) 993 if ((command->cmd_arg == NULL) && (command->cmd_descr == NULL))
994 db_printf(" No help message.\n"); 994 db_printf(" No help message.\n");
995#endif 995#endif
996 996
997 db_skip_to_eol(); 997 db_skip_to_eol();
998} 998}
999 999
1000/*ARGSUSED*/ 1000/*ARGSUSED*/
1001static void 1001static void
1002db_map_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 1002db_map_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
1003 const char *modif) 1003 const char *modif)
1004{ 1004{
1005#ifdef _KERNEL 1005#ifdef _KERNEL
1006 bool full = false; 1006 bool full = false;
1007 1007
1008 if (modif[0] == 'f') 1008 if (modif[0] == 'f')
1009 full = true; 1009 full = true;
1010 1010
1011 if (have_addr == false) 1011 if (have_addr == false)
1012 addr = (db_expr_t)(uintptr_t)db_read_ptr("kernel_map"); 1012 addr = (db_expr_t)(uintptr_t)db_read_ptr("kernel_map");
1013 1013
1014 uvm_map_printit((struct vm_map *)(uintptr_t) addr, full, db_printf); 1014 uvm_map_printit((struct vm_map *)(uintptr_t) addr, full, db_printf);
1015#else 1015#else
1016 db_kernelonly(); 1016 db_kernelonly();
1017#endif /* XXX CRASH(8) */ 1017#endif /* XXX CRASH(8) */
1018} 1018}
1019 1019
1020/*ARGSUSED*/ 1020/*ARGSUSED*/
1021static void 1021static void
1022db_object_print_cmd(db_expr_t addr, bool have_addr, 1022db_object_print_cmd(db_expr_t addr, bool have_addr,
1023 db_expr_t count, const char *modif) 1023 db_expr_t count, const char *modif)
1024{ 1024{
1025#ifdef _KERNEL /* XXX CRASH(8) */ 1025#ifdef _KERNEL /* XXX CRASH(8) */
1026 bool full = false; 1026 bool full = false;
1027 1027
1028 if (modif[0] == 'f') 1028 if (modif[0] == 'f')
1029 full = true; 1029 full = true;
1030 1030
1031 uvm_object_printit((struct uvm_object *)(uintptr_t) addr, full, 1031 uvm_object_printit((struct uvm_object *)(uintptr_t) addr, full,
1032 db_printf); 1032 db_printf);
1033#else 1033#else
1034 db_kernelonly(); 1034 db_kernelonly();
1035#endif 1035#endif
1036} 1036}
1037 1037
1038/*ARGSUSED*/ 1038/*ARGSUSED*/
1039static void 1039static void
1040db_page_print_cmd(db_expr_t addr, bool have_addr, 1040db_page_print_cmd(db_expr_t addr, bool have_addr,
1041 db_expr_t count, const char *modif) 1041 db_expr_t count, const char *modif)
1042{ 1042{
1043#ifdef _KERNEL /* XXX CRASH(8) */ 1043#ifdef _KERNEL /* XXX CRASH(8) */
1044 bool full = false; 1044 bool full = false;
1045 1045
1046 if (modif[0] == 'f') 1046 if (modif[0] == 'f')
1047 full = true; 1047 full = true;
1048 1048
1049 uvm_page_printit((struct vm_page *)(uintptr_t) addr, full, db_printf); 1049 uvm_page_printit((struct vm_page *)(uintptr_t) addr, full, db_printf);
1050#else 1050#else
1051 db_kernelonly(); 1051 db_kernelonly();
1052#endif 1052#endif
1053} 1053}
1054 1054
1055/*ARGSUSED*/ 1055/*ARGSUSED*/
1056static void 1056static void
1057db_show_all_pages(db_expr_t addr, bool have_addr, 1057db_show_all_pages(db_expr_t addr, bool have_addr,
1058 db_expr_t count, const char *modif) 1058 db_expr_t count, const char *modif)
1059{ 1059{
1060 1060
1061#ifdef _KERNEL /* XXX CRASH(8) */ 1061#ifdef _KERNEL /* XXX CRASH(8) */
1062 uvm_page_printall(db_printf); 1062 uvm_page_printall(db_printf);
1063#else 1063#else
1064 db_kernelonly(); 1064 db_kernelonly();
1065#endif 1065#endif
1066} 1066}
1067 1067
1068/*ARGSUSED*/ 1068/*ARGSUSED*/
1069static void 1069static void
1070db_buf_print_cmd(db_expr_t addr, bool have_addr, 1070db_buf_print_cmd(db_expr_t addr, bool have_addr,
1071 db_expr_t count, const char *modif) 1071 db_expr_t count, const char *modif)
1072{ 1072{
1073#ifdef _KERNEL /* XXX CRASH(8) */ 1073#ifdef _KERNEL /* XXX CRASH(8) */
1074 bool full = false; 1074 bool full = false;
1075 1075
1076 if (modif[0] == 'f') 1076 if (modif[0] == 'f')
1077 full = true; 1077 full = true;
1078 1078
1079 vfs_buf_print((struct buf *)(uintptr_t) addr, full, db_printf); 1079 vfs_buf_print((struct buf *)(uintptr_t) addr, full, db_printf);
1080#else 1080#else
1081 db_kernelonly(); 1081 db_kernelonly();
1082#endif 1082#endif
1083} 1083}
1084 1084
1085/*ARGSUSED*/ 1085/*ARGSUSED*/
1086static void 1086static void
1087db_event_print_cmd(db_expr_t addr, bool have_addr, 1087db_event_print_cmd(db_expr_t addr, bool have_addr,
1088 db_expr_t count, const char *modif) 1088 db_expr_t count, const char *modif)
1089{ 1089{
1090 bool showzero = false; 1090 bool showzero = false;
1091 bool showall = true; 1091 bool showall = true;
1092 bool showintr = false; 1092 bool showintr = false;
1093 bool showtrap = false; 1093 bool showtrap = false;
1094 bool showmisc = false; 1094 bool showmisc = false;
1095 struct evcnt ev, *evp; 1095 struct evcnt ev, *evp;
1096 char buf[80]; 1096 char buf[80];
1097 int i; 1097 int i;
1098 1098
1099 i = 0; 1099 i = 0;
1100 while (modif[i]) { 1100 while (modif[i]) {
1101 switch (modif[i]) { 1101 switch (modif[i]) {
1102 case 'f': 1102 case 'f':
1103 showzero = true; 1103 showzero = true;
1104 break; 1104 break;
1105 case 'i': 1105 case 'i':
1106 showintr = true; 1106 showintr = true;
1107 showall = false; 1107 showall = false;
1108 break; 1108 break;
1109 case 't': 1109 case 't':
1110 showtrap = true; 1110 showtrap = true;
1111 showall = false; 1111 showall = false;
1112 break; 1112 break;
1113 case 'm': 1113 case 'm':
1114 showmisc = true; 1114 showmisc = true;
1115 showall = false; 1115 showall = false;
1116 break; 1116 break;
1117 } 1117 }
1118 i++; 1118 i++;
1119 } 1119 }
1120 1120
1121 if (showall) 1121 if (showall)
1122 showmisc = showintr = showtrap = true; 1122 showmisc = showintr = showtrap = true;
1123 1123
1124 evp = (struct evcnt *)db_read_ptr("allevents"); 1124 evp = (struct evcnt *)db_read_ptr("allevents");
1125 while (evp != NULL) { 1125 while (evp != NULL) {
1126 db_read_bytes((db_addr_t)evp, sizeof(ev), (char *)&ev); 1126 db_read_bytes((db_addr_t)evp, sizeof(ev), (char *)&ev);
1127 evp = ev.ev_list.tqe_next; 1127 evp = ev.ev_list.tqe_next;
1128 if (ev.ev_count == 0 && !showzero) 1128 if (ev.ev_count == 0 && !showzero)
1129 continue; 1129 continue;
1130 if (ev.ev_type == EVCNT_TYPE_INTR && !showintr) 1130 if (ev.ev_type == EVCNT_TYPE_INTR && !showintr)
1131 continue; 1131 continue;
1132 if (ev.ev_type == EVCNT_TYPE_TRAP && !showtrap) 1132 if (ev.ev_type == EVCNT_TYPE_TRAP && !showtrap)
1133 continue; 1133 continue;
1134 if (ev.ev_type == EVCNT_TYPE_MISC && !showmisc) 1134 if (ev.ev_type == EVCNT_TYPE_MISC && !showmisc)
1135 continue; 1135 continue;
1136 db_read_bytes((db_addr_t)ev.ev_group, ev.ev_grouplen + 1, buf); 1136 db_read_bytes((db_addr_t)ev.ev_group, ev.ev_grouplen + 1, buf);
1137 db_printf("evcnt type %d: %s ", ev.ev_type, buf); 1137 db_printf("evcnt type %d: %s ", ev.ev_type, buf);
1138 db_read_bytes((db_addr_t)ev.ev_name, ev.ev_namelen + 1, buf); 1138 db_read_bytes((db_addr_t)ev.ev_name, ev.ev_namelen + 1, buf);
1139 db_printf("%s = %lld\n", buf, (long long)ev.ev_count); 1139 db_printf("%s = %lld\n", buf, (long long)ev.ev_count);
1140 } 1140 }
1141} 1141}
1142 1142
1143/*ARGSUSED*/ 1143/*ARGSUSED*/
1144static void 1144static void
1145db_vnode_print_cmd(db_expr_t addr, bool have_addr, 1145db_vnode_print_cmd(db_expr_t addr, bool have_addr,
1146 db_expr_t count, const char *modif) 1146 db_expr_t count, const char *modif)
1147{ 1147{
1148#ifdef _KERNEL /* XXX CRASH(8) */ 1148#ifdef _KERNEL /* XXX CRASH(8) */
1149 bool full = false; 1149 bool full = false;
1150 1150
1151 if (modif[0] == 'f') 1151 if (modif[0] == 'f')
1152 full = true; 1152 full = true;
1153 1153
1154 vfs_vnode_print((struct vnode *)(uintptr_t) addr, full, db_printf); 1154 vfs_vnode_print((struct vnode *)(uintptr_t) addr, full, db_printf);
1155#else 1155#else
1156 db_kernelonly(); 1156 db_kernelonly();
1157#endif 1157#endif
1158} 1158}
1159 1159
1160/*ARGSUSED*/ 1160/*ARGSUSED*/
1161static void 1161static void
1162db_vnode_lock_print_cmd(db_expr_t addr, bool have_addr, 1162db_vnode_lock_print_cmd(db_expr_t addr, bool have_addr,
1163 db_expr_t count, const char *modif) 1163 db_expr_t count, const char *modif)
1164{ 1164{
1165#ifdef _KERNEL /* XXX CRASH(8) */ 1165#ifdef _KERNEL /* XXX CRASH(8) */
1166 bool full = false; 1166 bool full = false;
1167 1167
1168 if (modif[0] == 'f') 1168 if (modif[0] == 'f')
1169 full = true; 1169 full = true;
1170 1170
1171 vfs_vnode_lock_print((struct vnode *)(uintptr_t) addr, full, db_printf); 1171 vfs_vnode_lock_print((struct vnode *)(uintptr_t) addr, full, db_printf);
1172#else 1172#else
1173 db_kernelonly(); 1173 db_kernelonly();
1174#endif 1174#endif
1175} 1175}
1176 1176
1177/*ARGSUSED*/ 1177/*ARGSUSED*/
1178static void 1178static void
1179db_vmem_print_cmd(db_expr_t addr, bool have_addr, 1179db_vmem_print_cmd(db_expr_t addr, bool have_addr,
1180 db_expr_t count, const char *modif) 1180 db_expr_t count, const char *modif)
1181{ 1181{
1182 1182
1183#ifdef _KERNEL /* XXX CRASH(8) */ 1183#ifdef _KERNEL /* XXX CRASH(8) */
1184 vmem_print((uintptr_t) addr, modif, db_printf); 1184 vmem_print((uintptr_t) addr, modif, db_printf);
1185#else 1185#else
1186 db_kernelonly(); 1186 db_kernelonly();
1187#endif 1187#endif
1188} 1188}
1189 1189
1190static void 1190static void
1191db_mount_print_cmd(db_expr_t addr, bool have_addr, 1191db_mount_print_cmd(db_expr_t addr, bool have_addr,
1192 db_expr_t count, const char *modif) 1192 db_expr_t count, const char *modif)
1193{ 1193{
1194#ifdef _KERNEL /* XXX CRASH(8) */ 1194#ifdef _KERNEL /* XXX CRASH(8) */
1195 bool full = false; 1195 bool full = false;
1196 1196
1197 if (modif[0] == 'f') 1197 if (modif[0] == 'f')
1198 full = true; 1198 full = true;
1199 1199
1200 vfs_mount_print((struct mount *)(uintptr_t) addr, full, db_printf); 1200 vfs_mount_print((struct mount *)(uintptr_t) addr, full, db_printf);
1201#endif 1201#endif
1202} 1202}
1203 1203
1204static void 1204static void
1205db_show_all_mount(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 1205db_show_all_mount(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
1206{ 1206{
1207#ifdef _KERNEL /* XXX CRASH(8) */ 1207#ifdef _KERNEL /* XXX CRASH(8) */
1208 bool full = false; 1208 bool full = false;
1209 1209
1210 if (modif[0] == 'f') 1210 if (modif[0] == 'f')
1211 full = true; 1211 full = true;
1212 1212
1213 vfs_mount_print_all(full, db_printf); 1213 vfs_mount_print_all(full, db_printf);
1214#else 1214#else
1215 db_kernelonly(); 1215 db_kernelonly();
1216#endif 1216#endif
1217} 1217}
1218 1218
1219/*ARGSUSED*/ 1219/*ARGSUSED*/
1220static void 1220static void
1221db_mbuf_print_cmd(db_expr_t addr, bool have_addr, 1221db_mbuf_print_cmd(db_expr_t addr, bool have_addr,
1222 db_expr_t count, const char *modif) 1222 db_expr_t count, const char *modif)
1223{ 1223{
1224 1224
1225#ifdef _KERNEL /* XXX CRASH(8) */ 1225#ifdef _KERNEL /* XXX CRASH(8) */
1226 m_print((const struct mbuf *)(uintptr_t) addr, modif, db_printf); 1226 m_print((const struct mbuf *)(uintptr_t) addr, modif, db_printf);
1227#else 1227#else
1228 db_kernelonly(); 1228 db_kernelonly();
1229#endif 1229#endif
1230} 1230}
1231 1231
1232/*ARGSUSED*/ 1232/*ARGSUSED*/
1233static void 1233static void
1234db_pool_print_cmd(db_expr_t addr, bool have_addr, 1234db_pool_print_cmd(db_expr_t addr, bool have_addr,
1235 db_expr_t count, const char *modif) 1235 db_expr_t count, const char *modif)
1236{ 1236{
1237 1237
1238#ifdef _KERNEL /* XXX CRASH(8) */ 1238#ifdef _KERNEL /* XXX CRASH(8) */
1239 pool_printit((struct pool *)(uintptr_t) addr, modif, db_printf); 1239 pool_printit((struct pool *)(uintptr_t) addr, modif, db_printf);
1240#else 1240#else
1241 db_kernelonly(); 1241 db_kernelonly();
1242#endif 1242#endif
1243} 1243}
1244 1244
1245/*ARGSUSED*/ 1245/*ARGSUSED*/
1246static void 1246static void
1247db_namecache_print_cmd(db_expr_t addr, bool have_addr, 1247db_namecache_print_cmd(db_expr_t addr, bool have_addr,
1248 db_expr_t count, const char *modif) 1248 db_expr_t count, const char *modif)
1249{ 1249{
1250 1250
1251#ifdef _KERNEL /* XXX CRASH(8) */ 1251#ifdef _KERNEL /* XXX CRASH(8) */
1252 namecache_print((struct vnode *)(uintptr_t) addr, db_printf); 1252 namecache_print((struct vnode *)(uintptr_t) addr, db_printf);
1253#else 1253#else
1254 db_kernelonly(); 1254 db_kernelonly();
1255#endif 1255#endif
1256} 1256}
1257 1257
1258/*ARGSUSED*/ 1258/*ARGSUSED*/
1259static void 1259static void
1260db_uvmexp_print_cmd(db_expr_t addr, bool have_addr, 1260db_uvmexp_print_cmd(db_expr_t addr, bool have_addr,
1261 db_expr_t count, const char *modif) 1261 db_expr_t count, const char *modif)
1262{ 1262{
1263 1263
1264#ifdef _KERNEL /* XXX CRASH(8) */ 1264#ifdef _KERNEL /* XXX CRASH(8) */
1265 uvmexp_print(db_printf); 1265 uvmexp_print(db_printf);
1266#else 1266#else
1267 db_kernelonly(); 1267 db_kernelonly();
1268#endif 1268#endif
1269} 1269}
1270 1270
1271/*ARGSUSED */ 1271/*ARGSUSED */
1272static void 1272static void
1273db_socket_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count, 1273db_socket_print_cmd(db_expr_t addr, bool have_addr, db_expr_t count,
1274 const char *modif) 1274 const char *modif)
1275{ 1275{
1276 1276
1277#ifdef _KERNEL /* XXX CRASH(8) */ 1277#ifdef _KERNEL /* XXX CRASH(8) */
1278 socket_print(modif, db_printf); 1278 socket_print(modif, db_printf);
1279#else 1279#else
1280 db_kernelonly(); 1280 db_kernelonly();
1281#endif 1281#endif
1282} 1282}
1283 1283
1284#ifdef KERNHIST 1284#ifdef KERNHIST
1285/*ARGSUSED*/ 1285/*ARGSUSED*/
1286static void 1286static void
1287db_kernhist_print_cmd(db_expr_t addr, bool have_addr, 1287db_kernhist_print_cmd(db_expr_t addr, bool have_addr,
1288 db_expr_t count, const char *modif) 1288 db_expr_t count, const char *modif)
1289{ 1289{
1290 1290
1291 if (!have_addr) 1291 if (!have_addr)
1292 addr = 0; 1292 addr = 0;
1293 1293
1294 if (count == -1) 1294 if (count == -1)
1295 count = 0; 1295 count = 0;
1296 1296
1297 kernhist_print((void *)(uintptr_t)addr, count, modif, db_printf); 1297 kernhist_print((void *)(uintptr_t)addr, count, modif, db_printf);
1298} 1298}
1299#endif 1299#endif
1300 1300
1301/*ARGSUSED*/ 1301/*ARGSUSED*/
1302static void 1302static void
1303db_lock_print_cmd(db_expr_t addr, bool have_addr, 1303db_lock_print_cmd(db_expr_t addr, bool have_addr,
1304 db_expr_t count, const char *modif) 1304 db_expr_t count, const char *modif)
1305{ 1305{
1306 1306
1307 lockdebug_lock_print(have_addr ? (void *)(uintptr_t)addr : NULL, 1307 lockdebug_lock_print(have_addr ? (void *)(uintptr_t)addr : NULL,
1308 db_printf); 1308 db_printf);
1309} 1309}
1310 1310
1311static void 1311static void
1312db_show_all_locks(db_expr_t addr, bool have_addr, 1312db_show_all_locks(db_expr_t addr, bool have_addr,
1313 db_expr_t count, const char *modif) 1313 db_expr_t count, const char *modif)
1314{ 1314{
1315 1315
1316#ifdef _KERNEL /* XXX CRASH(8) */ 1316#ifdef _KERNEL /* XXX CRASH(8) */
1317 lockdebug_show_all_locks(db_printf, modif); 1317 lockdebug_show_all_locks(db_printf, modif);
1318#else 1318#else
1319 db_kernelonly(); 1319 db_kernelonly();
1320#endif 1320#endif
1321} 1321}
1322 1322
1323static void 1323static void
1324db_show_all_freelists(db_expr_t addr, bool have_addr, 1324db_show_all_freelists(db_expr_t addr, bool have_addr,
1325 db_expr_t count, const char *modif) 1325 db_expr_t count, const char *modif)
1326{ 1326{
1327 1327
1328#ifdef _KERNEL /* XXX CRASH(8) */ 1328#ifdef _KERNEL /* XXX CRASH(8) */
1329 uvm_page_print_freelists(db_printf); 1329 uvm_page_print_freelists(db_printf);
1330#else 1330#else
1331 db_kernelonly(); 1331 db_kernelonly();
1332#endif 1332#endif
1333} 1333}
1334 1334
1335static void 1335static void
1336db_show_lockstats(db_expr_t addr, bool have_addr, 1336db_show_lockstats(db_expr_t addr, bool have_addr,
1337 db_expr_t count, const char *modif) 1337 db_expr_t count, const char *modif)
1338{ 1338{
1339 1339
1340#ifdef _KERNEL /* XXX CRASH(8) */ 1340#ifdef _KERNEL /* XXX CRASH(8) */
1341 lockdebug_show_lockstats(db_printf); 1341 lockdebug_show_lockstats(db_printf);
1342#else 1342#else
1343 db_kernelonly(); 1343 db_kernelonly();
1344#endif 1344#endif
1345} 1345}
1346 1346
1347/* 1347/*
1348 * Call random function: 1348 * Call random function:
1349 * !expr(arg,arg,arg) 1349 * !expr(arg,arg,arg)
1350 */ 1350 */
1351/*ARGSUSED*/ 1351/*ARGSUSED*/
1352static void 1352static void
1353db_fncall(db_expr_t addr, bool have_addr, 1353db_fncall(db_expr_t addr, bool have_addr,
1354 db_expr_t count, const char *modif) 1354 db_expr_t count, const char *modif)
1355{ 1355{
1356#ifdef _KERNEL 1356#ifdef _KERNEL
1357 db_expr_t fn_addr; 1357 db_expr_t fn_addr;
1358#define MAXARGS 11 1358#define MAXARGS 11
1359 db_expr_t args[MAXARGS]; 1359 db_expr_t args[MAXARGS];
1360 int nargs = 0; 1360 int nargs = 0;
1361 db_expr_t retval; 1361 db_expr_t retval;
1362 db_expr_t (*func)(db_expr_t, ...); 1362 db_expr_t (*func)(db_expr_t, ...);
1363 int t; 1363 int t;
1364 1364
1365 if (!db_expression(&fn_addr)) { 1365 if (!db_expression(&fn_addr)) {
1366 db_printf("Bad function\n"); 1366 db_printf("Bad function\n");
1367 db_flush_lex(); 1367 db_flush_lex();
1368 return; 1368 return;
1369 } 1369 }
1370 func = (db_expr_t (*)(db_expr_t, ...))(uintptr_t) fn_addr; 1370 func = (db_expr_t (*)(db_expr_t, ...))(uintptr_t) fn_addr;
1371 1371
1372 t = db_read_token(); 1372 t = db_read_token();
1373 if (t == tLPAREN) { 1373 if (t == tLPAREN) {
1374 if (db_expression(&args[0])) { 1374 if (db_expression(&args[0])) {
1375 nargs++; 1375 nargs++;
1376 while ((t = db_read_token()) == tCOMMA) { 1376 while ((t = db_read_token()) == tCOMMA) {
1377 if (nargs == MAXARGS) { 1377 if (nargs == MAXARGS) {
1378 db_printf("Too many arguments\n"); 1378 db_printf("Too many arguments\n");
1379 db_flush_lex(); 1379 db_flush_lex();
1380 return; 1380 return;
1381 } 1381 }
1382 if (!db_expression(&args[nargs])) { 1382 if (!db_expression(&args[nargs])) {
1383 db_printf("Argument missing\n"); 1383 db_printf("Argument missing\n");
1384 db_flush_lex(); 1384 db_flush_lex();
1385 return; 1385 return;
1386 } 1386 }
1387 nargs++; 1387 nargs++;
1388 } 1388 }
1389 db_unread_token(t); 1389 db_unread_token(t);
1390 } 1390 }
1391 if (db_read_token() != tRPAREN) { 1391 if (db_read_token() != tRPAREN) {
1392 db_printf("?\n"); 1392 db_printf("?\n");
1393 db_flush_lex(); 1393 db_flush_lex();
1394 return; 1394 return;
1395 } 1395 }
1396 } 1396 }
1397 db_skip_to_eol(); 1397 db_skip_to_eol();
1398 1398
1399 while (nargs < MAXARGS) { 1399 while (nargs < MAXARGS) {
1400 args[nargs++] = 0; 1400 args[nargs++] = 0;
1401 } 1401 }
1402 1402
1403 retval = (*func)(args[0], args[1], args[2], args[3], args[4], 1403 retval = (*func)(args[0], args[1], args[2], args[3], args[4],
1404 args[5], args[6], args[7], args[8], args[9]); 1404 args[5], args[6], args[7], args[8], args[9]);
1405 db_printf("%s\n", db_num_to_str(retval)); 1405 db_printf("%s\n", db_num_to_str(retval));
1406#else /* _KERNEL */ 1406#else /* _KERNEL */
1407 db_kernelonly(); 1407 db_kernelonly();
1408#endif /* _KERNEL */ 1408#endif /* _KERNEL */
1409} 1409}
1410 1410
1411static void 1411static void
1412db_reboot_cmd(db_expr_t addr, bool have_addr, 1412db_reboot_cmd(db_expr_t addr, bool have_addr,
1413 db_expr_t count, const char *modif) 1413 db_expr_t count, const char *modif)
1414{ 1414{
1415#ifdef _KERNEL 1415#ifdef _KERNEL
1416 db_expr_t bootflags; 1416 db_expr_t bootflags;
1417 1417
1418 /* Flags, default to RB_AUTOBOOT */ 1418 /* Flags, default to RB_AUTOBOOT */
1419 if (!db_expression(&bootflags)) 1419 if (!db_expression(&bootflags))
1420 bootflags = (db_expr_t)RB_AUTOBOOT; 1420 bootflags = (db_expr_t)RB_AUTOBOOT;
1421 if (db_read_token() != tEOL) { 1421 if (db_read_token() != tEOL) {
1422 db_error("?\n"); 1422 db_error("?\n");
1423 /*NOTREACHED*/ 1423 /*NOTREACHED*/
1424 } 1424 }
1425 /* 1425 /*
1426 * We are leaving DDB, never to return upward. 1426 * We are leaving DDB, never to return upward.
1427 * Clear db_recover so that we can debug faults in functions 1427 * Clear db_recover so that we can debug faults in functions
1428 * called from cpu_reboot. 1428 * called from cpu_reboot.
1429 */ 1429 */
1430 db_recover = 0; 1430 db_recover = 0;
1431 /* Avoid all mutex errors */ 1431 /* Avoid all mutex errors */
1432 lockdebug_dismiss(); 1432 lockdebug_dismiss();
1433 panicstr = "reboot forced via kernel debugger"; 1433 panicstr = "reboot forced via kernel debugger";
1434 /* Make it possible to break into the debugger again */ 1434 /* Make it possible to break into the debugger again */
1435 spl0(); 1435 spl0();
1436 kern_reboot((int)bootflags, NULL); 1436 kern_reboot((int)bootflags, NULL);
1437#else /* _KERNEL */ 1437#else /* _KERNEL */
1438 db_kernelonly(); 1438 db_kernelonly();
1439#endif /* _KERNEL */ 1439#endif /* _KERNEL */
1440} 1440}
1441 1441
1442static void 1442static void
1443db_sifting_cmd(db_expr_t addr, bool have_addr, 1443db_sifting_cmd(db_expr_t addr, bool have_addr,
1444 db_expr_t count, const char *modif) 1444 db_expr_t count, const char *modif)
1445{ 1445{
1446 int mode, t; 1446 int mode, t;
1447 1447
1448 t = db_read_token(); 1448 t = db_read_token();
1449 if (t == tSLASH) { 1449 if (t == tSLASH) {
1450 t = db_read_token(); 1450 t = db_read_token();
1451 if (t != tIDENT) { 1451 if (t != tIDENT) {
1452 bad_modifier: 1452 bad_modifier:
1453 db_printf("Bad modifier\n"); 1453 db_printf("Bad modifier\n");
1454 db_flush_lex(); 1454 db_flush_lex();
1455 return; 1455 return;
1456 } 1456 }
1457 if (!strcmp(db_tok_string, "F")) 1457 if (!strcmp(db_tok_string, "F"))
1458 mode = 'F'; 1458 mode = 'F';
1459 else 1459 else
1460 goto bad_modifier; 1460 goto bad_modifier;
1461 t = db_read_token(); 1461 t = db_read_token();
1462 } else 1462 } else
1463 mode = 0; 1463 mode = 0;
1464 1464
1465 if (t == tIDENT) 1465 if (t == tIDENT)
1466 db_sifting(db_tok_string, mode); 1466 db_sifting(db_tok_string, mode);
1467 else { 1467 else {
1468 db_printf("Bad argument (non-string)\n"); 1468 db_printf("Bad argument (non-string)\n");
1469 db_flush_lex(); 1469 db_flush_lex();
1470 } 1470 }
1471} 1471}
1472 1472
1473static void 1473static void
1474db_stack_trace_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif) 1474db_stack_trace_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)

cvs diff -r1.38 -r1.39 src/sys/ddb/db_command.h (switch to unified diff)

--- src/sys/ddb/db_command.h 2020/05/31 09:51:55 1.38
+++ src/sys/ddb/db_command.h 2020/10/30 06:57:08 1.39
@@ -1,156 +1,156 @@ @@ -1,156 +1,156 @@
1/* $NetBSD: db_command.h,v 1.38 2020/05/31 09:51:55 rin Exp $ */ 1/* $NetBSD: db_command.h,v 1.39 2020/10/30 06:57:08 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 1996, 1997, 1998, 1999, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Hamsik. 8 * by Adam Hamsik.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Mach Operating System 33 * Mach Operating System
34 * Copyright (c) 1991,1990 Carnegie Mellon University 34 * Copyright (c) 1991,1990 Carnegie Mellon University
35 * All Rights Reserved. 35 * All Rights Reserved.
36 * 36 *
37 * Permission to use, copy, modify and distribute this software and its 37 * Permission to use, copy, modify and distribute this software and its
38 * documentation is hereby granted, provided that both the copyright 38 * documentation is hereby granted, provided that both the copyright
39 * notice and this permission notice appear in all copies of the 39 * notice and this permission notice appear in all copies of the
40 * software, derivative works or modified versions, and any portions 40 * software, derivative works or modified versions, and any portions
41 * thereof, and that both notices appear in supporting documentation. 41 * thereof, and that both notices appear in supporting documentation.
42 * 42 *
43 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 43 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
44 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 44 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
45 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 45 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
46 * 46 *
47 * Carnegie Mellon requests users of this software to return to 47 * Carnegie Mellon requests users of this software to return to
48 * 48 *
49 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 49 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
50 * School of Computer Science 50 * School of Computer Science
51 * Carnegie Mellon University 51 * Carnegie Mellon University
52 * Pittsburgh PA 15213-3890 52 * Pittsburgh PA 15213-3890
53 * 53 *
54 * any improvements or extensions that they make and grant Carnegie the 54 * any improvements or extensions that they make and grant Carnegie the
55 * rights to redistribute these changes. 55 * rights to redistribute these changes.
56 * 56 *
57 * Author: David B. Golub, Carnegie Mellon University 57 * Author: David B. Golub, Carnegie Mellon University
58 * Date: 7/90 58 * Date: 7/90
59 */ 59 */
60 60
61#ifndef _DDB_COMMAND_ 61#ifndef _DDB_COMMAND_
62#define _DDB_COMMAND_ 62#define _DDB_COMMAND_
63 63
64void db_skip_to_eol(void); 64void db_skip_to_eol(void);
65void db_command_loop(void); 65void db_command_loop(void);
66void db_error(const char *) __dead; 66void db_error(const char *) __dead;
67 67
68extern db_addr_t db_dot; /* current location */ 68extern db_addr_t db_dot; /* current location */
69extern db_addr_t db_last_addr; /* last explicit address typed */ 69extern db_addr_t db_last_addr; /* last explicit address typed */
70extern db_addr_t db_prev; /* last address examined 70extern db_addr_t db_prev; /* last address examined
71 or written */ 71 or written */
72extern db_addr_t db_next; /* next address to be examined 72extern db_addr_t db_next; /* next address to be examined
73 or written */ 73 or written */
74 74
75extern char db_cmd_on_enter[]; 75extern char db_cmd_on_enter[];
76 76
77struct db_command; 77struct db_command;
78 78
79 79
80 80
81/* 81/*
82 * Macro include help when DDB_VERBOSE_HELP option(9) is used 82 * Macro include help when DDB_VERBOSE_HELP option(9) is used
83 */ 83 */
84#ifdef DDB_VERBOSE_HELP 84#ifdef DDB_VERBOSE_HELP
85#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,arg_desc)\ 85#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,arg_desc)\
86 name,funct,type,cmd_descr,cmd_arg,arg_desc 86 name,funct,type,cmd_descr,cmd_arg,arg_desc
87#else 87#else
88#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,arg_desc)\ 88#define DDB_ADD_CMD(name,funct,type,cmd_descr,cmd_arg,arg_desc)\
89 name,funct,type 89 name,funct,type
90#endif 90#endif
91  91
92 92
93 93
94/* 94/*
95 * we have two types of lists one for base commands like reboot 95 * we have two types of lists one for base commands like reboot
96 * and another list for show subcommands. 96 * and another list for show subcommands.
97 */ 97 */
98 98
99#define DDB_BASE_CMD 0 99#define DDB_BASE_CMD 0
100#define DDB_SHOW_CMD 1 100#define DDB_SHOW_CMD 1
101#define DDB_MACH_CMD 2 101#define DDB_MACH_CMD 2
102 102
103 103
104int db_register_tbl(uint8_t, const struct db_command *); 104int db_register_tbl(uint8_t, const struct db_command *);
105int db_unregister_tbl(uint8_t, const struct db_command *); 105int db_unregister_tbl(uint8_t, const struct db_command *);
106 106
107/* 107/*
108 * Command table 108 * Command table
109 */ 109 */
110struct db_command { 110struct db_command {
111 const char *name; /* command name */ 111 const char *name; /* command name */
112  112
113 /* function to call */ 113 /* function to call */
114 void (*fcn)(db_expr_t, bool, db_expr_t, const char *); 114 void (*fcn)(db_expr_t, bool, db_expr_t, const char *);
115 /* 115 /*
116 * Flag is used for modifing command behaviour. 116 * Flag is used for modifing command behaviour.
117 * CS_OWN && CS_MORE are specify type of command arguments. 117 * CS_OWN && CS_MORE are specify type of command arguments.
118 * CS_OWN commandmanage arguments in own way. 118 * CS_OWN commandmanage arguments in own way.
119 * CS_MORE db_command() prepare argument list. 119 * CS_MORE db_command() prepare argument list.
120 * 120 *
121 * CS_COMPAT is set for all level 2 commands with level 3 childs (show all pages) 121 * CS_COMPAT is set for all level 2 commands with level 3 childs (show all pages)
122 * 122 *
123 * CS_SHOW identify show command in BASE command list 123 * CS_SHOW identify show command in BASE command list
124 * CS_MACH identify mach command in BASE command list 124 * CS_MACH identify mach command in BASE command list
125 * 125 *
126 * CS_SET_DOT specify if this command is put to last added command memory. 126 * CS_SET_DOT specify if this command is put to last added command memory.
127 * CS_NOREPEAT this command does not repeat 127 * CS_NOREPEAT this command does not repeat
128 */ 128 */
129 uint16_t flag; /* extra info: */ 129 uint16_t flag; /* extra info: */
130#define CS_OWN 0x1 /* non-standard syntax */ 130#define CS_OWN 0x1 /* non-standard syntax */
131#define CS_MORE 0x2 /* standard syntax, but may have other 131#define CS_MORE 0x2 /* standard syntax, but may have other
132 words at end */ 132 words at end */
133#define CS_COMPAT 0x4 /* is set for compatibilty with old  133#define CS_COMPAT 0x4 /* is set for compatibilty with old
134 ddb versions*/ 134 ddb versions*/
135#define CS_SHOW 0x8 /* select show list */ 135#define CS_SHOW 0x8 /* select show list */
136#define CS_MACH 0x10 /* select machine dependent list */ 136#define CS_MACH 0x10 /* select machine dependent list */
137 137
138#define CS_SET_DOT 0x100 /* set dot after command */ 138#define CS_SET_DOT 0x100 /* set dot after command */
139#define CS_NOREPEAT 0x200 /* don't set last_command */ 139#define CS_NOREPEAT 0x200 /* don't set last_command */
140#ifdef DDB_VERBOSE_HELP 140#ifdef DDB_VERBOSE_HELP
141 const char *cmd_descr; /* description of command */ 141 const char *cmd_descr; /* description of command */
142 const char *cmd_arg; /* command arguments */ 142 const char *cmd_arg; /* command arguments */
143 const char *cmd_arg_help; /* arguments description */ 143 const char *cmd_arg_help; /* arguments description */
144#endif 144#endif
145}; 145};
146 146
147void *db_alloc(size_t); 147void *db_alloc(size_t);
148void *db_zalloc(size_t); 148void *db_zalloc(size_t);
149void db_free(void *, size_t); 149void db_free(void *, size_t);
150 150
151#ifndef _KERNEL 151#ifndef _KERNEL
152#define db_kernelonly() \ 152#define db_kernelonly() \
153 db_printf("%s: can only be used in-kernel.\n", __func__) 153 db_printf("%s: can only be used in-kernel.\n", __func__)
154#endif 154#endif
155 155
156#endif /*_DDB_COMMAND_*/ 156#endif /*_DDB_COMMAND_*/

cvs diff -r1.27 -r1.28 src/sys/ddb/db_input.c (switch to unified diff)

--- src/sys/ddb/db_input.c 2019/09/29 02:00:22 1.27
+++ src/sys/ddb/db_input.c 2020/10/30 06:57:08 1.28
@@ -1,405 +1,405 @@ @@ -1,405 +1,405 @@
1/* $NetBSD: db_input.c,v 1.27 2019/09/29 02:00:22 uwe Exp $ */ 1/* $NetBSD: db_input.c,v 1.28 2020/10/30 06:57:08 skrll Exp $ */
2 2
3/* 3/*
4 * Mach Operating System 4 * Mach Operating System
5 * Copyright (c) 1991,1990 Carnegie Mellon University 5 * Copyright (c) 1991,1990 Carnegie Mellon University
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Permission to use, copy, modify and distribute this software and its 8 * Permission to use, copy, modify and distribute this software and its
9 * documentation is hereby granted, provided that both the copyright 9 * documentation is hereby granted, provided that both the copyright
10 * notice and this permission notice appear in all copies of the 10 * notice and this permission notice appear in all copies of the
11 * software, derivative works or modified versions, and any portions 11 * software, derivative works or modified versions, and any portions
12 * thereof, and that both notices appear in supporting documentation. 12 * thereof, and that both notices appear in supporting documentation.
13 * 13 *
14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 15 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 * 17 *
18 * Carnegie Mellon requests users of this software to return to 18 * Carnegie Mellon requests users of this software to return to
19 * 19 *
20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 20 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
21 * School of Computer Science 21 * School of Computer Science
22 * Carnegie Mellon University 22 * Carnegie Mellon University
23 * Pittsburgh PA 15213-3890 23 * Pittsburgh PA 15213-3890
24 * 24 *
25 * any improvements or extensions that they make and grant Carnegie the 25 * any improvements or extensions that they make and grant Carnegie the
26 * rights to redistribute these changes. 26 * rights to redistribute these changes.
27 * 27 *
28 * Author: David B. Golub, Carnegie Mellon University 28 * Author: David B. Golub, Carnegie Mellon University
29 * Date: 7/90 29 * Date: 7/90
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: db_input.c,v 1.27 2019/09/29 02:00:22 uwe Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: db_input.c,v 1.28 2020/10/30 06:57:08 skrll Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_ddbparam.h" 36#include "opt_ddbparam.h"
37#endif 37#endif
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/proc.h> 40#include <sys/proc.h>
41 41
42#include <ddb/ddb.h> 42#include <ddb/ddb.h>
43 43
44#include <dev/cons.h> 44#include <dev/cons.h>
45 45
46#ifndef DDB_HISTORY_SIZE 46#ifndef DDB_HISTORY_SIZE
47#define DDB_HISTORY_SIZE 0 47#define DDB_HISTORY_SIZE 0
48#endif /* DDB_HISTORY_SIZE */ 48#endif /* DDB_HISTORY_SIZE */
49 49
50/* 50/*
51 * Character input and editing. 51 * Character input and editing.
52 */ 52 */
53 53
54/* 54/*
55 * We don't track output position while editing input, 55 * We don't track output position while editing input,
56 * since input always ends with a new-line. We just 56 * since input always ends with a new-line. We just
57 * reset the line position at the end. 57 * reset the line position at the end.
58 */ 58 */
59static char *db_lbuf_start; /* start of input line buffer */ 59static char *db_lbuf_start; /* start of input line buffer */
60static char *db_lbuf_end; /* end of input line buffer */ 60static char *db_lbuf_end; /* end of input line buffer */
61static char *db_lc; /* current character */ 61static char *db_lc; /* current character */
62static char *db_le; /* one past last character */ 62static char *db_le; /* one past last character */
63#if DDB_HISTORY_SIZE != 0 63#if DDB_HISTORY_SIZE != 0
64static char db_history[DDB_HISTORY_SIZE]; /* start of history buffer */ 64static char db_history[DDB_HISTORY_SIZE]; /* start of history buffer */
65static char *db_history_curr = db_history; /* start of current line */ 65static char *db_history_curr = db_history; /* start of current line */
66static char *db_history_last = db_history; /* start of last line */ 66static char *db_history_last = db_history; /* start of last line */
67static char *db_history_prev = (char *) 0; /* start of previous line */ 67static char *db_history_prev = (char *) 0; /* start of previous line */
68#endif 68#endif
69 69
70 70
71#define CTRL(c) ((c) & 0x1f) 71#define CTRL(c) ((c) & 0x1f)
72#define isspace(c) ((c) == ' ' || (c) == '\t') 72#define isspace(c) ((c) == ' ' || (c) == '\t')
73#define BLANK ' ' 73#define BLANK ' '
74#define BACKUP '\b' 74#define BACKUP '\b'
75 75
76static int cnmaygetc(void); 76static int cnmaygetc(void);
77static void db_putstring(const char *, int); 77static void db_putstring(const char *, int);
78static void db_putnchars(int, int); 78static void db_putnchars(int, int);
79static void db_delete(int, int); 79static void db_delete(int, int);
80static void db_delete_line(void); 80static void db_delete_line(void);
81static int db_inputchar(int); 81static int db_inputchar(int);
82 82
83static void 83static void
84db_putstring(const char *s, int count) 84db_putstring(const char *s, int count)
85{ 85{
86 86
87 while (--count >= 0) 87 while (--count >= 0)
88 cnputc(*s++); 88 cnputc(*s++);
89} 89}
90 90
91static void 91static void
92db_putnchars(int c, int count) 92db_putnchars(int c, int count)
93{ 93{
94 94
95 while (--count >= 0) 95 while (--count >= 0)
96 cnputc(c); 96 cnputc(c);
97} 97}
98 98
99/* 99/*
100 * Delete N characters, forward or backward 100 * Delete N characters, forward or backward
101 */ 101 */
102#define DEL_FWD 0 102#define DEL_FWD 0
103#define DEL_BWD 1 103#define DEL_BWD 1
104static void 104static void
105db_delete(int n, int bwd) 105db_delete(int n, int bwd)
106{ 106{
107 char *p; 107 char *p;
108 108
109 if (bwd) { 109 if (bwd) {
110 db_lc -= n; 110 db_lc -= n;
111 db_putnchars(BACKUP, n); 111 db_putnchars(BACKUP, n);
112 } 112 }
113 for (p = db_lc; p < db_le-n; p++) { 113 for (p = db_lc; p < db_le-n; p++) {
114 *p = *(p+n); 114 *p = *(p+n);
115 cnputc(*p); 115 cnputc(*p);
116 } 116 }
117 db_putnchars(BLANK, n); 117 db_putnchars(BLANK, n);
118 db_putnchars(BACKUP, db_le - db_lc); 118 db_putnchars(BACKUP, db_le - db_lc);
119 db_le -= n; 119 db_le -= n;
120} 120}
121 121
122static void 122static void
123db_delete_line(void) 123db_delete_line(void)
124{ 124{
125 125
126 db_delete(db_le - db_lc, DEL_FWD); 126 db_delete(db_le - db_lc, DEL_FWD);
127 db_delete(db_lc - db_lbuf_start, DEL_BWD); 127 db_delete(db_lc - db_lbuf_start, DEL_BWD);
128 db_le = db_lc = db_lbuf_start; 128 db_le = db_lc = db_lbuf_start;
129} 129}
130 130
131#if DDB_HISTORY_SIZE != 0 131#if DDB_HISTORY_SIZE != 0
132 132
133#define INC_DB_CURR() do { \ 133#define INC_DB_CURR() do { \
134 ++db_history_curr; \ 134 ++db_history_curr; \
135 if (db_history_curr > db_history + DDB_HISTORY_SIZE - 1) \ 135 if (db_history_curr > db_history + DDB_HISTORY_SIZE - 1) \
136 db_history_curr = db_history; \ 136 db_history_curr = db_history; \
137 } while (0) 137 } while (0)
138#define DEC_DB_CURR() do { \ 138#define DEC_DB_CURR() do { \
139 --db_history_curr; \ 139 --db_history_curr; \
140 if (db_history_curr < db_history) \ 140 if (db_history_curr < db_history) \
141 db_history_curr = db_history + DDB_HISTORY_SIZE - 1; \ 141 db_history_curr = db_history + DDB_HISTORY_SIZE - 1; \
142 } while (0) 142 } while (0)
143 143
144static inline void 144static inline void
145db_hist_put(int c) 145db_hist_put(int c)
146{ 146{
147 KASSERT(&db_history[0] <= db_history_last); 147 KASSERT(&db_history[0] <= db_history_last);
148 KASSERT(db_history_last <= &db_history[DDB_HISTORY_SIZE-1]); 148 KASSERT(db_history_last <= &db_history[DDB_HISTORY_SIZE-1]);
149 149
150 *db_history_last++ = c; 150 *db_history_last++ = c;
151 151
152 if (db_history_last > &db_history[DDB_HISTORY_SIZE-1]) 152 if (db_history_last > &db_history[DDB_HISTORY_SIZE-1])
153 db_history_last = db_history; 153 db_history_last = db_history;
154} 154}
155#endif 155#endif
156  156
157 157
158/* returns true at end-of-line */ 158/* returns true at end-of-line */
159static int 159static int
160db_inputchar(int c) 160db_inputchar(int c)
161{ 161{
162 switch (c) { 162 switch (c) {
163 case CTRL('b'): 163 case CTRL('b'):
164 /* back up one character */ 164 /* back up one character */
165 if (db_lc > db_lbuf_start) { 165 if (db_lc > db_lbuf_start) {
166 cnputc(BACKUP); 166 cnputc(BACKUP);
167 db_lc--; 167 db_lc--;
168 } 168 }
169 break; 169 break;
170 case CTRL('f'): 170 case CTRL('f'):
171 /* forward one character */ 171 /* forward one character */
172 if (db_lc < db_le) { 172 if (db_lc < db_le) {
173 cnputc(*db_lc); 173 cnputc(*db_lc);
174 db_lc++; 174 db_lc++;
175 } 175 }
176 break; 176 break;
177 case CTRL('a'): 177 case CTRL('a'):
178 /* beginning of line */ 178 /* beginning of line */
179 while (db_lc > db_lbuf_start) { 179 while (db_lc > db_lbuf_start) {
180 cnputc(BACKUP); 180 cnputc(BACKUP);
181 db_lc--; 181 db_lc--;
182 } 182 }
183 break; 183 break;
184 case CTRL('e'): 184 case CTRL('e'):
185 /* end of line */ 185 /* end of line */
186 while (db_lc < db_le) { 186 while (db_lc < db_le) {
187 cnputc(*db_lc); 187 cnputc(*db_lc);
188 db_lc++; 188 db_lc++;
189 } 189 }
190 break; 190 break;
191 case CTRL('h'): 191 case CTRL('h'):
192 case 0177: 192 case 0177:
193 /* erase previous character */ 193 /* erase previous character */
194 if (db_lc > db_lbuf_start) 194 if (db_lc > db_lbuf_start)
195 db_delete(1, DEL_BWD); 195 db_delete(1, DEL_BWD);
196 break; 196 break;
197 case CTRL('d'): 197 case CTRL('d'):
198 /* erase next character */ 198 /* erase next character */
199 if (db_lc < db_le) 199 if (db_lc < db_le)
200 db_delete(1, DEL_FWD); 200 db_delete(1, DEL_FWD);
201 break; 201 break;
202 case CTRL('k'): 202 case CTRL('k'):
203 /* delete to end of line */ 203 /* delete to end of line */
204 if (db_lc < db_le) 204 if (db_lc < db_le)
205 db_delete(db_le - db_lc, DEL_FWD); 205 db_delete(db_le - db_lc, DEL_FWD);
206 break; 206 break;
207 case CTRL('u'): 207 case CTRL('u'):
208 /* delete line */ 208 /* delete line */
209 db_delete_line(); 209 db_delete_line();
210 break; 210 break;
211 case CTRL('t'): 211 case CTRL('t'):
212 /* twiddle last 2 characters */ 212 /* twiddle last 2 characters */
213 if (db_lc >= db_lbuf_start + 1) { 213 if (db_lc >= db_lbuf_start + 1) {
214 if (db_lc < db_le) { 214 if (db_lc < db_le) {
215 c = db_lc[-1]; 215 c = db_lc[-1];
216 db_lc[-1] = db_lc[0]; 216 db_lc[-1] = db_lc[0];
217 db_lc[0] = c; 217 db_lc[0] = c;
218 cnputc(BACKUP); 218 cnputc(BACKUP);
219 cnputc(db_lc[-1]); 219 cnputc(db_lc[-1]);
220 cnputc(db_lc[0]); 220 cnputc(db_lc[0]);
221 db_lc++; 221 db_lc++;
222 } else if (db_lc >= db_lbuf_start + 2) { 222 } else if (db_lc >= db_lbuf_start + 2) {
223 c = db_lc[-2]; 223 c = db_lc[-2];
224 db_lc[-2] = db_lc[-1]; 224 db_lc[-2] = db_lc[-1];
225 db_lc[-1] = c; 225 db_lc[-1] = c;
226 cnputc(BACKUP); 226 cnputc(BACKUP);
227 cnputc(BACKUP); 227 cnputc(BACKUP);
228 cnputc(db_lc[-2]); 228 cnputc(db_lc[-2]);
229 cnputc(db_lc[-1]); 229 cnputc(db_lc[-1]);
230 } 230 }
231 } 231 }
232 break; 232 break;
233#if DDB_HISTORY_SIZE != 0 233#if DDB_HISTORY_SIZE != 0
234 case CTRL('p'): 234 case CTRL('p'):
235 DEC_DB_CURR(); 235 DEC_DB_CURR();
236 while (db_history_curr != db_history_last) { 236 while (db_history_curr != db_history_last) {
237 DEC_DB_CURR(); 237 DEC_DB_CURR();
238 if (*db_history_curr == '\0') 238 if (*db_history_curr == '\0')
239 break; 239 break;
240 } 240 }
241 db_delete_line(); 241 db_delete_line();
242 if (db_history_curr == db_history_last) { 242 if (db_history_curr == db_history_last) {
243 INC_DB_CURR(); 243 INC_DB_CURR();
244 db_le = db_lc = db_lbuf_start; 244 db_le = db_lc = db_lbuf_start;
245 } else { 245 } else {
246 char *p; 246 char *p;
247 INC_DB_CURR(); 247 INC_DB_CURR();
248 for (p = db_history_curr, db_le = db_lbuf_start; 248 for (p = db_history_curr, db_le = db_lbuf_start;
249 *p; ) { 249 *p; ) {
250 *db_le++ = *p++; 250 *db_le++ = *p++;
251 if (p >= db_history + DDB_HISTORY_SIZE) { 251 if (p >= db_history + DDB_HISTORY_SIZE) {
252 p = db_history; 252 p = db_history;
253 } 253 }
254 } 254 }
255 db_lc = db_le; 255 db_lc = db_le;
256 } 256 }
257 db_putstring(db_lbuf_start, db_le - db_lbuf_start); 257 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
258 break; 258 break;
259 case CTRL('n'): 259 case CTRL('n'):
260 while (db_history_curr != db_history_last) { 260 while (db_history_curr != db_history_last) {
261 if (*db_history_curr == '\0') 261 if (*db_history_curr == '\0')
262 break; 262 break;
263 INC_DB_CURR(); 263 INC_DB_CURR();
264 } 264 }
265 if (db_history_curr != db_history_last) { 265 if (db_history_curr != db_history_last) {
266 INC_DB_CURR(); 266 INC_DB_CURR();
267 db_delete_line(); 267 db_delete_line();
268 if (db_history_curr != db_history_last) { 268 if (db_history_curr != db_history_last) {
269 char *p; 269 char *p;
270 for (p = db_history_curr, 270 for (p = db_history_curr,
271 db_le = db_lbuf_start; *p;) { 271 db_le = db_lbuf_start; *p;) {
272 *db_le++ = *p++; 272 *db_le++ = *p++;
273 if (p >= db_history + DDB_HISTORY_SIZE) { 273 if (p >= db_history + DDB_HISTORY_SIZE) {
274 p = db_history; 274 p = db_history;
275 } 275 }
276 } 276 }
277 db_lc = db_le; 277 db_lc = db_le;
278 } 278 }
279 db_putstring(db_lbuf_start, db_le - db_lbuf_start); 279 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
280 } 280 }
281 break; 281 break;
282#endif 282#endif
283 case CTRL('r'): 283 case CTRL('r'):
284 db_putstring("^R\n", 3); 284 db_putstring("^R\n", 3);
285 if (db_le > db_lbuf_start) { 285 if (db_le > db_lbuf_start) {
286 db_putstring(db_lbuf_start, db_le - db_lbuf_start); 286 db_putstring(db_lbuf_start, db_le - db_lbuf_start);
287 db_putnchars(BACKUP, db_le - db_lc); 287 db_putnchars(BACKUP, db_le - db_lc);
288 } 288 }
289 break; 289 break;
290 case '\n': 290 case '\n':
291 case '\r': 291 case '\r':
292#if DDB_HISTORY_SIZE != 0 292#if DDB_HISTORY_SIZE != 0
293 /* Check if it same than previous line */ 293 /* Check if it same than previous line */
294 if (db_history_curr == db_history_prev) { 294 if (db_history_curr == db_history_prev) {
295 char *pp, *pc; 295 char *pp, *pc;
296 296
297 /* Is it unmodified */ 297 /* Is it unmodified */
298 for (pp = db_history_prev, pc = db_lbuf_start; 298 for (pp = db_history_prev, pc = db_lbuf_start;
299 pc != db_le && *pp; pp++, pc++) { 299 pc != db_le && *pp; pp++, pc++) {
300 if (*pp != *pc) 300 if (*pp != *pc)
301 break; 301 break;
302 if (++pp >= db_history + DDB_HISTORY_SIZE) { 302 if (++pp >= db_history + DDB_HISTORY_SIZE) {
303 pp = db_history; 303 pp = db_history;
304 } 304 }
305 if (++pc >= db_history + DDB_HISTORY_SIZE) { 305 if (++pc >= db_history + DDB_HISTORY_SIZE) {
306 pc = db_history; 306 pc = db_history;
307 } 307 }
308 } 308 }
309 if (!*pp && pc == db_le) { 309 if (!*pp && pc == db_le) {
310 /* Repeted previous line, not saved */ 310 /* Repeted previous line, not saved */
311 db_history_curr = db_history_last; 311 db_history_curr = db_history_last;
312 *db_le++ = c; 312 *db_le++ = c;
313 return (true); 313 return (true);
314 } 314 }
315 } 315 }
316 if (db_le != db_lbuf_start) { 316 if (db_le != db_lbuf_start) {
317 char *p; 317 char *p;
318 318
319 db_history_prev = db_history_last; 319 db_history_prev = db_history_last;
320 320
321 for (p = db_lbuf_start; p != db_le; ) { 321 for (p = db_lbuf_start; p != db_le; ) {
322 db_hist_put(*p++); 322 db_hist_put(*p++);
323 } 323 }
324 db_hist_put(0); 324 db_hist_put(0);
325 } 325 }
326 db_history_curr = db_history_last; 326 db_history_curr = db_history_last;
327#endif 327#endif
328 *db_le++ = c; 328 *db_le++ = c;
329 return (1); 329 return (1);
330 default: 330 default:
331 if (db_le == db_lbuf_end) { 331 if (db_le == db_lbuf_end) {
332 cnputc('\007'); 332 cnputc('\007');
333 } 333 }
334 else if (c >= ' ' && c <= '~') { 334 else if (c >= ' ' && c <= '~') {
335 char *p; 335 char *p;
336 336
337 for (p = db_le; p > db_lc; p--) 337 for (p = db_le; p > db_lc; p--)
338 *p = *(p-1); 338 *p = *(p-1);
339 *db_lc++ = c; 339 *db_lc++ = c;
340 db_le++; 340 db_le++;
341 cnputc(c); 341 cnputc(c);
342 db_putstring(db_lc, db_le - db_lc); 342 db_putstring(db_lc, db_le - db_lc);
343 db_putnchars(BACKUP, db_le - db_lc); 343 db_putnchars(BACKUP, db_le - db_lc);
344 } 344 }
345 break; 345 break;
346 } 346 }
347 return (0); 347 return (0);
348} 348}
349 349
350int 350int
351db_readline(char *lstart, int lsize) 351db_readline(char *lstart, int lsize)
352{ 352{
353 353
354 db_force_whitespace(); /* synch output position */ 354 db_force_whitespace(); /* synch output position */
355 355
356 db_lbuf_start = lstart; 356 db_lbuf_start = lstart;
357 db_lbuf_end = lstart + lsize; 357 db_lbuf_end = lstart + lsize;
358 db_lc = lstart; 358 db_lc = lstart;
359 db_le = lstart; 359 db_le = lstart;
360 360
361 while (!db_inputchar(cngetc())) 361 while (!db_inputchar(cngetc()))
362 continue; 362 continue;
363 363
364 db_putchar('\n'); /* synch output position */ 364 db_putchar('\n'); /* synch output position */
365 365
366 *db_le = 0; 366 *db_le = 0;
367 return (db_le - db_lbuf_start); 367 return (db_le - db_lbuf_start);
368} 368}
369 369
370void 370void
371db_check_interrupt(void) 371db_check_interrupt(void)
372{ 372{
373 int c; 373 int c;
374 374
375 c = cnmaygetc(); 375 c = cnmaygetc();
376 switch (c) { 376 switch (c) {
377 case -1: /* no character */ 377 case -1: /* no character */
378 return; 378 return;
379 379
380 case CTRL('c'): 380 case CTRL('c'):
381 db_error((char *)0); 381 db_error((char *)0);
382 /*NOTREACHED*/ 382 /*NOTREACHED*/
383 383
384 case CTRL('s'): 384 case CTRL('s'):
385 do { 385 do {
386 c = cnmaygetc(); 386 c = cnmaygetc();
387 if (c == CTRL('c')) { 387 if (c == CTRL('c')) {
388 db_error((char *)0); 388 db_error((char *)0);
389 /*NOTREACHED*/ 389 /*NOTREACHED*/
390 } 390 }
391 } while (c != CTRL('q')); 391 } while (c != CTRL('q'));
392 break; 392 break;
393 393
394 default: 394 default:
395 /* drop on floor */ 395 /* drop on floor */
396 break; 396 break;
397 } 397 }
398} 398}
399 399
400static int 400static int
401cnmaygetc(void) 401cnmaygetc(void)
402{ 402{
403 403
404 return (-1); 404 return (-1);
405} 405}

cvs diff -r1.12 -r1.13 src/sys/ddb/db_proc.c (switch to unified diff)

--- src/sys/ddb/db_proc.c 2020/04/04 13:59:16 1.12
+++ src/sys/ddb/db_proc.c 2020/10/30 06:57:08 1.13
@@ -1,363 +1,363 @@ @@ -1,363 +1,363 @@
1/* $NetBSD: db_proc.c,v 1.12 2020/04/04 13:59:16 mlelstv Exp $ */ 1/* $NetBSD: db_proc.c,v 1.13 2020/10/30 06:57:08 skrll Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2009, 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2009, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1982, 1986, 1989, 1991, 1993 33 * Copyright (c) 1982, 1986, 1989, 1991, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * from: kern_proc.c 8.4 (Berkeley) 1/4/94 60 * from: kern_proc.c 8.4 (Berkeley) 1/4/94
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.12 2020/04/04 13:59:16 mlelstv Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: db_proc.c,v 1.13 2020/10/30 06:57:08 skrll Exp $");
65 65
66#ifndef _KERNEL 66#ifndef _KERNEL
67#include <stdbool.h> 67#include <stdbool.h>
68#endif 68#endif
69 69
70#include <sys/param.h> 70#include <sys/param.h>
71#include <sys/cpu.h> 71#include <sys/cpu.h>
72#include <sys/proc.h> 72#include <sys/proc.h>
73#ifdef _KERNEL /* XXX */ 73#ifdef _KERNEL /* XXX */
74#include <sys/kauth.h> 74#include <sys/kauth.h>
75#endif 75#endif
76 76
77#include <ddb/ddb.h> 77#include <ddb/ddb.h>
78 78
79proc_t * 79proc_t *
80db_proc_first(void) 80db_proc_first(void)
81{ 81{
82 82
83 return db_read_ptr("allproc"); 83 return db_read_ptr("allproc");
84} 84}
85 85
86proc_t * 86proc_t *
87db_proc_next(proc_t *p) 87db_proc_next(proc_t *p)
88{ 88{
89 89
90 db_read_bytes((db_addr_t)&p->p_list.le_next, sizeof(p), (char *)&p); 90 db_read_bytes((db_addr_t)&p->p_list.le_next, sizeof(p), (char *)&p);
91 return p; 91 return p;
92} 92}
93 93
94proc_t * 94proc_t *
95db_proc_find(pid_t pid) 95db_proc_find(pid_t pid)
96{ 96{
97 proc_t *p; 97 proc_t *p;
98 pid_t tp; 98 pid_t tp;
99 99
100 for (p = db_proc_first(); p != NULL; p = db_proc_next(p)) { 100 for (p = db_proc_first(); p != NULL; p = db_proc_next(p)) {
101 db_read_bytes((db_addr_t)&p->p_pid, sizeof(tp), 101 db_read_bytes((db_addr_t)&p->p_pid, sizeof(tp),
102 (char *)&tp); 102 (char *)&tp);
103 if (tp == pid) { 103 if (tp == pid) {
104 return p; 104 return p;
105 } 105 }
106 } 106 }
107 return NULL; 107 return NULL;
108} 108}
109 109
110static void 110static void
111db_read_string(const char *src, size_t len, char *dst) 111db_read_string(const char *src, size_t len, char *dst)
112{ 112{
113 size_t i; 113 size_t i;
114 114
115 for (i = 0; i < len; i++) { 115 for (i = 0; i < len; i++) {
116 db_read_bytes((db_addr_t)&src[i], 1, &dst[i]); 116 db_read_bytes((db_addr_t)&src[i], 1, &dst[i]);
117 if (dst[i] == '\0') 117 if (dst[i] == '\0')
118 break; 118 break;
119 } 119 }
120} 120}
121 121
122void 122void
123db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count, 123db_show_all_procs(db_expr_t addr, bool haddr, db_expr_t count,
124 const char *modif) 124 const char *modif)
125{ 125{
126 static struct pgrp pgrp; 126 static struct pgrp pgrp;
127 static proc_t p; 127 static proc_t p;
128 static lwp_t l; 128 static lwp_t l;
129 const char *mode, *ename; 129 const char *mode, *ename;
130 proc_t *pp; 130 proc_t *pp;
131 lwp_t *lp; 131 lwp_t *lp;
132 char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1]; 132 char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
133 bool run; 133 bool run;
134 int cpuno; 134 int cpuno;
135 135
136 if (modif[0] == 0) 136 if (modif[0] == 0)
137 mode = "l"; /* default == lwp mode */ 137 mode = "l"; /* default == lwp mode */
138 else 138 else
139 mode = strchr("mawln", modif[0]); 139 mode = strchr("mawln", modif[0]);
140 140
141 if (mode == NULL || *mode == 'm') { 141 if (mode == NULL || *mode == 'm') {
142 db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n"); 142 db_printf("usage: show all procs [/a] [/l] [/n] [/w]\n");
143 db_printf("\t/a == show process address info\n"); 143 db_printf("\t/a == show process address info\n");
144 db_printf("\t/l == show LWP info [default]\n"); 144 db_printf("\t/l == show LWP info [default]\n");
145 db_printf("\t/n == show normal process info\n"); 145 db_printf("\t/n == show normal process info\n");
146 db_printf("\t/w == show process wait/emul info\n"); 146 db_printf("\t/w == show process wait/emul info\n");
147 return; 147 return;
148 } 148 }
149 149
150 switch (*mode) { 150 switch (*mode) {
151 case 'a': 151 case 'a':
152 db_printf("PID %10s %18s %18s %18s\n", 152 db_printf("PID %10s %18s %18s %18s\n",
153 "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP"); 153 "COMMAND", "STRUCT PROC *", "UAREA *", "VMSPACE/VM_MAP");
154 break; 154 break;
155 case 'l': 155 case 'l':
156 db_printf("PID %4s S %3s %9s %18s %18s %-8s\n", 156 db_printf("PID %4s S %3s %9s %18s %18s %-8s\n",
157 "LID", "CPU", "FLAGS", "STRUCT LWP *", "NAME", "WAIT"); 157 "LID", "CPU", "FLAGS", "STRUCT LWP *", "NAME", "WAIT");
158 break; 158 break;
159 case 'n': 159 case 'n':
160 db_printf("PID %8s %8s %10s S %7s %4s %16s %7s\n", 160 db_printf("PID %8s %8s %10s S %7s %4s %16s %7s\n",
161 "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT"); 161 "PPID", "PGRP", "UID", "FLAGS", "LWPS", "COMMAND", "WAIT");
162 break; 162 break;
163 case 'w': 163 case 'w':
164 db_printf("PID %4s %16s %8s %4s %-12s%s\n", 164 db_printf("PID %4s %16s %8s %4s %-12s%s\n",
165 "LID", "COMMAND", "EMUL", "PRI", "WAIT-MSG", 165 "LID", "COMMAND", "EMUL", "PRI", "WAIT-MSG",
166 "WAIT-CHANNEL"); 166 "WAIT-CHANNEL");
167 break; 167 break;
168 } 168 }
169 169
170 for (pp = db_proc_first(); pp != NULL; pp = db_proc_next(pp)) { 170 for (pp = db_proc_first(); pp != NULL; pp = db_proc_next(pp)) {
171 db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p); 171 db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
172 if (p.p_stat == 0) { 172 if (p.p_stat == 0) {
173 continue; 173 continue;
174 } 174 }
175 lp = p.p_lwps.lh_first; 175 lp = p.p_lwps.lh_first;
176 if (lp != NULL) { 176 if (lp != NULL) {
177 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); 177 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
178 } 178 }
179 db_printf("%-5d", p.p_pid); 179 db_printf("%-5d", p.p_pid);
180 180
181 switch (*mode) { 181 switch (*mode) {
182 case 'a': 182 case 'a':
183 db_printf("%10.10s %18lx %18lx %18lx\n", 183 db_printf("%10.10s %18lx %18lx %18lx\n",
184 p.p_comm, (long)pp, 184 p.p_comm, (long)pp,
185 (long)(lp != NULL ? l.l_addr : 0), 185 (long)(lp != NULL ? l.l_addr : 0),
186 (long)p.p_vmspace); 186 (long)p.p_vmspace);
187 break; 187 break;
188 case 'l': 188 case 'l':
189 while (lp != NULL) { 189 while (lp != NULL) {
190 if (l.l_name != NULL) { 190 if (l.l_name != NULL) {
191 db_read_string(l.l_name, 191 db_read_string(l.l_name,
192 MAXCOMLEN, db_nbuf); 192 MAXCOMLEN, db_nbuf);
193 db_nbuf[MAXCOMLEN] = '\0'; 193 db_nbuf[MAXCOMLEN] = '\0';
194 } else { 194 } else {
195 strlcpy(db_nbuf, p.p_comm, 195 strlcpy(db_nbuf, p.p_comm,
196 sizeof(db_nbuf)); 196 sizeof(db_nbuf));
197 } 197 }
198 run = (l.l_stat == LSONPROC || 198 run = (l.l_stat == LSONPROC ||
199 (l.l_pflag & LP_RUNNING) != 0); 199 (l.l_pflag & LP_RUNNING) != 0);
200 if (l.l_cpu != NULL) { 200 if (l.l_cpu != NULL) {
201 db_read_bytes((db_addr_t) 201 db_read_bytes((db_addr_t)
202 &l.l_cpu->ci_data.cpu_index, 202 &l.l_cpu->ci_data.cpu_index,
203 sizeof(cpuno), (char *)&cpuno); 203 sizeof(cpuno), (char *)&cpuno);
204 } else 204 } else
205 cpuno = -1; 205 cpuno = -1;
206 if (l.l_wchan && l.l_wmesg) { 206 if (l.l_wchan && l.l_wmesg) {
207 db_read_string(l.l_wmesg, 207 db_read_string(l.l_wmesg,
208 sizeof(wbuf), wbuf); 208 sizeof(wbuf), wbuf);
209 wbuf[MAXCOMLEN] = '\0'; 209 wbuf[MAXCOMLEN] = '\0';
210 } else { 210 } else {
211 wbuf[0] = '\0'; 211 wbuf[0] = '\0';
212 } 212 }
213 db_printf("%c%4d %d %3d %9x %18lx %18s %-8s\n", 213 db_printf("%c%4d %d %3d %9x %18lx %18s %-8s\n",
214 (run ? '>' : ' '), l.l_lid, 214 (run ? '>' : ' '), l.l_lid,
215 l.l_stat, cpuno, l.l_flag, (long)lp, 215 l.l_stat, cpuno, l.l_flag, (long)lp,
216 db_nbuf, wbuf); 216 db_nbuf, wbuf);
217 lp = LIST_NEXT((&l), l_sibling); 217 lp = LIST_NEXT((&l), l_sibling);
218 if (lp != NULL) { 218 if (lp != NULL) {
219 db_printf("%-5d", p.p_pid); 219 db_printf("%-5d", p.p_pid);
220 db_read_bytes((db_addr_t)lp, sizeof(l), 220 db_read_bytes((db_addr_t)lp, sizeof(l),
221 (char *)&l); 221 (char *)&l);
222 } 222 }
223 } 223 }
224 break; 224 break;
225 case 'n': 225 case 'n':
226 db_read_bytes((db_addr_t)p.p_pgrp, sizeof(pgrp), 226 db_read_bytes((db_addr_t)p.p_pgrp, sizeof(pgrp),
227 (char *)&pgrp); 227 (char *)&pgrp);
228 if (lp != NULL && l.l_wchan && l.l_wmesg) { 228 if (lp != NULL && l.l_wchan && l.l_wmesg) {
229 db_read_string(l.l_wmesg, 229 db_read_string(l.l_wmesg,
230 sizeof(wbuf), wbuf); 230 sizeof(wbuf), wbuf);
231 wbuf[MAXCOMLEN] = '\0'; 231 wbuf[MAXCOMLEN] = '\0';
232 } else { 232 } else {
233 wbuf[0] = '\0'; 233 wbuf[0] = '\0';
234 } 234 }
235 db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n", 235 db_printf("%8d %8d %10d %d %#7x %4d %16s %7.7s\n",
236 p.p_pptr != NULL ? p.p_pptr->p_pid : -1, pgrp.pg_id, 236 p.p_pptr != NULL ? p.p_pptr->p_pid : -1, pgrp.pg_id,
237#ifdef _KERNEL 237#ifdef _KERNEL
238 kauth_cred_getuid(p.p_cred), 238 kauth_cred_getuid(p.p_cred),
239#else 239#else
240 /* XXX CRASH(8) */ 666, 240 /* XXX CRASH(8) */ 666,
241#endif  241#endif
242 p.p_stat, p.p_flag, 242 p.p_stat, p.p_flag,
243 p.p_nlwps, p.p_comm, 243 p.p_nlwps, p.p_comm,
244 (p.p_nlwps != 1) ? "*" : wbuf); 244 (p.p_nlwps != 1) ? "*" : wbuf);
245 break; 245 break;
246 246
247 case 'w': 247 case 'w':
248 while (lp != NULL) { 248 while (lp != NULL) {
249 if (l.l_wchan && l.l_wmesg) { 249 if (l.l_wchan && l.l_wmesg) {
250 db_read_string(l.l_wmesg, 250 db_read_string(l.l_wmesg,
251 sizeof(wbuf), wbuf); 251 sizeof(wbuf), wbuf);
252 wbuf[MAXCOMLEN] = '\0'; 252 wbuf[MAXCOMLEN] = '\0';
253 } else { 253 } else {
254 wbuf[0] = '\0'; 254 wbuf[0] = '\0';
255 } 255 }
256 run = (l.l_stat == LSONPROC || 256 run = (l.l_stat == LSONPROC ||
257 (l.l_pflag & LP_RUNNING) != 0); 257 (l.l_pflag & LP_RUNNING) != 0);
258 db_read_bytes((db_addr_t)&p.p_emul->e_name, 258 db_read_bytes((db_addr_t)&p.p_emul->e_name,
259 sizeof(ename), (char *)&ename); 259 sizeof(ename), (char *)&ename);
260 260
261 db_read_string(ename, sizeof(db_nbuf), db_nbuf); 261 db_read_string(ename, sizeof(db_nbuf), db_nbuf);
262 db_nbuf[MAXCOMLEN] = '\0'; 262 db_nbuf[MAXCOMLEN] = '\0';
263 263
264 db_printf( 264 db_printf(
265 "%c%4d %16s %8s %4d %-12s %-18lx\n", 265 "%c%4d %16s %8s %4d %-12s %-18lx\n",
266 (run ? '>' : ' '), l.l_lid, 266 (run ? '>' : ' '), l.l_lid,
267 p.p_comm, db_nbuf, 267 p.p_comm, db_nbuf,
268 l.l_priority, wbuf, (long)l.l_wchan); 268 l.l_priority, wbuf, (long)l.l_wchan);
269 lp = LIST_NEXT((&l), l_sibling); 269 lp = LIST_NEXT((&l), l_sibling);
270 if (lp != NULL) { 270 if (lp != NULL) {
271 db_printf("%-5d", p.p_pid); 271 db_printf("%-5d", p.p_pid);
272 db_read_bytes((db_addr_t)lp, sizeof(l), 272 db_read_bytes((db_addr_t)lp, sizeof(l),
273 (char *)&l); 273 (char *)&l);
274 } 274 }
275 } 275 }
276 break; 276 break;
277 } 277 }
278 } 278 }
279} 279}
280 280
281void 281void
282db_show_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif) 282db_show_proc(db_expr_t addr, bool haddr, db_expr_t count, const char *modif)
283{ 283{
284 static proc_t p; 284 static proc_t p;
285 static lwp_t l; 285 static lwp_t l;
286 const char *mode; 286 const char *mode;
287 proc_t *pp; 287 proc_t *pp;
288 lwp_t *lp; 288 lwp_t *lp;
289 char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1]; 289 char db_nbuf[MAXCOMLEN + 1], wbuf[MAXCOMLEN + 1];
290 bool run; 290 bool run;
291 int cpuno; 291 int cpuno;
292 292
293 if (modif[0] == 0) 293 if (modif[0] == 0)
294 mode = "p"; /* default == by pid */ 294 mode = "p"; /* default == by pid */
295 else 295 else
296 mode = strchr("ap", modif[0]); 296 mode = strchr("ap", modif[0]);
297 297
298 if (mode == NULL || !haddr) { 298 if (mode == NULL || !haddr) {
299 db_printf("usage: show proc [/a] [/p] address|pid\n"); 299 db_printf("usage: show proc [/a] [/p] address|pid\n");
300 db_printf("\t/a == argument is an address of any lwp\n"); 300 db_printf("\t/a == argument is an address of any lwp\n");
301 db_printf("\t/p == argument is a pid [default]\n"); 301 db_printf("\t/p == argument is a pid [default]\n");
302 return; 302 return;
303 } 303 }
304 304
305 switch (*mode) { 305 switch (*mode) {
306 case 'a': 306 case 'a':
307 lp = (lwp_t *)(uintptr_t)addr; 307 lp = (lwp_t *)(uintptr_t)addr;
308 db_printf("lwp_t %lx\n", (long)lp); 308 db_printf("lwp_t %lx\n", (long)lp);
309 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); 309 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
310 pp = l.l_proc; 310 pp = l.l_proc;
311 break; 311 break;
312 default: 312 default:
313 case 'p': 313 case 'p':
314 pp = db_proc_find((pid_t)addr); 314 pp = db_proc_find((pid_t)addr);
315 lp = NULL; 315 lp = NULL;
316 break; 316 break;
317 } 317 }
318 318
319 if (pp == NULL) { 319 if (pp == NULL) {
320 db_printf("bad address\n"); 320 db_printf("bad address\n");
321 return; 321 return;
322 } 322 }
323 323
324 db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p); 324 db_read_bytes((db_addr_t)pp, sizeof(p), (char *)&p);
325 if (lp == NULL) 325 if (lp == NULL)
326 lp = p.p_lwps.lh_first; 326 lp = p.p_lwps.lh_first;
327 327
328 db_printf("%s: pid %d proc %lx vmspace/map %lx flags %x\n", 328 db_printf("%s: pid %d proc %lx vmspace/map %lx flags %x\n",
329 p.p_comm, p.p_pid, (long)pp, (long)p.p_vmspace, p.p_flag); 329 p.p_comm, p.p_pid, (long)pp, (long)p.p_vmspace, p.p_flag);
330 330
331 while (lp != NULL) { 331 while (lp != NULL) {
332 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l); 332 db_read_bytes((db_addr_t)lp, sizeof(l), (char *)&l);
333 333
334 run = (l.l_stat == LSONPROC || 334 run = (l.l_stat == LSONPROC ||
335 (l.l_pflag & LP_RUNNING) != 0); 335 (l.l_pflag & LP_RUNNING) != 0);
336 336
337 db_printf("%slwp %d", (run ? "> " : " "), l.l_lid); 337 db_printf("%slwp %d", (run ? "> " : " "), l.l_lid);
338 if (l.l_name != NULL) { 338 if (l.l_name != NULL) {
339 db_read_string(l.l_name, MAXCOMLEN, db_nbuf); 339 db_read_string(l.l_name, MAXCOMLEN, db_nbuf);
340 db_nbuf[MAXCOMLEN] = '\0'; 340 db_nbuf[MAXCOMLEN] = '\0';
341 db_printf(" [%s]", db_nbuf); 341 db_printf(" [%s]", db_nbuf);
342 } 342 }
343 db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr); 343 db_printf(" %lx pcb %lx\n", (long)lp, (long)l.l_addr);
344 344
345 if (l.l_cpu != NULL) { 345 if (l.l_cpu != NULL) {
346 db_read_bytes((db_addr_t) 346 db_read_bytes((db_addr_t)
347 &l.l_cpu->ci_data.cpu_index, 347 &l.l_cpu->ci_data.cpu_index,
348 sizeof(cpuno), (char *)&cpuno); 348 sizeof(cpuno), (char *)&cpuno);
349 } else 349 } else
350 cpuno = -1; 350 cpuno = -1;
351 db_printf(" stat %d flags %x cpu %d pri %d ref %d\n", 351 db_printf(" stat %d flags %x cpu %d pri %d ref %d\n",
352 l.l_stat, l.l_flag, cpuno, l.l_priority, l.l_refcnt); 352 l.l_stat, l.l_flag, cpuno, l.l_priority, l.l_refcnt);
353 353
354 if (l.l_wchan && l.l_wmesg) { 354 if (l.l_wchan && l.l_wmesg) {
355 db_read_string(l.l_wmesg, MAXCOMLEN, wbuf); 355 db_read_string(l.l_wmesg, MAXCOMLEN, wbuf);
356 wbuf[MAXCOMLEN] = '\0'; 356 wbuf[MAXCOMLEN] = '\0';
357 db_printf(" wmesg %s wchan %lx\n", 357 db_printf(" wmesg %s wchan %lx\n",
358 wbuf, (long)l.l_wchan); 358 wbuf, (long)l.l_wchan);
359 } 359 }
360 360
361 lp = LIST_NEXT(&l, l_sibling); 361 lp = LIST_NEXT(&l, l_sibling);
362 } 362 }
363} 363}