/* Handle shared libraries for GDB, the GNU Debugger.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002, 2003, 2005
Free Software Foundation, Inc.
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. */
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
#include "defs.h"
#include "observer.h"
#include "readline/readline.h"
+/* Architecture-specific operations. */
+
+/* Per-architecture data key. */
+static struct gdbarch_data *solib_data;
+
+static void *
+solib_init (struct obstack *obstack)
+{
+ struct target_so_ops **ops;
+
+ ops = OBSTACK_ZALLOC (obstack, struct target_so_ops *);
+ *ops = current_target_so_ops;
+ return ops;
+}
+
+static struct target_so_ops *
+solib_ops (struct gdbarch *gdbarch)
+{
+ struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+ return *ops;
+}
+\f
+
/* external data declarations */
/* FIXME: gdbarch needs to control this variable */
symbol files. This takes precedence over the environment variables PATH
and LD_LIBRARY_PATH. */
static char *solib_search_path = NULL;
+static void
+show_solib_search_path (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("\
+The search path for loading non-absolute shared library symbol files is %s.\n"),
+ value);
+}
/*
int
solib_open (char *in_pathname, char **found_pathname)
{
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
int found_file = -1;
char *temp_pathname = NULL;
char *p = in_pathname;
}
/* Now see if we can open it. */
- found_file = open (temp_pathname, O_RDONLY, 0);
+ found_file = open (temp_pathname, O_RDONLY | O_BINARY, 0);
}
/* If the search in solib_absolute_prefix failed, and the path name is
/* If not found, search the solib_search_path (if any). */
if (found_file < 0 && solib_search_path != NULL)
found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
- in_pathname, O_RDONLY, 0, &temp_pathname);
+ in_pathname, O_RDONLY | O_BINARY, 0, &temp_pathname);
/* If not found, next search the solib_search_path (if any) for the basename
only (ignoring the path). This is to allow reading solibs from a path
that differs from the opened path. */
if (found_file < 0 && solib_search_path != NULL)
found_file = openp (solib_search_path, OPF_TRY_CWD_FIRST,
- lbasename (in_pathname), O_RDONLY, 0,
+ lbasename (in_pathname), O_RDONLY | O_BINARY, 0,
&temp_pathname);
/* If not found, try to use target supplied solib search method */
- if (found_file < 0 && TARGET_SO_FIND_AND_OPEN_SOLIB != NULL)
- found_file = TARGET_SO_FIND_AND_OPEN_SOLIB
- (in_pathname, O_RDONLY, &temp_pathname);
+ if (found_file < 0 && ops->find_and_open_solib)
+ found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY,
+ &temp_pathname);
/* If not found, next search the inferior's $PATH environment variable. */
if (found_file < 0 && solib_absolute_prefix == NULL)
found_file = openp (get_in_environ (inferior_environ, "PATH"),
- OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY, 0,
+ OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
/* If not found, next search the inferior's $LD_LIBRARY_PATH
environment variable. */
if (found_file < 0 && solib_absolute_prefix == NULL)
found_file = openp (get_in_environ (inferior_environ, "LD_LIBRARY_PATH"),
- OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY, 0,
+ OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY, 0,
&temp_pathname);
/* Done. If not found, tough luck. Return found_file and
}
/* Leave scratch_pathname allocated. abfd->name will point to it. */
- abfd = bfd_fdopenr (scratch_pathname, gnutarget, scratch_chan);
+ abfd = bfd_fopen (scratch_pathname, gnutarget, FOPEN_RB, scratch_chan);
if (!abfd)
{
close (scratch_chan);
for (p = so->sections; p < so->sections_end; p++)
{
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
+
/* Relocate the section binding addresses as recorded in the shared
object's file by the base address to which the object was actually
mapped. */
- TARGET_SO_RELOCATE_SECTION_ADDRESSES (so, p);
+ ops->relocate_section_addresses (so, p);
if (strcmp (p->the_bfd_section->name, ".text") == 0)
{
so->textsection = p;
void
free_so (struct so_list *so)
{
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
char *bfd_filename = 0;
if (so->sections)
if (bfd_filename)
xfree (bfd_filename);
- TARGET_SO_FREE_SO (so);
+ ops->free_so (so);
xfree (so);
}
static void
update_solib_list (int from_tty, struct target_ops *target)
{
- struct so_list *inferior = TARGET_SO_CURRENT_SOS ();
+ struct target_so_ops *ops = solib_ops (current_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
symbols now! */
if (attach_flag &&
symfile_objfile == NULL)
- catch_errors (TARGET_SO_OPEN_SYMBOL_FILE_OBJECT, &from_tty,
+ catch_errors (ops->open_symbol_file_object, &from_tty,
"Error reading attached process's symbol file.\n",
RETURN_MASK_ALL);
if (loaded_any_symbols)
{
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
+
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
- TARGET_SO_SPECIAL_SYMBOL_HANDLING ();
+ ops->special_symbol_handling ();
}
}
}
int header_done = 0;
int addr_width;
- if (TARGET_PTR_BIT == 32)
- addr_width = 8 + 4;
- else if (TARGET_PTR_BIT == 64)
- addr_width = 16 + 4;
- else
- {
- internal_error (__FILE__, __LINE__,
- _("TARGET_PTR_BIT returned unknown size %d"),
- TARGET_PTR_BIT);
- }
+ /* "0x", a little whitespace, and two hex digits per byte of pointers. */
+ addr_width = 4 + (TARGET_PTR_BIT / 4);
update_solib_list (from_tty, 0);
void
clear_solib (void)
{
+ struct target_so_ops *ops = solib_ops (current_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
(for compatibility with SunOS 4), both of which can use shared
free_so (so);
}
- TARGET_SO_CLEAR_SOLIB ();
+ ops->clear_solib ();
}
static void
void
solib_create_inferior_hook (void)
{
- TARGET_SO_SOLIB_CREATE_INFERIOR_HOOK ();
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
+ ops->solib_create_inferior_hook();
}
/* GLOBAL FUNCTION
int
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
- return TARGET_SO_IN_DYNSYM_RESOLVE_CODE (pc);
+ struct target_so_ops *ops = solib_ops (current_gdbarch);
+ return ops->in_dynsym_resolve_code (pc);
}
/*
solib_add (NULL, from_tty, NULL, auto_solib_add);
}
+static void
+show_auto_solib_add (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file, _("Autoloading of shared library symbols is %s.\n"),
+ value);
+}
+
+
extern initialize_file_ftype _initialize_solib; /* -Wmissing-prototypes */
void
{
struct cmd_list_element *c;
+ solib_data = gdbarch_data_register_pre_init (solib_init);
+
add_com ("sharedlibrary", class_files, sharedlibrary_command,
_("Load shared object library symbols for files matching REGEXP."));
add_info ("sharedlibrary", info_sharedlibrary_command,
informs gdb that a new library has been loaded, or when attaching to the\n\
inferior. Otherwise, symbols must be loaded manually, using `sharedlibrary'."),
NULL,
- NULL, /* FIXME: i18n: */
+ show_auto_solib_add,
&setlist, &showlist);
add_setshow_filename_cmd ("solib-absolute-prefix", class_support,
Show the search path for loading non-absolute shared library symbol files."), _("\
This takes precedence over the environment variables PATH and LD_LIBRARY_PATH."),
reload_shared_libraries,
- NULL, /* FIXME: i18n: */
+ show_solib_search_path,
&setlist, &showlist);
}