X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fminsyms.c;h=cb4545c06fc7bad66d92078bd2d37948642a2b85;hb=91158a569dc571a9916dfad98c6c95ce789ad18d;hp=4069e6fb10a9202d7ae3d5a745c9b4b7edc49b71;hpb=714835d5a63b86bb0e82c13d2a4840d8b5e633d3;p=binutils-gdb.git diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 4069e6fb10a..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, 2008 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. @@ -48,6 +48,8 @@ #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 @@ -80,6 +82,7 @@ unsigned int msymbol_hash_iw (const char *string) { unsigned int hash = 0; + while (*string && *string != '(') { while (isspace (*string)) @@ -99,6 +102,7 @@ unsigned int msymbol_hash (const char *string) { unsigned int hash = 0; + for (; *string; ++string) hash = hash * 67 + *string - 113; return hash; @@ -113,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; } @@ -128,6 +133,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, { unsigned int hash = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE; + sym->demangled_hash_next = table[hash]; table[hash] = sym; } @@ -187,19 +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; + int needtofreename = 0; + const char *modified_name; + if (sfile != NULL) { char *p = strrchr (sfile, '/'); + if (p != NULL) sfile = p + 1; } + /* 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 - || objf->separate_debug_objfile == 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. */ @@ -218,9 +241,16 @@ lookup_minimal_symbol (const char *name, const char *sfile, int match; if (pass == 1) - match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0; + { + match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), + modified_name) == 0; + } else - match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, name); + { + match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, + modified_name); + } + if (match) { switch (MSYMBOL_TYPE (msymbol)) @@ -259,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; @@ -296,7 +330,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf) objfile = objfile->next) { if (objf == NULL || objf == objfile - || objf->separate_debug_objfile == objfile) + || objf == objfile->separate_debug_objfile_backlink) { for (msymbol = objfile->msymbol_hash[hash]; msymbol != NULL && found_symbol == NULL; @@ -349,7 +383,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name, objfile = objfile->next) { if (objf == NULL || objf == objfile - || objf->separate_debug_objfile == objfile) + || objf == objfile->separate_debug_objfile_backlink) { for (msymbol = objfile->msymbol_hash[hash]; msymbol != NULL; @@ -388,7 +422,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name, objfile = objfile->next) { if (objf == NULL || objf == objfile - || objf->separate_debug_objfile == objfile) + || objf == objfile->separate_debug_objfile_backlink) { for (msymbol = objfile->msymbol_hash[hash]; msymbol != NULL && found_symbol == NULL; @@ -406,13 +440,14 @@ 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. + 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. @@ -429,20 +464,12 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, 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; want_type = want_trampoline ? mst_solib_trampoline : mst_text; other_type = want_trampoline ? mst_text : mst_solib_trampoline; - - /* 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; - /* 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 @@ -451,11 +478,11 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, 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 @@ -531,7 +558,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, 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; @@ -652,6 +679,15 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, 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); } @@ -661,13 +697,38 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section) 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); + 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; } @@ -725,18 +786,19 @@ 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; @@ -755,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; @@ -770,7 +835,7 @@ 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; @@ -788,8 +853,8 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address, } 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, @@ -803,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. */ @@ -1061,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); @@ -1086,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) { @@ -1164,6 +1246,7 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc) SYMBOL_LINKAGE_NAME (tsymbol)) == 0) { CORE_ADDR func; + func = gdbarch_convert_from_func_ptr_addr (get_objfile_arch (objfile), SYMBOL_VALUE_ADDRESS (msymbol),