]> git.saurik.com Git - apple/xnu.git/blob - osfmk/ddb/db_variables.c
ba7192c60a25dbe53063964ca3d659f840997fe8
[apple/xnu.git] / osfmk / ddb / db_variables.c
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25 /*
26 * @OSF_COPYRIGHT@
27 */
28 /*
29 * HISTORY
30 *
31 * Revision 1.1.1.1 1998/09/22 21:05:48 wsanchez
32 * Import of Mac OS X kernel (~semeria)
33 *
34 * Revision 1.1.1.1 1998/03/07 02:26:09 wsanchez
35 * Import of OSF Mach kernel (~mburg)
36 *
37 * Revision 1.2.18.5 1996/01/09 19:16:34 devrcs
38 * Search the alternate register names if configured
39 * Changed declarations of 'register foo' to 'register int foo'.
40 * [1995/12/01 21:42:42 jfraser]
41 *
42 * Merged '64-bit safe' changes from DEC alpha port.
43 * [1995/11/21 18:03:56 jfraser]
44 *
45 * Revision 1.2.18.4 1995/02/23 21:43:56 alanl
46 * Merged with DIPC2_SHARED.
47 * [1995/01/05 13:35:55 alanl]
48 *
49 * Revision 1.2.21.1 1994/11/04 09:53:26 dwm
50 * mk6 CR668 - 1.3b26 merge
51 * * Revision 1.2.4.6 1994/05/06 18:40:13 tmt
52 * Merged osc1.3dec/shared with osc1.3b19
53 * Merge Alpha changes into osc1.312b source code.
54 * 64bit cleanup.
55 * * End1.3merge
56 * [1994/11/04 08:50:12 dwm]
57 *
58 * Revision 1.2.18.2 1994/09/23 01:22:35 ezf
59 * change marker to not FREE
60 * [1994/09/22 21:11:24 ezf]
61 *
62 * Revision 1.2.18.1 1994/06/11 21:12:37 bolinger
63 * Merge up to NMK17.2.
64 * [1994/06/11 20:03:04 bolinger]
65 *
66 * Revision 1.2.23.1 1994/12/06 19:43:18 alanl
67 * Intel merge, Oct 94 code drop.
68 * Added db_find_reg_name (came from db_print.c).
69 * [94/11/28 mmp]
70 *
71 * Revision 1.2.16.1 1994/02/08 10:59:08 bernadat
72 * Added completion variable.
73 * [93/08/17 paire]
74 *
75 * Set up new fields (hidden_xxx) of db_vars[] array that are supposed
76 * to be helpful to display variables depending on an internal value
77 * like db_macro_level for macro arguments.
78 * Added db_auto_wrap as new variable.
79 * Added "set help" for listing all available variables.
80 * Added db_show_variable() and db_show_one_variable()
81 * to print variable values.
82 * [93/08/12 paire]
83 * [94/02/08 bernadat]
84 *
85 * Revision 1.2.4.4 1993/08/11 20:38:20 elliston
86 * Add ANSI Prototypes. CR #9523.
87 * [1993/08/11 03:34:13 elliston]
88 *
89 * Revision 1.2.4.3 1993/07/27 18:28:27 elliston
90 * Add ANSI prototypes. CR #9523.
91 * [1993/07/27 18:13:22 elliston]
92 *
93 * Revision 1.2.4.2 1993/06/09 02:21:02 gm
94 * Added to OSF/1 R1.3 from NMK15.0.
95 * [1993/06/02 20:57:43 jeffc]
96 *
97 * Revision 1.2 1993/04/19 16:03:25 devrcs
98 * Changes from mk78:
99 * Added void to db_read_write_variable().
100 * Removed unused variable 'func' from db_set_cmd().
101 * [92/05/16 jfriedl]
102 * [93/02/02 bruel]
103 *
104 * Print old value when changing register values.
105 * [barbou@gr.osf.org]
106 * [92/12/03 bernadat]
107 *
108 * Revision 1.1 1992/09/30 02:01:31 robert
109 * Initial revision
110 *
111 * $EndLog$
112 */
113 /* CMU_HIST */
114 /*
115 * Revision 2.5 91/10/09 16:03:59 af
116 * Revision 2.4.3.1 91/10/05 13:08:27 jeffreyh
117 * Added suffix handling and thread handling of variables.
118 * Added new variables: lines, task, thread, work and arg.
119 * Moved db_read_variable and db_write_variable to db_variables.h
120 * as macros, and added db_read_write_variable instead.
121 * Changed some error messages.
122 * [91/08/29 tak]
123 *
124 * Revision 2.4.3.1 91/10/05 13:08:27 jeffreyh
125 * Added suffix handling and thread handling of variables.
126 * Added new variables: lines, task, thread, work and arg.
127 * Moved db_read_variable and db_write_variable to db_variables.h
128 * as macros, and added db_read_write_variable instead.
129 * Changed some error messages.
130 * [91/08/29 tak]
131 *
132 * Revision 2.4 91/05/14 15:36:57 mrt
133 * Correcting copyright
134 *
135 * Revision 2.3 91/02/05 17:07:19 mrt
136 * Changed to new Mach copyright
137 * [91/01/31 16:19:46 mrt]
138 *
139 * Revision 2.2 90/08/27 21:53:24 dbg
140 * New db_read/write_variable functions. Should be used instead
141 * of dereferencing valuep directly, which might not be a true
142 * pointer if there is an fcn() access function.
143 * [90/08/20 af]
144 *
145 * Fix declarations.
146 * Check for trailing garbage after last expression on command line.
147 * [90/08/10 14:34:54 dbg]
148 *
149 * Created.
150 * [90/07/25 dbg]
151 *
152 */
153 /* CMU_ENDHIST */
154 /*
155 * Mach Operating System
156 * Copyright (c) 1991,1990 Carnegie Mellon University
157 * All Rights Reserved.
158 *
159 * Permission to use, copy, modify and distribute this software and its
160 * documentation is hereby granted, provided that both the copyright
161 * notice and this permission notice appear in all copies of the
162 * software, derivative works or modified versions, and any portions
163 * thereof, and that both notices appear in supporting documentation.
164 *
165 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
166 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
167 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
168 *
169 * Carnegie Mellon requests users of this software to return to
170 *
171 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
172 * School of Computer Science
173 * Carnegie Mellon University
174 * Pittsburgh PA 15213-3890
175 *
176 * any improvements or extensions that they make and grant Carnegie Mellon
177 * the rights to redistribute these changes.
178 */
179 /*
180 */
181 /*
182 * Author: David B. Golub, Carnegie Mellon University
183 * Date: 7/90
184 */
185
186 #include <machine/db_machdep.h>
187 #include <string.h> /* For strcpy() */
188
189 #include <ddb/db_lex.h>
190 #include <ddb/db_variables.h>
191 #include <ddb/db_task_thread.h>
192 #include <ddb/db_sym.h>
193 #include <ddb/db_command.h>
194 #include <ddb/db_expr.h>
195 #include <ddb/db_macro.h>
196 #include <ddb/db_output.h> /* For db_printf() */
197
198 extern db_expr_t db_radix;
199 extern db_expr_t db_max_width;
200 extern db_expr_t db_tab_stop_width;
201 extern db_expr_t db_max_line;
202 extern db_expr_t db_auto_wrap;
203 extern db_expr_t db_macro_level;
204 extern db_expr_t db_auto_completion;
205
206 #define DB_NWORK 32 /* number of work variable */
207
208 db_expr_t db_work[DB_NWORK]; /* work variable */
209
210 struct db_variable db_vars[] = {
211 { "maxoff", (db_expr_t*)&db_maxoff, FCN_NULL },
212 { "autowrap", &db_auto_wrap, FCN_NULL },
213 { "completion", &db_auto_completion, FCN_NULL },
214 { "maxwidth", &db_max_width, FCN_NULL },
215 { "radix", &db_radix, FCN_NULL },
216 { "tabstops", &db_tab_stop_width, FCN_NULL },
217 { "lines", &db_max_line, FCN_NULL },
218 { "thr_act", 0, db_set_default_act },
219 { "task", 0, db_get_task_act,
220 1, 2, -1, -1 },
221 { "work", &db_work[0], FCN_NULL,
222 1, 1, 0, DB_NWORK-1 },
223 { "arg", 0, db_arg_variable,
224 1, 1, 1, DB_MACRO_NARGS,
225 1, 0, DB_MACRO_LEVEL-1, (int *)&db_macro_level },
226 };
227 struct db_variable *db_evars = db_vars + sizeof(db_vars)/sizeof(db_vars[0]);
228
229
230
231 /* Prototypes for functions local to this file.
232 */
233
234 static char *db_get_suffix(
235 register char *suffix,
236 short *suffix_value);
237
238 static boolean_t db_cmp_variable_name(
239 struct db_variable *vp,
240 char *name,
241 register db_var_aux_param_t ap);
242
243 static int db_find_variable(
244 struct db_variable **varp,
245 db_var_aux_param_t ap);
246
247 static int db_set_variable(db_expr_t value);
248
249 void db_list_variable(void);
250
251 static char *
252 db_get_suffix(
253 register char *suffix,
254 short *suffix_value)
255 {
256 register int value;
257
258 for (value = 0; *suffix && *suffix != '.' && *suffix != ':'; suffix++) {
259 if (*suffix < '0' || *suffix > '9')
260 return(0);
261 value = value*10 + *suffix - '0';
262 }
263 *suffix_value = value;
264 if (*suffix == '.')
265 suffix++;
266 return(suffix);
267 }
268
269 static boolean_t
270 db_cmp_variable_name(
271 struct db_variable *vp,
272 char *name,
273 register db_var_aux_param_t ap)
274 {
275 register char *var_np, *np;
276 register int level;
277
278 for (np = name, var_np = vp->name; *var_np; ) {
279 if (*np++ != *var_np++)
280 return(FALSE);
281 }
282 for (level = 0; *np && *np != ':' && level < vp->max_level; level++){
283 if ((np = db_get_suffix(np, &ap->suffix[level])) == 0)
284 return(FALSE);
285 }
286 if ((*np && *np != ':') || level < vp->min_level
287 || (level > 0 && (ap->suffix[0] < vp->low
288 || (vp->high >= 0 && ap->suffix[0] > vp->high))))
289 return(FALSE);
290 strcpy(ap->modif, (*np)? np+1: "");
291 ap->thr_act = (db_option(ap->modif, 't')?db_default_act: THR_ACT_NULL);
292 ap->level = level;
293 ap->hidden_level = -1;
294 return(TRUE);
295 }
296
297 static int
298 db_find_variable(
299 struct db_variable **varp,
300 db_var_aux_param_t ap)
301 {
302 int t;
303 struct db_variable *vp;
304
305 t = db_read_token();
306 if (t == tIDENT) {
307 for (vp = db_vars; vp < db_evars; vp++) {
308 if (db_cmp_variable_name(vp, db_tok_string, ap)) {
309 *varp = vp;
310 return (1);
311 }
312 }
313 for (vp = db_regs; vp < db_eregs; vp++) {
314 if (db_cmp_variable_name(vp, db_tok_string, ap)) {
315 *varp = vp;
316 return (1);
317 }
318 }
319 #if defined(ALTERNATE_REGISTER_DEFS)
320 for (vp = db_altregs; vp < db_ealtregs; vp++) {
321 if (db_cmp_variable_name(vp, db_tok_string, ap)) {
322 *varp = vp;
323 return (1);
324 }
325 }
326 #endif /* defined(ALTERNATE_REGISTER_DEFS) */
327 }
328 db_printf("Unknown variable \"$%s\"\n", db_tok_string);
329 db_error(0);
330 return (0);
331 }
332
333 int
334 db_get_variable(db_expr_t *valuep)
335 {
336 struct db_variable *vp;
337 struct db_var_aux_param aux_param;
338 char modif[TOK_STRING_SIZE];
339
340 aux_param.modif = modif;
341 if (!db_find_variable(&vp, &aux_param))
342 return (0);
343
344 db_read_write_variable(vp, valuep, DB_VAR_GET, &aux_param);
345
346 return (1);
347 }
348
349 static int
350 db_set_variable(db_expr_t value)
351 {
352 struct db_variable *vp;
353 struct db_var_aux_param aux_param;
354 char modif[TOK_STRING_SIZE];
355
356 aux_param.modif = modif;
357 if (!db_find_variable(&vp, &aux_param))
358 return (0);
359
360 db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
361
362 return (1);
363 }
364
365 void
366 db_read_write_variable(
367 struct db_variable *vp,
368 db_expr_t *valuep,
369 int rw_flag,
370 db_var_aux_param_t ap)
371 {
372 int (*func)(struct db_variable*, db_expr_t*,int, db_var_aux_param_t)
373 = vp->fcn;
374 struct db_var_aux_param aux_param;
375 db_expr_t old_value;
376
377 if (ap == 0) {
378 ap = &aux_param;
379 ap->modif = "";
380 ap->level = 0;
381 ap->thr_act = THR_ACT_NULL;
382 }
383 if (rw_flag == DB_VAR_SET && vp->precious)
384 db_read_write_variable(vp, &old_value, DB_VAR_GET, ap);
385 if (func == FCN_NULL) {
386 if (rw_flag == DB_VAR_SET)
387 vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0] = *valuep;
388 else
389 *valuep = vp->valuep[(ap->level)? (ap->suffix[0] - vp->low): 0];
390 } else
391 (*func)(vp, valuep, rw_flag, ap);
392 if (rw_flag == DB_VAR_SET && vp->precious)
393 db_printf("\t$%s:%s<%#x>\t%#8n\t=\t%#8n\n", vp->name,
394 ap->modif, ap->thr_act, old_value, *valuep);
395 }
396
397 void
398 db_list_variable(void)
399 {
400 register struct db_variable *new;
401 register struct db_variable *old;
402 register struct db_variable *cur;
403 unsigned int l;
404 unsigned int len;
405 short i;
406 unsigned int j;
407
408 len = 1;
409 for (cur = db_vars; cur < db_evars; cur++) {
410 if (cur->min_level > 0 || cur->max_level > 0) {
411 j = 3 * (cur->max_level - cur->min_level + 1) - 1;
412 if (cur->max_level > cur->min_level)
413 j += 2;
414 } else
415 j = 0;
416 if ((l = strlen(cur->name) + j) >= len)
417 len = l + 1;
418 }
419
420 old = (struct db_variable *)0;
421 for (;;) {
422 new = (struct db_variable *)0;
423 for (cur = db_vars; cur < db_evars; cur++)
424 if ((new == (struct db_variable *)0 ||
425 strcmp(cur->name, new->name) < 0) &&
426 (old == (struct db_variable *)0 ||
427 strcmp(cur->name, old->name) > 0))
428 new = cur;
429 if (new == (struct db_variable *)0)
430 return;
431 db_reserve_output_position(len);
432 db_printf(new->name);
433 j = strlen(new->name);
434 if (new->min_level > 0) {
435 db_putchar('?');
436 db_putchar('?');
437 j += 2;
438 for (i = new->min_level - 1; i > 0; i--) {
439 db_putchar('.');
440 db_putchar('?');
441 db_putchar('?');
442 j += 3;
443 }
444 if (new->max_level > new->min_level) {
445 db_putchar('[');
446 db_putchar('.');
447 db_putchar('?');
448 db_putchar('?');
449 j += 4;
450 }
451 i = new->min_level + 1;
452 } else {
453 if (new->max_level > new->min_level) {
454 db_putchar('[');
455 j++;
456 }
457 i = new->min_level;
458 }
459 while (i++ < new->max_level) {
460 db_putchar('.');
461 db_putchar('?');
462 db_putchar('?');
463 j += 3;
464 }
465 if (new->max_level > new->min_level) {
466 db_putchar(']');
467 j++;
468 }
469 while (j++ < len)
470 db_putchar(' ');
471 old = new;
472 }
473 }
474
475 void
476 db_set_cmd(void)
477 {
478 db_expr_t value;
479 int t;
480 struct db_variable *vp;
481 struct db_var_aux_param aux_param;
482 char modif[TOK_STRING_SIZE];
483
484 aux_param.modif = modif;
485 t = db_read_token();
486 if (t == tIDENT && strcmp("help", db_tok_string) == 0) {
487 db_list_variable();
488 return;
489 }
490 if (t != tDOLLAR) {
491 db_error("Variable name should be prefixed with $\n");
492 return;
493 }
494 if (!db_find_variable(&vp, &aux_param)) {
495 db_error("Unknown variable\n");
496 return;
497 }
498
499 t = db_read_token();
500 if (t != tEQ)
501 db_unread_token(t);
502
503 if (!db_expression(&value)) {
504 db_error("No value\n");
505 return;
506 }
507 if ((t = db_read_token()) == tSEMI_COLON)
508 db_unread_token(t);
509 else if (t != tEOL)
510 db_error("?\n");
511
512 db_read_write_variable(vp, &value, DB_VAR_SET, &aux_param);
513 }
514
515 void
516 db_show_one_variable(void)
517 {
518 struct db_variable *cur;
519 unsigned int len;
520 unsigned int sl;
521 unsigned int slen;
522 short h;
523 short i;
524 short j;
525 short k;
526 short low;
527 int hidden_level;
528 struct db_var_aux_param aux_param;
529 char *p;
530 char *q;
531 char *name;
532 db_addr_t offset;
533
534 for (cur = db_vars; cur < db_evars; cur++)
535 if (db_cmp_variable_name(cur, db_tok_string, &aux_param))
536 break;
537 if (cur == db_evars) {
538 for (cur = db_vars; cur < db_evars; cur++) {
539 for (q = cur->name, p = db_tok_string; *q && *p == *q; p++,q++)
540 continue;
541 if (*q == '\0')
542 break;
543 }
544 if (cur == db_evars) {
545 db_error("Unknown variable\n");
546 return;
547 }
548
549 for (i = 0; *p && *p != ':' && i < cur->max_level; i++, p = q)
550 if ((q = db_get_suffix(p, &aux_param.suffix[i])) == 0)
551 break;
552 aux_param.level = i;
553 if ((*p && *p != ':') ||
554 (i > 0 && (aux_param.suffix[0] < cur->low ||
555 (cur->high >= 0 &&
556 aux_param.suffix[0] > cur->high)))) {
557 db_error("Unknown variable format\n");
558 return;
559 }
560
561 strcpy(aux_param.modif, *p ? p + 1 : "");
562 aux_param.thr_act = (db_option(aux_param.modif, 't') ?
563 db_default_act : THR_ACT_NULL);
564 }
565
566 if (cur->hidden_level)
567 if (*cur->hidden_levelp >= cur->hidden_low &&
568 *cur->hidden_levelp <= cur->hidden_high) {
569 hidden_level = 1;
570 aux_param.hidden_level = h = *cur->hidden_levelp;
571 } else {
572 hidden_level = 0;
573 aux_param.hidden_level = h = cur->hidden_low;
574 slen = 1;
575 for (k = aux_param.level > 0 ? aux_param.suffix[0] : cur->high;
576 k > 9; k /= 10)
577 slen++;
578 }
579 else
580 aux_param.hidden_level = -1;
581
582 if ((cur->min_level == 0 && !cur->hidden_level) || cur->high < 0)
583 j = 0;
584 else {
585 if (cur->min_level > 0) {
586 j = 1;
587 for (k = aux_param.level > 0 ?
588 aux_param.suffix[0] : cur->high; k > 9; k /= 10)
589 j++;
590 } else
591 j = 0;
592 if (cur->hidden_level && hidden_level == 0) {
593 j += 3;
594 for (k = aux_param.hidden_level >= 0 ?
595 aux_param.hidden_level : cur->hidden_high; k > 9; k /= 10)
596 j++;
597 }
598 }
599 len = strlen(cur->name) + j;
600 i = low = aux_param.level > 0 ? aux_param.suffix[0] : cur->low;
601
602 for (;;) {
603 db_printf(cur->name);
604 j = strlen(cur->name);
605 if (cur->high >= 0) {
606 if (cur->min_level > 0) {
607 db_printf("%d", i);
608 j++;
609 for (k = i; k > 9; k /= 10)
610 j++;
611 }
612 if (cur->hidden_level && hidden_level == 0) {
613 sl = 1;
614 for (k = i; k > 9; k /= 10)
615 sl++;
616 while (sl++ < slen) {
617 db_putchar(' ');
618 j++;
619 }
620 db_printf("[%d]", h);
621 j += 3;
622 for (k = h; k > 9; k /= 10)
623 j++;
624 }
625 }
626
627 while (j++ < len)
628 db_putchar(' ');
629 db_putchar(':');
630 db_putchar(' ');
631
632 if (cur->fcn) {
633 aux_param.suffix[0] = i;
634 (*cur->fcn)(cur, (db_expr_t *)0, DB_VAR_SHOW, &aux_param);
635 } else {
636 db_printf("%#n", *(cur->valuep + i));
637 db_find_xtrn_task_sym_and_offset(*(cur->valuep + i), &name,
638 &offset, TASK_NULL);
639 if (name != (char *)0 && offset <= db_maxoff &&
640 offset != *(cur->valuep + i)) {
641 db_printf("\t%s", name);
642 if (offset != 0)
643 db_printf("+%#r", offset);
644 }
645 }
646 db_putchar('\n');
647 if (cur->high < 0)
648 break;
649 if (aux_param.level > 0 || i++ == cur->high) {
650 if (!cur->hidden_level ||
651 hidden_level == 0 ||
652 h++ == cur->hidden_high)
653 break;
654 aux_param.hidden_level = h;
655 i = low;
656 }
657 }
658 }
659
660 void
661 db_show_variable(void)
662 {
663 struct db_variable *cur;
664 unsigned int l;
665 unsigned int len;
666 unsigned int sl;
667 unsigned int slen;
668 short h;
669 short i;
670 short j;
671 short k;
672 int t;
673 int t1;
674 struct db_var_aux_param aux_param;
675 char *name;
676 db_addr_t offset;
677
678 switch(t = db_read_token()) {
679 case tEOL:
680 case tEOF:
681 case tSEMI_COLON:
682 break;
683
684 case tDOLLAR:
685 t1 = db_read_token();
686 if (t1 == tIDENT) {
687 db_show_one_variable();
688 return;
689 }
690 db_error("Not a variable name after $\n");
691 db_unread_token(t);
692 return;
693
694 default:
695 db_error("Variable name should be prefixed with $\n");
696 db_unread_token(t);
697 return;
698 }
699 db_unread_token(t);
700
701 slen = len = 1;
702 for (cur = db_vars; cur < db_evars; cur++) {
703 if ((cur->min_level == 0 && !cur->hidden_level) || cur->high < 0)
704 j = 0;
705 else {
706 if (cur->min_level > 0) {
707 j = 1;
708 for (k = cur->high; k > 9; k /= 10)
709 j++;
710 } else
711 j = 0;
712 if (cur->hidden_level &&
713 (*cur->hidden_levelp < cur->hidden_low ||
714 *cur->hidden_levelp > cur->hidden_high)) {
715 j += 3;
716 for (k = cur->hidden_high; k > 9; k /= 10)
717 j++;
718 }
719 }
720 if ((l = strlen(cur->name) + j) >= len)
721 len = l + 1;
722 }
723
724 aux_param.modif = "";
725 aux_param.level = 1;
726 aux_param.thr_act = THR_ACT_NULL;
727
728 for (cur = db_vars; cur < db_evars; cur++) {
729 i = cur->low;
730 if (cur->hidden_level) {
731 if (*cur->hidden_levelp >= cur->hidden_low &&
732 *cur->hidden_levelp <= cur->hidden_high) {
733 h = cur->hidden_low - 1;
734 aux_param.hidden_level = *cur->hidden_levelp;
735 } else {
736 h = cur->hidden_low;
737 aux_param.hidden_level = cur->hidden_low;
738 }
739 slen = 1;
740 for (k = cur->high; k > 9; k /= 10)
741 slen++;
742 } else
743 aux_param.hidden_level = -1;
744
745 if (cur != db_vars && cur->high >= 0 &&
746 (cur->min_level > 0 || cur->hidden_level))
747 db_putchar('\n');
748
749 for (;;) {
750 db_printf(cur->name);
751 j = strlen(cur->name);
752 if (cur->high >= 0) {
753 if (cur->min_level > 0) {
754 db_printf("%d", i);
755 j++;
756 for (k = i; k > 9; k /= 10)
757 j++;
758 }
759 if (cur->hidden_level && h >= cur->hidden_low) {
760 sl = 1;
761 for (k = i; k > 9; k /= 10)
762 sl++;
763 while (sl++ < slen) {
764 db_putchar(' ');
765 j++;
766 }
767 db_printf("[%d]", h);
768 j += 3;
769 for (k = h; k > 9; k /= 10)
770 j++;
771 }
772 }
773 while (j++ < len)
774 db_putchar(' ');
775 db_putchar(':');
776 db_putchar(' ');
777
778 if (cur->fcn) {
779 aux_param.suffix[0] = i;
780 (*cur->fcn)(cur, (db_expr_t *)0, DB_VAR_SHOW, &aux_param);
781 } else {
782 db_printf("%#n", *(cur->valuep + i));
783 db_find_xtrn_task_sym_and_offset(*(cur->valuep + i), &name,
784 &offset, TASK_NULL);
785 if (name != (char *)0 && offset <= db_maxoff &&
786 offset != *(cur->valuep + i)) {
787 db_printf("\t%s", name);
788 if (offset != 0)
789 db_printf("+%#r", offset);
790 }
791 }
792 db_putchar('\n');
793 if (cur->high < 0)
794 break;
795 if (i++ == cur->high) {
796 if (!cur->hidden_level || h++ == cur->hidden_high)
797 break;
798 aux_param.hidden_level = h;
799 i = cur->low;
800 }
801 }
802 }
803 }
804
805 /*
806 * given a name of a machine register, return a variable pointer to it.
807 */
808 db_variable_t
809 db_find_reg_name(
810 char *s)
811 {
812 register db_variable_t regp;
813
814 if ( s == (char *)0 )
815 return DB_VAR_NULL;
816
817 for (regp = db_regs; regp < db_eregs; regp++) {
818 if ( strcmp( s, regp->name) == 0 )
819 return regp;
820 }
821 return DB_VAR_NULL;
822 }