From 76212295984365ba3f767cf7c99d1d535360fb99 Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Sat, 8 Oct 1994 11:54:29 +0000 Subject: [PATCH] Speed up GDB startup time by not demangling partial symbols. * symfile.h (ADD_PSYMBOL_VT_TO_LIST), symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): No longer demangle partial symbols. * symtab.c (lookup_symbol, list_symbols): Handle mangled variables, e.g. C++ static members, via the minimal symbols. Handle reordered functions in an objfile, for Irix 5.2 shared libraries. * objfiles.h (OBJF_REORDERED): New bit in the objfile flags, set if the functions in an objfile are reordered. * mdebugread.c (parse_partial_symbols): Detect reordered functions in an objfile. * symtab.c (find_pc_psymtab, find_pc_symtab): Use expensive lookup algorithm if the functions in the objfile are reordered. * xcoffexec.c (exec_close): If the current target has a copy of the exec_ops sections, reflect the freeing of the sections in current_target. * valops.c (call_function_by_hand): Use `sizeof dummy1', not `sizeof dummy', for constructing the call dummy code. * config/sparc/tm-sparc.h: Add PARAMS declarations to all function declarations. * sparc-tdep.c (sparc_pop_frame): Cast result of read_memory_integer to CORE_ADDR when passing it to PC_ADJUST. * irix5-nat.c (enable_break): Set breakpoint at the entry point of the executable, to handle the case where main resides in a shared library. * irix5-nat.c (solib_create_inferior_hook): Reset stop_soon_quietly after shared library symbol reading, to get rid of a warning from heuristic_proc_start if the startup code has no symbolic debug info. * breakpoint.h (struct breakpoint): Add new fields language and input_radix, to enable breakpoint resetting with the proper language and radix. * breakpoint.c (set_raw_breakpoint): Initialize them. (breakpoint_re_set_one): Use them when resetting the breakpoint. (breakpoint_re_set): Preserve current language and input_radix across breakpoint_re_set_one calls. * symtab.c (decode_line_1): Do not build a canonical line specification for `*expr' line specifications. * breakpoint.h (bpstat_stop_status): Fix prototype declaration. --- gdb/ChangeLog | 50 ++++++++ gdb/irix5-nat.c | 101 +++------------ gdb/mdebugread.c | 29 +++++ gdb/objfiles.h | 8 ++ gdb/sparc-tdep.c | 2 +- gdb/symfile.c | 24 ++-- gdb/symtab.c | 322 +++++++++++++++++++++++++++-------------------- gdb/xcoffexec.c | 10 ++ 8 files changed, 314 insertions(+), 232 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9a5013edbe9..1459919d872 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,53 @@ +Sat Oct 8 04:27:21 1994 Peter Schauer (pes@regent.e-technik.tu-muenchen.de) + + Speed up GDB startup time by not demangling partial symbols. + * symfile.h (ADD_PSYMBOL_VT_TO_LIST), + symfile.c (add_psymbol_to_list, add_psymbol_addr_to_list): + No longer demangle partial symbols. + * symtab.c (lookup_symbol, list_symbols): Handle mangled + variables, e.g. C++ static members, via the minimal symbols. + + Handle reordered functions in an objfile, for Irix 5.2 shared + libraries. + * objfiles.h (OBJF_REORDERED): New bit in the objfile flags, + set if the functions in an objfile are reordered. + * mdebugread.c (parse_partial_symbols): Detect reordered + functions in an objfile. + * symtab.c (find_pc_psymtab, find_pc_symtab): Use expensive + lookup algorithm if the functions in the objfile are reordered. + + * xcoffexec.c (exec_close): If the current target has a copy + of the exec_ops sections, reflect the freeing of the sections + in current_target. + + * valops.c (call_function_by_hand): Use `sizeof dummy1', not + `sizeof dummy', for constructing the call dummy code. + + * config/sparc/tm-sparc.h: Add PARAMS declarations to all + function declarations. + * sparc-tdep.c (sparc_pop_frame): Cast result of + read_memory_integer to CORE_ADDR when passing it to PC_ADJUST. + + * irix5-nat.c (enable_break): Set breakpoint at the entry point + of the executable, to handle the case where main resides in a + shared library. + * irix5-nat.c (solib_create_inferior_hook): Reset stop_soon_quietly + after shared library symbol reading, to get rid of a warning from + heuristic_proc_start if the startup code has no symbolic debug info. + + * breakpoint.h (struct breakpoint): Add new fields language + and input_radix, to enable breakpoint resetting with the + proper language and radix. + * breakpoint.c (set_raw_breakpoint): Initialize them. + (breakpoint_re_set_one): Use them when resetting the breakpoint. + (breakpoint_re_set): Preserve current language and input_radix + across breakpoint_re_set_one calls. + + * symtab.c (decode_line_1): Do not build a canonical line + specification for `*expr' line specifications. + + * breakpoint.h (bpstat_stop_status): Fix prototype declaration. + Fri Oct 7 08:48:18 1994 Jim Kingdon (kingdon@lioth.cygnus.com) The point of these changes is to avoid reading the frame pointer diff --git a/gdb/irix5-nat.c b/gdb/irix5-nat.c index 38cc0949ab9..f4137383b91 100644 --- a/gdb/irix5-nat.c +++ b/gdb/irix5-nat.c @@ -194,21 +194,6 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) #include "inferior.h" #include "language.h" -/* We need to set a breakpoint at a point when we know that the - mapping of shared libraries is complete. dbx simply breaks at main - (or, for FORTRAN, MAIN__), so we do the same. We can not break at - the very beginning of main, because the startup code will jump into - main after the GP initialization instructions. SOLIB_BKPT_OFFSET - is used to skip those instructions. */ - -#define SOLIB_BKPT_OFFSET 12 - -static char *bkpt_names[] = { - "main", - "MAIN__", - NULL -}; - /* The symbol which starts off the list of shared libraries. */ #define DEBUG_BASE "__rld_obj_head" @@ -878,84 +863,22 @@ SYNOPSIS DESCRIPTION - Both the SunOS and the SVR4 dynamic linkers have, as part of their - debugger interface, support for arranging for the inferior to hit - a breakpoint after mapping in the shared libraries. This function - enables that breakpoint. - - For SunOS, there is a special flag location (in_debugger) which we - set to 1. When the dynamic linker sees this flag set, it will set - a breakpoint at a location known only to itself, after saving the - original contents of that place and the breakpoint address itself, - in it's own internal structures. When we resume the inferior, it - will eventually take a SIGTRAP when it runs into the breakpoint. - We handle this (in a different place) by restoring the contents of - the breakpointed location (which is only known after it stops), - chasing around to locate the shared libraries that have been - loaded, then resuming. - - For SVR4, the debugger interface structure contains a member (r_brk) - which is statically initialized at the time the shared library is - built, to the offset of a function (_r_debug_state) which is guaran- - teed to be called once before mapping in a library, and again when - the mapping is complete. At the time we are examining this member, - it contains only the unrelocated offset of the function, so we have - to do our own relocation. Later, when the dynamic linker actually - runs, it relocates r_brk to be the actual address of _r_debug_state(). - - The debugger interface structure also contains an enumeration which - is set to either RT_ADD or RT_DELETE prior to changing the mapping, - depending upon whether or not the library is being mapped or unmapped, - and then set to RT_CONSISTENT after the library is mapped/unmapped. - - Irix 5, on the other hand, has no such features. Instead, we - set a breakpoint at main. + This functions inserts a breakpoint at the entry point of the + main executable, where all shared libraries are mapped in. */ static int enable_break () { - int success = 0; - struct minimal_symbol *msymbol; - char **bkpt_namep; - CORE_ADDR bkpt_addr; - - /* Scan through the list of symbols, trying to look up the symbol and - set a breakpoint there. Terminate loop when we/if we succeed. */ - - breakpoint_addr = 0; - for (bkpt_namep = bkpt_names; *bkpt_namep != NULL; bkpt_namep++) + if (symfile_objfile != NULL + && target_insert_breakpoint (symfile_objfile->ei.entry_point, + shadow_contents) == 0) { - msymbol = lookup_minimal_symbol (*bkpt_namep, symfile_objfile); - if ((msymbol != NULL) && (SYMBOL_VALUE_ADDRESS (msymbol) != 0)) - { - bkpt_addr = SYMBOL_VALUE_ADDRESS (msymbol); -#ifdef SOLIB_BKPT_OFFSET - /* We only want to skip if bkpt_addr is currently pointing - at a GP setting instruction. */ - { - char buf[4]; - - if (target_read_memory (bkpt_addr, buf, 4) == 0) - { - unsigned long insn; - - insn = extract_unsigned_integer (buf, 4); - if ((insn & 0xffff0000) == 0x3c1c0000) /* lui $gp,n */ - bkpt_addr += SOLIB_BKPT_OFFSET; - } - } -#endif - if (target_insert_breakpoint (bkpt_addr, shadow_contents) == 0) - { - breakpoint_addr = bkpt_addr; - success = 1; - break; - } - } + breakpoint_addr = symfile_objfile->ei.entry_point; + return 1; } - return (success); + return 0; } /* @@ -1033,7 +956,6 @@ solib_create_inferior_hook() wait_for_inferior (); } while (stop_signal != SIGTRAP); - stop_soon_quietly = 0; /* We are now either at the "mapping complete" breakpoint (or somewhere else, a condition we aren't prepared to deal with anyway), so adjust @@ -1051,7 +973,14 @@ solib_create_inferior_hook() warning ("shared library handler failed to disable breakpoint"); } + /* solib_add will call reinit_frame_cache. + But we are stopped in the startup code and we might not have symbols + for the startup code, so heuristic_proc_start could be called + and will put out an annoying warning. + Delaying the resetting of stop_soon_quietly until after symbol loading + suppresses the warning. */ solib_add ((char *) 0, 0, (struct target_ops *) 0); + stop_soon_quietly = 0; } /* diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c index 5d1325d68d8..7b30ec30cb3 100644 --- a/gdb/mdebugread.c +++ b/gdb/mdebugread.c @@ -2793,6 +2793,35 @@ parse_partial_symbols (objfile, section_offsets) objfile->ei.entry_file_lowpc = save_pst->textlow; objfile->ei.entry_file_highpc = save_pst->texthigh; } + + /* The objfile has its functions reordered if this partial symbol + table overlaps any other partial symbol table. + We cannot assume a reordered objfile if a partial symbol table + is contained within another partial symbol table, as partial symbol + tables for include files with executable code are contained + within the partial symbol table for the including source file, + and we do not want to flag the objfile reordered for these cases. + + This strategy works well for Irix-5.2 shared libraries, but we + might have to use a more elaborate (and slower) algorithm for + other cases. */ + save_pst = fdr_to_pst[f_idx].pst; + if (save_pst != NULL + && save_pst->textlow != 0 + && !(objfile->flags & OBJF_REORDERED)) + { + ALL_OBJFILE_PSYMTABS (objfile, pst) + { + if (save_pst != pst + && save_pst->textlow >= pst->textlow + && save_pst->textlow < pst->texthigh + && save_pst->texthigh > pst->texthigh) + { + objfile->flags |= OBJF_REORDERED; + break; + } + } + } } /* Now scan the FDRs for dependencies */ diff --git a/gdb/objfiles.h b/gdb/objfiles.h index f7cd113eda6..a4b3d2cd99f 100644 --- a/gdb/objfiles.h +++ b/gdb/objfiles.h @@ -343,6 +343,14 @@ struct objfile #define OBJF_SYMS (1 << 1) /* Have tried to read symbols */ +/* When an object file has its functions reordered (currently Irix-5.2 + shared libraries exhibit this behaviour), we will need an expensive + algorithm to locate a partial symtab or symtab via an address. + To avoid this penalty for normal object files, we use this flag, + whose setting is determined upon symbol table read in. */ + +#define OBJF_REORDERED (2 << 1) /* Functions are reordered */ + /* The object file that the main symbol table was loaded from (e.g. the argument to the "symbol-file" or "file" command). */ diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index e67fae74513..a0cb2cc1180 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -572,7 +572,7 @@ sparc_pop_frame () else if (fsr.regs[I7_REGNUM]) { /* Return address in %i7 -- adjust it, then restore PC and NPC from it */ - pc = PC_ADJUST (read_memory_integer (fsr.regs[I7_REGNUM], 4)); + pc = PC_ADJUST ((CORE_ADDR) read_memory_integer (fsr.regs[I7_REGNUM], 4)); write_register (PC_REGNUM, pc); write_register (NPC_REGNUM, pc + 4); } diff --git a/gdb/symfile.c b/gdb/symfile.c index 577aaa486c0..24e7c6e3f62 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -620,11 +620,6 @@ symbol_file_add (name, from_tty, addr, mainline, mapped, readnow) } new_symfile_objfile (objfile, mainline, from_tty); - - /* Getting new symbols may change our opinion about what is - frameless. */ - - reinit_frame_cache (); return (objfile); } @@ -710,6 +705,11 @@ symbol_file_command (args, from_tty) else symbol_file_add (name, from_tty, (CORE_ADDR)text_relocation, 0, mapped, readnow); + + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); + set_initial_language (); } argv++; @@ -1025,6 +1025,10 @@ add_symbol_file_command (args, from_tty) error ("Not confirmed."); symbol_file_add (name, 0, text_addr, 0, mapped, readnow); + + /* Getting new symbols may change our opinion about what is + frameless. */ + reinit_frame_cache (); } static void @@ -1079,6 +1083,7 @@ reread_symbols () struct section_offsets *offsets; int num_offsets; int section_offsets_size; + char *obfd_filename; printf_filtered ("`%s' has changed; re-reading symbols.\n", objfile->name); @@ -1100,9 +1105,10 @@ reread_symbols () /* Clean up any state BFD has sitting around. We don't need to close the descriptor but BFD lacks a way of closing the BFD without closing the descriptor. */ + obfd_filename = bfd_get_filename (objfile->obfd); if (!bfd_close (objfile->obfd)) error ("Can't close BFD for %s.", objfile->name); - objfile->obfd = bfd_openr (objfile->name, gnutarget); + objfile->obfd = bfd_openr (obfd_filename, gnutarget); if (objfile->obfd == NULL) error ("Can't open %s to read symbols.", objfile->name); /* bfd_openr sets cacheable to true, which is what we want. */ @@ -1237,6 +1243,8 @@ deduce_language_from_filename (filename) return language_cplus; else if (STREQ (c, ".ch") || STREQ (c, ".c186") || STREQ (c, ".c286")) return language_chill; + else if (STREQ (c, ".f") || STREQ (c, ".F")) + return language_fortran; else if (STREQ (c, ".mod")) return language_m2; else if (STREQ (c, ".s") || STREQ (c, ".S")) @@ -1603,7 +1611,7 @@ add_psymbol_to_list (name, namelength, namespace, class, list, val, language, SYMBOL_LANGUAGE (psym) = language; PSYMBOL_NAMESPACE (psym) = namespace; PSYMBOL_CLASS (psym) = class; - SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack); + SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language); } /* Add a symbol with a CORE_ADDR value to a psymtab. */ @@ -1637,7 +1645,7 @@ add_psymbol_addr_to_list (name, namelength, namespace, class, list, val, SYMBOL_LANGUAGE (psym) = language; PSYMBOL_NAMESPACE (psym) = namespace; PSYMBOL_CLASS (psym) = class; - SYMBOL_INIT_DEMANGLED_NAME (psym, &objfile->psymbol_obstack); + SYMBOL_INIT_LANGUAGE_SPECIFIC (psym, language); } #endif /* !INLINE_ADD_PSYMBOL */ diff --git a/gdb/symtab.c b/gdb/symtab.c index 0a639641d71..3f6c00efeb7 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -35,7 +35,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "demangle.h" #include -#include #include #include @@ -291,7 +290,6 @@ gdb_mangle_name (type, i, j) if (!is_destructor) is_destructor = (strncmp(physname, "__dt", 4) == 0); -#ifndef GCC_MANGLE_BUG if (is_destructor || is_full_physname_constructor) { mangled_name = (char*) xmalloc(strlen(physname)+1); @@ -305,6 +303,13 @@ gdb_mangle_name (type, i, j) if (strcmp(buf, "__") == 0) buf[0] = '\0'; } + else if (newname != NULL && strchr (newname, '<') != NULL) + { + /* Template methods are fully mangled. */ + sprintf (buf, "__%s%s", const_prefix, volatile_prefix); + newname = NULL; + len = 0; + } else { sprintf (buf, "__%s%s%d", const_prefix, volatile_prefix, len); @@ -343,51 +348,6 @@ gdb_mangle_name (type, i, j) if (newname != NULL) strcat (mangled_name, newname); -#else - - if (is_constructor) - { - buf[0] = '\0'; - } - else - { - sprintf (buf, "__%s%s", const_prefix, volatile_prefix); - } - - mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) - + strlen (buf) + strlen (physname) + 1); - - /* Only needed for GNU-mangled names. ANSI-mangled names - work with the normal mechanisms. */ - if (OPNAME_PREFIX_P (field_name)) - { - char *opname; - opname = cplus_mangle_opname (field_name + 3, 0); - if (opname == NULL) - { - error ("No mangling for \"%s\"", field_name); - } - mangled_name_len += strlen (opname); - mangled_name = (char *) xmalloc (mangled_name_len); - - strncpy (mangled_name, field_name, 3); - strcpy (mangled_name + 3, opname); - } - else - { - mangled_name = (char *) xmalloc (mangled_name_len); - if (is_constructor) - { - mangled_name[0] = '\0'; - } - else - { - strcpy (mangled_name, field_name); - } - } - strcat (mangled_name, buf); - -#endif strcat (mangled_name, physname); return (mangled_name); } @@ -405,7 +365,36 @@ find_pc_psymtab (pc) ALL_PSYMTABS (objfile, pst) { if (pc >= pst->textlow && pc < pst->texthigh) - return (pst); + { + struct minimal_symbol *msymbol; + struct partial_symtab *tpst; + + /* An objfile that has its functions reordered might have + many partial symbol tables containing the PC, but + we want the partial symbol table that contains the + function containing the PC. */ + if (!(objfile->flags & OBJF_REORDERED)) + return (pst); + + msymbol = lookup_minimal_symbol_by_pc (pc); + if (msymbol == NULL) + return (pst); + + for (tpst = pst; tpst != NULL; tpst = tpst->next) + { + if (pc >= tpst->textlow && pc < tpst->texthigh) + { + struct partial_symbol *p; + + p = find_pc_psymbol (tpst, pc); + if (p != NULL + && SYMBOL_VALUE_ADDRESS(p) + == SYMBOL_VALUE_ADDRESS (msymbol)) + return (tpst); + } + } + return (pst); + } } return (NULL); } @@ -590,9 +579,9 @@ found: } } - /* Check for the possibility of the symbol being a global function - that is stored in one of the minimal symbol tables. Eventually, all - global symbols might be resolved in this way. */ + /* Check for the possibility of the symbol being a function or + a mangled variable that is stored in one of the minimal symbol tables. + Eventually, all global symbols might be resolved in this way. */ if (namespace == VAR_NAMESPACE) { @@ -600,10 +589,9 @@ found: if (msymbol != NULL) { s = find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)); - /* If S is NULL, there are no debug symbols for this file. - Skip this stuff and check for matching static symbols below. */ if (s != NULL) { + /* This is a function which has a symtab for its address. */ bv = BLOCKVECTOR (s); block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); sym = lookup_block_symbol (block, SYMBOL_NAME (msymbol), @@ -633,6 +621,18 @@ found: *symtab = s; return sym; } + else if (MSYMBOL_TYPE (msymbol) != mst_text + && MSYMBOL_TYPE (msymbol) != mst_file_text + && !STREQ (name, SYMBOL_NAME (msymbol))) + { + /* This is a mangled variable, look it up by its + mangled name. */ + return lookup_symbol (SYMBOL_NAME (msymbol), block, + namespace, is_a_field_of_this, symtab); + } + /* There are no debug symbols for this file, or we are looking + for an unmangled variable. + Try to find a matching static symbol below. */ } } @@ -765,7 +765,8 @@ lookup_partial_symbol (pst, name, global, namespace) while (top > bottom) { center = bottom + (top - bottom) / 2; - assert (center < top); + if (!(center < top)) + abort (); if (!do_linear_search && SYMBOL_LANGUAGE (center) == language_cplus) { do_linear_search = 1; @@ -779,7 +780,8 @@ lookup_partial_symbol (pst, name, global, namespace) bottom = center + 1; } } - assert (top == bottom); + if (!(top == bottom)) + abort (); while (STREQ (SYMBOL_NAME (top), name)) { if (SYMBOL_NAMESPACE (top) == namespace) @@ -1003,8 +1005,15 @@ find_pc_symtab (pc) to deal with a case like symtab a is at 0x1000-0x2000 and 0x3000-0x4000 and symtab b is at 0x2000-0x3000. So the GLOBAL_BLOCK for a is from 0x1000-0x4000, but for address 0x2345 we want to return symtab b. - This is said to happen for the mips; it might be swifter to create - several symtabs with the same name like xcoff does (I'm not sure). */ + + This happens for native ecoff format, where code from included files + gets its own symtab. The symtab for the included file should have + been read in already via the dependency mechanism. + It might be swifter to create several symtabs with the same name + like xcoff does (I'm not sure). + + It also happens for objfiles that have their functions reordered. + For these, the symtab we are looking for is not necessarily read in. */ ALL_SYMTABS (objfile, s) { @@ -1015,6 +1024,18 @@ find_pc_symtab (pc) && (distance == 0 || BLOCK_END (b) - BLOCK_START (b) < distance)) { + /* For an objfile that has its functions reordered, + find_pc_psymtab will find the proper partial symbol table + and we simply return its corresponding symtab. */ + if (objfile->flags & OBJF_REORDERED) + { + ps = find_pc_psymtab (pc); + if (ps) + s = PSYMTAB_TO_SYMTAB (ps); + else + s = NULL; + return (s); + } distance = BLOCK_END (b) - BLOCK_START (b); best_s = s; } @@ -1500,6 +1521,51 @@ find_pc_line_pc_range (pc, startptr, endptr) *endptr = sal.end; return sal.symtab != 0; } + +/* Given a function symbol SYM, find the symtab and line for the start + of the function. + If the argument FUNFIRSTLINE is nonzero, we want the first line + of real code inside the function. */ + +static struct symtab_and_line +find_function_start_sal PARAMS ((struct symbol *sym, int)); + +static struct symtab_and_line +find_function_start_sal (sym, funfirstline) + struct symbol *sym; + int funfirstline; +{ + CORE_ADDR pc; + struct symtab_and_line sal; + + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + if (funfirstline) + { + pc += FUNCTION_START_OFFSET; + SKIP_PROLOGUE (pc); + } + sal = find_pc_line (pc, 0); + +#ifdef PROLOGUE_FIRSTLINE_OVERLAP + /* Convex: no need to suppress code on first line, if any */ + sal.pc = pc; +#else + /* Check if SKIP_PROLOGUE left us in mid-line, and the next + line is still part of the same function. */ + if (sal.pc != pc + && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= sal.end + && sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + { + /* First pc of next line */ + pc = sal.end; + /* Recalculate the line number (might not be N+1). */ + sal = find_pc_line (pc, 0); + } + sal.pc = pc; +#endif + + return sal; +} /* If P is of the form "operator[ \t]+..." where `...' is some legitimate operator text, return a pointer to the @@ -1752,7 +1818,8 @@ build_canonical_line_spec (sal, symname, canonical) FUNCTION may be an undebuggable function found in minimal symbol table. If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside a function when a function is specified. + of real code inside a function when a function is specified, and it is + not OK to specify a variable or type to get its line number. DEFAULT_SYMTAB specifies the file to use if none is specified. It defaults to current_source_symtab. @@ -1846,17 +1913,13 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (**argptr == '*') { - if (**argptr == '*') - { - (*argptr)++; - } + (*argptr)++; pc = parse_and_eval_address_1 (argptr); values.sals = (struct symtab_and_line *) xmalloc (sizeof (struct symtab_and_line)); values.nelts = 1; values.sals[0] = find_pc_line (pc, 0); values.sals[0].pc = pc; - build_canonical_line_spec (values.sals, NULL, canonical); return values; } @@ -1871,7 +1934,7 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) { if (p[0] == '<') { - while(!++p && *p != '>'); + while(++p && *p != '>'); if (!p) { error ("non-matching '<' and '>' in command"); @@ -1988,17 +2051,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) { - /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); values.nelts = 1; - values.sals[0] = find_pc_line (pc, 0); - values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc; + values.sals[0] = find_function_start_sal (sym, + funfirstline); } else { @@ -2185,32 +2241,8 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) if (SYMBOL_CLASS (sym) == LOC_BLOCK) { /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } - val = find_pc_line (pc, 0); -#ifdef PROLOGUE_FIRSTLINE_OVERLAP - /* Convex: no need to suppress code on first line, if any */ - val.pc = pc; -#else - /* Check if SKIP_PROLOGUE left us in mid-line, and the next - line is still part of the same function. */ - if (val.pc != pc - && BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= val.end - && val.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) - { - /* First pc of next line */ - pc = val.end; - /* Recalculate the line number (might not be N+1). */ - val = find_pc_line (pc, 0); - } - val.pc = pc; -#endif values.sals = (struct symtab_and_line *)xmalloc (sizeof (struct symtab_and_line)); - values.sals[0] = val; + values.sals[0] = find_function_start_sal (sym, funfirstline); values.nelts = 1; /* Don't use the SYMBOL_LINE; if used at all it points to @@ -2228,23 +2260,29 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line, canonical) } return values; } - else if (SYMBOL_LINE (sym) != 0) + else { - /* We know its line number. */ - values.sals = (struct symtab_and_line *) - xmalloc (sizeof (struct symtab_and_line)); - values.nelts = 1; - memset (&values.sals[0], 0, sizeof (values.sals[0])); - values.sals[0].symtab = sym_symtab; - values.sals[0].line = SYMBOL_LINE (sym); - return values; + if (funfirstline) + error ("\"%s\" is not a function", copy); + else if (SYMBOL_LINE (sym) != 0) + { + /* We know its line number. */ + values.sals = (struct symtab_and_line *) + xmalloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + memset (&values.sals[0], 0, sizeof (values.sals[0])); + values.sals[0].symtab = sym_symtab; + values.sals[0].line = SYMBOL_LINE (sym); + return values; + } + else + /* This can happen if it is compiled with a compiler which doesn't + put out line numbers for variables. */ + /* FIXME: Shouldn't we just set .line and .symtab to zero + and return? For example, "info line foo" could print + the address. */ + error ("Line number not known for symbol \"%s\"", copy); } - else - /* This can happen if it is compiled with a compiler which doesn't - put out line numbers for variables. */ - /* FIXME: Shouldn't we just set .line and .symtab to zero and - return? For example, "info line foo" could print the address. */ - error ("Line number not known for symbol \"%s\"", copy); } msymbol = lookup_minimal_symbol (copy, (struct objfile *) NULL); @@ -2301,7 +2339,6 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical) char ***canonical; { struct symtabs_and_lines values, return_values; - register CORE_ADDR pc; char *args, *arg1; int i; char *prompt; @@ -2327,20 +2364,15 @@ decode_line_2 (sym_arr, nelts, funfirstline, canonical) { if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) { - /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i])); - if (funfirstline) - { - pc += FUNCTION_START_OFFSET; - SKIP_PROLOGUE (pc); - } - values.sals[i] = find_pc_line (pc, 0); - values.sals[i].pc = (values.sals[i].end && values.sals[i].pc != pc) ? - values.sals[i].end : pc; - printf_unfiltered("[%d] %s at %s:%d\n", (i+2), SYMBOL_SOURCE_NAME (sym_arr[i]), - values.sals[i].symtab->filename, values.sals[i].line); + values.sals[i] = find_function_start_sal (sym_arr[i], funfirstline); + printf_unfiltered ("[%d] %s at %s:%d\n", + (i+2), + SYMBOL_SOURCE_NAME (sym_arr[i]), + values.sals[i].symtab->filename, + values.sals[i].line); } - else printf_unfiltered ("?HERE\n"); + else + printf_unfiltered ("?HERE\n"); i++; } @@ -2652,13 +2684,20 @@ list_symbols (regexp, class, bpt, from_tty) } } - /* Here, we search through the minimal symbol tables for functions that - match, and call find_pc_symtab on them to force their symbols to - be read. The symbol will then be found during the scan of symtabs - below. If find_pc_symtab fails, set found_misc so that we will - rescan to print any matching symbols without debug info. */ + /* Here, we search through the minimal symbol tables for functions + and variables that match, and force their symbols to be read. + This is in particular necessary for demangled variable names, + which are no longer put into the partial symbol tables. + The symbol will then be found during the scan of symtabs below. + + For functions, find_pc_symtab should succeed if we have debug info + for the function, for variables we have to call lookup_symbol + to determine if the variable has debug info. + If the lookup fails, set found_misc so that we will rescan to print + any matching symbols without debug info. + */ - if (class == 1) + if (class == 0 || class == 1) { ALL_MSYMBOLS (objfile, msymbol) { @@ -2671,7 +2710,12 @@ list_symbols (regexp, class, bpt, from_tty) { if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol))) { - found_misc = 1; + if (class == 1 + || lookup_symbol (SYMBOL_NAME (msymbol), + (struct block *) NULL, + VAR_NAMESPACE, + 0, (struct symtab **) NULL) == NULL) + found_misc = 1; } } } @@ -2724,14 +2768,18 @@ list_symbols (regexp, class, bpt, from_tty) same name but in different files. In order to set breakpoints on all of them, we must give both the file name and the function name to - break_command. */ + break_command. + Quoting the symbol name gets rid of problems + with mangled symbol names that contain + CPLUS_MARKER characters. */ char *string = (char *) alloca (strlen (s->filename) + strlen (SYMBOL_NAME(sym)) - + 2); + + 4); strcpy (string, s->filename); - strcat (string, ":"); + strcat (string, ":'"); strcat (string, SYMBOL_NAME(sym)); + strcat (string, "'"); break_command (string, from_tty); } } diff --git a/gdb/xcoffexec.c b/gdb/xcoffexec.c index 775ccf8f0d7..35c8902fd7b 100644 --- a/gdb/xcoffexec.c +++ b/gdb/xcoffexec.c @@ -111,6 +111,16 @@ exec_close (quitting) if (exec_ops.to_sections) { + /* Reflect to_sections freeing in current_target if it is + the exec target. Otherwise target_xfer_memory (eventually + called from clear_symtab_users) might access the freed + exec_ops.to_sections via the copy in current_target. */ + if (current_target.to_sections == exec_ops.to_sections) + { + current_target.to_sections = NULL; + current_target.to_sections_end = NULL; + } + free (exec_ops.to_sections); exec_ops.to_sections = NULL; exec_ops.to_sections_end = NULL; -- 2.30.2