* gcore.c: Include solib.h.
authorJoseph Myers <joseph@codesourcery.com>
Tue, 1 Dec 2009 22:46:15 +0000 (22:46 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 1 Dec 2009 22:46:15 +0000 (22:46 +0000)
(gcore_create_callback): Call solib_keep_data_in_core when
considering not saving memory in core file.
* solib-svr4.c (svr4_keep_data_in_core): New.
(_initialize_svr4_solib): Initialize
svr4_so_ops.keep_data_in_core.
* solib.c (solib_keep_data_in_core): New.
* solib.h (solib_keep_data_in_core): Declare.
* solist.h (struct target_so_ops): Add keep_data_in_core.

gdb/ChangeLog
gdb/gcore.c
gdb/solib-svr4.c
gdb/solib.c
gdb/solib.h
gdb/solist.h

index 2cf92a9a799daaeeafd6e21b53d5433f58093332..613db8031a5106fafaa1d1649bc2b8b899a1e1ef 100644 (file)
@@ -1,3 +1,15 @@
+2009-12-01  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcore.c: Include solib.h.
+       (gcore_create_callback): Call solib_keep_data_in_core when
+       considering not saving memory in core file.
+       * solib-svr4.c (svr4_keep_data_in_core): New.
+       (_initialize_svr4_solib): Initialize
+       svr4_so_ops.keep_data_in_core.
+       * solib.c (solib_keep_data_in_core): New.
+       * solib.h (solib_keep_data_in_core): Declare.
+       * solist.h (struct target_so_ops): Add keep_data_in_core.
+
 2009-11-30  Joseph Myers  <joseph@codesourcery.com>
 
        * configure: Regenerate.
index d1f8b4933cbb500a7214d39aaabb334021fab0a8..6d6ca47d146ed530c8acfecc6e0330af42836937 100644 (file)
@@ -24,6 +24,7 @@
 #include "inferior.h"
 #include "gdbcore.h"
 #include "objfiles.h"
+#include "solib.h"
 #include "symfile.h"
 #include "arch-utils.h"
 #include "completer.h"
@@ -389,7 +390,7 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
       return 0;
     }
 
-  if (write == 0)
+  if (write == 0 && !solib_keep_data_in_core (vaddr, size))
     {
       /* See if this region of memory lies inside a known file on disk.
         If so, we can avoid copying its contents by clearing SEC_LOAD.  */
index 21055f678d6eb8765c75b319acb16c34e331234d..4bc459c6c11fbfdbd090ad60ab120663a2ea8b70 100644 (file)
@@ -866,6 +866,50 @@ solib_svr4_r_ldsomap (struct svr4_info *info)
                                    ptr_type);
 }
 
+/* On Solaris systems with some versions of the dynamic linker,
+   ld.so's l_name pointer points to the SONAME in the string table
+   rather than into writable memory.  So that GDB can find shared
+   libraries when loading a core file generated by gcore, ensure that
+   memory areas containing the l_name string are saved in the core
+   file.  */
+
+static int
+svr4_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+{
+  struct svr4_info *info;
+  CORE_ADDR ldsomap;
+  struct so_list *new;
+  struct cleanup *old_chain;
+  struct link_map_offsets *lmo;
+  CORE_ADDR lm_name;
+
+  info = get_svr4_info ();
+
+  info->debug_base = 0;
+  locate_base (info);
+  if (!info->debug_base)
+    return 0;
+
+  ldsomap = solib_svr4_r_ldsomap (info);
+  if (!ldsomap)
+    return 0;
+
+  lmo = svr4_fetch_link_map_offsets ();
+  new = XZALLOC (struct so_list);
+  old_chain = make_cleanup (xfree, new);
+  new->lm_info = xmalloc (sizeof (struct lm_info));
+  make_cleanup (xfree, new->lm_info);
+  new->lm_info->l_addr = (CORE_ADDR)-1;
+  new->lm_info->lm_addr = ldsomap;
+  new->lm_info->lm = xzalloc (lmo->link_map_size);
+  make_cleanup (xfree, new->lm_info->lm);
+  read_memory (ldsomap, new->lm_info->lm, lmo->link_map_size);
+  lm_name = LM_NAME (new);
+  do_cleanups (old_chain);
+
+  return (lm_name >= vaddr && lm_name < vaddr + size);
+}
+
 /*
 
   LOCAL FUNCTION
@@ -1918,4 +1962,5 @@ _initialize_svr4_solib (void)
   svr4_so_ops.bfd_open = solib_bfd_open;
   svr4_so_ops.lookup_lib_global_symbol = elf_lookup_lib_symbol;
   svr4_so_ops.same = svr4_same;
+  svr4_so_ops.keep_data_in_core = svr4_keep_data_in_core;
 }
index 6ad22fed2d52cc2571807ab802044775be809d20..e563512a991ced43433c521b7f60b78f12ad4680 100644 (file)
@@ -948,6 +948,23 @@ solib_name_from_address (struct program_space *pspace, CORE_ADDR address)
   return (0);
 }
 
+/* Return whether the data starting at VADDR, size SIZE, must be kept
+   in a core file for shared libraries loaded before "gcore" is used
+   to be handled correctly when the core file is loaded.  This only
+   applies when the section would otherwise not be kept in the core
+   file (in particular, for readonly sections).  */
+
+int
+solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size)
+{
+  struct target_so_ops *ops = solib_ops (target_gdbarch);
+
+  if (ops->keep_data_in_core)
+    return ops->keep_data_in_core (vaddr, size);
+  else
+    return 0;
+}
+
 /* Called by free_all_symtabs */
 
 void
index fee8d1c4434bbe395405066c8faa10e535c52122..c12de944e7b1df3250c51893b222dddbdc95abf0 100644 (file)
@@ -52,6 +52,14 @@ extern char *solib_name_from_address (struct program_space *, CORE_ADDR);
 
 extern int solib_contains_address_p (const struct so_list *, CORE_ADDR);
 
+/* Return whether the data starting at VADDR, size SIZE, must be kept
+   in a core file for shared libraries loaded before "gcore" is used
+   to be handled correctly when the core file is loaded.  This only
+   applies when the section would otherwise not be kept in the core
+   file (in particular, for readonly sections).  */
+
+extern int solib_keep_data_in_core (CORE_ADDR vaddr, unsigned long size);
+
 /* Return 1 if PC lies in the dynamic symbol resolution code of the
    run time loader.  */
 
index 4c164e64834d36b98057aace496e1d72bf9243a3..4e8e88b9ce6b89c2eb69ca89bdfaddc97ab27353 100644 (file)
@@ -126,6 +126,14 @@ struct target_so_ops
        Falls back to using strcmp on so_original_name field when set
        to NULL.  */
     int (*same) (struct so_list *gdb, struct so_list *inferior);
+
+    /* Return whether a region of memory must be kept in a core file
+       for shared libraries loaded before "gcore" is used to be
+       handled correctly when the core file is loaded.  This only
+       applies when the section would otherwise not be kept in the
+       core file (in particular, for readonly sections).  */
+    int (*keep_data_in_core) (CORE_ADDR vaddr,
+                             unsigned long size);
   };
 
 /* Free the memory associated with a (so_list *).  */