Index: gdb/gcore.c |
diff --git a/gdb/gcore.c b/gdb/gcore.c |
index aedda412eb6771adccb86983cdb977a4c3ccd748..49f9b2204b0be2fef9630d93e2b2826d56e196d6 100644 |
--- a/gdb/gcore.c |
+++ b/gdb/gcore.c |
@@ -1,6 +1,6 @@ |
/* Generate a core file for the inferior process. |
- Copyright (C) 2001-2012 Free Software Foundation, Inc. |
+ Copyright (C) 2001-2013 Free Software Foundation, Inc. |
This file is part of GDB. |
@@ -33,6 +33,8 @@ |
#include <fcntl.h> |
#include "regcache.h" |
#include "regset.h" |
+#include "gdb_bfd.h" |
+#include "readline/tilde.h" |
/* The largest amount of memory to read from the target at once. We |
must throttle it to limit the amount of memory used by GDB during |
@@ -48,9 +50,9 @@ static int gcore_memory_sections (bfd *); |
Open a new bfd core file for output, and return the handle. */ |
bfd * |
-create_gcore_bfd (char *filename) |
+create_gcore_bfd (const char *filename) |
{ |
- bfd *obfd = bfd_openw (filename, default_gcore_target ()); |
+ bfd *obfd = gdb_bfd_openw (filename, default_gcore_target ()); |
if (!obfd) |
error (_("Failed to open '%s' for output."), filename); |
@@ -74,10 +76,10 @@ write_gcore_file (bfd *obfd) |
/* 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)) |
+ 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); |
+ note_data = gdbarch_make_corefile_notes (target_gdbarch (), obfd, ¬e_size); |
if (note_data == NULL || note_size == 0) |
error (_("Target does not support core file generation.")); |
@@ -110,7 +112,7 @@ do_bfd_delete_cleanup (void *arg) |
bfd *obfd = arg; |
const char *filename = obfd->filename; |
- bfd_close (arg); |
+ gdb_bfd_unref (arg); |
unlink (filename); |
} |
@@ -120,8 +122,9 @@ do_bfd_delete_cleanup (void *arg) |
static void |
gcore_command (char *args, int from_tty) |
{ |
- struct cleanup *old_chain; |
- char *corefilename, corefilename_buffer[40]; |
+ struct cleanup *filename_chain; |
+ struct cleanup *bfd_chain; |
+ char *corefilename; |
bfd *obfd; |
/* No use generating a corefile without a target process. */ |
@@ -129,13 +132,13 @@ gcore_command (char *args, int from_tty) |
noprocess (); |
if (args && *args) |
- corefilename = args; |
+ corefilename = tilde_expand (args); |
else |
{ |
/* Default corefile name is "core.PID". */ |
- sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid)); |
- corefilename = corefilename_buffer; |
+ corefilename = xstrprintf ("core.%d", ptid_get_pid (inferior_ptid)); |
} |
+ filename_chain = make_cleanup (xfree, corefilename); |
if (info_verbose) |
fprintf_filtered (gdb_stdout, |
@@ -145,16 +148,17 @@ gcore_command (char *args, int from_tty) |
obfd = create_gcore_bfd (corefilename); |
/* Need a cleanup that will close and delete the file. */ |
- old_chain = make_cleanup (do_bfd_delete_cleanup, obfd); |
+ bfd_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); |
+ discard_cleanups (bfd_chain); |
+ gdb_bfd_unref (obfd); |
- discard_cleanups (old_chain); |
- bfd_close (obfd); |
+ fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename); |
+ do_cleanups (filename_chain); |
} |
static unsigned long |
@@ -164,7 +168,7 @@ default_gcore_mach (void) |
return 0; |
#else |
- const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch); |
+ const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ()); |
if (bfdarch != NULL) |
return bfdarch->mach; |
@@ -178,7 +182,7 @@ default_gcore_mach (void) |
static enum bfd_architecture |
default_gcore_arch (void) |
{ |
- const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch); |
+ const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ()); |
if (bfdarch != NULL) |
return bfdarch->arch; |
@@ -192,8 +196,8 @@ static const char * |
default_gcore_target (void) |
{ |
/* The gdbarch may define a target to use for core files. */ |
- if (gdbarch_gcore_bfd_target_p (target_gdbarch)) |
- return gdbarch_gcore_bfd_target (target_gdbarch); |
+ if (gdbarch_gcore_bfd_target_p (target_gdbarch ())) |
+ return gdbarch_gcore_bfd_target (target_gdbarch ()); |
/* Otherwise, try to fall back to the exec_bfd target. This will probably |
not work for non-ELF targets. */ |
@@ -378,9 +382,12 @@ make_output_phdrs (bfd *obfd, asection *osec, void *ignored) |
bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec); |
} |
+/* find_memory_region_ftype implementation. DATA is 'bfd *' for the core file |
+ GDB is creating. */ |
+ |
static int |
-gcore_create_callback (CORE_ADDR vaddr, unsigned long size, |
- int read, int write, int exec, void *data) |
+gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read, |
+ int write, int exec, int modified, void *data) |
{ |
bfd *obfd = data; |
asection *osec; |
@@ -389,18 +396,18 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, |
/* If the memory segment has no permissions set, ignore it, otherwise |
when we later try to access it for read/write, we'll get an error |
or jam the kernel. */ |
- if (read == 0 && write == 0 && exec == 0) |
+ if (read == 0 && write == 0 && exec == 0 && modified == 0) |
{ |
if (info_verbose) |
{ |
fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at %s\n", |
- plongest (size), paddress (target_gdbarch, vaddr)); |
+ plongest (size), paddress (target_gdbarch (), vaddr)); |
} |
return 0; |
} |
- if (write == 0 && !solib_keep_data_in_core (vaddr, size)) |
+ if (write == 0 && modified == 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. */ |
@@ -423,8 +430,9 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, |
This BFD was synthesized from reading target memory, |
we don't want to omit that. */ |
- if (((vaddr >= start && vaddr + size <= end) |
- || (start >= vaddr && end <= vaddr + size)) |
+ if (objfile->separate_debug_objfile_backlink == NULL |
+ && ((vaddr >= start && vaddr + size <= end) |
+ || (start >= vaddr && end <= vaddr + size)) |
&& !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY)) |
{ |
flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS); |
@@ -432,10 +440,12 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, |
} |
} |
- keep: |
- flags |= SEC_READONLY; |
+ keep:; |
} |
+ if (write == 0) |
+ flags |= SEC_READONLY; |
+ |
if (exec) |
flags |= SEC_CODE; |
else |
@@ -452,7 +462,7 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, |
if (info_verbose) |
{ |
fprintf_filtered (gdb_stdout, "Save segment, %s bytes at %s\n", |
- plongest (size), paddress (target_gdbarch, vaddr)); |
+ plongest (size), paddress (target_gdbarch (), vaddr)); |
} |
bfd_set_section_size (obfd, osec, size); |
@@ -476,6 +486,10 @@ objfile_find_memory_regions (find_memory_region_ftype func, void *obfd) |
asection *isec = objsec->the_bfd_section; |
flagword flags = bfd_get_section_flags (ibfd, isec); |
+ /* Separate debug info files are irrelevant for gcore. */ |
+ if (objfile->separate_debug_objfile_backlink != NULL) |
+ continue; |
+ |
if ((flags & SEC_ALLOC) || (flags & SEC_LOAD)) |
{ |
int size = bfd_section_size (ibfd, isec); |
@@ -485,6 +499,7 @@ objfile_find_memory_regions (find_memory_region_ftype func, void *obfd) |
1, /* All sections will be readable. */ |
(flags & SEC_READONLY) == 0, /* Writable. */ |
(flags & SEC_CODE) != 0, /* Executable. */ |
+ 1, /* MODIFIED is unknown, pass it as true. */ |
obfd); |
if (ret != 0) |
return ret; |
@@ -497,6 +512,7 @@ objfile_find_memory_regions (find_memory_region_ftype func, void *obfd) |
1, /* Stack section will be readable. */ |
1, /* Stack section will be writable. */ |
0, /* Stack section will not be executable. */ |
+ 1, /* Stack section will be modified. */ |
obfd); |
/* Make a heap segment. */ |
@@ -505,6 +521,7 @@ objfile_find_memory_regions (find_memory_region_ftype func, void *obfd) |
1, /* Heap section will be readable. */ |
1, /* Heap section will be writable. */ |
0, /* Heap section will not be executable. */ |
+ 1, /* Heap section will be modified. */ |
obfd); |
return 0; |
@@ -541,7 +558,7 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored) |
warning (_("Memory read failed for corefile " |
"section, %s bytes at %s."), |
plongest (size), |
- paddress (target_gdbarch, bfd_section_vma (obfd, osec))); |
+ paddress (target_gdbarch (), bfd_section_vma (obfd, osec))); |
break; |
} |
if (!bfd_set_section_contents (obfd, osec, memhunk, offset, size)) |
@@ -562,8 +579,8 @@ static int |
gcore_memory_sections (bfd *obfd) |
{ |
/* Try gdbarch method first, then fall back to target method. */ |
- if (!gdbarch_find_memory_regions_p (target_gdbarch) |
- || gdbarch_find_memory_regions (target_gdbarch, |
+ 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) |