return NULL;
}
+/* Lookup the value for a specific symbol from dynamic symbol table. Look
+ up symbol from ABFD. MATCH_SYM is a callback function to determine
+ whether to pick up a symbol. DATA is the input of this callback
+ function. Return NULL if symbol is not found. */
+
+CORE_ADDR
+gdb_bfd_lookup_symbol_from_symtab (bfd *abfd,
+ int (*match_sym) (asymbol *, void *),
+ void *data)
+{
+ long storage_needed = bfd_get_symtab_upper_bound (abfd);
+ CORE_ADDR symaddr = 0;
+
+ if (storage_needed > 0)
+ {
+ unsigned int i;
+
+ asymbol **symbol_table = (asymbol **) xmalloc (storage_needed);
+ struct cleanup *back_to = make_cleanup (xfree, symbol_table);
+ unsigned int number_of_symbols =
+ bfd_canonicalize_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ asymbol *sym = *symbol_table++;
+
+ if (match_sym (sym, data))
+ {
+ /* BFD symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+
+ return symaddr;
+}
+
+/* Lookup the value for a specific symbol from symbol table. Look up symbol
+ from ABFD. MATCH_SYM is a callback function to determine whether to pick
+ up a symbol. DATA is the input of this callback function. Return NULL
+ if symbol is not found. */
+
+static CORE_ADDR
+bfd_lookup_symbol_from_dyn_symtab (bfd *abfd,
+ int (*match_sym) (asymbol *, void *),
+ void *data)
+{
+ long storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
+ CORE_ADDR symaddr = 0;
+
+ if (storage_needed > 0)
+ {
+ unsigned int i;
+ asymbol **symbol_table = (asymbol **) xmalloc (storage_needed);
+ struct cleanup *back_to = make_cleanup (xfree, symbol_table);
+ unsigned int number_of_symbols =
+ bfd_canonicalize_dynamic_symtab (abfd, symbol_table);
+
+ for (i = 0; i < number_of_symbols; i++)
+ {
+ asymbol *sym = *symbol_table++;
+
+ if (match_sym (sym, data))
+ {
+ /* BFD symbols are section relative. */
+ symaddr = sym->value + sym->section->vma;
+ break;
+ }
+ }
+ do_cleanups (back_to);
+ }
+ return symaddr;
+}
+
+/* Lookup the value for a specific symbol from symbol table and dynamic
+ symbol table. Look up symbol from ABFD. MATCH_SYM is a callback
+ function to determine whether to pick up a symbol. DATA is the
+ input of this callback function. Return NULL if symbol is not
+ found. */
+
+CORE_ADDR
+gdb_bfd_lookup_symbol (bfd *abfd,
+ int (*match_sym) (asymbol *, void *),
+ void *data)
+{
+ CORE_ADDR symaddr = gdb_bfd_lookup_symbol_from_symtab (abfd, match_sym, data);
+
+ /* On FreeBSD, the dynamic linker is stripped by default. So we'll
+ have to check the dynamic string table too. */
+ if (symaddr == 0)
+ symaddr = bfd_lookup_symbol_from_dyn_symtab (abfd, match_sym, data);
+
+ return symaddr;
+}
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */