2004-11-03 Andrew Cagney * stack.c (frame_info): List registers saved in another register. Use the standard format when printing the source and frame information. Only print the frame's args or locals address when different to the frame's base address. Index: stack.c =================================================================== RCS file: /cvs/src/src/gdb/stack.c,v retrieving revision 1.115 diff -p -u -r1.115 stack.c --- stack.c 30 Oct 2004 21:16:10 -0000 1.115 +++ stack.c 3 Nov 2004 15:55:50 -0000 @@ -851,106 +851,30 @@ frame_info (char *addr_exp, int from_tty struct frame_info *fi; struct symtab_and_line sal; struct symbol *func; - struct symtab *s; struct frame_info *calling_frame_info; - int i, count, numregs; + int i; char *funname = 0; enum language funlang = language_unknown; const char *pc_regname; int selected_frame_p; + struct gdbarch *gdbarch; fi = parse_frame_specification_1 (addr_exp, "No stack.", &selected_frame_p); - - /* Name of the value returned by get_frame_pc(). Per comments, "pc" - is not a good name. */ - if (PC_REGNUM >= 0) - /* OK, this is weird. The PC_REGNUM hardware register's value can - easily not match that of the internal value returned by - get_frame_pc(). */ - pc_regname = REGISTER_NAME (PC_REGNUM); - else - /* But then, this is weird to. Even without PC_REGNUM, an - architectures will often have a hardware register called "pc", - and that register's value, again, can easily not match - get_frame_pc(). */ - pc_regname = "pc"; - - find_frame_sal (fi, &sal); - func = get_frame_function (fi); - /* FIXME: cagney/2002-11-28: Why bother? Won't sal.symtab contain - the same value. */ - s = find_pc_symtab (get_frame_pc (fi)); - if (func) - { - /* I'd like to use SYMBOL_PRINT_NAME() here, to display - * the demangled name that we already have stored in - * the symbol table, but we stored a version with - * DMGL_PARAMS turned on, and here we don't want - * to display parameters. So call the demangler again, - * with DMGL_ANSI only. RT - * (Yes, I know that printf_symbol_filtered() will - * again try to demangle the name on the fly, but - * the issue is that if cplus_demangle() fails here, - * it'll fail there too. So we want to catch the failure - * ("demangled==NULL" case below) here, while we still - * have our hands on the function symbol.) - */ - char *demangled; - funname = DEPRECATED_SYMBOL_NAME (func); - funlang = SYMBOL_LANGUAGE (func); - if (funlang == language_cplus) - { - demangled = cplus_demangle (funname, DMGL_ANSI); - /* If the demangler fails, try the demangled name - * from the symbol table. This'll have parameters, - * but that's preferable to diplaying a mangled name. - */ - if (demangled == NULL) - funname = SYMBOL_PRINT_NAME (func); - } - } - else - { - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (get_frame_pc (fi)); - if (msymbol != NULL) - { - funname = DEPRECATED_SYMBOL_NAME (msymbol); - funlang = SYMBOL_LANGUAGE (msymbol); - } - } + gdbarch = get_frame_arch (fi); calling_frame_info = get_prev_frame (fi); - if (selected_frame_p && frame_relative_level (fi) >= 0) - { - printf_filtered ("Stack level %d, frame at ", - frame_relative_level (fi)); - print_address_numeric (get_frame_base (fi), 1, gdb_stdout); - printf_filtered (":\n"); - } + /* Opening line, dump out the frame's stack address ... */ + if (selected_frame_p) + fprintf_filtered (gdb_stdout, "Stack level %d, frame at ", + frame_relative_level (fi)); else - { - printf_filtered ("Stack frame at "); - print_address_numeric (get_frame_base (fi), 1, gdb_stdout); - printf_filtered (":\n"); - } - printf_filtered (" %s = ", pc_regname); - print_address_numeric (get_frame_pc (fi), 1, gdb_stdout); - - wrap_here (" "); - if (funname) - { - printf_filtered (" in "); - fprintf_symbol_filtered (gdb_stdout, funname, funlang, - DMGL_ANSI | DMGL_PARAMS); - } - wrap_here (" "); - if (sal.symtab) - printf_filtered (" (%s:%d)", sal.symtab->filename, sal.line); - puts_filtered ("; "); - wrap_here (" "); - printf_filtered ("saved %s ", pc_regname); - print_address_numeric (frame_pc_unwind (fi), 1, gdb_stdout); - printf_filtered ("\n"); + fprintf_filtered (gdb_stdout, "Stack frame at "); + print_address_numeric (get_frame_base (fi), 1, gdb_stdout); + fprintf_filtered (gdb_stdout, ":\n"); + + /* Report where this frame is. */ + fprintf_filtered (gdb_stdout, " Code at "); + print_frame_info (fi, 0/*level*/, LOC_AND_ADDRESS, 1/*print_args*/); if (calling_frame_info) { @@ -969,56 +893,49 @@ frame_info (char *addr_exp, int from_tty } if (get_next_frame (fi) || calling_frame_info) puts_filtered ("\n"); - if (s) - printf_filtered (" source language %s.\n", - language_str (s->language)); + /* The source language, if known. */ { - /* Address of the argument list for this frame, or 0. */ - CORE_ADDR arg_list = get_frame_args_address (fi); - /* Number of args for this frame, or -1 if unknown. */ - int numargs; - - if (arg_list == 0) - printf_filtered (" Arglist at unknown address.\n"); - else - { - printf_filtered (" Arglist at "); - print_address_numeric (arg_list, 1, gdb_stdout); - printf_filtered (","); - - if (!FRAME_NUM_ARGS_P ()) - { - numargs = -1; - puts_filtered (" args: "); - } - else - { - numargs = FRAME_NUM_ARGS (fi); - gdb_assert (numargs >= 0); - if (numargs == 0) - puts_filtered (" no args."); - else if (numargs == 1) - puts_filtered (" 1 arg: "); - else - printf_filtered (" %d args: ", numargs); - } - print_frame_args (func, fi, numargs, gdb_stdout); - puts_filtered ("\n"); - } + struct symtab *s; + s = find_pc_symtab (get_frame_pc (fi)); + if (s) + printf_filtered (" Source language %s.\n", + language_str (s->language)); } + + /* Print the frame's base, args, and locals addresses (if any are + different). */ { - /* Address of the local variables for this frame, or 0. */ - CORE_ADDR arg_list = get_frame_locals_address (fi); + CORE_ADDR base_addr; + CORE_ADDR args_addr; + CORE_ADDR locals_addr; - if (arg_list == 0) - printf_filtered (" Locals at unknown address,"); + base_addr = get_frame_base_address (fi); + if (base_addr) + { + fprintf_filtered (gdb_stdout, " Frame base at "); + print_address_numeric (base_addr, 1, gdb_stdout); + } else + printf_filtered (" Frame base at unknown address"); + args_addr = get_frame_args_address (fi); + if (args_addr && args_addr != base_addr) + { + fprintf_filtered (gdb_stdout, ","); + wrap_here (" "); + fprintf_filtered (gdb_stdout, " arglist at "); + print_address_numeric (args_addr, 1, gdb_stdout); + } + locals_addr = get_frame_locals_address (fi); + if (locals_addr && locals_addr != base_addr) { - printf_filtered (" Locals at "); - print_address_numeric (arg_list, 1, gdb_stdout); - printf_filtered (","); + fprintf_filtered (gdb_stdout, ","); + wrap_here (" "); + fprintf_filtered (gdb_stdout, " locals at "); + print_address_numeric (locals_addr, 1, gdb_stdout); } + if (base_addr || args_addr || locals_addr) + fprintf_filtered (gdb_stdout, ".\n"); } /* Print as much information as possible on the location of all the @@ -1028,77 +945,50 @@ frame_info (char *addr_exp, int from_tty int optimized; CORE_ADDR addr; int realnum; - int count; - int i; - int need_nl = 1; - - /* The sp is special; what's displayed isn't the save address, but - the value of the previous frame's sp. This is a legacy thing, - at one stage the frame cached the previous frame's SP instead - of its address, hence it was easiest to just display the cached - value. */ - if (SP_REGNUM >= 0) + int regnum; + int count = 0; + const int numregs = NUM_REGS + NUM_PSEUDO_REGS; + + for (regnum = 0; regnum < numregs; regnum++) { - /* Find out the location of the saved stack pointer with out - actually evaluating it. */ - frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr, + /* Filter out system registers and the like. */ + if (!gdbarch_register_reggroup_p (current_gdbarch, regnum, + all_reggroup)) + continue; + /* Find out the location of the saved register without + fetching the corresponding value. */ + frame_register_unwind (fi, regnum, &optimized, &lval, &addr, &realnum, NULL); - if (!optimized && lval == not_lval) + /* Filter out registers that haven't been saved in another + register or memory. */ + if (optimized) + continue; + if (lval != lval_memory + && (lval != lval_register || realnum == regnum)) + continue; + /* Print the value. */ + if (count == 0) + puts_filtered (" Registers saved by this frame:\n "); + else { - char value[MAX_REGISTER_SIZE]; - CORE_ADDR sp; - frame_register_unwind (fi, SP_REGNUM, &optimized, &lval, &addr, - &realnum, value); - /* NOTE: cagney/2003-05-22: This is assuming that the - stack pointer was packed as an unsigned integer. That - may or may not be valid. */ - sp = extract_unsigned_integer (value, register_size (current_gdbarch, SP_REGNUM)); - printf_filtered (" Previous frame's sp is "); - print_address_numeric (sp, 1, gdb_stdout); - printf_filtered ("\n"); - need_nl = 0; + puts_filtered (","); + wrap_here (" "); } - else if (!optimized && lval == lval_memory) + count++; + printf_filtered (" %s", gdbarch_register_name (gdbarch, regnum)); + switch (lval) { - printf_filtered (" Previous frame's sp at "); + case lval_memory: + printf_filtered (" at "); print_address_numeric (addr, 1, gdb_stdout); - printf_filtered ("\n"); - need_nl = 0; - } - else if (!optimized && lval == lval_register) - { - printf_filtered (" Previous frame's sp in %s\n", - REGISTER_NAME (realnum)); - need_nl = 0; + break; + case lval_register: + printf_filtered (" in %s", + gdbarch_register_name (gdbarch, realnum)); + break; } - /* else keep quiet. */ } - - count = 0; - numregs = NUM_REGS + NUM_PSEUDO_REGS; - for (i = 0; i < numregs; i++) - if (i != SP_REGNUM - && gdbarch_register_reggroup_p (current_gdbarch, i, all_reggroup)) - { - /* Find out the location of the saved register without - fetching the corresponding value. */ - frame_register_unwind (fi, i, &optimized, &lval, &addr, &realnum, - NULL); - /* For moment, only display registers that were saved on the - stack. */ - if (!optimized && lval == lval_memory) - { - if (count == 0) - puts_filtered (" Saved registers:\n "); - else - puts_filtered (","); - wrap_here (" "); - printf_filtered (" %s at ", REGISTER_NAME (i)); - print_address_numeric (addr, 1, gdb_stdout); - count++; - } - } - if (count || need_nl) + if (count) puts_filtered ("\n"); } }