From 1994afbf19892c9e614a034fbf1a5233e9addce3 Mon Sep 17 00:00:00 2001 From: Doug Evans Date: Tue, 23 Dec 2014 07:55:39 -0800 Subject: [PATCH] Look up primitive types as symbols. gdb/ChangeLog: * ada-lang.c (user_select_syms): Only fetch symtab if symbol is objfile-owned. (cache_symbol): Ignore symbols that are not objfile-owned. * block.c (block_objfile): New function. (block_gdbarch): New function. * block.h (block_objfile): Declare. (block_gdbarch): Declare. * c-exp.y (classify_name): Remove call to language_lookup_primitive_type. No longer necessary. * gdbtypes.c (lookup_typename): Call lookup_symbol_in_language. Remove call to language_lookup_primitive_type. No longer necessary. * guile/scm-symbol.c (syscm_gdbarch_data_key): New static global. (syscm_gdbarch_data): New struct. (syscm_init_arch_symbols): New function. (syscm_get_symbol_map): Renamed from syscm_objfile_symbol_map. All callers updated. Handle symbols owned by arches. (gdbscm_symbol_symtab): Handle symbols owned by arches. (gdbscm_initialize_symbols): Initialize syscm_gdbarch_data_key. * language.c (language_lookup_primitive_type_1): New function. (language_lookup_primitive_type): Call it. (language_alloc_type_symbol): New function. (language_init_primitive_type_symbols): New function. (language_lookup_primitive_type_as_symbol): New function. * language.h (struct language_arch_info) : New member. (language_lookup_primitive_type): Add function comment. (language_lookup_primitive_type_as_symbol): Declare. * printcmd.c (address_info): Handle arch-owned symbols. * python/py-symbol.c (sympy_get_symtab): Ditto. (set_symbol): Ditto. (sympy_dealloc): Ditto. * symmisc.c (print_symbol): Ditto. * symtab.c (fixup_symbol_section): Ditto. (lookup_symbol_aux): Initialize block_found. (basic_lookup_symbol_nonlocal): Try looking up the symbol as a primitive type. (initialize_objfile_symbol_1): New function. (initialize_objfile_symbol): Call it. (allocate_symbol): Call it. (allocate_template_symbol): Call it. (symbol_objfile): Assert symbol is objfile-owned. (symbol_arch, symbol_symtab, symbol_set_symtab): Ditto. * symtab.h (struct symbol) : Replaces member "symtab". (struct symbol) : New member. (SYMBOL_OBJFILE_OWNED): New macro. * cp-namespace.c (cp_lookup_bare_symbol): New arg langdef. All callers updated. Try to find the symbol as a primitive type. (lookup_namespace_scope): New arg langdef. All callers updated. Call cp_lookup_bare_symbol directly for simple bare symbols. --- gdb/ChangeLog | 52 +++++++++++++++++ gdb/ada-lang.c | 10 +++- gdb/block.c | 26 +++++++++ gdb/block.h | 8 +++ gdb/c-exp.y | 7 --- gdb/cp-namespace.c | 51 +++++++++++++--- gdb/gdbtypes.c | 7 +-- gdb/guile/scm-symbol.c | 60 +++++++++++++++---- gdb/language.c | 130 ++++++++++++++++++++++++++++++++++++----- gdb/language.h | 16 +++++ gdb/printcmd.c | 5 +- gdb/python/py-symbol.c | 7 ++- gdb/symmisc.c | 8 ++- gdb/symtab.c | 60 ++++++++++++++++--- gdb/symtab.h | 27 +++++++-- 15 files changed, 411 insertions(+), 63 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index acf692fdca..dc1cb15f1a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,55 @@ +2014-12-23 Doug Evans + + * ada-lang.c (user_select_syms): Only fetch symtab if symbol is + objfile-owned. + (cache_symbol): Ignore symbols that are not objfile-owned. + * block.c (block_objfile): New function. + (block_gdbarch): New function. + * block.h (block_objfile): Declare. + (block_gdbarch): Declare. + * c-exp.y (classify_name): Remove call to + language_lookup_primitive_type. No longer necessary. + * gdbtypes.c (lookup_typename): Call lookup_symbol_in_language. + Remove call to language_lookup_primitive_type. No longer necessary. + * guile/scm-symbol.c (syscm_gdbarch_data_key): New static global. + (syscm_gdbarch_data): New struct. + (syscm_init_arch_symbols): New function. + (syscm_get_symbol_map): Renamed from syscm_objfile_symbol_map. + All callers updated. Handle symbols owned by arches. + (gdbscm_symbol_symtab): Handle symbols owned by arches. + (gdbscm_initialize_symbols): Initialize syscm_gdbarch_data_key. + * language.c (language_lookup_primitive_type_1): New function. + (language_lookup_primitive_type): Call it. + (language_alloc_type_symbol): New function. + (language_init_primitive_type_symbols): New function. + (language_lookup_primitive_type_as_symbol): New function. + * language.h (struct language_arch_info) : + New member. + (language_lookup_primitive_type): Add function comment. + (language_lookup_primitive_type_as_symbol): Declare. + * printcmd.c (address_info): Handle arch-owned symbols. + * python/py-symbol.c (sympy_get_symtab): Ditto. + (set_symbol): Ditto. + (sympy_dealloc): Ditto. + * symmisc.c (print_symbol): Ditto. + * symtab.c (fixup_symbol_section): Ditto. + (lookup_symbol_aux): Initialize block_found. + (basic_lookup_symbol_nonlocal): Try looking up the symbol as a + primitive type. + (initialize_objfile_symbol_1): New function. + (initialize_objfile_symbol): Call it. + (allocate_symbol): Call it. + (allocate_template_symbol): Call it. + (symbol_objfile): Assert symbol is objfile-owned. + (symbol_arch, symbol_symtab, symbol_set_symtab): Ditto. + * symtab.h (struct symbol) : Replaces member "symtab". + (struct symbol) : New member. + (SYMBOL_OBJFILE_OWNED): New macro. + * cp-namespace.c (cp_lookup_bare_symbol): New arg langdef. + All callers updated. Try to find the symbol as a primitive type. + (lookup_namespace_scope): New arg langdef. All callers updated. + Call cp_lookup_bare_symbol directly for simple bare symbols. + 2014-12-23 Doug Evans * symtab.h (SYMBOL_DOMAIN_BITS): New macro. diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c index 5d4ea2f5c0..5d5d613190 100644 --- a/gdb/ada-lang.c +++ b/gdb/ada-lang.c @@ -3716,7 +3716,10 @@ See set/show multiple-symbol.")); (SYMBOL_CLASS (syms[i].sym) == LOC_CONST && SYMBOL_TYPE (syms[i].sym) != NULL && TYPE_CODE (SYMBOL_TYPE (syms[i].sym)) == TYPE_CODE_ENUM); - struct symtab *symtab = symbol_symtab (syms[i].sym); + struct symtab *symtab = NULL; + + if (SYMBOL_OBJFILE_OWNED (syms[i].sym)) + symtab = symbol_symtab (syms[i].sym); if (SYMBOL_LINE (syms[i].sym) != 0 && symtab != NULL) printf_unfiltered (_("[%d] %s at %s:%d\n"), @@ -4466,6 +4469,11 @@ cache_symbol (const char *name, domain_enum namespace, struct symbol *sym, char *copy; struct cache_entry *e; + /* Symbols for builtin types don't have a block. + For now don't cache such symbols. */ + if (sym != NULL && !SYMBOL_OBJFILE_OWNED (sym)) + return; + /* If the symbol is a local symbol, then do not cache it, as a search for that symbol depends on the context. To determine whether the symbol is local or not, we check the block where we found it diff --git a/gdb/block.c b/gdb/block.c index e791c73acc..8d45b6ed97 100644 --- a/gdb/block.c +++ b/gdb/block.c @@ -25,6 +25,7 @@ #include "cp-support.h" #include "addrmap.h" #include "gdbtypes.h" +#include "objfiles.h" /* This is used by struct block to store namespace-related info for C++ files, namely using declarations and the current namespace in @@ -39,6 +40,31 @@ struct block_namespace_info static void block_initialize_namespace (struct block *block, struct obstack *obstack); +/* See block.h. */ + +struct objfile * +block_objfile (const struct block *block) +{ + const struct global_block *global_block; + + if (BLOCK_FUNCTION (block) != NULL) + return symbol_objfile (BLOCK_FUNCTION (block)); + + global_block = (struct global_block *) block_global_block (block); + return COMPUNIT_OBJFILE (global_block->compunit_symtab); +} + +/* See block. */ + +struct gdbarch * +block_gdbarch (const struct block *block) +{ + if (BLOCK_FUNCTION (block) != NULL) + return symbol_arch (BLOCK_FUNCTION (block)); + + return get_objfile_arch (block_objfile (block)); +} + /* Return Nonzero if block a is lexically nested within block b, or if a and b have the same pc range. Return zero otherwise. */ diff --git a/gdb/block.h b/gdb/block.h index 409a5c750c..e6c5feb499 100644 --- a/gdb/block.h +++ b/gdb/block.h @@ -136,6 +136,14 @@ struct blockvector #define BLOCKVECTOR_BLOCK(blocklist,n) (blocklist)->block[n] #define BLOCKVECTOR_MAP(blocklist) ((blocklist)->map) +/* Return the objfile of BLOCK, which must be non-NULL. */ + +extern struct objfile *block_objfile (const struct block *block); + +/* Return the architecture of BLOCK, which must be non-NULL. */ + +extern struct gdbarch *block_gdbarch (const struct block *block); + extern struct symbol *block_linkage_function (const struct block *); extern struct symbol *block_containing_function (const struct block *); diff --git a/gdb/c-exp.y b/gdb/c-exp.y index 707e504ebe..91728eeac2 100644 --- a/gdb/c-exp.y +++ b/gdb/c-exp.y @@ -2941,13 +2941,6 @@ classify_name (struct parser_state *par_state, const struct block *block, return TYPENAME; } - yylval.tsym.type - = language_lookup_primitive_type (parse_language (par_state), - parse_gdbarch (par_state), - copy); - if (yylval.tsym.type != NULL) - return TYPENAME; - /* See if it's an ObjC classname. */ if (parse_language (par_state)->la_language == language_objc && !sym) { diff --git a/gdb/cp-namespace.c b/gdb/cp-namespace.c index 6599d45eb0..9e9dce009d 100644 --- a/gdb/cp-namespace.c +++ b/gdb/cp-namespace.c @@ -242,12 +242,18 @@ cp_basic_lookup_symbol (const char *name, const struct block *block, } /* Search bare symbol NAME in DOMAIN in BLOCK. - NAME is guaranteed to not have any scope (no "::"). + NAME is guaranteed to not have any scope (no "::") in its name, though + if for example NAME is a template spec then "::" may appear in the + argument list. + If LANGDEF is non-NULL then try to lookup NAME as a primitive type in + that language. Normally we wouldn't need LANGDEF but fortran also uses + this code. If SEARCH is non-zero then see if we can determine "this" from BLOCK, and if so then also search for NAME in that class. */ static struct symbol * -cp_lookup_bare_symbol (const char *name, const struct block *block, +cp_lookup_bare_symbol (const struct language_defn *langdef, + const char *name, const struct block *block, const domain_enum domain, int search) { struct symbol *sym; @@ -262,6 +268,25 @@ cp_lookup_bare_symbol (const char *name, const struct block *block, if (sym != NULL) return sym; + /* If we didn't find a definition for a builtin type in the static block, + search for it now. This is actually the right thing to do and can be + a massive performance win. E.g., when debugging a program with lots of + shared libraries we could search all of them only to find out the + builtin type isn't defined in any of them. This is common for types + like "void". */ + if (langdef != NULL && domain == VAR_DOMAIN) + { + struct gdbarch *gdbarch; + + if (block == NULL) + gdbarch = target_gdbarch (); + else + gdbarch = block_gdbarch (block); + sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name); + if (sym != NULL) + return sym; + } + sym = lookup_global_symbol (name, block, domain); if (sym != NULL) return sym; @@ -378,7 +403,7 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name, prefix_len = cp_entire_prefix_len (name); if (prefix_len == 0) - return cp_lookup_bare_symbol (name, block, domain, search); + return cp_lookup_bare_symbol (NULL, name, block, domain, search); /* This would be simpler if we just called cp_lookup_nested_symbol at this point. But that would require first looking up the containing @@ -753,7 +778,8 @@ cp_lookup_symbol_namespace (const char *scope, "x". */ static struct symbol * -lookup_namespace_scope (const char *name, +lookup_namespace_scope (const struct language_defn *langdef, + const char *name, const struct block *block, const domain_enum domain, const char *scope, @@ -775,14 +801,25 @@ lookup_namespace_scope (const char *name, new_scope_len += 2; } new_scope_len += cp_find_first_component (scope + new_scope_len); - sym = lookup_namespace_scope (name, block, domain, + sym = lookup_namespace_scope (langdef, name, block, domain, scope, new_scope_len); if (sym != NULL) return sym; } /* Okay, we didn't find a match in our children, so look for the - name in the current namespace. */ + name in the current namespace. + + If we there is no scope and we know we have a bare symbol, then short + circuit everything and call cp_lookup_bare_symbol directly. + This isn't an optimization, rather it allows us to pass LANGDEF which + is needed for primitive type lookup. The test doesn't have to be + perfect: if NAME is a bare symbol that our test doesn't catch (e.g., a + template symbol with "::" in the argument list) then + cp_lookup_symbol_in_namespace will catch it. */ + + if (scope_len == 0 && strchr (name, ':') == NULL) + return cp_lookup_bare_symbol (langdef, name, block, domain, 1); namespace = alloca (scope_len + 1); strncpy (namespace, scope, scope_len); @@ -817,7 +854,7 @@ cp_lookup_symbol_nonlocal (const struct language_defn *langdef, /* First, try to find the symbol in the given namespace, and all containing namespaces. */ - sym = lookup_namespace_scope (name, block, domain, scope, 0); + sym = lookup_namespace_scope (langdef, name, block, domain, scope, 0); /* Search for name in namespaces imported to this and parent blocks. */ if (sym == NULL) diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 0048f6a1a5..0297243621 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -1306,14 +1306,11 @@ lookup_typename (const struct language_defn *language, struct symbol *sym; struct type *type; - sym = lookup_symbol (name, block, VAR_DOMAIN, 0); + sym = lookup_symbol_in_language (name, block, VAR_DOMAIN, + language->la_language, NULL); if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF) return SYMBOL_TYPE (sym); - type = language_lookup_primitive_type (language, gdbarch, name); - if (type) - return type; - if (noerr) return NULL; error (_("No type named %s."), name); diff --git a/gdb/guile/scm-symbol.c b/gdb/guile/scm-symbol.c index 6a19648567..a627f94d52 100644 --- a/gdb/guile/scm-symbol.c +++ b/gdb/guile/scm-symbol.c @@ -50,6 +50,13 @@ static SCM domain_keyword; static SCM frame_keyword; static const struct objfile_data *syscm_objfile_data_key; +static struct gdbarch_data *syscm_gdbarch_data_key; + +struct syscm_gdbarch_data +{ + /* Hash table to implement eqable gdbarch symbols. */ + htab_t htab; +}; /* Administrivia for symbol smobs. */ @@ -75,20 +82,44 @@ syscm_eq_symbol_smob (const void *ap, const void *bp) && a->symbol != NULL); } +static void * +syscm_init_arch_symbols (struct gdbarch *gdbarch) +{ + struct syscm_gdbarch_data *data + = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct syscm_gdbarch_data); + + data->htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob, + syscm_eq_symbol_smob); + return data; +} + /* Return the struct symbol pointer -> SCM mapping table. It is created if necessary. */ static htab_t -syscm_objfile_symbol_map (struct symbol *symbol) +syscm_get_symbol_map (struct symbol *symbol) { - struct objfile *objfile = symbol_objfile (symbol); - htab_t htab = objfile_data (objfile, syscm_objfile_data_key); + htab_t htab; - if (htab == NULL) + if (SYMBOL_OBJFILE_OWNED (symbol)) { - htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob, - syscm_eq_symbol_smob); - set_objfile_data (objfile, syscm_objfile_data_key, htab); + struct objfile *objfile = symbol_objfile (symbol); + + htab = objfile_data (objfile, syscm_objfile_data_key); + if (htab == NULL) + { + htab = gdbscm_create_eqable_gsmob_ptr_map (syscm_hash_symbol_smob, + syscm_eq_symbol_smob); + set_objfile_data (objfile, syscm_objfile_data_key, htab); + } + } + else + { + struct gdbarch *gdbarch = symbol_arch (symbol); + struct syscm_gdbarch_data *data = gdbarch_data (gdbarch, + syscm_gdbarch_data_key); + + htab = data->htab; } return htab; @@ -103,7 +134,7 @@ syscm_free_symbol_smob (SCM self) if (s_smob->symbol != NULL) { - htab_t htab = syscm_objfile_symbol_map (s_smob->symbol); + htab_t htab = syscm_get_symbol_map (s_smob->symbol); gdbscm_clear_eqable_gsmob_ptr_slot (htab, &s_smob->base); } @@ -181,7 +212,7 @@ syscm_scm_from_symbol (struct symbol *symbol) /* If we've already created a gsmob for this symbol, return it. This makes symbols eq?-able. */ - htab = syscm_objfile_symbol_map (symbol); + htab = syscm_get_symbol_map (symbol); s_smob_for_lookup.symbol = symbol; slot = gdbscm_find_eqable_gsmob_ptr_slot (htab, &s_smob_for_lookup.base); if (*slot != NULL) @@ -319,8 +350,9 @@ gdbscm_symbol_type (SCM self) return tyscm_scm_from_type (SYMBOL_TYPE (symbol)); } -/* (symbol-symtab ) -> - Return the symbol table of SELF. */ +/* (symbol-symtab ) -> | #f + Return the symbol table of SELF. + If SELF does not have a symtab (it is arch-owned) return #f. */ static SCM gdbscm_symbol_symtab (SCM self) @@ -329,6 +361,8 @@ gdbscm_symbol_symtab (SCM self) = syscm_get_valid_symbol_smob_arg_unsafe (self, SCM_ARG1, FUNC_NAME); const struct symbol *symbol = s_smob->symbol; + if (!SYMBOL_OBJFILE_OWNED (symbol)) + return SCM_BOOL_F; return stscm_scm_from_symtab (symbol_symtab (symbol)); } @@ -761,4 +795,8 @@ gdbscm_initialize_symbols (void) invalidate symbols when an object file is about to be deleted. */ syscm_objfile_data_key = register_objfile_data_with_cleanup (NULL, syscm_del_objfile_symbols); + + /* Arch-specific symbol data. */ + syscm_gdbarch_data_key + = gdbarch_data_register_post_init (syscm_init_arch_symbols); } diff --git a/gdb/language.c b/gdb/language.c index df45ddd97c..fa43857ab8 100644 --- a/gdb/language.c +++ b/gdb/language.c @@ -987,6 +987,24 @@ language_bool_type (const struct language_defn *la, return ld->arch_info[la->la_language].bool_type_default; } +/* Helper function for primitive type lookup. */ + +static struct type ** +language_lookup_primitive_type_1 (const struct language_arch_info *lai, + const char *name) +{ + struct type **p; + + for (p = lai->primitive_type_vector; (*p) != NULL; p++) + { + if (strcmp (TYPE_NAME (*p), name) == 0) + return p; + } + return NULL; +} + +/* See language.h. */ + struct type * language_lookup_primitive_type (const struct language_defn *la, struct gdbarch *gdbarch, @@ -994,33 +1012,113 @@ language_lookup_primitive_type (const struct language_defn *la, { struct language_gdbarch *ld = gdbarch_data (gdbarch, language_gdbarch_data); - struct type *const *p; + struct type **typep; + + typep = language_lookup_primitive_type_1 (&ld->arch_info[la->la_language], + name); + if (typep == NULL) + return NULL; + return *typep; +} + +/* Helper function for type lookup as a symbol. + Create the symbol corresponding to type TYPE in language LANG. */ + +static struct symbol * +language_alloc_type_symbol (enum language lang, struct type *type) +{ + struct symbol *symbol; + struct gdbarch *gdbarch; + + gdb_assert (!TYPE_OBJFILE_OWNED (type)); + + gdbarch = TYPE_OWNER (type).gdbarch; + symbol = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct symbol); + + symbol->ginfo.name = TYPE_NAME (type); + symbol->ginfo.language = lang; + symbol->owner.arch = gdbarch; + SYMBOL_OBJFILE_OWNED (symbol) = 0; + SYMBOL_TYPE (symbol) = type; + SYMBOL_DOMAIN (symbol) = VAR_DOMAIN; + SYMBOL_ACLASS_INDEX (symbol) = LOC_TYPEDEF; + + return symbol; +} + +/* Initialize the primitive type symbols of language LD. + The primitive type vector must have already been initialized. */ + +static void +language_init_primitive_type_symbols (struct language_arch_info *lai, + const struct language_defn *la, + struct gdbarch *gdbarch) +{ + int n; + struct compunit_symtab *cust; + struct symtab *symtab; + struct block *static_block, *global_block; + + gdb_assert (lai->primitive_type_vector != NULL); + + for (n = 0; lai->primitive_type_vector[n] != NULL; ++n) + continue; + + lai->primitive_type_symbols + = GDBARCH_OBSTACK_CALLOC (gdbarch, n + 1, struct symbol *); + + for (n = 0; lai->primitive_type_vector[n] != NULL; ++n) + { + lai->primitive_type_symbols[n] + = language_alloc_type_symbol (la->la_language, + lai->primitive_type_vector[n]); + } + + /* Note: The result of symbol lookup is normally a symbol *and* the block + it was found in (returned in global block_found). Builtin types don't + live in blocks. We *could* give them one, but there is no current need + so to keep things simple symbol lookup is extended to allow for + BLOCK_FOUND to be NULL. */ +} + +/* See language.h. */ + +struct symbol * +language_lookup_primitive_type_as_symbol (const struct language_defn *la, + struct gdbarch *gdbarch, + const char *name) +{ + struct language_gdbarch *ld = gdbarch_data (gdbarch, + language_gdbarch_data); + struct language_arch_info *lai = &ld->arch_info[la->la_language]; + struct type **typep; + struct symbol *sym; if (symbol_lookup_debug) { fprintf_unfiltered (gdb_stdlog, - "language_lookup_primitive_type (%s, %s, %s)", + "language_lookup_primitive_type_as_symbol" + " (%s, %s, %s)", la->la_name, host_address_to_string (gdbarch), name); } - for (p = ld->arch_info[la->la_language].primitive_type_vector; - (*p) != NULL; - p++) + typep = language_lookup_primitive_type_1 (lai, name); + if (typep == NULL) { - if (strcmp (TYPE_NAME (*p), name) == 0) - { - if (symbol_lookup_debug) - { - fprintf_unfiltered (gdb_stdlog, " = %s\n", - host_address_to_string (*p)); - } - return (*p); - } + if (symbol_lookup_debug) + fprintf_unfiltered (gdb_stdlog, " = NULL\n"); + return NULL; } + /* The set of symbols is lazily initialized. */ + if (lai->primitive_type_symbols == NULL) + language_init_primitive_type_symbols (lai, la, gdbarch); + + sym = lai->primitive_type_symbols[typep - lai->primitive_type_vector]; + if (symbol_lookup_debug) - fprintf_unfiltered (gdb_stdlog, " = NULL\n"); - return (NULL); + fprintf_unfiltered (gdb_stdlog, " = %s\n", host_address_to_string (sym)); + return sym; } /* Initialize the language routines. */ diff --git a/gdb/language.h b/gdb/language.h index 2a47e64534..1103fe92dc 100644 --- a/gdb/language.h +++ b/gdb/language.h @@ -111,6 +111,11 @@ struct language_arch_info expressions, regardless of whether the program being debugged actually defines such a type. */ struct type **primitive_type_vector; + + /* Symbol wrappers around primitive_type_vector, so that the symbol lookup + machinery can return them. */ + struct symbol **primitive_type_symbols; + /* Type of elements of strings. */ struct type *string_char_type; @@ -436,10 +441,21 @@ struct type *language_bool_type (const struct language_defn *l, struct type *language_string_char_type (const struct language_defn *l, struct gdbarch *gdbarch); +/* Look up type NAME in language L, and return its definition for architecture + GDBARCH. Returns NULL if not found. */ + struct type *language_lookup_primitive_type (const struct language_defn *l, struct gdbarch *gdbarch, const char *name); +/* Wrapper around language_lookup_primitive_type to return the + corresponding symbol. */ + +struct symbol * + language_lookup_primitive_type_as_symbol (const struct language_defn *l, + struct gdbarch *gdbarch, + const char *name); + /* These macros define the behaviour of the expression evaluator. */ diff --git a/gdb/printcmd.c b/gdb/printcmd.c index 58b7ac0b4d..020a47c6d8 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1251,7 +1251,10 @@ address_info (char *exp, int from_tty) current_language->la_language, DMGL_ANSI); printf_filtered ("\" is "); val = SYMBOL_VALUE (sym); - section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym); + if (SYMBOL_OBJFILE_OWNED (sym)) + section = SYMBOL_OBJ_SECTION (symbol_objfile (sym), sym); + else + section = NULL; gdbarch = symbol_arch (sym); if (SYMBOL_COMPUTED_OPS (sym) != NULL) diff --git a/gdb/python/py-symbol.c b/gdb/python/py-symbol.c index 62fde6482f..fdff53fa15 100644 --- a/gdb/python/py-symbol.c +++ b/gdb/python/py-symbol.c @@ -87,6 +87,9 @@ sympy_get_symtab (PyObject *self, void *closure) SYMPY_REQUIRE_VALID (self, symbol); + if (!SYMBOL_OBJFILE_OWNED (symbol)) + Py_RETURN_NONE; + return symtab_to_symtab_object (symbol_symtab (symbol)); } @@ -290,7 +293,8 @@ set_symbol (symbol_object *obj, struct symbol *symbol) { obj->symbol = symbol; obj->prev = NULL; - if (symbol_symtab (symbol) != NULL) + if (SYMBOL_OBJFILE_OWNED (symbol) + && symbol_symtab (symbol) != NULL) { struct objfile *objfile = symbol_objfile (symbol); @@ -334,6 +338,7 @@ sympy_dealloc (PyObject *obj) if (sym_obj->prev) sym_obj->prev->next = sym_obj->next; else if (sym_obj->symbol != NULL + && SYMBOL_OBJFILE_OWNED (sym_obj->symbol) && symbol_symtab (sym_obj->symbol) != NULL) { set_objfile_data (symbol_objfile (sym_obj->symbol), diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 3b6639df65..9ae0847f58 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -466,8 +466,12 @@ print_symbol (void *args) struct symbol *symbol = ((struct print_symbol_args *) args)->symbol; int depth = ((struct print_symbol_args *) args)->depth; struct ui_file *outfile = ((struct print_symbol_args *) args)->outfile; - struct obj_section *section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol), - symbol); + struct obj_section *section; + + if (SYMBOL_OBJFILE_OWNED (symbol)) + section = SYMBOL_OBJ_SECTION (symbol_objfile (symbol), symbol); + else + section = NULL; print_spaces (depth, outfile); if (SYMBOL_DOMAIN (symbol) == LABEL_DOMAIN) diff --git a/gdb/symtab.c b/gdb/symtab.c index e7cd5afc8c..0efd9d2d48 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1150,6 +1150,9 @@ fixup_symbol_section (struct symbol *sym, struct objfile *objfile) if (!sym) return NULL; + if (!SYMBOL_OBJFILE_OWNED (sym)) + return sym; + /* We either have an OBJFILE, or we can get at it from the sym's symtab. Anything else is a bug. */ gdb_assert (objfile || symbol_symtab (sym)); @@ -1421,6 +1424,13 @@ lookup_symbol_aux (const char *name, const struct block *block, domain_name (domain), language_str (language)); } + /* Initialize block_found so that the language la_lookup_symbol_nonlocal + routines don't have to set it (to NULL) if a primitive type is found. + We do this early so that block_found is also NULL if no symbol is + found (though this is not part of the API, and callers cannot assume + this). */ + block_found = NULL; + /* 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 certainly use it later. If we don't set it, the contents of @@ -1848,6 +1858,25 @@ basic_lookup_symbol_nonlocal (const struct language_defn *langdef, if (sym != NULL) return sym; + /* If we didn't find a definition for a builtin type in the static block, + search for it now. This is actually the right thing to do and can be + a massive performance win. E.g., when debugging a program with lots of + shared libraries we could search all of them only to find out the + builtin type isn't defined in any of them. This is common for types + like "void". */ + if (domain == VAR_DOMAIN) + { + struct gdbarch *gdbarch; + + if (block == NULL) + gdbarch = target_gdbarch (); + else + gdbarch = block_gdbarch (block); + sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name); + if (sym != NULL) + return sym; + } + return lookup_global_symbol (name, block, domain); } @@ -5313,13 +5342,23 @@ initialize_ordinary_address_classes (void) -/* Initialize the symbol SYM. */ +/* Helper function to initialize the fields of an objfile-owned symbol. + It assumed that *SYM is already all zeroes. */ + +static void +initialize_objfile_symbol_1 (struct symbol *sym) +{ + SYMBOL_OBJFILE_OWNED (sym) = 1; + SYMBOL_SECTION (sym) = -1; +} + +/* Initialize the symbol SYM, and mark it as being owned by an objfile. */ void initialize_objfile_symbol (struct symbol *sym) { memset (sym, 0, sizeof (*sym)); - SYMBOL_SECTION (sym) = -1; + initialize_objfile_symbol_1 (sym); } /* Allocate and initialize a new 'struct symbol' on OBJFILE's @@ -5331,7 +5370,7 @@ allocate_symbol (struct objfile *objfile) struct symbol *result; result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct symbol); - SYMBOL_SECTION (result) = -1; + initialize_objfile_symbol_1 (result); return result; } @@ -5345,7 +5384,7 @@ allocate_template_symbol (struct objfile *objfile) struct template_symbol *result; result = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct template_symbol); - SYMBOL_SECTION (&result->base) = -1; + initialize_objfile_symbol_1 (&result->base); return result; } @@ -5355,7 +5394,8 @@ allocate_template_symbol (struct objfile *objfile) struct objfile * symbol_objfile (const struct symbol *symbol) { - return SYMTAB_OBJFILE (symbol->symtab); + gdb_assert (SYMBOL_OBJFILE_OWNED (symbol)); + return SYMTAB_OBJFILE (symbol->owner.symtab); } /* See symtab.h. */ @@ -5363,7 +5403,9 @@ symbol_objfile (const struct symbol *symbol) struct gdbarch * symbol_arch (const struct symbol *symbol) { - return get_objfile_arch (symbol_objfile (symbol)); + if (!SYMBOL_OBJFILE_OWNED (symbol)) + return symbol->owner.arch; + return get_objfile_arch (SYMTAB_OBJFILE (symbol->owner.symtab)); } /* See symtab.h. */ @@ -5371,7 +5413,8 @@ symbol_arch (const struct symbol *symbol) struct symtab * symbol_symtab (const struct symbol *symbol) { - return symbol->symtab; + gdb_assert (SYMBOL_OBJFILE_OWNED (symbol)); + return symbol->owner.symtab; } /* See symtab.h. */ @@ -5379,7 +5422,8 @@ symbol_symtab (const struct symbol *symbol) void symbol_set_symtab (struct symbol *symbol, struct symtab *symtab) { - symbol->symtab = symtab; + gdb_assert (SYMBOL_OBJFILE_OWNED (symbol)); + symbol->owner.symtab = symtab; } diff --git a/gdb/symtab.h b/gdb/symtab.h index b3a9a6b74e..3f645b1bd9 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -711,10 +711,19 @@ struct symbol struct type *type; - /* The symbol table containing this symbol. This is the file - associated with LINE. It can be NULL during symbols read-in but it is - never NULL during normal operation. */ - struct symtab *symtab; + /* The owner of this symbol. + Which one to use is defined by symbol.is_arch_owned. */ + + union + { + /* The symbol table containing this symbol. This is the file associated + with LINE. It can be NULL during symbols read-in but it is never NULL + during normal operation. */ + struct symtab *symtab; + + /* For types defined by the architecture. */ + struct gdbarch *arch; + } owner; /* Domain code. */ @@ -726,6 +735,11 @@ struct symbol unsigned int aclass_index : SYMBOL_ACLASS_BITS; + /* If non-zero then symbol is objfile-owned, use owner.symtab. + Otherwise symbol is arch-owned, use owner.arch. */ + + unsigned int is_objfile_owned : 1; + /* Whether this is an argument. */ unsigned is_argument : 1; @@ -742,6 +756,7 @@ struct symbol SYMBOL_INLINED set) this is the line number of the function's call site. Inlined function symbols are not definitions, and they are never found by symbol table lookup. + If this symbol is arch-owned, LINE shall be zero. FIXME: Should we really make the assumption that nobody will try to debug files longer than 64K lines? What about machine @@ -769,10 +784,14 @@ struct symbol extern const struct symbol_impl *symbol_impls; +/* Note: There is no accessor macro for symbol.owner because it is + "private". */ + #define SYMBOL_DOMAIN(symbol) (symbol)->domain #define SYMBOL_IMPL(symbol) (symbol_impls[(symbol)->aclass_index]) #define SYMBOL_ACLASS_INDEX(symbol) (symbol)->aclass_index #define SYMBOL_CLASS(symbol) (SYMBOL_IMPL (symbol).aclass) +#define SYMBOL_OBJFILE_OWNED(symbol) ((symbol)->is_objfile_owned) #define SYMBOL_IS_ARGUMENT(symbol) (symbol)->is_argument #define SYMBOL_INLINED(symbol) (symbol)->is_inlined #define SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION(symbol) \ -- 2.34.1