X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fminsyms.c;h=cb4545c06fc7bad66d92078bd2d37948642a2b85;hb=91158a569dc571a9916dfad98c6c95ce789ad18d;hp=0798426eaf20d744f0c73730d00ac092608ccb66;hpb=a9762ec78a53fbe9209fe1654db42df0cd328d50;p=binutils-gdb.git diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 0798426eaf2..cb4545c06fc 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -1,6 +1,6 @@ /* GDB routines for manipulating the minimal symbol tables. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004, 2007 Free Software Foundation, Inc. + 2002, 2003, 2004, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Cygnus Support, using pieces from other GDB modules. This file is part of GDB. @@ -47,6 +47,9 @@ #include "demangle.h" #include "value.h" #include "cp-abi.h" +#include "target.h" +#include "cp-support.h" +#include "language.h" /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE. At the end, copy them all into one newly allocated location on an objfile's @@ -79,6 +82,7 @@ unsigned int msymbol_hash_iw (const char *string) { unsigned int hash = 0; + while (*string && *string != '(') { while (isspace (*string)) @@ -98,6 +102,7 @@ unsigned int msymbol_hash (const char *string) { unsigned int hash = 0; + for (; *string; ++string) hash = hash * 67 + *string - 113; return hash; @@ -112,6 +117,7 @@ add_minsym_to_hash_table (struct minimal_symbol *sym, { unsigned int hash = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; + sym->hash_next = table[hash]; table[hash] = sym; } @@ -125,13 +131,35 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, { if (sym->demangled_hash_next == NULL) { - unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; + unsigned int hash + = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; + sym->demangled_hash_next = table[hash]; table[hash] = sym; } } +/* Return OBJFILE where minimal symbol SYM is defined. */ +struct objfile * +msymbol_objfile (struct minimal_symbol *sym) +{ + struct objfile *objf; + struct minimal_symbol *tsym; + + unsigned int hash + = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; + + for (objf = object_files; objf; objf = objf->next) + for (tsym = objf->msymbol_hash[hash]; tsym; tsym = tsym->hash_next) + if (tsym == sym) + return objf; + + /* We should always be able to find the objfile ... */ + internal_error (__FILE__, __LINE__, _("failed internal consistency check")); +} + + /* Look through all the current minimal symbol tables and find the first minimal symbol that matches NAME. If OBJF is non-NULL, limit the search to that objfile. If SFILE is non-NULL, the only file-scope @@ -165,20 +193,36 @@ lookup_minimal_symbol (const char *name, const char *sfile, unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE; -#ifdef SOFUN_ADDRESS_MAYBE_MISSING + int needtofreename = 0; + const char *modified_name; + if (sfile != NULL) { char *p = strrchr (sfile, '/'); + if (p != NULL) sfile = p + 1; } -#endif + + /* For C++, canonicalize the input name. */ + modified_name = name; + if (current_language->la_language == language_cplus) + { + char *cname = cp_canonicalize_string (name); + + if (cname) + { + modified_name = cname; + needtofreename = 1; + } + } for (objfile = object_files; objfile != NULL && found_symbol == NULL; objfile = objfile->next) { - if (objf == NULL || objf == objfile) + if (objf == NULL || objf == objfile + || objf == objfile->separate_debug_objfile_backlink) { /* Do two passes: the first over the ordinary hash table, and the second over the demangled hash table. */ @@ -194,33 +238,29 @@ lookup_minimal_symbol (const char *name, const char *sfile, while (msymbol != NULL && found_symbol == NULL) { - /* FIXME: carlton/2003-02-27: This is an unholy - mixture of linkage names and natural names. If - you want to test the linkage names with strcmp, - do that. If you want to test the natural names - with strcmp_iw, use SYMBOL_MATCHES_NATURAL_NAME. */ - if (strcmp (DEPRECATED_SYMBOL_NAME (msymbol), (name)) == 0 - || (SYMBOL_DEMANGLED_NAME (msymbol) != NULL - && strcmp_iw (SYMBOL_DEMANGLED_NAME (msymbol), - (name)) == 0)) + int match; + + if (pass == 1) + { + match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), + modified_name) == 0; + } + else + { + match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, + modified_name); + } + + if (match) { switch (MSYMBOL_TYPE (msymbol)) { case mst_file_text: case mst_file_data: case mst_file_bss: -#ifdef SOFUN_ADDRESS_MAYBE_MISSING if (sfile == NULL || strcmp (msymbol->filename, sfile) == 0) found_file_symbol = msymbol; -#else - /* We have neither the ability nor the need to - deal with the SFILE parameter. If we find - more than one symbol, just return the latest - one (the user can't expect useful behavior in - that case). */ - found_file_symbol = msymbol; -#endif break; case mst_solib_trampoline: @@ -249,6 +289,10 @@ lookup_minimal_symbol (const char *name, const char *sfile, } } } + + if (needtofreename) + xfree ((void *) modified_name); + /* External symbols are best. */ if (found_symbol) return found_symbol; @@ -285,7 +329,8 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) objfile != NULL && found_symbol == NULL; objfile = objfile->next) { - if (objf == NULL || objf == objfile) + if (objf == NULL || objf == objfile + || objf == objfile->separate_debug_objfile_backlink) { for (msymbol = objfile->msymbol_hash[hash]; msymbol != NULL && found_symbol == NULL; @@ -319,6 +364,41 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) return NULL; } +/* Look through all the current minimal symbol tables and find the + first minimal symbol that matches NAME and PC. If OBJF is non-NULL, + limit the search to that objfile. Returns a pointer to the minimal + symbol that matches, or NULL if no match is found. */ + +struct minimal_symbol * +lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name, + struct objfile *objf) +{ + struct objfile *objfile; + struct minimal_symbol *msymbol; + + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; + + for (objfile = object_files; + objfile != NULL; + objfile = objfile->next) + { + if (objf == NULL || objf == objfile + || objf == objfile->separate_debug_objfile_backlink) + { + for (msymbol = objfile->msymbol_hash[hash]; + msymbol != NULL; + msymbol = msymbol->hash_next) + { + if (SYMBOL_VALUE_ADDRESS (msymbol) == pc + && strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0) + return msymbol; + } + } + } + + return NULL; +} + /* Look through all the current minimal symbol tables and find the first minimal symbol that matches NAME and is a solib trampoline. If OBJF is non-NULL, limit the search to that objfile. Returns a @@ -341,7 +421,8 @@ lookup_minimal_symbol_solib_trampoline (const char *name, objfile != NULL && found_symbol == NULL; objfile = objfile->next) { - if (objf == NULL || objf == objfile) + if (objf == NULL || objf == objfile + || objf == objfile->separate_debug_objfile_backlink) { for (msymbol = objfile->msymbol_hash[hash]; msymbol != NULL && found_symbol == NULL; @@ -359,16 +440,23 @@ lookup_minimal_symbol_solib_trampoline (const char *name, /* Search through the minimal symbol table for each objfile and find the symbol whose address is the largest address that is still less - than or equal to PC, and matches SECTION (if non-NULL). Returns a - pointer to the minimal symbol if such a symbol is found, or NULL if - PC is not in a suitable range. Note that we need to look through - ALL the minimal symbol tables before deciding on the symbol that - comes closest to the specified PC. This is because objfiles can - overlap, for example objfile A has .text at 0x100 and .data at - 0x40000 and objfile B has .text at 0x234 and .data at 0x40048. */ - -struct minimal_symbol * -lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) + than or equal to PC, and matches SECTION (which is not NULL). + Returns a pointer to the minimal symbol if such a symbol is found, + or NULL if PC is not in a suitable range. + Note that we need to look through ALL the minimal symbol tables + before deciding on the symbol that comes closest to the specified PC. + This is because objfiles can overlap, for example objfile A has .text + at 0x100 and .data at 0x40000 and objfile B has .text at 0x234 and + .data at 0x40048. + + If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when + there are text and trampoline symbols at the same address. + Otherwise prefer mst_text symbols. */ + +static struct minimal_symbol * +lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, + struct obj_section *section, + int want_trampoline) { int lo; int hi; @@ -376,16 +464,12 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) struct objfile *objfile; struct minimal_symbol *msymbol; struct minimal_symbol *best_symbol = NULL; - struct obj_section *pc_section; + enum minimal_symbol_type want_type, other_type; - /* PC has to be in a known section. This ensures that anything - beyond the end of the last segment doesn't appear to be part of - the last function in the last segment. */ - pc_section = find_pc_section (pc); - if (pc_section == NULL) - return NULL; + want_type = want_trampoline ? mst_solib_trampoline : mst_text; + other_type = want_trampoline ? mst_text : mst_solib_trampoline; - /* We can not require the symbol found to be in pc_section, because + /* We can not require the symbol found to be in section, because e.g. IRIX 6.5 mdebug relies on this code returning an absolute symbol - but find_pc_section won't return an absolute section and hence the code below would skip over absolute symbols. We can @@ -394,11 +478,11 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) files, search both the file and its separate debug file. There's no telling which one will have the minimal symbols. */ - objfile = pc_section->objfile; - if (objfile->separate_debug_objfile) - objfile = objfile->separate_debug_objfile; + gdb_assert (section != NULL); - for (; objfile != NULL; objfile = objfile->separate_debug_objfile_backlink) + for (objfile = section->objfile; + objfile != NULL; + objfile = objfile_separate_debug_iterate (section->objfile, objfile)) { /* If this objfile has a minimal symbol table, go search it using a binary search. Note that a minimal symbol table always consists @@ -474,7 +558,7 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) triggered by a special mst_abs_or_lib or some such. */ - if (msymbol[hi].type == mst_abs) + if (MSYMBOL_TYPE (&msymbol[hi]) == mst_abs) { hi--; continue; @@ -486,9 +570,27 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) /* Some types of debug info, such as COFF, don't fill the bfd_section member, so don't throw away symbols on those platforms. */ - && SYMBOL_BFD_SECTION (&msymbol[hi]) != NULL - && (!matching_bfd_sections - (SYMBOL_BFD_SECTION (&msymbol[hi]), section))) + && SYMBOL_OBJ_SECTION (&msymbol[hi]) != NULL + && (!matching_obj_sections + (SYMBOL_OBJ_SECTION (&msymbol[hi]), section))) + { + hi--; + continue; + } + + /* If we are looking for a trampoline and this is a + text symbol, or the other way around, check the + preceeding symbol too. If they are otherwise + identical prefer that one. */ + if (hi > 0 + && MSYMBOL_TYPE (&msymbol[hi]) == other_type + && MSYMBOL_TYPE (&msymbol[hi - 1]) == want_type + && (MSYMBOL_SIZE (&msymbol[hi]) + == MSYMBOL_SIZE (&msymbol[hi - 1])) + && (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) + == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1])) + && (SYMBOL_OBJ_SECTION (&msymbol[hi]) + == SYMBOL_OBJ_SECTION (&msymbol[hi - 1]))) { hi--; continue; @@ -574,19 +676,59 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) return (best_symbol); } +struct minimal_symbol * +lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section) +{ + if (section == NULL) + { + /* NOTE: cagney/2004-01-27: This was using find_pc_mapped_section to + force the section but that (well unless you're doing overlay + debugging) always returns NULL making the call somewhat useless. */ + section = find_pc_section (pc); + if (section == NULL) + return NULL; + } + return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0); +} + /* Backward compatibility: search through the minimal symbol table for a matching PC (no section given) */ struct minimal_symbol * lookup_minimal_symbol_by_pc (CORE_ADDR pc) { - /* NOTE: cagney/2004-01-27: This was using find_pc_mapped_section to - force the section but that (well unless you're doing overlay - debugging) always returns NULL making the call somewhat useless. */ - struct obj_section *section = find_pc_section (pc); - if (section == NULL) - return NULL; - return lookup_minimal_symbol_by_pc_section (pc, section->the_bfd_section); + return lookup_minimal_symbol_by_pc_section (pc, NULL); +} + +/* Find the minimal symbol named NAME, and return both the minsym + struct and its objfile. This only checks the linkage name. Sets + *OBJFILE_P and returns the minimal symbol, if it is found. If it + is not found, returns NULL. */ + +struct minimal_symbol * +lookup_minimal_symbol_and_objfile (const char *name, + struct objfile **objfile_p) +{ + struct objfile *objfile; + unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE; + + ALL_OBJFILES (objfile) + { + struct minimal_symbol *msym; + + for (msym = objfile->msymbol_hash[hash]; + msym != NULL; + msym = msym->hash_next) + { + if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0) + { + *objfile_p = objfile; + return msym; + } + } + } + + return 0; } @@ -644,19 +786,21 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address, } prim_record_minimal_symbol_and_info (name, address, ms_type, - NULL, section, NULL, objfile); + section, NULL, objfile); } /* Record a minimal symbol in the msym bunches. Returns the symbol newly created. */ struct minimal_symbol * -prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, - enum minimal_symbol_type ms_type, - char *info, int section, - asection *bfd_section, - struct objfile *objfile) +prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name, + CORE_ADDR address, + enum minimal_symbol_type ms_type, + int section, + asection *bfd_section, + struct objfile *objfile) { + struct obj_section *obj_section; struct msym_bunch *new; struct minimal_symbol *msymbol; @@ -673,14 +817,17 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, /* It's safe to strip the leading char here once, since the name is also stored stripped in the minimal symbol table. */ if (name[0] == get_symbol_leading_char (objfile->obfd)) - ++name; + { + ++name; + --name_len; + } if (ms_type == mst_file_text && strncmp (name, "__gnu_compiled", 14) == 0) return (NULL); if (msym_bunch_index == BUNCH_SIZE) { - new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch)); + new = XCALLOC (1, struct msym_bunch); msym_bunch_index = 0; new->next = msym_bunch; msym_bunch = new; @@ -688,15 +835,26 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, msymbol = &msym_bunch->contents[msym_bunch_index]; SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown); SYMBOL_LANGUAGE (msymbol) = language_auto; - SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile); + SYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile); SYMBOL_VALUE_ADDRESS (msymbol) = address; SYMBOL_SECTION (msymbol) = section; - SYMBOL_BFD_SECTION (msymbol) = bfd_section; + SYMBOL_OBJ_SECTION (msymbol) = NULL; + + /* Find obj_section corresponding to bfd_section. */ + if (bfd_section) + ALL_OBJFILE_OSECTIONS (objfile, obj_section) + { + if (obj_section->the_bfd_section == bfd_section) + { + SYMBOL_OBJ_SECTION (msymbol) = obj_section; + break; + } + } MSYMBOL_TYPE (msymbol) = ms_type; - /* FIXME: This info, if it remains, needs its own field. */ - MSYMBOL_INFO (msymbol) = info; /* FIXME! */ + MSYMBOL_TARGET_FLAG_1 (msymbol) = 0; + MSYMBOL_TARGET_FLAG_2 (msymbol) = 0; MSYMBOL_SIZE (msymbol) = 0; /* The hash pointers must be cleared! If they're not, @@ -710,6 +868,21 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, return msymbol; } +/* Record a minimal symbol in the msym bunches. Returns the symbol + newly created. */ + +struct minimal_symbol * +prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, + enum minimal_symbol_type ms_type, + int section, + asection *bfd_section, + struct objfile *objfile) +{ + return prim_record_minimal_symbol_full (name, strlen (name), 1, + address, ms_type, section, + bfd_section, objfile); +} + /* Compare two minimal symbols by address and return a signed result based on unsigned comparisons, so that we sort into unsigned numeric order. Within groups with the same address, sort by name. */ @@ -968,7 +1141,8 @@ install_minimal_symbols (struct objfile *objfile) SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL; SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0; - MSYMBOL_INFO (&msymbols[mcount]) = NULL; + MSYMBOL_TARGET_FLAG_1 (&msymbols[mcount]) = 0; + MSYMBOL_TARGET_FLAG_2 (&msymbols[mcount]) = 0; MSYMBOL_SIZE (&msymbols[mcount]) = 0; MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown; SYMBOL_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown); @@ -993,6 +1167,7 @@ install_minimal_symbols (struct objfile *objfile) mixing ABIs then the user will need to "set cp-abi" manually. */ const char *name = SYMBOL_LINKAGE_NAME (&objfile->msymbols[i]); + if (name[0] == '_' && name[1] == 'Z' && SYMBOL_DEMANGLED_NAME (&objfile->msymbols[i]) != NULL) { @@ -1027,7 +1202,12 @@ msymbols_sort (struct objfile *objfile) struct minimal_symbol * lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc) { - struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc); + struct obj_section *section = find_pc_section (pc); + struct minimal_symbol *msymbol; + + if (section == NULL) + return NULL; + msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1); if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline) return msymbol; @@ -1059,6 +1239,23 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc) && strcmp (SYMBOL_LINKAGE_NAME (msymbol), SYMBOL_LINKAGE_NAME (tsymbol)) == 0) return SYMBOL_VALUE_ADDRESS (msymbol); + + /* Also handle minimal symbols pointing to function descriptors. */ + if (MSYMBOL_TYPE (msymbol) == mst_data + && strcmp (SYMBOL_LINKAGE_NAME (msymbol), + SYMBOL_LINKAGE_NAME (tsymbol)) == 0) + { + CORE_ADDR func; + + func = gdbarch_convert_from_func_ptr_addr + (get_objfile_arch (objfile), + SYMBOL_VALUE_ADDRESS (msymbol), + ¤t_target); + + /* Ignore data symbols that are not function descriptors. */ + if (func != SYMBOL_VALUE_ADDRESS (msymbol)) + return func; + } } } return 0;