X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fminsyms.c;h=cb4545c06fc7bad66d92078bd2d37948642a2b85;hb=91158a569dc571a9916dfad98c6c95ce789ad18d;hp=83aef9d442876dd2c16c466c9729582685fd6229;hpb=43b54b88e73a74b1505df5eb4de6d6885bd4c3b4;p=binutils-gdb.git diff --git a/gdb/minsyms.c b/gdb/minsyms.c index 83aef9d4428..cb4545c06fc 100644 --- a/gdb/minsyms.c +++ b/gdb/minsyms.c @@ -1,14 +1,13 @@ /* GDB routines for manipulating the minimal symbol tables. - Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, - 2002, 2003, 2004 - Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 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. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -17,9 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + along with this program. If not, see . */ /* This file contains support routines for creating, manipulating, and @@ -50,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 @@ -82,6 +82,7 @@ unsigned int msymbol_hash_iw (const char *string) { unsigned int hash = 0; + while (*string && *string != '(') { while (isspace (*string)) @@ -101,6 +102,7 @@ unsigned int msymbol_hash (const char *string) { unsigned int hash = 0; + for (; *string; ++string) hash = hash * 67 + *string - 113; return hash; @@ -115,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,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 @@ -145,7 +170,15 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym, Note: One instance where there may be duplicate minimal symbols with the same name is when the symbol tables for a shared library and the symbol tables for an executable contain global symbols with the same - names (the dynamic linker deals with the duplication). */ + names (the dynamic linker deals with the duplication). + + It's also possible to have minimal symbols with different mangled + names, but identical demangled names. For example, the GNU C++ v3 + ABI requires the generation of two (or perhaps three) copies of + constructor functions --- "in-charge", "not-in-charge", and + "allocate" copies; destructors may be duplicated as well. + Obviously, there must be distinct mangled names for each of these, + but the demangled names are all the same: S::S or S::~S. */ struct minimal_symbol * lookup_minimal_symbol (const char *name, const char *sfile, @@ -160,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. */ @@ -189,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: @@ -244,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; @@ -280,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; @@ -314,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 @@ -336,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; @@ -352,19 +438,25 @@ lookup_minimal_symbol_solib_trampoline (const char *name, return NULL; } - /* 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; @@ -372,29 +464,25 @@ 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; - /* NOTE: cagney/2004-01-27: Removed code (added 2003-07-19) that was - trying to force the PC into a valid section as returned by - find_pc_section. It broke IRIX 6.5 mdebug which relies on this - code returning an absolute symbol - the problem was that - find_pc_section wasn't returning an absolute section and hence - the code below would skip over absolute symbols. Since the - original problem was with finding a frame's function, and that - uses [indirectly] lookup_minimal_symbol_by_pc, the original - problem has been fixed by having that function use - find_pc_section. */ + /* 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 + still take advantage of the call to find_pc_section, though - the + object file still must match. In case we have separate debug + files, search both the file and its separate debug file. There's + no telling which one will have the minimal symbols. */ - for (objfile = object_files; + gdb_assert (section != NULL); + + for (objfile = section->objfile; objfile != NULL; - objfile = objfile->next) + 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 @@ -404,6 +492,8 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) if (objfile->minimal_symbol_count > 0) { + int best_zero_sized = -1; + msymbol = objfile->msymbols; lo = 0; hi = objfile->minimal_symbol_count - 1; @@ -453,34 +543,126 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section) == SYMBOL_VALUE_ADDRESS (&msymbol[hi + 1]))) hi++; + /* Skip various undesirable symbols. */ + while (hi >= 0) + { + /* Skip any absolute symbols. This is apparently + what adb and dbx do, and is needed for the CM-5. + There are two known possible problems: (1) on + ELF, apparently end, edata, etc. are absolute. + Not sure ignoring them here is a big deal, but if + we want to use them, the fix would go in + elfread.c. (2) I think shared library entry + points on the NeXT are absolute. If we want + special handling for this it probably should be + triggered by a special mst_abs_or_lib or some + such. */ + + if (MSYMBOL_TYPE (&msymbol[hi]) == mst_abs) + { + hi--; + continue; + } + + /* If SECTION was specified, skip any symbol from + wrong section. */ + if (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_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; + } + + /* If the minimal symbol has a zero size, save it + but keep scanning backwards looking for one with + a non-zero size. A zero size may mean that the + symbol isn't an object or function (e.g. a + label), or it may just mean that the size was not + specified. */ + if (MSYMBOL_SIZE (&msymbol[hi]) == 0 + && best_zero_sized == -1) + { + best_zero_sized = hi; + hi--; + continue; + } + + /* If we are past the end of the current symbol, try + the previous symbol if it has a larger overlapping + size. This happens on i686-pc-linux-gnu with glibc; + the nocancel variants of system calls are inside + the cancellable variants, but both have sizes. */ + if (hi > 0 + && MSYMBOL_SIZE (&msymbol[hi]) != 0 + && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) + + MSYMBOL_SIZE (&msymbol[hi])) + && pc < (SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]) + + MSYMBOL_SIZE (&msymbol[hi - 1]))) + { + hi--; + continue; + } + + /* Otherwise, this symbol must be as good as we're going + to get. */ + break; + } + + /* If HI has a zero size, and best_zero_sized is set, + then we had two or more zero-sized symbols; prefer + the first one we found (which may have a higher + address). Also, if we ran off the end, be sure + to back up. */ + if (best_zero_sized != -1 + && (hi < 0 || MSYMBOL_SIZE (&msymbol[hi]) == 0)) + hi = best_zero_sized; + + /* If the minimal symbol has a non-zero size, and this + PC appears to be outside the symbol's contents, then + refuse to use this symbol. If we found a zero-sized + symbol with an address greater than this symbol's, + use that instead. We assume that if symbols have + specified sizes, they do not overlap. */ + + if (hi >= 0 + && MSYMBOL_SIZE (&msymbol[hi]) != 0 + && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) + + MSYMBOL_SIZE (&msymbol[hi]))) + { + if (best_zero_sized != -1) + hi = best_zero_sized; + else + /* Go on to the next object file. */ + continue; + } + /* The minimal symbol indexed by hi now is the best one in this objfile's minimal symbol table. See if it is the best one overall. */ - /* Skip any absolute symbols. This is apparently what adb - and dbx do, and is needed for the CM-5. There are two - known possible problems: (1) on ELF, apparently end, edata, - etc. are absolute. Not sure ignoring them here is a big - deal, but if we want to use them, the fix would go in - elfread.c. (2) I think shared library entry points on the - NeXT are absolute. If we want special handling for this - it probably should be triggered by a special - mst_abs_or_lib or some such. */ - while (hi >= 0 - && msymbol[hi].type == mst_abs) - --hi; - - /* If "section" specified, skip any symbol from wrong section */ - /* This is the new code that distinguishes it from the old function */ - if (section) - while (hi >= 0 - /* 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 - && SYMBOL_BFD_SECTION (&msymbol[hi]) != section) - --hi; - if (hi >= 0 && ((best_symbol == NULL) || (SYMBOL_VALUE_ADDRESS (best_symbol) < @@ -494,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; } @@ -564,46 +786,48 @@ 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; - if (ms_type == mst_file_text) + /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into + the minimal symbols, because if there is also another symbol + at the same address (e.g. the first function of the file), + lookup_minimal_symbol_by_pc would have no way of getting the + right one. */ + if (ms_type == mst_file_text && name[0] == 'g' + && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0 + || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)) + return (NULL); + + /* 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)) { - /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into - the minimal symbols, because if there is also another symbol - at the same address (e.g. the first function of the file), - lookup_minimal_symbol_by_pc would have no way of getting the - right one. */ - if (name[0] == 'g' - && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0 - || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)) - return (NULL); - - { - const char *tempstring = name; - if (tempstring[0] == get_symbol_leading_char (objfile->obfd)) - ++tempstring; - if (strncmp (tempstring, "__gnu_compiled", 14) == 0) - return (NULL); - } + ++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; @@ -611,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, @@ -633,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. */ @@ -794,7 +1044,7 @@ build_minimal_symbol_hash_tables (struct objfile *objfile) add_minsym_to_hash_table (msym, objfile->msymbol_hash); msym->demangled_hash_next = 0; - if (SYMBOL_DEMANGLED_NAME (msym) != NULL) + if (SYMBOL_SEARCH_NAME (msym) != SYMBOL_LINKAGE_NAME (msym)) add_minsym_to_demangled_hash_table (msym, objfile->msymbol_demangled_hash); } @@ -831,7 +1081,6 @@ install_minimal_symbols (struct objfile *objfile) struct msym_bunch *bunch; struct minimal_symbol *msymbols; int alloc_count; - char leading_char; if (msym_count > 0) { @@ -859,18 +1108,11 @@ install_minimal_symbols (struct objfile *objfile) each bunch is full. */ mcount = objfile->minimal_symbol_count; - leading_char = get_symbol_leading_char (objfile->obfd); for (bunch = msym_bunch; bunch != NULL; bunch = bunch->next) { for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++) - { - msymbols[mcount] = bunch->contents[bindex]; - if (SYMBOL_LINKAGE_NAME (&msymbols[mcount])[0] == leading_char) - { - SYMBOL_LINKAGE_NAME (&msymbols[mcount])++; - } - } + msymbols[mcount] = bunch->contents[bindex]; msym_bunch_index = BUNCH_SIZE; } @@ -899,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); @@ -924,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) { @@ -958,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; @@ -976,7 +1225,7 @@ lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc) a duplicate function in case this matters someday. */ CORE_ADDR -find_solib_trampoline_target (CORE_ADDR pc) +find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc) { struct objfile *objfile; struct minimal_symbol *msymbol; @@ -990,6 +1239,23 @@ find_solib_trampoline_target (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;