summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog12
-rw-r--r--gdb/gcore.c3
-rw-r--r--gdb/solib-svr4.c45
-rw-r--r--gdb/solib.c17
-rw-r--r--gdb/solib.h8
-rw-r--r--gdb/solist.h8
6 files changed, 92 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 2cf92a9a799..613db8031a5 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/gcore.c b/gdb/gcore.c
index d1f8b4933cb..6d6ca47d146 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -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. */
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 21055f678d6..4bc459c6c11 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -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;
}
diff --git a/gdb/solib.c b/gdb/solib.c
index 6ad22fed2d5..e563512a991 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -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
diff --git a/gdb/solib.h b/gdb/solib.h
index fee8d1c4434..c12de944e7b 100644
--- a/gdb/solib.h
+++ b/gdb/solib.h
@@ -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. */
diff --git a/gdb/solist.h b/gdb/solist.h
index 4c164e64834..4e8e88b9ce6 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -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 *). */