return ops;
}
-static struct target_so_ops *
+static const struct target_so_ops *
solib_ops (struct gdbarch *gdbarch)
{
- struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+ const struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
return *ops;
}
/* Set the solib operations for GDBARCH to NEW_OPS. */
void
-set_solib_ops (struct gdbarch *gdbarch, struct target_so_ops *new_ops)
+set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
{
- struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+ const struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
*ops = new_ops;
}
char *
solib_find (char *in_pathname, int *fd)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
int found_file = -1;
char *temp_pathname = NULL;
int gdb_sysroot_is_empty;
{
int need_dir_separator;
- need_dir_separator = !IS_DIR_SEPARATOR (in_pathname[0]);
+ /* Concatenate the sysroot and the target reported filename. We
+ may need to glue them with a directory separator. Cases to
+ consider:
+
+ | sysroot | separator | in_pathname |
+ |-----------------+-----------+----------------|
+ | /some/dir | / | c:/foo/bar.dll |
+ | /some/dir | | /foo/bar.dll |
+ | remote: | | c:/foo/bar.dll |
+ | remote: | | /foo/bar.dll |
+ | remote:some/dir | / | c:/foo/bar.dll |
+ | remote:some/dir | | /foo/bar.dll |
+
+ IOW, we don't need to add a separator if IN_PATHNAME already
+ has one, or when the the sysroot is exactly "remote:".
+ There's no need to check for drive spec explicitly, as we only
+ get here if IN_PATHNAME is considered an absolute path. */
+ need_dir_separator = !(IS_DIR_SEPARATOR (in_pathname[0])
+ || strcmp (REMOTE_SYSROOT_PREFIX, sysroot) == 0);
/* Cat the prefixed pathname together. */
temp_pathname = concat (sysroot,
/* 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,
+ found_file = openp (solib_search_path,
+ OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
in_pathname, O_RDONLY | O_BINARY, &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,
+ found_file = openp (solib_search_path,
+ OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
target_lbasename (fskind, in_pathname),
O_RDONLY | O_BINARY, &temp_pathname);
if (found_file < 0 && gdb_sysroot_is_empty)
found_file = openp (get_in_environ (current_inferior ()->environment,
"PATH"),
- OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY,
- &temp_pathname);
+ OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
+ O_RDONLY | O_BINARY, &temp_pathname);
/* If not found, next search the inferior's $LD_LIBRARY_PATH
environment variable. */
if (found_file < 0 && gdb_sysroot_is_empty)
found_file = openp (get_in_environ (current_inferior ()->environment,
"LD_LIBRARY_PATH"),
- OPF_TRY_CWD_FIRST, in_pathname, O_RDONLY | O_BINARY,
- &temp_pathname);
+ OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
+ O_RDONLY | O_BINARY, &temp_pathname);
*fd = found_file;
return temp_pathname;
static int
solib_map_sections (struct so_list *so)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
char *filename;
struct target_section *p;
struct cleanup *old_chain;
return 1;
}
-/* Free symbol-file related contents of SO. If we have opened a BFD
- for SO, close it. If we have placed SO's sections in some target's
- section table, the caller is responsible for removing them.
+/* Free symbol-file related contents of SO and reset for possible reloading
+ of SO. If we have opened a BFD for SO, close it. If we have placed SO's
+ sections in some target's section table, the caller is responsible for
+ removing them.
This function doesn't mess with objfiles at all. If there is an
objfile associated with SO that needs to be removed, the caller is
responsible for taking care of that. */
static void
-free_so_symbols (struct so_list *so)
+clear_so (struct so_list *so)
{
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
+
if (so->sections)
{
xfree (so->sections);
/* Restore the target-supplied file name. SO_NAME may be the path
of the symbol file. */
strcpy (so->so_name, so->so_original_name);
+
+ /* Do the same for target-specific data. */
+ if (ops->clear_so != NULL)
+ ops->clear_so (so);
}
/* Free the storage associated with the `struct so_list' object SO.
void
free_so (struct so_list *so)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
- free_so_symbols (so);
+ clear_so (so);
ops->free_so (so);
xfree (so);
/* Have we already loaded this shared object? */
ALL_OBJFILES (so->objfile)
{
- if (filename_cmp (so->objfile->name, so->so_name) == 0
+ if (filename_cmp (objfile_name (so->objfile), so->so_name) == 0
&& so->objfile->addr_low == so->addr_low)
break;
}
sap = build_section_addr_info_from_section_table (so->sections,
so->sections_end);
- so->objfile = symbol_file_add_from_bfd (so->abfd,
+ so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
flags, sap, OBJF_SHARED,
NULL);
so->objfile->addr_low = so->addr_low;
static void
update_solib_list (int from_tty, struct target_ops *target)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
struct so_list *inferior = ops->current_sos();
struct so_list *gdb, **gdb_link;
/* Some targets' section tables might be referring to
sections from so->abfd; remove them. */
- remove_target_sections (gdb, gdb->abfd);
+ remove_target_sections (gdb);
free_so (gdb);
gdb = *gdb_link;
if (loaded_any_symbols)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
/* Getting new symbols may change our opinion about what is
frameless. */
int
solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
if (ops->keep_data_in_core)
return ops->keep_data_in_core (vaddr, size);
void
clear_solib (void)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const 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
so_list_head = so->next;
observer_notify_solib_unloaded (so);
- if (so->abfd)
- remove_target_sections (so, so->abfd);
+ remove_target_sections (so);
free_so (so);
}
void
solib_create_inferior_hook (int from_tty)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
ops->solib_create_inferior_hook (from_tty);
}
int
in_solib_dynsym_resolve_code (CORE_ADDR pc)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
return ops->in_dynsym_resolve_code (pc);
}
objfile_purge_solibs ();
}
+/* See solib.h. */
+
+void
+update_solib_breakpoints (void)
+{
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
+
+ if (ops->update_breakpoints != NULL)
+ ops->update_breakpoints ();
+}
+
+/* See solib.h. */
+
+void
+handle_solib_event (void)
+{
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
+
+ if (ops->handle_event != NULL)
+ ops->handle_event ();
+
+ clear_program_space_solib_cache (current_inferior ()->pspace);
+
+ /* Check for any newly added shared libraries if we're supposed to
+ be adding them automatically. Switch terminal for any messages
+ produced by breakpoint_re_set. */
+ target_terminal_ours_for_output ();
+ solib_add (NULL, 0, ¤t_target, auto_solib_add);
+ target_terminal_inferior ();
+}
+
/* Reload shared libraries, but avoid reloading the same symbol file
we already have loaded. */
if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED)
&& !solib_used (so))
free_objfile (so->objfile);
- remove_target_sections (so, so->abfd);
- free_so_symbols (so);
+ remove_target_sections (so);
+ clear_so (so);
}
/* If this shared library is now associated with a new symbol
reload_shared_libraries (char *ignored, int from_tty,
struct cmd_list_element *e)
{
- struct target_so_ops *ops;
+ const struct target_so_ops *ops;
reload_shared_libraries_1 (from_tty);
const char *name,
const domain_enum domain)
{
- struct target_so_ops *ops = solib_ops (target_gdbarch ());
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
if (ops->lookup_lib_global_symbol != NULL)
return ops->lookup_lib_global_symbol (objfile, name, domain);