PR ld/16021
[deliverable/binutils-gdb.git] / gdb / solib.c
index 72db375b0d8fdf88c9dd61a77c55443462e7b175..8ed492a4136f18e6de854e6d43ca6e7c0debf8a1 100644 (file)
@@ -64,10 +64,10 @@ solib_init (struct obstack *obstack)
   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;
 }
@@ -75,9 +75,9 @@ solib_ops (struct gdbarch *gdbarch)
 /* 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;
 }
@@ -144,7 +144,7 @@ show_solib_search_path (struct ui_file *file, int from_tty,
 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;
@@ -230,7 +230,25 @@ solib_find (char *in_pathname, int *fd)
     {
       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,
@@ -318,14 +336,16 @@ solib_find (char *in_pathname, int *fd)
 
   /* 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);
 
@@ -338,16 +358,16 @@ solib_find (char *in_pathname, int *fd)
   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;
@@ -449,7 +469,7 @@ solib_bfd_open (char *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;
@@ -511,7 +531,7 @@ solib_map_sections (struct so_list *so)
 static void
 clear_so (struct so_list *so)
 {
-  struct target_so_ops *ops = solib_ops (target_gdbarch ());
+  const struct target_so_ops *ops = solib_ops (target_gdbarch ());
 
   if (so->sections)
     {
@@ -551,7 +571,7 @@ clear_so (struct so_list *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 ());
 
   clear_so (so);
   ops->free_so (so);
@@ -598,7 +618,7 @@ solib_read_symbols (struct so_list *so, int flags)
          /* 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;
            }
@@ -607,7 +627,7 @@ solib_read_symbols (struct so_list *so, int flags)
 
          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;
@@ -670,7 +690,7 @@ solib_used (const struct so_list *const known)
 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;
 
@@ -769,7 +789,7 @@ update_solib_list (int from_tty, struct target_ops *target)
 
          /* 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;
@@ -932,7 +952,7 @@ solib_add (char *pattern, int from_tty,
 
     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.  */
@@ -1105,7 +1125,7 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
 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);
@@ -1118,7 +1138,7 @@ solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long 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
@@ -1150,8 +1170,7 @@ clear_solib (void)
 
       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);
     }
 
@@ -1166,7 +1185,7 @@ clear_solib (void)
 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);
 }
@@ -1177,7 +1196,7 @@ solib_create_inferior_hook (int 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);
 }
@@ -1208,6 +1227,37 @@ no_shared_libraries (char *ignored, int from_tty)
   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, &current_target, auto_solib_add);
+  target_terminal_inferior ();
+}
+
 /* Reload shared libraries, but avoid reloading the same symbol file
    we already have loaded.  */
 
@@ -1244,7 +1294,7 @@ reload_shared_libraries_1 (int from_tty)
          if (so->objfile && ! (so->objfile->flags & OBJF_USERLOADED)
              && !solib_used (so))
            free_objfile (so->objfile);
-         remove_target_sections (so, so->abfd);
+         remove_target_sections (so);
          clear_so (so);
        }
 
@@ -1275,7 +1325,7 @@ static void
 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);
 
@@ -1342,7 +1392,7 @@ solib_global_lookup (const struct objfile *objfile,
                     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);
This page took 0.027196 seconds and 4 git commands to generate.