X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fsymtab.c;h=bdf34d6d3ade8a2a22d83247abdbf1d54c9eb06e;hb=f74656046a5263f1849d9288488d7de73627e1e1;hp=ecf0cb6620e346776ab1ff6b9afb4c8f227864fd;hpb=a6c727b2f1c9804ca95ebc61de518246d03abb37;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/symtab.c b/gdb/symtab.c index ecf0cb6620..bdf34d6d3a 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -2,7 +2,7 @@ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2007, 2008, 2009, - 2010 Free Software Foundation, Inc. + 2010, 2011 Free Software Foundation, Inc. This file is part of GDB. @@ -39,6 +39,7 @@ #include "source.h" #include "filenames.h" /* for FILENAME_CMP */ #include "objc-lang.h" +#include "d-lang.h" #include "ada-lang.h" #include "p-lang.h" #include "addrmap.h" @@ -190,6 +191,7 @@ got_symtab: if (full_path != NULL) { const char *fp = symtab_to_fullname (s); + if (fp != NULL && FILENAME_CMP (full_path, fp) == 0) { return s; @@ -199,9 +201,11 @@ got_symtab: if (real_path != NULL) { char *fullname = symtab_to_fullname (s); + if (fullname != NULL) { char *rp = gdb_realpath (fullname); + make_cleanup (xfree, rp); if (FILENAME_CMP (real_path, rp) == 0) { @@ -287,8 +291,8 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) is_full_physname_constructor = is_constructor_name (physname); - is_constructor = - is_full_physname_constructor || (newname && strcmp (field_name, newname) == 0); + is_constructor = is_full_physname_constructor + || (newname && strcmp (field_name, newname) == 0); if (!is_destructor) is_destructor = (strncmp (physname, "__dt", 4) == 0); @@ -319,13 +323,12 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) mangled_name_len = ((is_constructor ? 0 : strlen (field_name)) + strlen (buf) + len + strlen (physname) + 1); - { - mangled_name = (char *) xmalloc (mangled_name_len); - if (is_constructor) - mangled_name[0] = '\0'; - else - strcpy (mangled_name, field_name); - } + mangled_name = (char *) xmalloc (mangled_name_len); + if (is_constructor) + mangled_name[0] = '\0'; + else + strcpy (mangled_name, field_name); + strcat (mangled_name, buf); /* If the class doesn't have a name, i.e. newname NULL, then we just mangle it using 0 for the length of the class. Thus it gets mangled @@ -337,20 +340,74 @@ gdb_mangle_name (struct type *type, int method_id, int signature_id) return (mangled_name); } +/* Initialize the cplus_specific structure. 'cplus_specific' should + only be allocated for use with cplus symbols. */ + +static void +symbol_init_cplus_specific (struct general_symbol_info *gsymbol, + struct objfile *objfile) +{ + /* A language_specific structure should not have been previously + initialized. */ + gdb_assert (gsymbol->language_specific.cplus_specific == NULL); + gdb_assert (objfile != NULL); + + gsymbol->language_specific.cplus_specific = + OBSTACK_ZALLOC (&objfile->objfile_obstack, struct cplus_specific); +} + +/* Set the demangled name of GSYMBOL to NAME. NAME must be already + correctly allocated. For C++ symbols a cplus_specific struct is + allocated so OBJFILE must not be NULL. If this is a non C++ symbol + OBJFILE can be NULL. */ +void +symbol_set_demangled_name (struct general_symbol_info *gsymbol, + char *name, + struct objfile *objfile) +{ + if (gsymbol->language == language_cplus) + { + if (gsymbol->language_specific.cplus_specific == NULL) + symbol_init_cplus_specific (gsymbol, objfile); + + gsymbol->language_specific.cplus_specific->demangled_name = name; + } + else + gsymbol->language_specific.mangled_lang.demangled_name = name; +} + +/* Return the demangled name of GSYMBOL. */ +char * +symbol_get_demangled_name (const struct general_symbol_info *gsymbol) +{ + if (gsymbol->language == language_cplus) + { + if (gsymbol->language_specific.cplus_specific != NULL) + return gsymbol->language_specific.cplus_specific->demangled_name; + else + return NULL; + } + else + return gsymbol->language_specific.mangled_lang.demangled_name; +} + /* Initialize the language dependent portion of a symbol depending upon the language for the symbol. */ void -symbol_init_language_specific (struct general_symbol_info *gsymbol, - enum language language) +symbol_set_language (struct general_symbol_info *gsymbol, + enum language language) { gsymbol->language = language; - if (gsymbol->language == language_cplus + if (gsymbol->language == language_d || gsymbol->language == language_java - || gsymbol->language == language_objc) + || gsymbol->language == language_objc + || gsymbol->language == language_fortran) { - gsymbol->language_specific.cplus_specific.demangled_name = NULL; + symbol_set_demangled_name (gsymbol, NULL, NULL); } + else if (gsymbol->language == language_cplus) + gsymbol->language_specific.cplus_specific = NULL; else { memset (&gsymbol->language_specific, 0, @@ -372,6 +429,7 @@ static hashval_t hash_demangled_name_entry (const void *data) { const struct demangled_name_entry *e = data; + return htab_hash_string (e->mangled); } @@ -381,6 +439,7 @@ eq_demangled_name_entry (const void *a, const void *b) { const struct demangled_name_entry *da = a; const struct demangled_name_entry *db = b; + return strcmp (da->mangled, db->mangled) == 0; } @@ -449,6 +508,21 @@ symbol_find_demangled_name (struct general_symbol_info *gsymbol, return demangled; } } + if (gsymbol->language == language_d + || gsymbol->language == language_auto) + { + demangled = d_demangle(mangled, 0); + if (demangled != NULL) + { + gsymbol->language = language_d; + return demangled; + } + } + /* We could support `gsymbol->language == language_fortran' here to provide + module namespaces also for inferiors with only minimal symbol table (ELF + symbols). Just the mangling standard is not standardized across compilers + and there is no DW_AT_producer available for inferiors with only the ELF + symbols to check the mangling kind. */ return NULL; } @@ -515,7 +589,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, memcpy (gsymbol->name, linkage_name, len); gsymbol->name[len] = '\0'; } - gsymbol->language_specific.cplus_specific.demangled_name = NULL; + symbol_set_demangled_name (gsymbol, NULL, NULL); return; } @@ -529,8 +603,8 @@ symbol_set_names (struct general_symbol_info *gsymbol, if (gsymbol->language == language_java) { char *alloc_name; - lookup_len = len + JAVA_PREFIX_LEN; + lookup_len = len + JAVA_PREFIX_LEN; alloc_name = alloca (lookup_len + 1); memcpy (alloc_name, JAVA_PREFIX, JAVA_PREFIX_LEN); memcpy (alloc_name + JAVA_PREFIX_LEN, linkage_name, len); @@ -542,8 +616,8 @@ symbol_set_names (struct general_symbol_info *gsymbol, else if (linkage_name[len] != '\0') { char *alloc_name; - lookup_len = len; + lookup_len = len; alloc_name = alloca (lookup_len + 1); memcpy (alloc_name, linkage_name, len); alloc_name[lookup_len] = '\0'; @@ -578,7 +652,7 @@ symbol_set_names (struct general_symbol_info *gsymbol, It turns out that it is actually important to still save such an entry in the hash table, because storing this name gives - us better backache hit rates for partial symbols. */ + us better bcache hit rates for partial symbols. */ if (!copy_name && lookup_name == linkage_name) { *slot = obstack_alloc (&objfile->objfile_obstack, @@ -611,10 +685,9 @@ symbol_set_names (struct general_symbol_info *gsymbol, gsymbol->name = (*slot)->mangled + lookup_len - len; if ((*slot)->demangled[0] != '\0') - gsymbol->language_specific.cplus_specific.demangled_name - = (*slot)->demangled; + symbol_set_demangled_name (gsymbol, (*slot)->demangled, objfile); else - gsymbol->language_specific.cplus_specific.demangled_name = NULL; + symbol_set_demangled_name (gsymbol, NULL, objfile); } /* Return the source code name of a symbol. In languages where @@ -626,14 +699,16 @@ symbol_natural_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: - if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) - return gsymbol->language_specific.cplus_specific.demangled_name; + case language_fortran: + if (symbol_get_demangled_name (gsymbol) != NULL) + return symbol_get_demangled_name (gsymbol); break; case language_ada: - if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) - return gsymbol->language_specific.cplus_specific.demangled_name; + if (symbol_get_demangled_name (gsymbol) != NULL) + return symbol_get_demangled_name (gsymbol); else return ada_decode_symbol (gsymbol); break; @@ -651,14 +726,16 @@ symbol_demangled_name (const struct general_symbol_info *gsymbol) switch (gsymbol->language) { case language_cplus: + case language_d: case language_java: case language_objc: - if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) - return gsymbol->language_specific.cplus_specific.demangled_name; + case language_fortran: + if (symbol_get_demangled_name (gsymbol) != NULL) + return symbol_get_demangled_name (gsymbol); break; case language_ada: - if (gsymbol->language_specific.cplus_specific.demangled_name != NULL) - return gsymbol->language_specific.cplus_specific.demangled_name; + if (symbol_get_demangled_name (gsymbol) != NULL) + return symbol_get_demangled_name (gsymbol); else return ada_decode_symbol (gsymbol); break; @@ -782,6 +859,7 @@ find_pc_sect_symtab_via_partial (CORE_ADDR pc, struct obj_section *section) ALL_OBJFILES (objfile) { struct symtab *result = NULL; + if (objfile->sf) result = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol, pc, section, 0); @@ -851,6 +929,7 @@ fixup_section (struct general_symbol_info *ginfo, a search of the section table. */ struct obj_section *s; + ALL_OBJFILE_OSECTIONS (objfile, s) { int idx = s->the_bfd_section->index; @@ -940,8 +1019,8 @@ lookup_symbol_in_language (const char *name, const struct block *block, modified_name = name; - /* If we are using C++ or Java, demangle the name before doing a lookup, so - we can always binary search. */ + /* If we are using C++, D, or Java, demangle the name before doing a + lookup, so we can always binary search. */ if (lang == language_cplus) { demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); @@ -972,6 +1051,15 @@ lookup_symbol_in_language (const char *name, const struct block *block, make_cleanup (xfree, demangled_name); } } + else if (lang == language_d) + { + demangled_name = d_demangle (name, 0); + if (demangled_name) + { + modified_name = demangled_name; + make_cleanup (xfree, demangled_name); + } + } if (case_sensitivity == case_sensitive_off) { @@ -1017,7 +1105,6 @@ lookup_symbol_aux (const char *name, const struct block *block, { struct symbol *sym; const struct language_defn *langdef; - struct objfile *objfile; /* Make sure we do something sensible with is_a_field_of_this, since the callers that set this parameter to some non-null value will @@ -1044,6 +1131,7 @@ lookup_symbol_aux (const char *name, const struct block *block, { struct symbol *sym = NULL; const struct block *function_block = block; + /* 'this' is only defined in the function's block, so find the enclosing function block. */ for (; function_block && !BLOCK_FUNCTION (function_block); @@ -1084,10 +1172,21 @@ lookup_symbol_aux (const char *name, const struct block *block, return sym; /* Now search all static file-level symbols. Not strictly correct, - but more useful than an error. Do the symtabs first, then check - the psymtabs. If a psymtab indicates the existence of the - desired name as a file-level static, then do psymtab-to-symtab - conversion on the fly and return the found symbol. */ + but more useful than an error. */ + + return lookup_static_symbol_aux (name, domain); +} + +/* Search all static file-level symbols for NAME from DOMAIN. Do the symtabs + first, then check the psymtabs. If a psymtab indicates the existence of the + desired name as a file-level static, then do psymtab-to-symtab conversion on + the fly and return the found symbol. */ + +struct symbol * +lookup_static_symbol_aux (const char *name, const domain_enum domain) +{ + struct objfile *objfile; + struct symbol *sym; sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain); if (sym != NULL) @@ -1126,14 +1225,10 @@ lookup_symbol_aux_local (const char *name, const struct block *block, if (sym != NULL) return sym; - if (language == language_cplus) + if (language == language_cplus || language == language_fortran) { - sym = cp_lookup_symbol_imports (scope, - name, - block, - domain, - 1, - 1); + sym = cp_lookup_symbol_imports_or_template (scope, name, block, + domain); if (sym != NULL) return sym; } @@ -1150,7 +1245,7 @@ lookup_symbol_aux_local (const char *name, const struct block *block, /* Look up OBJFILE to BLOCK. */ -static struct objfile * +struct objfile * lookup_objfile_from_block (const struct block *block) { struct objfile *obj; @@ -1247,16 +1342,25 @@ lookup_symbol_aux_symtabs (int block_index, const char *name, const struct block *block; struct symtab *s; - ALL_PRIMARY_SYMTABS (objfile, s) + ALL_OBJFILES (objfile) { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, block_index); - sym = lookup_block_symbol (block, name, domain); - if (sym) - { - block_found = block; - return fixup_symbol_section (sym, objfile); - } + if (objfile->sf) + objfile->sf->qf->pre_expand_symtabs_matching (objfile, + block_index, + name, domain); + + ALL_OBJFILE_SYMTABS (objfile, s) + if (s->primary) + { + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, block_index); + sym = lookup_block_symbol (block, name, domain); + if (sym) + { + block_found = block; + return fixup_symbol_section (sym, objfile); + } + } } return NULL; @@ -1272,7 +1376,6 @@ lookup_symbol_aux_quick (struct objfile *objfile, int kind, struct symtab *symtab; struct blockvector *bv; const struct block *block; - struct partial_symtab *ps; struct symbol *sym; if (!objfile->sf) @@ -1302,7 +1405,10 @@ lookup_symbol_aux_quick (struct objfile *objfile, int kind, STATIC_BLOCK : GLOBAL_BLOCK); sym = lookup_block_symbol (block, name, domain); if (!sym) - error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s)."), + error (_("\ +Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n\ +%s may be an inlined function, or may be a template function\n\ +(if a template, try specifying an instantiation: %s)."), kind == GLOBAL_BLOCK ? "global" : "static", name, symtab->filename, name, name); } @@ -1412,6 +1518,7 @@ symbol_matches_domain (enum language symbol_language, A Java class declaration also defines a typedef for the class. Similarly, any Ada type declaration implicitly defines a typedef. */ if (symbol_language == language_cplus + || symbol_language == language_d || symbol_language == language_java || symbol_language == language_ada) { @@ -1467,7 +1574,8 @@ basic_lookup_transparent_type_quick (struct objfile *objfile, int kind, sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); if (!sym) /* FIXME; error is wrong in one case */ - error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ + error (_("\ +Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\ %s may be an inlined function, or may be a template function\n\ (if a template, try specifying an instantiation: %s)."), name, symtab->filename, name, name); @@ -1499,15 +1607,24 @@ basic_lookup_transparent_type (const char *name) of the desired name as a global, then do psymtab-to-symtab conversion on the fly and return the found symbol. */ - ALL_PRIMARY_SYMTABS (objfile, s) + ALL_OBJFILES (objfile) { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); - if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) - { - return SYMBOL_TYPE (sym); - } + if (objfile->sf) + objfile->sf->qf->pre_expand_symtabs_matching (objfile, + GLOBAL_BLOCK, + name, STRUCT_DOMAIN); + + ALL_OBJFILE_SYMTABS (objfile, s) + if (s->primary) + { + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK); + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); + if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + { + return SYMBOL_TYPE (sym); + } + } } ALL_OBJFILES (objfile) @@ -1525,14 +1642,21 @@ basic_lookup_transparent_type (const char *name) conversion on the fly and return the found symbol. */ - ALL_PRIMARY_SYMTABS (objfile, s) + ALL_OBJFILES (objfile) { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); - sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); - if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + if (objfile->sf) + objfile->sf->qf->pre_expand_symtabs_matching (objfile, STATIC_BLOCK, + name, STRUCT_DOMAIN); + + ALL_OBJFILE_SYMTABS (objfile, s) { - return SYMBOL_TYPE (sym); + bv = BLOCKVECTOR (s); + block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK); + sym = lookup_block_symbol (block, name, STRUCT_DOMAIN); + if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym))) + { + return SYMBOL_TYPE (sym); + } } } @@ -1551,14 +1675,16 @@ basic_lookup_transparent_type (const char *name) /* FIXME: What about languages without main() or specially linked executables that have no main() ? */ -char * +const char * find_main_filename (void) { struct objfile *objfile; - char *result, *name = main_name (); + char *name = main_name (); ALL_OBJFILES (objfile) { + const char *result; + if (!objfile->sf) continue; result = objfile->sf->qf->find_symbol_file (objfile, name); @@ -1637,7 +1763,6 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) struct blockvector *bv; struct symtab *s = NULL; struct symtab *best_s = NULL; - struct partial_symtab *ps; struct objfile *objfile; struct program_space *pspace; CORE_ADDR distance = 0; @@ -1693,6 +1818,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) if ((objfile->flags & OBJF_REORDERED) && objfile->sf) { struct symtab *result; + result = objfile->sf->qf->find_pc_sect_symtab (objfile, msymbol, @@ -1726,6 +1852,7 @@ find_pc_sect_symtab (CORE_ADDR pc, struct obj_section *section) ALL_OBJFILES (objfile) { struct symtab *result; + if (!objfile->sf) continue; result = objfile->sf->qf->find_pc_sect_symtab (objfile, @@ -1877,12 +2004,15 @@ find_pc_sect_line (CORE_ADDR pc, struct obj_section *section, int notcurrent) * so of course we can't find the real func/line info, * but the "break" still works, and the warning is annoying. * So I commented out the warning. RT */ - /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ; + /* warning ("In stub for %s; unable to find real function/line info", + SYMBOL_LINKAGE_NAME (msymbol)) */ ; /* fall through */ - else if (SYMBOL_VALUE_ADDRESS (mfunsym) == SYMBOL_VALUE_ADDRESS (msymbol)) + else if (SYMBOL_VALUE_ADDRESS (mfunsym) + == SYMBOL_VALUE_ADDRESS (msymbol)) /* Avoid infinite recursion */ /* See above comment about why warning is commented out */ - /* warning ("In stub for %s; unable to find real function/line info", SYMBOL_LINKAGE_NAME (msymbol)) */ ; + /* warning ("In stub for %s; unable to find real function/line info", + SYMBOL_LINKAGE_NAME (msymbol)) */ ; /* fall through */ else return find_pc_line (SYMBOL_VALUE_ADDRESS (mfunsym), 0); @@ -2025,7 +2155,8 @@ find_pc_line (CORE_ADDR pc, int notcurrent) If not found, return NULL. */ struct symtab * -find_line_symtab (struct symtab *symtab, int line, int *index, int *exact_match) +find_line_symtab (struct symtab *symtab, int line, + int *index, int *exact_match) { int exact = 0; /* Initialized here to avoid a compiler warning. */ @@ -2234,32 +2365,13 @@ int find_pc_line_pc_range (CORE_ADDR pc, CORE_ADDR *startptr, CORE_ADDR *endptr) { struct symtab_and_line sal; + sal = find_pc_line (pc, 0); *startptr = sal.pc; *endptr = sal.end; return sal.symtab != 0; } -/* Given a function start address PC and SECTION, find the first - address after the function prologue. */ -CORE_ADDR -find_function_start_pc (struct gdbarch *gdbarch, - CORE_ADDR pc, struct obj_section *section) -{ - /* If the function is in an unmapped overlay, use its unmapped LMA address, - so that gdbarch_skip_prologue has something unique to work on. */ - if (section_is_overlay (section) && !section_is_mapped (section)) - pc = overlay_unmapped_address (pc, section); - - pc += gdbarch_deprecated_function_start_offset (gdbarch); - pc = gdbarch_skip_prologue (gdbarch, pc); - - /* For overlays, map pc back into its mapped VMA range. */ - pc = overlay_mapped_address (pc, section); - - return pc; -} - /* Given a function start address FUNC_ADDR and SYMTAB, find the first address for that function that has an entry in SYMTAB's line info table. If such an entry cannot be found, return FUNC_ADDR @@ -2269,9 +2381,7 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab) { CORE_ADDR func_start, func_end; struct linetable *l; - int ind, i, len; - int best_lineno = 0; - CORE_ADDR best_pc = func_addr; + int i; /* Give up if this symbol has no lineinfo table. */ l = LINETABLE (symtab); @@ -2309,52 +2419,122 @@ skip_prologue_using_lineinfo (CORE_ADDR func_addr, struct symtab *symtab) struct symtab_and_line find_function_start_sal (struct symbol *sym, int funfirstline) { - struct block *block = SYMBOL_BLOCK_VALUE (sym); - struct objfile *objfile = lookup_objfile_from_block (block); - struct gdbarch *gdbarch = get_objfile_arch (objfile); + struct symtab_and_line sal; + fixup_symbol_section (sym, NULL); + sal = find_pc_sect_line (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)), + SYMBOL_OBJ_SECTION (sym), 0); + + /* We always should have a line for the function start address. + If we don't, something is odd. Create a plain SAL refering + just the PC and hope that skip_prologue_sal (if requested) + can find a line number for after the prologue. */ + if (sal.pc < BLOCK_START (SYMBOL_BLOCK_VALUE (sym))) + { + init_sal (&sal); + sal.pspace = current_program_space; + sal.pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + sal.section = SYMBOL_OBJ_SECTION (sym); + } + + if (funfirstline) + skip_prologue_sal (&sal); + + return sal; +} + +/* Adjust SAL to the first instruction past the function prologue. + If the PC was explicitly specified, the SAL is not changed. + If the line number was explicitly specified, at most the SAL's PC + is updated. If SAL is already past the prologue, then do nothing. */ +void +skip_prologue_sal (struct symtab_and_line *sal) +{ + struct symbol *sym; + struct symtab_and_line start_sal; + struct cleanup *old_chain; CORE_ADDR pc; - struct symtab_and_line sal; + struct obj_section *section; + const char *name; + struct objfile *objfile; + struct gdbarch *gdbarch; struct block *b, *function_block; - struct cleanup *old_chain; + /* Do not change the SAL is PC was specified explicitly. */ + if (sal->explicit_pc) + return; old_chain = save_current_space_and_thread (); - switch_to_program_space_and_thread (objfile->pspace); + switch_to_program_space_and_thread (sal->pspace); - pc = BLOCK_START (block); - fixup_symbol_section (sym, objfile); - if (funfirstline) + sym = find_pc_sect_function (sal->pc, sal->section); + if (sym != NULL) { - /* Skip "first line" of function (which is actually its prologue). */ - pc = find_function_start_pc (gdbarch, pc, SYMBOL_OBJ_SECTION (sym)); + fixup_symbol_section (sym, NULL); + + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + section = SYMBOL_OBJ_SECTION (sym); + name = SYMBOL_LINKAGE_NAME (sym); + objfile = SYMBOL_SYMTAB (sym)->objfile; + } + else + { + struct minimal_symbol *msymbol + = lookup_minimal_symbol_by_pc_section (sal->pc, sal->section); + + if (msymbol == NULL) + { + do_cleanups (old_chain); + return; + } + + pc = SYMBOL_VALUE_ADDRESS (msymbol); + section = SYMBOL_OBJ_SECTION (msymbol); + name = SYMBOL_LINKAGE_NAME (msymbol); + objfile = msymbol_objfile (msymbol); } - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + + gdbarch = get_objfile_arch (objfile); + + /* If the function is in an unmapped overlay, use its unmapped LMA address, + so that gdbarch_skip_prologue has something unique to work on. */ + if (section_is_overlay (section) && !section_is_mapped (section)) + pc = overlay_unmapped_address (pc, section); + + /* Skip "first line" of function (which is actually its prologue). */ + pc += gdbarch_deprecated_function_start_offset (gdbarch); + pc = gdbarch_skip_prologue (gdbarch, pc); + + /* For overlays, map pc back into its mapped VMA range. */ + pc = overlay_mapped_address (pc, section); + + /* Calculate line number. */ + start_sal = find_pc_sect_line (pc, section, 0); /* Check if gdbarch_skip_prologue left us in mid-line, and the next line is still part of the same function. */ - if (sal.pc != pc - && BLOCK_START (block) <= sal.end - && sal.end < BLOCK_END (block)) + if (start_sal.pc != pc + && (sym? (BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) <= start_sal.end + && start_sal.end < BLOCK_END (SYMBOL_BLOCK_VALUE (sym))) + : (lookup_minimal_symbol_by_pc_section (start_sal.end, section) + == lookup_minimal_symbol_by_pc_section (pc, section)))) { /* First pc of next line */ - pc = sal.end; + pc = start_sal.end; /* Recalculate the line number (might not be N+1). */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } /* On targets with executable formats that don't have a concept of constructors (ELF with .init has, PE doesn't), gcc emits a call to `__main' in `main' between the prologue and before user code. */ - if (funfirstline - && gdbarch_skip_main_prologue_p (gdbarch) - && SYMBOL_LINKAGE_NAME (sym) - && strcmp (SYMBOL_LINKAGE_NAME (sym), "main") == 0) + if (gdbarch_skip_main_prologue_p (gdbarch) + && name && strcmp (name, "main") == 0) { pc = gdbarch_skip_main_prologue (gdbarch, pc); /* Recalculate the line number (might not be N+1). */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } /* If we still don't have a valid source line, try to find the first @@ -2365,19 +2545,35 @@ find_function_start_sal (struct symbol *sym, int funfirstline) the case with the DJGPP target using "gcc -gcoff" when the compiler inserted code after the prologue to make sure the stack is aligned. */ - if (funfirstline && sal.symtab == NULL) + if (sym && start_sal.symtab == NULL) { pc = skip_prologue_using_lineinfo (pc, SYMBOL_SYMTAB (sym)); /* Recalculate the line number. */ - sal = find_pc_sect_line (pc, SYMBOL_OBJ_SECTION (sym), 0); + start_sal = find_pc_sect_line (pc, section, 0); } - sal.pc = pc; - sal.pspace = objfile->pspace; + do_cleanups (old_chain); + + /* If we're already past the prologue, leave SAL unchanged. Otherwise + forward SAL to the end of the prologue. */ + if (sal->pc >= pc) + return; + + sal->pc = pc; + sal->section = section; + + /* Unless the explicit_line flag was set, update the SAL line + and symtab to correspond to the modified PC location. */ + if (sal->explicit_line) + return; + + sal->symtab = start_sal.symtab; + sal->line = start_sal.line; + sal->end = start_sal.end; /* Check if we are now inside an inlined function. If we can, use the call site of the function instead. */ - b = block_for_pc_sect (sal.pc, SYMBOL_OBJ_SECTION (sym)); + b = block_for_pc_sect (sal->pc, sal->section); function_block = NULL; while (b != NULL) { @@ -2390,12 +2586,9 @@ find_function_start_sal (struct symbol *sym, int funfirstline) if (function_block != NULL && SYMBOL_LINE (BLOCK_FUNCTION (function_block)) != 0) { - sal.line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); - sal.symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); + sal->line = SYMBOL_LINE (BLOCK_FUNCTION (function_block)); + sal->symtab = SYMBOL_SYMTAB (BLOCK_FUNCTION (function_block)); } - - do_cleanups (old_chain); - return sal; } /* If P is of the form "operator[ \t]+..." where `...' is @@ -2424,6 +2617,7 @@ operator_chars (char *p, char **end) if (isalpha (*p) || *p == '_' || *p == '$') { char *q = p + 1; + while (isalnum (*q) || *q == '_' || *q == '$') q++; *end = q; @@ -2436,7 +2630,7 @@ operator_chars (char *p, char **end) case '\\': /* regexp quoting */ if (p[1] == '*') { - if (p[2] == '=') /* 'operator\*=' */ + if (p[2] == '=') /* 'operator\*=' */ *end = p + 3; else /* 'operator\*' */ *end = p + 2; @@ -2445,7 +2639,8 @@ operator_chars (char *p, char **end) else if (p[1] == '[') { if (p[2] == ']') - error (_("mismatched quoting on brackets, try 'operator\\[\\]'")); + error (_("mismatched quoting on brackets, " + "try 'operator\\[\\]'")); else if (p[2] == '\\' && p[3] == ']') { *end = p + 4; /* 'operator\[\]' */ @@ -2508,17 +2703,20 @@ operator_chars (char *p, char **end) return p; case '(': if (p[1] != ')') - error (_("`operator ()' must be specified without whitespace in `()'")); + error (_("`operator ()' must be specified " + "without whitespace in `()'")); *end = p + 2; return p; case '?': if (p[1] != ':') - error (_("`operator ?:' must be specified without whitespace in `?:'")); + error (_("`operator ?:' must be specified " + "without whitespace in `?:'")); *end = p + 2; return p; case '[': if (p[1] != ']') - error (_("`operator []' must be specified without whitespace in `[]'")); + error (_("`operator []' must be specified " + "without whitespace in `[]'")); *end = p + 2; return p; default: @@ -2622,7 +2820,6 @@ static void sources_info (char *ignore, int from_tty) { struct symtab *s; - struct partial_symtab *ps; struct objfile *objfile; int first; @@ -2637,11 +2834,13 @@ sources_info (char *ignore, int from_tty) ALL_SYMTABS (objfile, s) { const char *fullname = symtab_to_fullname (s); + output_source_filename (fullname ? fullname : s->filename, &first); } printf_filtered ("\n\n"); - printf_filtered ("Source files for which symbols will be read in on demand:\n\n"); + printf_filtered ("Source files for which symbols " + "will be read in on demand:\n\n"); first = 1; map_partial_symbol_filenames (output_partial_symbol_filename, &first); @@ -2753,6 +2952,7 @@ static int search_symbols_file_matches (const char *filename, void *user_data) { struct search_symbols_data *data = user_data; + return file_matches (filename, data->files, data->nfiles); } @@ -2761,6 +2961,7 @@ static int search_symbols_name_matches (const char *symname, void *user_data) { struct search_symbols_data *data = user_data; + return data->regexp == NULL || re_exec (symname); } @@ -2792,18 +2993,14 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], struct minimal_symbol *msymbol; char *val; int found_misc = 0; - static enum minimal_symbol_type types[] - = - {mst_data, mst_text, mst_abs, mst_unknown}; - static enum minimal_symbol_type types2[] - = - {mst_bss, mst_file_text, mst_abs, mst_unknown}; - static enum minimal_symbol_type types3[] - = - {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown}; - static enum minimal_symbol_type types4[] - = - {mst_file_bss, mst_text, mst_abs, mst_unknown}; + static const enum minimal_symbol_type types[] + = {mst_data, mst_text, mst_abs, mst_unknown}; + static const enum minimal_symbol_type types2[] + = {mst_bss, mst_file_text, mst_abs, mst_unknown}; + static const enum minimal_symbol_type types3[] + = {mst_file_data, mst_solib_trampoline, mst_abs, mst_unknown}; + static const enum minimal_symbol_type types4[] + = {mst_file_bss, mst_text, mst_abs, mst_unknown}; enum minimal_symbol_type ourtype; enum minimal_symbol_type ourtype2; enum minimal_symbol_type ourtype3; @@ -2833,9 +3030,12 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], and or . */ char *opend; char *opname = operator_chars (regexp, &opend); + if (*opname) { - int fix = -1; /* -1 means ok; otherwise number of spaces needed. */ + int fix = -1; /* -1 means ok; otherwise number of + spaces needed. */ + if (isalpha (*opname) || *opname == '_' || *opname == '$') { /* There should 1 space between 'operator' and 'TYPENAME'. */ @@ -2852,6 +3052,7 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], if (fix >= 0) { char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1); + sprintf (tmp, "operator%.*s%s", fix, " ", opname); regexp = tmp; } @@ -2932,24 +3133,35 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], { struct symbol_search *prevtail = tail; int nfound = 0; + b = BLOCKVECTOR_BLOCK (bv, i); ALL_BLOCK_SYMBOLS (b, iter, sym) { struct symtab *real_symtab = SYMBOL_SYMTAB (sym); + QUIT; if (file_matches (real_symtab->filename, files, nfiles) && ((regexp == NULL || re_exec (SYMBOL_NATURAL_NAME (sym)) != 0) - && ((kind == VARIABLES_DOMAIN && SYMBOL_CLASS (sym) != LOC_TYPEDEF + && ((kind == VARIABLES_DOMAIN + && SYMBOL_CLASS (sym) != LOC_TYPEDEF && SYMBOL_CLASS (sym) != LOC_UNRESOLVED && SYMBOL_CLASS (sym) != LOC_BLOCK - && SYMBOL_CLASS (sym) != LOC_CONST) - || (kind == FUNCTIONS_DOMAIN && SYMBOL_CLASS (sym) == LOC_BLOCK) - || (kind == TYPES_DOMAIN && SYMBOL_CLASS (sym) == LOC_TYPEDEF)))) + /* LOC_CONST can be used for more than just enums, + e.g., c++ static const members. + We only want to skip enums here. */ + && !(SYMBOL_CLASS (sym) == LOC_CONST + && TYPE_CODE (SYMBOL_TYPE (sym)) + == TYPE_CODE_ENUM)) + || (kind == FUNCTIONS_DOMAIN + && SYMBOL_CLASS (sym) == LOC_BLOCK) + || (kind == TYPES_DOMAIN + && SYMBOL_CLASS (sym) == LOC_TYPEDEF)))) { /* match */ - psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); + psr = (struct symbol_search *) + xmalloc (sizeof (struct symbol_search)); psr->block = i; psr->symtab = real_symtab; psr->symbol = sym; @@ -3008,7 +3220,8 @@ search_symbols (char *regexp, domain_enum kind, int nfiles, char *files[], == NULL) { /* match */ - psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search)); + psr = (struct symbol_search *) + xmalloc (sizeof (struct symbol_search)); psr->block = i; psr->msymbol = msymbol; psr->symtab = NULL; @@ -3098,9 +3311,8 @@ print_msymbol_info (struct minimal_symbol *msymbol) static void symtab_symbol_info (char *regexp, domain_enum kind, int from_tty) { - static char *classnames[] - = - {"variable", "function", "type", "method"}; + static const char * const classnames[] = + {"variable", "function", "type", "method"}; struct symbol_search *symbols; struct symbol_search *p; struct cleanup *old_chain; @@ -3170,23 +3382,66 @@ rbreak_command_wrapper (char *regexp, int from_tty) rbreak_command (regexp, from_tty); } +/* A cleanup function that calls end_rbreak_breakpoints. */ + +static void +do_end_rbreak_breakpoints (void *ignore) +{ + end_rbreak_breakpoints (); +} + static void rbreak_command (char *regexp, int from_tty) { struct symbol_search *ss; struct symbol_search *p; struct cleanup *old_chain; + char *string = NULL; + int len = 0; + char **files = NULL; + int nfiles = 0; - search_symbols (regexp, FUNCTIONS_DOMAIN, 0, (char **) NULL, &ss); + if (regexp) + { + char *colon = strchr (regexp, ':'); + + if (colon && *(colon + 1) != ':') + { + int colon_index; + char * file_name; + + colon_index = colon - regexp; + file_name = alloca (colon_index + 1); + memcpy (file_name, regexp, colon_index); + file_name[colon_index--] = 0; + while (isspace (file_name[colon_index])) + file_name[colon_index--] = 0; + files = &file_name; + nfiles = 1; + regexp = colon + 1; + while (isspace (*regexp)) regexp++; + } + } + + search_symbols (regexp, FUNCTIONS_DOMAIN, nfiles, files, &ss); old_chain = make_cleanup_free_search_symbols (ss); + make_cleanup (free_current_contents, &string); + start_rbreak_breakpoints (); + make_cleanup (do_end_rbreak_breakpoints, NULL); for (p = ss; p != NULL; p = p->next) { if (p->msymbol == NULL) { - char *string = alloca (strlen (p->symtab->filename) - + strlen (SYMBOL_LINKAGE_NAME (p->symbol)) - + 4); + int newlen = (strlen (p->symtab->filename) + + strlen (SYMBOL_LINKAGE_NAME (p->symbol)) + + 4); + + if (newlen > len) + { + string = xrealloc (string, newlen); + len = newlen; + } strcpy (string, p->symtab->filename); strcat (string, ":'"); strcat (string, SYMBOL_LINKAGE_NAME (p->symbol)); @@ -3200,8 +3455,13 @@ rbreak_command (char *regexp, int from_tty) } else { - char *string = alloca (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) - + 3); + int newlen = (strlen (SYMBOL_LINKAGE_NAME (p->msymbol)) + 3); + + if (newlen > len) + { + string = xrealloc (string, newlen); + len = newlen; + } strcpy (string, "'"); strcat (string, SYMBOL_LINKAGE_NAME (p->msymbol)); strcat (string, "'"); @@ -3235,7 +3495,6 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len, char *text, char *word) { int newsize; - int i; /* clip symbols that cannot match */ @@ -3249,6 +3508,7 @@ completion_list_add_name (char *symname, char *sym_text, int sym_text_len, { char *new; + if (word == sym_text) { new = xmalloc (strlen (symname) + 5); @@ -3420,6 +3680,7 @@ add_macro_name (const char *name, const struct macro_definition *ignore, void *user_data) { struct add_name_data *datum = (struct add_name_data *) user_data; + completion_list_add_name ((char *) name, datum->sym_text, datum->sym_text_len, datum->text, datum->word); @@ -3430,13 +3691,15 @@ static void add_partial_symbol_name (const char *name, void *user_data) { struct add_name_data *datum = (struct add_name_data *) user_data; + completion_list_add_name ((char *) name, datum->sym_text, datum->sym_text_len, datum->text, datum->word); } char ** -default_make_symbol_completion_list (char *text, char *word) +default_make_symbol_completion_list_break_on (char *text, char *word, + const char *break_on) { /* Problem: All of the symbols have to be copied because readline frees them. I'm not going to worry about this; hopefully there @@ -3499,7 +3762,7 @@ default_make_symbol_completion_list (char *text, char *word) while (p > text) { if (isalnum (p[-1]) || p[-1] == '_' || p[-1] == '\0' - || p[-1] == ':') + || p[-1] == ':' || strchr (break_on, p[-1]) != NULL) --p; else break; @@ -3625,6 +3888,12 @@ default_make_symbol_completion_list (char *text, char *word) return (return_val); } +char ** +default_make_symbol_completion_list (char *text, char *word) +{ + return default_make_symbol_completion_list_break_on (text, word, ""); +} + /* Return a NULL terminated array of all symbols (regardless of class) which begin by matching TEXT. If the answer is no symbols, then the return value is an array which contains only a NULL pointer. */ @@ -3821,7 +4090,7 @@ struct add_partial_filename_data /* A callback for map_partial_symbol_filenames. */ static void -maybe_add_partial_symtab_filename (const char *fullname, const char *filename, +maybe_add_partial_symtab_filename (const char *filename, const char *fullname, void *user_data) { struct add_partial_filename_data *data = user_data; @@ -3844,6 +4113,7 @@ maybe_add_partial_symtab_filename (const char *fullname, const char *filename, else { const char *base_name = lbasename (filename); + if (base_name != filename && !filename_seen (base_name, 1, data->first) #if HAVE_DOS_BASED_FILE_SYSTEM @@ -4043,7 +4313,6 @@ skip_prologue_using_sal (struct gdbarch *gdbarch, CORE_ADDR func_addr) if (prologue_sal.symtab->language != language_asm) { struct linetable *linetable = LINETABLE (prologue_sal.symtab); - int exact; int idx = 0; /* Skip any earlier lines, and any end-of-sequence marker @@ -4138,6 +4407,7 @@ decode_line_spec (char *string, int funfirstline) /* Track MAIN */ static char *name_of_main; +enum language language_of_main = language_unknown; void set_main_name (const char *name) @@ -4146,10 +4416,12 @@ set_main_name (const char *name) { xfree (name_of_main); name_of_main = NULL; + language_of_main = language_unknown; } if (name != NULL) { name_of_main = xstrdup (name); + language_of_main = language_unknown; } } @@ -4263,6 +4535,7 @@ append_exact_match_to_sals (char *filename, char *fullname, int lineno, { struct linetable *l; int len; + if (fullname != NULL && symtab_to_fullname (symtab) != NULL && FILENAME_CMP (fullname, symtab->fullname) != 0) @@ -4303,11 +4576,9 @@ append_exact_match_to_sals (char *filename, char *fullname, int lineno, struct symtabs_and_lines expand_line_sal (struct symtab_and_line sal) { - struct symtabs_and_lines ret, this_line; + struct symtabs_and_lines ret; int i, j; struct objfile *objfile; - struct partial_symtab *psymtab; - struct symtab *symtab; int lineno; int deleted = 0; struct block **blocks = NULL; @@ -4387,9 +4658,6 @@ expand_line_sal (struct symtab_and_line sal) blocks = alloca (ret.nelts * sizeof (struct block *)); for (i = 0; i < ret.nelts; ++i) { - struct blockvector *bl; - struct block *b; - set_current_program_space (ret.sals[i].pspace); filter[i] = 1;