📄 printcmd.c
字号:
(LONGEST) addr));}/* Optionally print address ADDR symbolically as <SYMBOL+OFFSET> on STREAM, after LEADIN. Print nothing if no symbolic name is found nearby. DO_DEMANGLE controls whether to print a symbol in its native "raw" form, or to interpret it as a possible C++ name and convert it back to source form. */voidprint_address_symbolic (addr, stream, do_demangle, leadin) CORE_ADDR addr; FILE *stream; int do_demangle; char *leadin;{ int name_location; register struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (addr); /* If nothing comes out, don't print anything symbolic. */ if (msymbol == NULL) return; fputs_filtered (leadin, stream); fputs_filtered ("<", stream); if (do_demangle) fputs_demangled (msymbol -> name, stream, DMGL_ANSI | DMGL_PARAMS); else fputs_filtered (msymbol -> name, stream); name_location = msymbol -> address; if (addr - name_location) fprintf_filtered (stream, "+%d>", addr - name_location); else fputs_filtered (">", stream);}/* Print address ADDR symbolically on STREAM. First print it as a number. Then perhaps print <SYMBOL + OFFSET> after the number. */voidprint_address (addr, stream) CORE_ADDR addr; FILE *stream;{#ifdef ADDR_BITS_REMOVE fprintf_filtered (stream, local_hex_format(), ADDR_BITS_REMOVE(addr));#else fprintf_filtered (stream, local_hex_format(), addr);#endif print_address_symbolic (addr, stream, asm_demangle, " ");}/* Print address ADDR symbolically on STREAM. Parameter DEMANGLE controls whether to print the symbolic name "raw" or demangled. Global setting "addressprint" controls whether to print hex address or not. */voidprint_address_demangle (addr, stream, do_demangle) CORE_ADDR addr; FILE *stream; int do_demangle;{ if (addr == 0) { fprintf_filtered (stream, "0"); } else if (addressprint) { fprintf_filtered (stream, local_hex_format(), addr); print_address_symbolic (addr, stream, do_demangle, " "); } else { print_address_symbolic (addr, stream, do_demangle, ""); }}static int asm_symbolic = 1;/* Examine data at address ADDR in format FMT. Fetch it from memory and print on stdout. */static voiddo_examine (fmt, addr) struct format_data fmt; CORE_ADDR addr;{ register char format = 0; register char size; register int count = 1; struct type *val_type; register int i; register int maxelts; format = fmt.format; size = fmt.size; count = fmt.count; next_address = addr; /* String or instruction format implies fetch single bytes regardless of the specified size. */ if (format == 's' || format == 'i') size = 'b'; if (size == 'b') val_type = builtin_type_char; else if (size == 'h') val_type = builtin_type_short; else if (size == 'w') val_type = builtin_type_long; else if (size == 'g')#ifndef LONG_LONG val_type = builtin_type_double;#else val_type = builtin_type_long_long;#endif maxelts = 8; if (size == 'w') maxelts = 4; if (size == 'g') maxelts = 2; if (format == 's' || format == 'i') maxelts = 1; /* Print as many objects as specified in COUNT, at most maxelts per line, with the address of the next one at the start of each line. */ while (count > 0) { if (asm_symbolic) print_address (next_address, stdout); else {#ifdef ADDR_BITS_REMOVE fprintf_filtered (stdout, local_hex_format(), ADDR_BITS_REMOVE(next_address));#else fprintf_filtered (stdout, local_hex_format(), next_address);#endif fputs_filtered (" ", stdout); } printf_filtered (":"); for (i = maxelts; i > 0 && count > 0; i--, count--) { printf_filtered (" "); /* Note that print_formatted sets next_address for the next object. */ last_examine_address = next_address; last_examine_value = value_at (val_type, next_address); print_formatted (last_examine_value, format, size); } printf_filtered ("\n"); fflush (stdout); }}static voidvalidate_format (fmt, cmdname) struct format_data fmt; char *cmdname;{ if (fmt.size != 0) error ("Size letters are meaningless in \"%s\" command.", cmdname); if (fmt.count != 1) error ("Item count other than 1 is meaningless in \"%s\" command.", cmdname); if (fmt.format == 'i' || fmt.format == 's') error ("Format letter \"%c\" is meaningless in \"%s\" command.", fmt.format, cmdname);}static voidprint_command_1 (exp, inspect, voidprint) char *exp; int inspect; int voidprint;{ struct expression *expr; register struct cleanup *old_chain = 0; register char format = 0; register value val; struct format_data fmt; int cleanup = 0; /* Pass inspect flag to the rest of the print routines in a global (sigh). */ inspect_it = inspect; if (exp && *exp == '/') { exp++; fmt = decode_format (&exp, last_format, 0); validate_format (fmt, "print"); last_format = format = fmt.format; } else { fmt.count = 1; fmt.format = 0; fmt.size = 0; } if (exp && *exp) { extern int objectprint; struct type *type; expr = parse_expression (exp); old_chain = make_cleanup (free_current_contents, &expr); cleanup = 1; val = evaluate_expression (expr); /* C++: figure out what type we actually want to print it as. */ type = VALUE_TYPE (val); if (objectprint && ( TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) && ( TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_STRUCT || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_UNION)) { value v; v = value_from_vtable_info (val, TYPE_TARGET_TYPE (type)); if (v != 0) { val = v; type = VALUE_TYPE (val); } } } else val = access_value_history (0); if (voidprint || (val && VALUE_TYPE (val) && TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_VOID)) { int histindex = record_latest_value (val); if (inspect) printf ("\031(gdb-makebuffer \"%s\" %d '(\"", exp, histindex); else if (histindex >= 0) printf_filtered ("$%d = ", histindex); print_formatted (val, format, fmt.size); printf_filtered ("\n"); if (inspect) printf("\") )\030"); } if (cleanup) do_cleanups (old_chain); inspect_it = 0; /* Reset print routines to normal */}/* ARGSUSED */static voidprint_command (exp, from_tty) char *exp; int from_tty;{ print_command_1 (exp, 0, 1);}/* Same as print, except in epoch, it gets its own window *//* ARGSUSED */static voidinspect_command (exp, from_tty) char *exp; int from_tty;{ extern int epoch_interface; print_command_1 (exp, epoch_interface, 1);}/* Same as print, except it doesn't print void results. *//* ARGSUSED */static voidcall_command (exp, from_tty) char *exp; int from_tty;{ print_command_1 (exp, 0, 0);}/* ARGSUSED */static voidoutput_command (exp, from_tty) char *exp; int from_tty;{ struct expression *expr; register struct cleanup *old_chain; register char format = 0; register value val; struct format_data fmt; if (exp && *exp == '/') { exp++; fmt = decode_format (&exp, 0, 0); validate_format (fmt, "output"); format = fmt.format; } expr = parse_expression (exp); old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); print_formatted (val, format, fmt.size); do_cleanups (old_chain);}/* ARGSUSED */static voidset_command (exp, from_tty) char *exp; int from_tty;{ struct expression *expr = parse_expression (exp); register struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); evaluate_expression (expr); do_cleanups (old_chain);}/* ARGSUSED */static voidaddress_info (exp, from_tty) char *exp; int from_tty;{ register struct symbol *sym; register struct minimal_symbol *msymbol; register long val; register long basereg; int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero if exp is a field of `this'. */ if (exp == 0) error ("Argument required."); sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE, &is_a_field_of_this, (struct symtab **)NULL); if (sym == 0) { if (is_a_field_of_this) { printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp); return; } msymbol = lookup_minimal_symbol (exp, (struct objfile *) NULL); if (msymbol != NULL) printf ("Symbol \"%s\" is at %s in a file compiled without debugging.\n", exp, local_hex_string(msymbol -> address)); else error ("No symbol \"%s\" in current context.", exp); return; } printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym)); val = SYMBOL_VALUE (sym); basereg = SYMBOL_BASEREG (sym); switch (SYMBOL_CLASS (sym)) { case LOC_CONST: case LOC_CONST_BYTES: printf ("constant"); break; case LOC_LABEL: printf ("a label at address %s", local_hex_string(SYMBOL_VALUE_ADDRESS (sym))); break; case LOC_REGISTER: printf ("a variable in register %s", reg_names[val]); break; case LOC_STATIC: printf ("static storage at address %s", local_hex_string(SYMBOL_VALUE_ADDRESS (sym))); break; case LOC_REGPARM: printf ("an argument in register %s", reg_names[val]); break; case LOC_ARG: if (SYMBOL_BASEREG_VALID (sym)) { printf ("an argument at offset %ld from register %s", val, reg_names[basereg]); } else { printf ("an argument at offset %ld", val); } break; case LOC_LOCAL_ARG: if (SYMBOL_BASEREG_VALID (sym)) { printf ("an argument at offset %ld from register %s", val, reg_names[basereg]); } else { printf ("an argument at frame offset %ld", val); } break; case LOC_LOCAL: if (SYMBOL_BASEREG_VALID (sym)) { printf ("a local variable at offset %ld from register %s", val, reg_names[basereg]); } else { printf ("a local variable at frame offset %ld", val); } break; case LOC_REF_ARG: printf ("a reference argument at offset %ld", val); break; case LOC_TYPEDEF: printf ("a typedef"); break; case LOC_BLOCK: printf ("a function at address %s", local_hex_string(BLOCK_START (SYMBOL_BLOCK_VALUE (sym)))); break; default: printf ("of unknown (botched) type"); break; } printf (".\n");}static voidx_command (exp, from_tty) char *exp; int from_tty;{ struct expression *expr; struct format_data fmt; struct cleanup *old_chain; struct value *val; fmt.format = last_format; fmt.size = last_size; fmt.count = 1; if (exp && *exp == '/') { exp++; fmt = decode_format (&exp, last_format, last_size); } /* If we have an expression, evaluate it and use it as the address. */ if (exp != 0 && *exp != 0) { expr = parse_expression (exp); /* Cause expression not to be there any more if this command is repeated with Newline. But don't clobber a user-defined command's definition. */ if (from_tty) *exp = 0; old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_expression (expr); if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF) val = value_ind (val); /* In rvalue contexts, such as this, functions are coerced into pointers to functions. This makes "x/i main" work. */ if (/* last_format == 'i' && */ TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC && VALUE_LVAL (val) == lval_memory) next_address = VALUE_ADDRESS (val); else next_address = value_as_pointer (val); do_cleanups (old_chain); } do_examine (fmt, next_address); /* If the examine succeeds, we remember its size and format for next time. */ last_size = fmt.size; last_format = fmt.format; /* Set a couple of internal variables if appropriate. */ if (last_examine_value) { /* Make last address examined available to the user as $_. Use the correct pointer type. */ set_internalvar (lookup_internalvar ("_"), value_from_longest ( lookup_pointer_type (VALUE_TYPE (last_examine_value)), (LONGEST) last_examine_address)); /* Make contents of last address examined available to the user as $__.*/ set_internalvar (lookup_internalvar ("__"), last_examine_value); }}/* Commands for printing types of things. *//* Print type of EXP, or last thing in value history if EXP == NULL. show is passed to type_print. */static voidwhatis_exp (exp, show) char *exp; int show;{ struct expression *expr; register value val; register struct cleanup *old_chain; if (exp) { expr = parse_expression (exp); old_chain = make_cleanup (free_current_contents, &expr); val = evaluate_type (expr); } else val = access_value_history (0); printf_filtered ("type = "); type_print (VALUE_TYPE (val), "", stdout, show); printf_filtered ("\n"); if (exp) do_cleanups (old_chain);}/* ARGSUSED */static voidwhatis_command (exp, from_tty) char *exp; int from_tty;{ /* Most of the time users do not want to see all the fields in a structure. If they do they can use the "ptype" command. Hence the "-1" below. */ whatis_exp (exp, -1);}/* Simple subroutine for ptype_command. */staticstruct type *ptype_eval(exp) struct expression *exp;{ if(exp->elts[0].opcode==OP_TYPE) return exp->elts[1].type; else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -