/* Handle shared libraries for GDB, the GNU Debugger.
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
+ 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2008
+ Free Software Foundation, Inc.
This file is part of GDB.
#include "solist.h"
#include "observer.h"
#include "readline/readline.h"
+#include "remote.h"
/* Architecture-specific operations. */
GLOBAL FUNCTION
- solib_open -- Find a shared library file and open it.
+ solib_bfd_open -- Find a shared library file and open BFD for it.
SYNOPSIS
- int solib_open (char *in_patname, char **found_pathname);
+ struct bfd *solib_open (char *in_pathname);
DESCRIPTION
RETURNS
- file handle for opened solib, or -1 for failure. */
+ BFD file handle for opened solib; throws error on failure. */
-int
-solib_open (char *in_pathname, char **found_pathname)
+bfd *
+solib_bfd_open (char *in_pathname)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
int found_file = -1;
char *temp_pathname = NULL;
char *p = in_pathname;
int gdb_sysroot_is_empty;
+ bfd *abfd;
gdb_sysroot_is_empty = (gdb_sysroot == NULL || *gdb_sysroot == 0);
strcat (temp_pathname, in_pathname);
}
+ /* Handle remote files. */
+ if (remote_filename_p (temp_pathname))
+ {
+ temp_pathname = xstrdup (temp_pathname);
+ abfd = remote_bfd_open (temp_pathname, gnutarget);
+ if (!abfd)
+ {
+ make_cleanup (xfree, temp_pathname);
+ error (_("Could not open `%s' as an executable file: %s"),
+ temp_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ bfd_close (abfd);
+ make_cleanup (xfree, temp_pathname);
+ error (_("`%s': not in executable format: %s"),
+ temp_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ return abfd;
+ }
+
/* Now see if we can open it. */
found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
- /* Done. If not found, tough luck. Return found_file and
- (optionally) found_pathname. */
- if (temp_pathname)
+ /* Done. If still not found, error. */
+ if (found_file < 0)
+ perror_with_name (in_pathname);
+
+ /* Leave temp_pathname allocated. abfd->name will point to it. */
+ abfd = bfd_fopen (temp_pathname, gnutarget, FOPEN_RB, found_file);
+ if (!abfd)
{
- if (found_pathname != NULL)
- *found_pathname = temp_pathname;
- else
- xfree (temp_pathname);
+ close (found_file);
+ make_cleanup (xfree, temp_pathname);
+ error (_("Could not open `%s' as an executable file: %s"),
+ temp_pathname, bfd_errmsg (bfd_get_error ()));
}
- return found_file;
+
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ bfd_close (abfd);
+ make_cleanup (xfree, temp_pathname);
+ error (_("`%s': not in executable format: %s"),
+ temp_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ bfd_set_cacheable (abfd, 1);
+ return abfd;
}
{
struct so_list *so = (struct so_list *) arg; /* catch_errors bogon */
char *filename;
- char *scratch_pathname;
- int scratch_chan;
struct section_table *p;
struct cleanup *old_chain;
bfd *abfd;
filename = tilde_expand (so->so_name);
-
old_chain = make_cleanup (xfree, filename);
- scratch_chan = solib_open (filename, &scratch_pathname);
-
- if (scratch_chan < 0)
- {
- perror_with_name (filename);
- }
-
- /* Leave scratch_pathname allocated. abfd->name will point to it. */
- abfd = bfd_fopen (scratch_pathname, gnutarget, FOPEN_RB, scratch_chan);
- if (!abfd)
- {
- close (scratch_chan);
- error (_("Could not open `%s' as an executable file: %s"),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
+ abfd = solib_bfd_open (filename);
+ do_cleanups (old_chain);
/* Leave bfd open, core_xfer_memory and "info files" need it. */
so->abfd = abfd;
- bfd_set_cacheable (abfd, 1);
/* copy full path name into so_name, so that later symbol_file_add
can find it */
- if (strlen (scratch_pathname) >= SO_NAME_MAX_PATH_SIZE)
- error (_("Full path name length of shared library exceeds SO_NAME_MAX_PATH_SIZE in so_list structure."));
- strcpy (so->so_name, scratch_pathname);
+ if (strlen (bfd_get_filename (abfd)) >= SO_NAME_MAX_PATH_SIZE)
+ error (_("Shared library file name is too long."));
+ strcpy (so->so_name, bfd_get_filename (abfd));
- if (!bfd_check_format (abfd, bfd_object))
- {
- error (_("\"%s\": not in executable format: %s."),
- scratch_pathname, bfd_errmsg (bfd_get_error ()));
- }
if (build_section_table (abfd, &so->sections, &so->sections_end))
{
error (_("Can't find the file sections in `%s': %s"),
for (p = so->sections; p < so->sections_end; p++)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
/* Relocate the section binding addresses as recorded in the shared
object's file by the base address to which the object was actually
}
}
- /* Free the file names, close the file now. */
- do_cleanups (old_chain);
-
return (1);
}
void
free_so (struct so_list *so)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
char *bfd_filename = 0;
if (so->sections)
"Error while reading shared library symbols:\n",
RETURN_MASK_ALL))
{
- if (from_tty)
+ if (from_tty && print_symbol_loading)
printf_unfiltered (_("Loaded symbols for %s\n"), so->so_name);
so->symbols_loaded = 1;
return 1;
static void
update_solib_list (int from_tty, struct target_ops *target)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
struct so_list *inferior = ops->current_sos();
struct so_list *gdb, **gdb_link;
- /* If we are attaching to a running process for which we
- have not opened a symbol file, we may be able to get its
- symbols now! */
- if (attach_flag &&
- symfile_objfile == NULL)
- catch_errors (ops->open_symbol_file_object, &from_tty,
- "Error reading attached process's symbol file.\n",
- RETURN_MASK_ALL);
+ /* We can reach here due to changing solib-search-path or the
+ sysroot, before having any inferior. */
+ if (target_has_execution && !ptid_equal (inferior_ptid, null_ptid))
+ {
+ struct inferior *inf = current_inferior ();
+
+ /* If we are attaching to a running process for which we
+ have not opened a symbol file, we may be able to get its
+ symbols now! */
+ if (inf->attach_flag && symfile_objfile == NULL)
+ catch_errors (ops->open_symbol_file_object, &from_tty,
+ "Error reading attached process's symbol file.\n",
+ RETURN_MASK_ALL);
+ }
/* GDB and the inferior's dynamic linker each maintain their own
list of currently loaded shared objects; we want to bring the
the inferior's current list. */
while (i)
{
- if (! strcmp (gdb->so_original_name, i->so_original_name))
- break;
+ if (ops->same)
+ {
+ if (ops->same (gdb, i))
+ break;
+ }
+ else
+ {
+ if (! strcmp (gdb->so_original_name, i->so_original_name))
+ break;
+ }
i_link = &i->next;
i = *i_link;
if (loaded_any_symbols)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
/* Getting new symbols may change our opinion about what is
frameless. */
int addr_width;
/* "0x", a little whitespace, and two hex digits per byte of pointers. */
- addr_width = 4 + (gdbarch_ptr_bit (current_gdbarch) / 4);
+ addr_width = 4 + (gdbarch_ptr_bit (target_gdbarch) / 4);
update_solib_list (from_tty, 0);
void
clear_solib (void)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
/* This function is expected to handle ELF shared libraries. It is
also used on Solaris, which can run either ELF or a.out binaries
void
solib_create_inferior_hook (void)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
ops->solib_create_inferior_hook();
}
int
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
return ops->in_dynsym_resolve_code (pc);
}
solib_global_lookup (const struct objfile *objfile,
const char *name,
const char *linkage_name,
- const domain_enum domain,
- struct symtab **symtab)
+ const domain_enum domain)
{
- struct target_so_ops *ops = solib_ops (current_gdbarch);
+ struct target_so_ops *ops = solib_ops (target_gdbarch);
if (ops->lookup_lib_global_symbol != NULL)
- return ops->lookup_lib_global_symbol (objfile, name, linkage_name,
- domain, symtab);
+ return ops->lookup_lib_global_symbol (objfile, name, linkage_name, domain);
return NULL;
}