+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.
#include "inferior.h"
#include "gdbcore.h"
#include "objfiles.h"
+#include "solib.h"
#include "symfile.h"
#include "arch-utils.h"
#include "completer.h"
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. */
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
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;
}
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
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. */
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 *). */