3bf57d21 |
1 | /* Print values for GNU debugger GDB. |
632ea0cc |
2 | Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. |
7b4ac7e1 |
3 | |
4 | GDB is distributed in the hope that it will be useful, but WITHOUT ANY |
5 | WARRANTY. No author or distributor accepts responsibility to anyone |
6 | for the consequences of using it or for whether it serves any |
7 | particular purpose or works at all, unless he says so in writing. |
8 | Refer to the GDB General Public License for full details. |
9 | |
10 | Everyone is granted permission to copy, modify and redistribute GDB, |
11 | but only under the conditions described in the GDB General Public |
12 | License. A copy of this license is supposed to have been given to you |
13 | along with GDB so you can know your rights and responsibilities. It |
14 | should be in a file named COPYING. Among other things, the copyright |
15 | notice and this notice must be preserved on all copies. |
16 | |
17 | In other words, go ahead and share GDB, but don't try to stop |
18 | anyone else from sharing it farther. Help stamp out software hoarding! |
19 | */ |
20 | |
21 | #include <stdio.h> |
22 | #include "defs.h" |
23 | #include "initialize.h" |
24 | #include "param.h" |
25 | #include "symtab.h" |
26 | #include "value.h" |
27 | #include "expression.h" |
28 | |
29 | struct format_data |
30 | { |
31 | int count; |
32 | char format; |
33 | char size; |
34 | }; |
35 | |
36 | /* Last specified output format. */ |
37 | |
38 | static char last_format = 'x'; |
39 | |
40 | /* Last specified examination size. 'b', 'h', 'w' or `q'. */ |
41 | |
42 | static char last_size = 'w'; |
43 | |
44 | /* Default address to examine next. */ |
45 | |
46 | static CORE_ADDR next_address; |
47 | |
48 | /* Last address examined. */ |
49 | |
50 | static CORE_ADDR last_examine_address; |
51 | |
52 | /* Contents of last address examined. |
53 | This is not valid past the end of the `x' command! */ |
54 | |
55 | static value last_examine_value; |
56 | |
3bf57d21 |
57 | /* Number of auto-display expression currently being displayed. |
58 | So that we can deleted it if we get an error or a signal within it. |
59 | -1 when not doing one. */ |
60 | |
61 | int current_display_number; |
62 | |
63 | static void do_one_display (); |
64 | |
7b4ac7e1 |
65 | void do_displays (); |
66 | void print_address (); |
3bf57d21 |
67 | void print_scalar_formatted (); |
7b4ac7e1 |
68 | |
69 | START_FILE |
70 | \f |
71 | /* Decode a format specification. *STRING_PTR should point to it. |
72 | OFORMAT and OSIZE are used as defaults for the format and size |
73 | if none are given in the format specification. |
74 | The structure returned describes all the data |
75 | found in the specification. In addition, *STRING_PTR is advanced |
76 | past the specification and past all whitespace following it. */ |
77 | |
78 | struct format_data |
79 | decode_format (string_ptr, oformat, osize) |
80 | char **string_ptr; |
81 | char oformat; |
82 | char osize; |
83 | { |
84 | struct format_data val; |
85 | register char *p = *string_ptr; |
86 | |
87 | val.format = oformat; |
88 | val.size = osize; |
89 | val.count = 1; |
90 | |
91 | if (*p >= '0' && *p <= '9') |
92 | val.count = atoi (p); |
93 | while (*p >= '0' && *p <= '9') p++; |
94 | |
95 | /* Now process size or format letters that follow. */ |
96 | |
97 | while (1) |
98 | { |
99 | if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g') |
100 | val.size = *p++; |
101 | else if (*p >= 'a' && *p <= 'z') |
102 | val.format = *p++; |
103 | else |
104 | break; |
105 | } |
106 | |
632ea0cc |
107 | /* Make sure 'g' size is not used on integer types. */ |
108 | if (val.size == 'g' && val.format != 'f') |
109 | val.size = 'w'; |
110 | |
7b4ac7e1 |
111 | while (*p == ' ' || *p == '\t') p++; |
112 | *string_ptr = p; |
113 | |
114 | return val; |
115 | } |
116 | \f |
117 | /* Print value VAL on stdout according to FORMAT, a letter or 0. |
118 | Do not end with a newline. |
632ea0cc |
119 | 0 means print VAL according to its own type. |
120 | SIZE is the letter for the size of datum being printed. |
121 | This is used to pad hex numbers so they line up. */ |
7b4ac7e1 |
122 | |
123 | static void |
632ea0cc |
124 | print_formatted (val, format, size) |
7b4ac7e1 |
125 | register value val; |
126 | register char format; |
632ea0cc |
127 | char size; |
7b4ac7e1 |
128 | { |
129 | register CORE_ADDR val_long; |
130 | int len = TYPE_LENGTH (VALUE_TYPE (val)); |
131 | |
132 | if (VALUE_LVAL (val) == lval_memory) |
133 | next_address = VALUE_ADDRESS (val) + len; |
134 | |
7b4ac7e1 |
135 | switch (format) |
136 | { |
137 | case 's': |
138 | next_address = VALUE_ADDRESS (val) |
3bf57d21 |
139 | + value_print (value_addr (val), stdout, 0); |
7b4ac7e1 |
140 | break; |
141 | |
142 | case 'i': |
143 | next_address = VALUE_ADDRESS (val) |
144 | + print_insn (VALUE_ADDRESS (val), stdout); |
145 | break; |
146 | |
3bf57d21 |
147 | default: |
148 | if (format == 0 |
149 | || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY |
150 | || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT |
151 | || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION) |
152 | value_print (val, stdout, format); |
153 | else |
154 | print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val), |
155 | format, size, stdout); |
156 | } |
157 | } |
158 | |
159 | /* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR, |
160 | according to letters FORMAT and SIZE on STREAM. |
161 | FORMAT may not be zero. Formats s and i are not supported at this level. |
162 | |
163 | This is how the elements of an array or structure are printed |
164 | with a format. */ |
165 | |
166 | void |
167 | print_scalar_formatted (valaddr, type, format, size, stream) |
168 | char *valaddr; |
169 | struct type *type; |
170 | char format; |
171 | int size; |
172 | FILE *stream; |
173 | { |
174 | long val_long; |
175 | int len = TYPE_LENGTH (type); |
176 | |
177 | val_long = unpack_long (type, valaddr); |
178 | |
179 | /* If value is unsigned, truncate it in case negative. */ |
180 | if (format != 'd') |
181 | { |
182 | if (len == sizeof (char)) |
183 | val_long &= (1 << 8 * sizeof(char)) - 1; |
184 | else if (len == sizeof (short)) |
185 | val_long &= (1 << 8 * sizeof(short)) - 1; |
186 | } |
187 | |
188 | switch (format) |
189 | { |
7b4ac7e1 |
190 | case 'x': |
632ea0cc |
191 | switch (size) |
192 | { |
193 | case 'b': |
194 | printf ("0x%02x", val_long); |
195 | break; |
196 | case 'h': |
197 | printf ("0x%04x", val_long); |
198 | break; |
199 | case 0: /* no size specified, like in print */ |
200 | case 'w': |
201 | printf ("0x%08x", val_long); |
202 | break; |
203 | case 'g': |
204 | printf ("0x%16x", val_long); |
205 | break; |
206 | default: |
207 | error ("Undefined output size \"%c\".", size); |
208 | } |
7b4ac7e1 |
209 | break; |
210 | |
211 | case 'd': |
212 | printf ("%d", val_long); |
213 | break; |
214 | |
215 | case 'u': |
216 | printf ("%u", val_long); |
217 | break; |
218 | |
219 | case 'o': |
220 | if (val_long) |
221 | printf ("0%o", val_long); |
222 | else |
223 | printf ("0"); |
224 | break; |
225 | |
226 | case 'a': |
3bf57d21 |
227 | print_address (val_long, stream); |
7b4ac7e1 |
228 | break; |
229 | |
230 | case 'c': |
3bf57d21 |
231 | value_print (value_from_long (builtin_type_char, val_long), stream, 0); |
7b4ac7e1 |
232 | break; |
233 | |
234 | case 'f': |
3bf57d21 |
235 | if (len == sizeof (float)) |
236 | type = builtin_type_float; |
237 | if (len == sizeof (double)) |
238 | type = builtin_type_double; |
7b4ac7e1 |
239 | #ifdef IEEE_FLOAT |
3bf57d21 |
240 | if (is_nan (unpack_double (type, valaddr))) |
7b4ac7e1 |
241 | { |
242 | printf ("Nan"); |
243 | break; |
244 | } |
245 | #endif |
3bf57d21 |
246 | printf ("%g", unpack_double (type, valaddr)); |
7b4ac7e1 |
247 | break; |
248 | |
249 | case 0: |
3bf57d21 |
250 | abort (); |
7b4ac7e1 |
251 | |
252 | default: |
253 | error ("Undefined output format \"%c\".", format); |
254 | } |
255 | } |
256 | |
257 | /* Specify default address for `x' command. |
258 | `info lines' uses this. */ |
259 | |
260 | void |
261 | set_next_address (addr) |
262 | CORE_ADDR addr; |
263 | { |
264 | next_address = addr; |
265 | |
266 | /* Make address available to the user as $_. */ |
267 | set_internalvar (lookup_internalvar ("_"), |
268 | value_from_long (builtin_type_int, addr)); |
269 | } |
270 | |
271 | /* Print address ADDR symbolically on STREAM. |
272 | First print it as a number. Then perhaps print |
273 | <SYMBOL + OFFSET> after the number. */ |
274 | |
275 | void |
276 | print_address (addr, stream) |
277 | CORE_ADDR addr; |
278 | FILE *stream; |
279 | { |
280 | register int i; |
281 | |
282 | fprintf (stream, "0x%x", addr); |
283 | |
284 | i = find_pc_misc_function (addr); |
285 | if (i >= 0) |
286 | if (misc_function_vector[i].address != addr) |
287 | fprintf (stream, " <%s+%d>", |
288 | misc_function_vector[i].name, |
289 | addr - misc_function_vector[i].address); |
290 | else |
291 | fprintf (stream, " <%s>", misc_function_vector[i].name); |
292 | |
293 | } |
294 | \f |
295 | /* Examine data at address ADDR in format FMT. |
296 | Fetch it from memory and print on stdout. */ |
297 | |
298 | static void |
299 | do_examine (fmt, addr) |
300 | struct format_data fmt; |
301 | CORE_ADDR addr; |
302 | { |
303 | register char format = 0; |
304 | register char size; |
305 | register int count = 1; |
306 | struct type *val_type; |
307 | register int i; |
308 | register int maxelts; |
309 | |
310 | format = fmt.format; |
311 | size = fmt.size; |
312 | count = fmt.count; |
313 | next_address = addr; |
314 | |
315 | /* String or instruction format implies fetch single bytes |
316 | regardless of the specified size. */ |
317 | if (format == 's' || format == 'i') |
318 | size = 'b'; |
319 | |
320 | if (size == 'b') |
321 | val_type = builtin_type_char; |
322 | else if (size == 'h') |
323 | val_type = builtin_type_short; |
324 | else if (size == 'w') |
325 | val_type = builtin_type_long; |
326 | else if (size == 'g') |
327 | val_type = builtin_type_double; |
328 | |
329 | maxelts = 8; |
330 | if (size == 'w') |
331 | maxelts = 4; |
332 | if (size == 'g') |
333 | maxelts = 2; |
334 | if (format == 's' || format == 'i') |
335 | maxelts = 1; |
336 | |
337 | /* Print as many objects as specified in COUNT, at most maxelts per line, |
338 | with the address of the next one at the start of each line. */ |
339 | |
340 | while (count > 0) |
341 | { |
342 | print_address (next_address, stdout); |
632ea0cc |
343 | fputc (':', stdout); |
7b4ac7e1 |
344 | for (i = maxelts; |
345 | i > 0 && count > 0; |
346 | i--, count--) |
347 | { |
348 | fputc ('\t', stdout); |
349 | /* Note that this sets next_address for the next object. */ |
350 | last_examine_address = next_address; |
351 | last_examine_value = value_at (val_type, next_address); |
632ea0cc |
352 | print_formatted (last_examine_value, format, size); |
7b4ac7e1 |
353 | } |
354 | fputc ('\n', stdout); |
355 | fflush (stdout); |
356 | } |
357 | } |
358 | \f |
359 | static void |
360 | validate_format (fmt, cmdname) |
361 | struct format_data fmt; |
362 | char *cmdname; |
363 | { |
364 | if (fmt.size != 0) |
365 | error ("Size letters are meaningless in \"%s\" command.", cmdname); |
366 | if (fmt.count != 1) |
367 | error ("Item count other than 1 is meaningless in \"%s\" command.", |
368 | cmdname); |
369 | if (fmt.format == 'i' || fmt.format == 's') |
370 | error ("Format letter \"%c\" is meaningless in \"%s\" command.", |
371 | fmt.format, cmdname); |
372 | } |
373 | |
374 | static void |
375 | print_command (exp) |
376 | char *exp; |
377 | { |
378 | struct expression *expr; |
379 | register struct cleanup *old_chain = 0; |
380 | register char format = 0; |
381 | register value val; |
382 | struct format_data fmt; |
383 | int histindex; |
384 | int cleanup = 0; |
385 | |
386 | if (exp && *exp == '/') |
387 | { |
388 | exp++; |
389 | fmt = decode_format (&exp, last_format, 0); |
390 | validate_format (fmt, "print"); |
391 | last_format = format = fmt.format; |
392 | } |
393 | |
394 | if (exp && *exp) |
395 | { |
396 | expr = parse_c_expression (exp); |
397 | old_chain = make_cleanup (free_current_contents, &expr); |
398 | cleanup = 1; |
399 | val = evaluate_expression (expr); |
400 | } |
401 | else |
402 | val = access_value_history (0); |
403 | |
404 | histindex = record_latest_value (val); |
405 | printf ("$%d = ", histindex); |
406 | |
632ea0cc |
407 | print_formatted (val, format, fmt.size); |
7b4ac7e1 |
408 | printf ("\n"); |
409 | |
410 | if (cleanup) |
411 | do_cleanups (old_chain); |
412 | } |
413 | |
414 | static void |
415 | output_command (exp) |
416 | char *exp; |
417 | { |
418 | struct expression *expr; |
419 | register struct cleanup *old_chain; |
420 | register char format = 0; |
421 | register value val; |
422 | struct format_data fmt; |
423 | |
424 | if (exp && *exp == '/') |
425 | { |
426 | exp++; |
427 | fmt = decode_format (&exp, 0, 0); |
428 | validate_format (fmt, "print"); |
429 | format = fmt.format; |
430 | } |
431 | |
432 | expr = parse_c_expression (exp); |
433 | old_chain = make_cleanup (free_current_contents, &expr); |
434 | |
435 | val = evaluate_expression (expr); |
436 | |
632ea0cc |
437 | print_formatted (val, format, fmt.size); |
7b4ac7e1 |
438 | |
439 | do_cleanups (old_chain); |
440 | } |
441 | |
442 | static void |
443 | set_command (exp) |
444 | char *exp; |
445 | { |
446 | struct expression *expr = parse_c_expression (exp); |
447 | register struct cleanup *old_chain |
448 | = make_cleanup (free_current_contents, &expr); |
449 | evaluate_expression (expr); |
450 | do_cleanups (old_chain); |
451 | } |
452 | |
453 | static void |
454 | address_info (exp) |
455 | char *exp; |
456 | { |
457 | register struct symbol *sym; |
458 | register CORE_ADDR val; |
459 | |
460 | if (exp == 0) |
461 | error ("Argument required."); |
462 | |
3bf57d21 |
463 | sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE); |
7b4ac7e1 |
464 | if (sym == 0) |
465 | { |
466 | register int i; |
467 | |
468 | for (i = 0; i < misc_function_count; i++) |
469 | if (!strcmp (misc_function_vector[i].name, exp)) |
470 | break; |
471 | |
472 | if (i < misc_function_count) |
473 | printf ("Symbol \"%s\" is at 0x%x in a file compiled without -g.\n", |
474 | exp, misc_function_vector[i].address); |
475 | else |
476 | error ("No symbol \"%s\" in current context.", exp); |
477 | return; |
478 | } |
479 | |
480 | printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym)); |
481 | val = SYMBOL_VALUE (sym); |
482 | |
483 | switch (SYMBOL_CLASS (sym)) |
484 | { |
485 | case LOC_CONST: |
486 | case LOC_CONST_BYTES: |
487 | printf ("constant"); |
488 | break; |
489 | |
490 | case LOC_LABEL: |
491 | printf ("a label at address 0x%x", val); |
492 | break; |
493 | |
494 | case LOC_REGISTER: |
495 | printf ("a variable in register %s", reg_names[val]); |
496 | break; |
497 | |
498 | case LOC_STATIC: |
499 | printf ("static at address 0x%x", val); |
500 | break; |
501 | |
502 | case LOC_ARG: |
503 | printf ("an argument at offset %d", val); |
504 | break; |
505 | |
506 | case LOC_LOCAL: |
507 | printf ("a local variable at frame offset %d", val); |
508 | break; |
509 | |
510 | case LOC_TYPEDEF: |
511 | printf ("a typedef"); |
512 | break; |
513 | |
514 | case LOC_BLOCK: |
515 | printf ("a function at address 0x%x", |
516 | BLOCK_START (SYMBOL_BLOCK_VALUE (sym))); |
517 | break; |
518 | } |
519 | printf (".\n"); |
520 | } |
521 | \f |
522 | static void |
523 | x_command (exp, from_tty) |
524 | char *exp; |
525 | int from_tty; |
526 | { |
527 | struct expression *expr; |
528 | struct format_data fmt; |
529 | struct cleanup *old_chain; |
530 | |
531 | fmt.format = last_format; |
532 | fmt.size = last_size; |
533 | fmt.count = 1; |
534 | |
535 | if (exp && *exp == '/') |
536 | { |
537 | exp++; |
538 | fmt = decode_format (&exp, last_format, last_size); |
539 | last_size = fmt.size; |
540 | last_format = fmt.format; |
541 | } |
542 | |
543 | /* If we have an expression, evaluate it and use it as the address. */ |
544 | |
545 | if (exp != 0 && *exp != 0) |
546 | { |
547 | expr = parse_c_expression (exp); |
548 | /* Cause expression not to be there any more |
549 | if this command is repeated with Newline. |
550 | But don't clobber a user-defined command's definition. */ |
551 | if (from_tty) |
552 | *exp = 0; |
553 | old_chain = make_cleanup (free_current_contents, &expr); |
554 | next_address = value_as_long (evaluate_expression (expr)); |
555 | do_cleanups (old_chain); |
556 | } |
557 | |
558 | do_examine (fmt, next_address); |
559 | |
560 | /* Make last address examined available to the user as $_. */ |
561 | set_internalvar (lookup_internalvar ("_"), |
562 | value_from_long (builtin_type_int, last_examine_address)); |
563 | |
564 | /* Make contents of last address examined available to the user as $__. */ |
565 | set_internalvar (lookup_internalvar ("__"), last_examine_value); |
566 | } |
567 | \f |
568 | /* Commands for printing types of things. */ |
569 | |
570 | static void |
571 | whatis_command (exp) |
572 | char *exp; |
573 | { |
574 | struct expression *expr; |
575 | register value val; |
576 | register struct cleanup *old_chain; |
577 | |
578 | if (exp) |
579 | { |
580 | expr = parse_c_expression (exp); |
581 | old_chain = make_cleanup (free_current_contents, &expr); |
582 | val = evaluate_type (expr); |
583 | } |
584 | else |
585 | val = access_value_history (0); |
586 | |
3bf57d21 |
587 | printf ("type = "); |
588 | type_print (VALUE_TYPE (val), "", stdout, 1); |
589 | printf ("\n"); |
7b4ac7e1 |
590 | |
591 | if (exp) |
592 | do_cleanups (old_chain); |
593 | } |
594 | |
595 | static void |
596 | ptype_command (typename) |
597 | char *typename; |
598 | { |
599 | register char *p = typename; |
600 | register int len; |
601 | extern struct block *get_current_block (); |
602 | register struct block *b |
603 | = (have_inferior_p () || have_core_file_p ()) ? get_current_block () : 0; |
604 | register struct type *type; |
605 | |
606 | if (typename == 0) |
607 | error_no_arg ("type name"); |
608 | |
609 | while (*p && *p != ' ' && *p != '\t') p++; |
610 | len = p - typename; |
611 | while (*p == ' ' || *p == '\t') p++; |
612 | |
613 | if (len == 6 && !strncmp (typename, "struct", 6)) |
614 | type = lookup_struct (p, b); |
615 | else if (len == 5 && !strncmp (typename, "union", 5)) |
616 | type = lookup_union (p, b); |
617 | else if (len == 4 && !strncmp (typename, "enum", 4)) |
618 | type = lookup_enum (p, b); |
619 | else |
620 | { |
621 | type = lookup_typename (typename, b, 1); |
622 | if (type == 0) |
623 | { |
624 | register struct symbol *sym |
625 | = lookup_symbol (typename, b, STRUCT_NAMESPACE); |
626 | if (sym == 0) |
627 | error ("No type named %s.", typename); |
628 | printf ("No type named %s, but there is a ", |
629 | typename); |
630 | switch (TYPE_CODE (SYMBOL_TYPE (sym))) |
631 | { |
632 | case TYPE_CODE_STRUCT: |
633 | printf ("struct"); |
634 | break; |
635 | |
636 | case TYPE_CODE_UNION: |
637 | printf ("union"); |
638 | break; |
639 | |
640 | case TYPE_CODE_ENUM: |
641 | printf ("enum"); |
642 | } |
643 | printf (" %s. Type \"help ptype\".\n", typename); |
644 | type = SYMBOL_TYPE (sym); |
645 | } |
646 | } |
647 | |
648 | type_print (type, "", stdout, 1); |
649 | printf ("\n"); |
650 | } |
651 | \f |
652 | struct display |
653 | { |
654 | /* Chain link to next auto-display item. */ |
655 | struct display *next; |
656 | /* Expression to be evaluated and displayed. */ |
657 | struct expression *exp; |
658 | /* Item number of this auto-display item. */ |
659 | int number; |
660 | /* Display format specified. */ |
661 | struct format_data format; |
662 | /* Block in which expression is to be evaluated. */ |
663 | struct block *block; |
664 | }; |
665 | |
666 | /* Chain of expressions whose values should be displayed |
667 | automatically each time the program stops. */ |
668 | |
669 | static struct display *display_chain; |
670 | |
671 | static int display_number; |
672 | |
673 | /* Add an expression to the auto-display chain. |
674 | Specify the expression. */ |
675 | |
676 | static void |
3bf57d21 |
677 | display_command (exp, from_tty) |
7b4ac7e1 |
678 | char *exp; |
3bf57d21 |
679 | int from_tty; |
7b4ac7e1 |
680 | { |
681 | struct format_data fmt; |
682 | register struct expression *expr; |
683 | register struct display *new; |
684 | |
685 | if (exp == 0) |
686 | { |
687 | do_displays (); |
688 | return; |
689 | } |
690 | |
691 | if (*exp == '/') |
692 | { |
693 | exp++; |
694 | fmt = decode_format (&exp, 0, 0); |
695 | if (fmt.size && fmt.format == 0) |
696 | fmt.format = 'x'; |
697 | if (fmt.format == 'i' || fmt.format == 's') |
698 | fmt.size = 'b'; |
699 | } |
700 | else |
701 | { |
702 | fmt.format = 0; |
703 | fmt.size = 0; |
704 | fmt.count = 0; |
705 | } |
706 | |
707 | expr = parse_c_expression (exp); |
708 | |
709 | new = (struct display *) xmalloc (sizeof (struct display)); |
710 | |
711 | new->exp = expr; |
712 | new->next = display_chain; |
713 | new->number = ++display_number; |
714 | new->format = fmt; |
715 | display_chain = new; |
716 | |
3bf57d21 |
717 | if (from_tty) |
718 | do_one_display (new); |
719 | |
7b4ac7e1 |
720 | dont_repeat (); |
721 | } |
722 | |
723 | static void |
724 | free_display (d) |
725 | struct display *d; |
726 | { |
727 | free (d->exp); |
728 | free (d); |
729 | } |
730 | |
731 | /* Clear out the display_chain. |
732 | Done when new symtabs are loaded, since this invalidates |
733 | the types stored in many expressions. */ |
734 | |
735 | void |
736 | clear_displays () |
737 | { |
738 | register struct display *d; |
739 | |
740 | while (d = display_chain) |
741 | { |
742 | free (d->exp); |
743 | display_chain = d->next; |
744 | free (d); |
745 | } |
746 | } |
747 | |
3bf57d21 |
748 | /* Delete the auto-display number NUM. */ |
749 | |
750 | void |
751 | delete_display (num) |
752 | int num; |
753 | { |
754 | register struct display *d1, *d; |
755 | |
756 | if (!display_chain) |
757 | error ("No display number %d.", num); |
758 | |
759 | if (display_chain->number == num) |
760 | { |
761 | d1 = display_chain; |
762 | display_chain = d1->next; |
763 | free_display (d1); |
764 | } |
765 | else |
766 | for (d = display_chain; ; d = d->next) |
767 | { |
768 | if (d->next == 0) |
769 | error ("No display number %d.", num); |
770 | if (d->next->number == num) |
771 | { |
772 | d1 = d->next; |
773 | d->next = d1->next; |
774 | free_display (d1); |
775 | break; |
776 | } |
777 | } |
778 | } |
779 | |
7b4ac7e1 |
780 | /* Delete some values from the auto-display chain. |
781 | Specify the element numbers. */ |
782 | |
783 | static void |
784 | undisplay_command (args) |
785 | char *args; |
786 | { |
787 | register char *p = args; |
788 | register char *p1; |
789 | register int num; |
790 | register struct display *d, *d1; |
791 | |
792 | if (args == 0) |
793 | { |
794 | if (query ("Delete all auto-display expressions? ")) |
795 | clear_displays (); |
796 | dont_repeat (); |
797 | return; |
798 | } |
799 | |
800 | while (*p) |
801 | { |
802 | p1 = p; |
803 | while (*p1 >= '0' && *p1 <= '9') p1++; |
804 | if (*p1 && *p1 != ' ' && *p1 != '\t') |
805 | error ("Arguments must be display numbers."); |
806 | |
807 | num = atoi (p); |
808 | |
3bf57d21 |
809 | delete_display (num); |
7b4ac7e1 |
810 | |
811 | p = p1; |
812 | while (*p == ' ' || *p == '\t') p++; |
813 | } |
814 | dont_repeat (); |
815 | } |
816 | |
3bf57d21 |
817 | /* Display a single auto-display. */ |
818 | |
819 | static void |
820 | do_one_display (d) |
821 | struct display *d; |
822 | { |
823 | current_display_number = d->number; |
824 | |
825 | printf ("%d: ", d->number); |
826 | if (d->format.size) |
827 | { |
828 | printf ("x/"); |
829 | if (d->format.count != 1) |
830 | printf ("%d", d->format.count); |
831 | printf ("%c", d->format.format); |
832 | if (d->format.format != 'i' && d->format.format != 's') |
833 | printf ("%c", d->format.size); |
834 | printf (" "); |
835 | print_expression (d->exp, stdout); |
836 | if (d->format.count != 1) |
837 | printf ("\n"); |
838 | else |
839 | printf (" "); |
840 | do_examine (d->format, |
841 | value_as_long (evaluate_expression (d->exp))); |
842 | } |
843 | else |
844 | { |
845 | if (d->format.format) |
846 | printf ("/%c ", d->format.format); |
847 | print_expression (d->exp, stdout); |
848 | printf (" = "); |
849 | print_formatted (evaluate_expression (d->exp), |
850 | d->format.format, d->format.size); |
851 | printf ("\n"); |
852 | } |
853 | |
854 | fflush (stdout); |
855 | current_display_number = -1; |
856 | } |
857 | |
7b4ac7e1 |
858 | /* Display all of the values on the auto-display chain. */ |
859 | |
860 | void |
861 | do_displays () |
862 | { |
863 | register struct display *d; |
864 | |
865 | for (d = display_chain; d; d = d->next) |
3bf57d21 |
866 | do_one_display (d); |
867 | } |
868 | |
869 | /* Delete the auto-display which we were in the process of displaying. |
870 | This is done when there is an error or a signal. */ |
871 | |
872 | void |
873 | delete_current_display () |
874 | { |
875 | if (current_display_number >= 0) |
7b4ac7e1 |
876 | { |
3bf57d21 |
877 | delete_display (current_display_number); |
878 | fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n", |
879 | current_display_number); |
7b4ac7e1 |
880 | } |
3bf57d21 |
881 | current_display_number = -1; |
7b4ac7e1 |
882 | } |
883 | |
884 | static void |
885 | display_info () |
886 | { |
887 | register struct display *d; |
888 | |
889 | if (!display_chain) |
890 | printf ("There are no auto-display expressions now.\n"); |
891 | else |
892 | printf ("Auto-display expressions now in effect:\n"); |
893 | for (d = display_chain; d; d = d->next) |
894 | { |
895 | printf ("%d: ", d->number); |
896 | if (d->format.size) |
897 | printf ("/%d%c%c ", d->format.count, d->format.size, |
898 | d->format.format); |
899 | else if (d->format.format) |
900 | printf ("/%c ", d->format.format); |
901 | print_expression (d->exp, stdout); |
902 | printf ("\n"); |
903 | fflush (stdout); |
904 | } |
905 | } |
906 | \f |
907 | /* Print the value in stack frame FRAME of a variable |
908 | specified by a struct symbol. */ |
909 | |
910 | void |
911 | print_variable_value (var, frame, stream) |
912 | struct symbol *var; |
913 | CORE_ADDR frame; |
914 | FILE *stream; |
915 | { |
916 | value val = read_var_value (var, frame); |
3bf57d21 |
917 | value_print (val, stream, 0); |
7b4ac7e1 |
918 | } |
919 | |
920 | /* Print the arguments of a stack frame, given the function FUNC |
921 | running in that frame (as a symbol), the address of the arglist, |
922 | and the number of args according to the stack frame (or -1 if unknown). */ |
923 | |
924 | static void print_frame_nameless_args (); |
925 | |
926 | print_frame_args (func, addr, num, stream) |
927 | struct symbol *func; |
928 | register CORE_ADDR addr; |
929 | int num; |
930 | FILE *stream; |
931 | { |
932 | struct block *b; |
933 | int nsyms = 0; |
934 | int first = 1; |
935 | register int i; |
936 | register int last_offset = FRAME_ARGS_SKIP; |
937 | register struct symbol *sym, *nextsym; |
938 | register value val; |
939 | |
940 | if (func) |
941 | { |
942 | b = SYMBOL_BLOCK_VALUE (func); |
943 | nsyms = BLOCK_NSYMS (b); |
944 | } |
945 | |
946 | while (1) |
947 | { |
948 | /* Find first arg that is not before LAST_OFFSET. */ |
949 | nextsym = 0; |
950 | for (i = 0; i < nsyms; i++) |
951 | { |
952 | QUIT; |
953 | sym = BLOCK_SYM (b, i); |
954 | if (SYMBOL_CLASS (sym) == LOC_ARG |
955 | && SYMBOL_VALUE (sym) >= last_offset |
956 | && (nextsym == 0 |
957 | || SYMBOL_VALUE (sym) < SYMBOL_VALUE (nextsym))) |
958 | nextsym = sym; |
959 | } |
960 | if (nextsym == 0) |
961 | break; |
962 | sym = nextsym; |
963 | /* Print any nameless args between the last arg printed |
964 | and the next arg. */ |
965 | if (last_offset != (SYMBOL_VALUE (sym) / sizeof (int)) * sizeof (int)) |
966 | { |
967 | print_frame_nameless_args (addr, last_offset, SYMBOL_VALUE (sym), |
968 | stream); |
969 | first = 0; |
970 | } |
971 | /* Print the next arg. */ |
972 | val = value_at (SYMBOL_TYPE (sym), addr + SYMBOL_VALUE (sym)); |
973 | if (! first) |
974 | fprintf (stream, ", "); |
975 | fprintf (stream, "%s=", SYMBOL_NAME (sym)); |
3bf57d21 |
976 | value_print (val, stream, 0); |
7b4ac7e1 |
977 | first = 0; |
978 | last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym)); |
979 | /* Round up address of next arg to multiple of size of int. */ |
980 | last_offset |
981 | = ((last_offset + sizeof (int) - 1) / sizeof (int)) * sizeof (int); |
982 | } |
983 | if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset) |
984 | print_frame_nameless_args (addr, last_offset, |
985 | num * sizeof (int) + FRAME_ARGS_SKIP, stream); |
986 | } |
987 | |
988 | static void |
989 | print_frame_nameless_args (argsaddr, start, end, stream) |
990 | CORE_ADDR argsaddr; |
991 | int start; |
992 | int end; |
993 | FILE *stream; |
994 | { |
995 | while (start < end) |
996 | { |
997 | QUIT; |
998 | if (start != FRAME_ARGS_SKIP) |
999 | fprintf (stream, ", "); |
1000 | fprintf (stream, "%d", |
1001 | read_memory_integer (argsaddr + start, sizeof (int))); |
1002 | start += sizeof (int); |
1003 | } |
1004 | } |
1005 | \f |
632ea0cc |
1006 | static void |
1007 | printf_command (arg) |
1008 | char *arg; |
1009 | { |
1010 | register char *f; |
1011 | register char *s = arg; |
1012 | char *string; |
1013 | value *val_args; |
1014 | int nargs = 0; |
1015 | int allocated_args = 20; |
1016 | char *arg_bytes; |
1017 | char *argclass; |
1018 | int i; |
1019 | int argindex; |
1020 | int nargs_wanted; |
1021 | |
1022 | val_args = (value *) xmalloc (allocated_args * sizeof (value)); |
1023 | |
1024 | if (s == 0) |
1025 | error_no_arg ("format-control string and values to print"); |
1026 | |
1027 | /* Skip white space before format string */ |
1028 | while (*s == ' ' || *s == '\t') s++; |
1029 | |
1030 | /* A format string should follow, enveloped in double quotes */ |
1031 | if (*s++ != '"') |
1032 | error ("Bad format string, missing '\"'."); |
1033 | |
1034 | /* Parse the format-control string and copy it into the string STRING, |
1035 | processing some kinds of escape sequence. */ |
1036 | |
1037 | f = string = (char *) alloca (strlen (s) + 1); |
1038 | while (*s != '"') |
1039 | { |
1040 | int c = *s++; |
1041 | switch (c) |
1042 | { |
1043 | case '\0': |
1044 | error ("Bad format string, non-terminated '\"'."); |
1045 | /* doesn't return */ |
1046 | |
1047 | case '\\': |
1048 | switch (c = *s++) |
1049 | { |
1050 | case '\\': |
1051 | *f++ = '\\'; |
1052 | break; |
1053 | case 'n': |
1054 | *f++ = '\n'; |
1055 | break; |
1056 | case 't': |
1057 | *f++ = '\t'; |
1058 | break; |
1059 | case 'r': |
1060 | *f++ = '\r'; |
1061 | break; |
1062 | case '"': |
1063 | *f++ = '"'; |
1064 | break; |
1065 | default: |
1066 | /* ??? TODO: handle other escape sequences */ |
1067 | error ("Unrecognized \\ escape character in format string."); |
1068 | } |
1069 | break; |
1070 | |
1071 | default: |
1072 | *f++ = c; |
1073 | } |
1074 | } |
1075 | |
1076 | /* Skip over " and following space and comma. */ |
1077 | s++; |
1078 | *f++ = '\0'; |
1079 | while (*s == ' ' || *s == '\t') s++; |
1080 | |
1081 | if (*s != ',' && *s != 0) |
1082 | error ("Invalid argument syntax"); |
1083 | |
1084 | if (*s == ',') s++; |
1085 | while (*s == ' ' || *s == '\t') s++; |
1086 | |
1087 | /* Now scan the string for %-specs and see what kinds of args they want. |
1088 | argclass[I] is set to 1 if the Ith arg should be a string. */ |
1089 | |
1090 | argclass = (char *) alloca (strlen (s)); |
1091 | nargs_wanted = 0; |
1092 | f = string; |
1093 | while (*f) |
1094 | if (*f++ == '%') |
1095 | { |
1096 | while (index ("0123456789.hlL-+ #", *f)) f++; |
1097 | if (*f == 's') |
1098 | argclass[nargs_wanted++] = 1; |
1099 | else if (*f != '%') |
1100 | argclass[nargs_wanted++] = 0; |
1101 | f++; |
1102 | } |
1103 | |
1104 | /* Now, parse all arguments and evaluate them. |
1105 | Store the VALUEs in VAL_ARGS. */ |
1106 | |
1107 | while (*s != '\0') |
1108 | { |
1109 | char *s1; |
1110 | if (nargs == allocated_args) |
1111 | val_args = (value *) xrealloc (val_args, |
1112 | (allocated_args *= 2) |
1113 | * sizeof (value)); |
1114 | s1 = s; |
1115 | val_args[nargs++] = parse_to_comma_and_eval (&s1); |
1116 | s = s1; |
1117 | if (*s == ',') |
1118 | s++; |
1119 | } |
1120 | |
1121 | if (nargs != nargs_wanted) |
1122 | error ("Wrong number of arguments for specified format-string"); |
1123 | |
1124 | /* Now lay out an argument-list containing the arguments |
1125 | as doubles, integers and C pointers. */ |
1126 | |
1127 | arg_bytes = (char *) alloca (sizeof (double) * nargs); |
1128 | argindex = 0; |
1129 | for (i = 0; i < nargs; i++) |
1130 | { |
1131 | if (argclass[i]) |
1132 | { |
1133 | char *str; |
1134 | int tem, j; |
1135 | tem = value_as_long (val_args[i]); |
1136 | |
1137 | /* This is a %s argument. Find the length of the string. */ |
1138 | for (j = 0; ; j++) |
1139 | { |
1140 | char c; |
1141 | QUIT; |
1142 | read_memory (tem + j, &c, 1); |
1143 | if (c == 0) |
1144 | break; |
1145 | } |
1146 | |
1147 | /* Copy the string contents into a string inside GDB. */ |
1148 | str = (char *) alloca (j + 1); |
1149 | read_memory (tem, str, j); |
1150 | str[j] = 0; |
1151 | |
1152 | /* Pass address of internal copy as the arg to vprintf. */ |
1153 | *((int *) &arg_bytes[argindex]) = (int) str; |
1154 | argindex += sizeof (int); |
1155 | } |
1156 | else if (VALUE_TYPE (val_args[i])->code == TYPE_CODE_FLT) |
1157 | { |
1158 | *((double *) &arg_bytes[argindex]) = value_as_double (val_args[i]); |
1159 | argindex += sizeof (double); |
1160 | } |
1161 | else |
1162 | { |
1163 | *((int *) &arg_bytes[argindex]) = value_as_long (val_args[i]); |
1164 | argindex += sizeof (int); |
1165 | } |
1166 | } |
1167 | |
1168 | vprintf (string, arg_bytes); |
1169 | } |
1170 | \f |
7b4ac7e1 |
1171 | static |
1172 | initialize () |
1173 | { |
3bf57d21 |
1174 | current_display_number = -1; |
1175 | |
7b4ac7e1 |
1176 | add_info ("address", address_info, |
1177 | "Describe where variable VAR is stored."); |
1178 | |
1179 | add_com ("x", class_vars, x_command, |
1180 | "Examine memory: x/FMT ADDRESS.\n\ |
1181 | ADDRESS is an expression for the memory address to examine.\n\ |
1182 | FMT is a repeat count followed by a format letter and a size letter.\n\ |
1183 | Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\ |
1184 | f(float), a(address), i(instruction), c(char) and s(string).\n\ |
1185 | Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\ |
1186 | g is meaningful only with f, for type double.\n\ |
1187 | The specified number of objects of the specified size are printed\n\ |
1188 | according to the format.\n\n\ |
1189 | Defaults for format and size letters are those previously used.\n\ |
1190 | Default count is 1. Default address is following last thing printed\n\ |
1191 | with this command or \"print\"."); |
1192 | |
1193 | add_com ("ptype", class_vars, ptype_command, |
1194 | "Print definition of type TYPE.\n\ |
1195 | Argument may be a type name defined by typedef, or \"struct STRUCTNAME\"\n\ |
1196 | or \"union UNIONNAME\" or \"enum ENUMNAME\".\n\ |
1197 | The selected stack frame's lexical context is used to look up the name."); |
1198 | |
1199 | add_com ("whatis", class_vars, whatis_command, |
1200 | "Print data type of expression EXP."); |
1201 | |
1202 | add_info ("display", display_info, |
1203 | "Expressions to display when program stops, with code numbers."); |
1204 | add_com ("undisplay", class_vars, undisplay_command, |
1205 | "Cancel some expressions to be displayed whenever program stops.\n\ |
1206 | Arguments are the code numbers of the expressions to stop displaying.\n\ |
1207 | No argument means cancel all automatic-display expressions.\n\ |
1208 | Do \"info display\" to see current list of code numbers."); |
1209 | add_com ("display", class_vars, display_command, |
1210 | "Print value of expression EXP each time the program stops.\n\ |
1211 | /FMT may be used before EXP as in the \"print\" command.\n\ |
1212 | /FMT \"i\" or \"s\" or including a size-letter is allowed,\n\ |
1213 | as in the \"x\" command, and then EXP is used to get the address to examine\n\ |
1214 | and examining is done as in the \"x\" command.\n\n\ |
1215 | With no argument, display all currently requested auto-display expressions.\n\ |
1216 | Use \"undisplay\" to cancel display requests previously made."); |
1217 | |
632ea0cc |
1218 | add_com ("printf", class_vars, printf_command, |
1219 | "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\ |
1220 | This is useful for formatted output in user-defined commands."); |
7b4ac7e1 |
1221 | add_com ("output", class_vars, output_command, |
1222 | "Like \"print\" but don't put in value history and don't print newline.\n\ |
1223 | This is useful in user-defined commands."); |
1224 | |
1225 | add_com ("set", class_vars, set_command, |
1226 | "Perform an assignment VAR = EXP. You must type the \"=\".\n\ |
1227 | VAR may be a debugger \"convenience\" variables (names starting with $),\n\ |
1228 | a register (a few standard names starting with $), or an actual variable\n\ |
1229 | in the program being debugger. EXP is any expression."); |
1230 | |
1231 | add_com ("print", class_vars, print_command, |
1232 | concat ("Print value of expression EXP.\n\ |
1233 | Variables accessible are those of the lexical environment of the selected\n\ |
1234 | stack frame, plus all those whose scope is global or an entire file.\n\ |
1235 | \n\ |
1236 | $NUM gets previous value number NUM. $ and $$ are the last two values.\n\ |
1237 | $$NUM refers to NUM'th value back from the last one.\n\ |
1238 | Names starting with $ refer to registers (with the values they would have\n\ |
1239 | if the program were to return to the stack frame now selected, restoring\n\ |
1240 | all registers saved by frames farther in) or else to debugger\n\ |
1241 | \"convenience\" variables (any such name not a known register).\n\ |
1242 | Use assignment expressions to give values to convenience variables.\n", |
1243 | "\n\ |
1244 | \{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.\n\ |
1245 | @ is a binary operator for treating consecutive data objects\n\ |
1246 | anywhere in memory as an array. FOO@NUM gives an array whose first\n\ |
1247 | element is FOO, whose second element is stored in the space following\n\ |
1248 | where FOO is stored, etc. FOO must be an expression whose value\n\ |
1249 | resides in memory.\n", |
1250 | "\n\ |
1251 | EXP may be preceded with /FMT, where FMT is a format letter\n\ |
1252 | but no count or size letter (see \"x\" command).")); |
1253 | add_com_alias ("p", "print", class_vars, 1); |
1254 | } |
1255 | |
1256 | END_FILE |