+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+ struct minimal_symbol *found_file_symbol = NULL;
+
+ unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile->next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ for (msymbol = objfile->msymbol_hash[hash];
+ msymbol != NULL && found_symbol == NULL;
+ msymbol = msymbol->hash_next)
+ {
+ if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
+ (MSYMBOL_TYPE (msymbol) == mst_text ||
+ MSYMBOL_TYPE (msymbol) == mst_file_text))
+ {
+ switch (MSYMBOL_TYPE (msymbol))
+ {
+ case mst_file_text:
+ found_file_symbol = msymbol;
+ break;
+ default:
+ found_symbol = msymbol;
+ break;
+ }
+ }
+ }
+ }
+ }
+ /* External symbols are best. */
+ if (found_symbol)
+ return found_symbol;
+
+ /* File-local symbols are next best. */
+ if (found_file_symbol)
+ return found_file_symbol;
+
+ 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
+ pointer to the minimal symbol that matches, or NULL if no match is
+ found.
+
+ This function only searches the mangled (linkage) names. */
+
+struct minimal_symbol *
+lookup_minimal_symbol_solib_trampoline (const char *name,
+ struct objfile *objf)
+{
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *found_symbol = NULL;
+
+ unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+ for (objfile = object_files;
+ objfile != NULL && found_symbol == NULL;
+ objfile = objfile->next)
+ {
+ if (objf == NULL || objf == objfile)
+ {
+ for (msymbol = objfile->msymbol_hash[hash];
+ msymbol != NULL && found_symbol == NULL;
+ msymbol = msymbol->hash_next)
+ {
+ if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
+ MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
+ return msymbol;
+ }
+ }
+ }
+
+ 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)
+{
+ int lo;
+ int hi;
+ int new;
+ struct objfile *objfile;
+ struct minimal_symbol *msymbol;
+ struct minimal_symbol *best_symbol = NULL;
+ struct obj_section *pc_section;
+
+ /* 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;
+
+ /* If no section was specified, then just make sure that the PC is in
+ the same section as the minimal symbol we find. */
+ if (section == NULL)
+ section = pc_section->the_bfd_section;
+
+ /* FIXME drow/2003-07-19: Should we also check that PC is in SECTION
+ if we were passed a non-NULL SECTION argument? */