/* Generate a core file for the inferior process.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2012 Free Software Foundation, Inc.
This file is part of GDB.
#include "inferior.h"
#include "gdbcore.h"
#include "objfiles.h"
+#include "solib.h"
#include "symfile.h"
#include "arch-utils.h"
#include "completer.h"
create_gcore_bfd (char *filename)
{
bfd *obfd = bfd_openw (filename, default_gcore_target ());
+
if (!obfd)
error (_("Failed to open '%s' for output."), filename);
bfd_set_format (obfd, bfd_core);
asection *note_sec = NULL;
/* An external target method must build the notes section. */
- note_data = target_make_corefile_notes (obfd, ¬e_size);
+ /* FIXME: uweigand/2011-10-06: All architectures that support core file
+ generation should be converted to gdbarch_make_corefile_notes; at that
+ point, the target vector method can be removed. */
+ if (!gdbarch_make_corefile_notes_p (target_gdbarch))
+ note_data = target_make_corefile_notes (obfd, ¬e_size);
+ else
+ note_data = gdbarch_make_corefile_notes (target_gdbarch, obfd, ¬e_size);
- /* Create the note section. */
- if (note_data != NULL && note_size != 0)
- {
- note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
- SEC_HAS_CONTENTS
- | SEC_READONLY
- | SEC_ALLOC);
- if (note_sec == NULL)
- error (_("Failed to create 'note' section for corefile: %s"),
- bfd_errmsg (bfd_get_error ()));
+ if (note_data == NULL || note_size == 0)
+ error (_("Target does not support core file generation."));
- bfd_set_section_vma (obfd, note_sec, 0);
- bfd_set_section_alignment (obfd, note_sec, 0);
- bfd_set_section_size (obfd, note_sec, note_size);
- }
+ /* Create the note section. */
+ note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
+ SEC_HAS_CONTENTS
+ | SEC_READONLY
+ | SEC_ALLOC);
+ if (note_sec == NULL)
+ error (_("Failed to create 'note' section for corefile: %s"),
+ bfd_errmsg (bfd_get_error ()));
+
+ bfd_set_section_vma (obfd, note_sec, 0);
+ bfd_set_section_alignment (obfd, note_sec, 0);
+ bfd_set_section_size (obfd, note_sec, note_size);
/* Now create the memory/load sections. */
if (gcore_memory_sections (obfd) == 0)
error (_("gcore: failed to get corefile memory sections from target."));
/* Write out the contents of the note section. */
- if (note_data != NULL && note_size != 0)
- {
- if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
- warning (_("writing note section (%s)"),
- bfd_errmsg (bfd_get_error ()));
- }
+ if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
+ warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
+}
+
+static void
+do_bfd_delete_cleanup (void *arg)
+{
+ bfd *obfd = arg;
+ const char *filename = obfd->filename;
+
+ bfd_close (arg);
+ unlink (filename);
}
/* gcore_command -- implements the 'gcore' command.
/* Open the output file. */
obfd = create_gcore_bfd (corefilename);
- /* Need a cleanup that will close the file (FIXME: delete it?). */
- old_chain = make_cleanup_bfd_close (obfd);
+ /* Need a cleanup that will close and delete the file. */
+ old_chain = make_cleanup (do_bfd_delete_cleanup, obfd);
/* Call worker function. */
write_gcore_file (obfd);
/* Succeeded. */
fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename);
- /* Clean-ups will close the output file and free malloc memory. */
- do_cleanups (old_chain);
- return;
+ discard_cleanups (old_chain);
+ bfd_close (obfd);
}
static unsigned long
static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
- struct gdbarch *gdbarch;
bfd_vma top_of_data_memory = 0;
bfd_vma top_of_heap = 0;
bfd_size_type sec_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. */
asec);
bfd_vma start = obj_section_addr (objsec) & -align;
bfd_vma end = (obj_section_endaddr (objsec) + align - 1) & -align;
+
/* Match if either the entire memory region lies inside the
section (i.e. a mapping covering some pages of a large
segment) or the entire section lies inside the memory region
|| (start >= vaddr && end <= vaddr + size))
&& !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
{
- flags &= ~SEC_LOAD;
- flags |= SEC_NEVER_LOAD;
- goto keep; /* break out of two nested for loops */
+ flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
+ goto keep; /* Break out of two nested for loops. */
}
}
}
static int
-objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
- int, int, int, void *),
- void *obfd)
+objfile_find_memory_regions (find_memory_region_ftype func, void *obfd)
{
/* Use objfile data to create memory sections. */
struct objfile *objfile;
bfd *ibfd = objfile->obfd;
asection *isec = objsec->the_bfd_section;
flagword flags = bfd_get_section_flags (ibfd, isec);
- int ret;
if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
{
int size = bfd_section_size (ibfd, isec);
int ret;
- ret = (*func) (obj_section_addr (objsec), bfd_section_size (ibfd, isec),
+ ret = (*func) (obj_section_addr (objsec), size,
1, /* All sections will be readable. */
(flags & SEC_READONLY) == 0, /* Writable. */
(flags & SEC_CODE) != 0, /* Executable. */
0, /* Stack section will not be executable. */
obfd);
- /* Make a heap segment. */
+ /* Make a heap segment. */
if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
(*func) (temp_bottom, temp_top - temp_bottom,
1, /* Heap section will be readable. */
size = min (total_size, MAX_COPY_BYTES);
memhunk = xmalloc (size);
- /* ??? This is crap since xmalloc should never return NULL. */
- if (memhunk == NULL)
- error (_("Not enough memory to create corefile."));
old_chain = make_cleanup (xfree, memhunk);
while (total_size > 0)
if (target_read_memory (bfd_section_vma (obfd, osec) + offset,
memhunk, size) != 0)
{
- warning (_("Memory read failed for corefile section, %s bytes at %s."),
+ warning (_("Memory read failed for corefile "
+ "section, %s bytes at %s."),
plongest (size),
paddress (target_gdbarch, bfd_section_vma (obfd, osec)));
break;
static int
gcore_memory_sections (bfd *obfd)
{
- if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
- return 0; /* FIXME: error return/msg? */
+ /* Try gdbarch method first, then fall back to target method. */
+ if (!gdbarch_find_memory_regions_p (target_gdbarch)
+ || gdbarch_find_memory_regions (target_gdbarch,
+ gcore_create_callback, obfd) != 0)
+ {
+ if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
+ return 0; /* FIXME: error return/msg? */
+ }
/* Record phdrs for section-to-segment mapping. */
bfd_map_over_sections (obfd, make_output_phdrs, NULL);