aboutsummaryrefslogtreecommitdiff
path: root/gdb/gcore.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-10-11 01:56:53 +0000
committerRoland McGrath <roland@gnu.org>2003-10-11 01:56:53 +0000
commitcbb83bd1ee373467c9e76feca9ef98f3b0de9154 (patch)
tree4664e4b5ab48c8d4925afb082fde0231b09b6905 /gdb/gcore.c
parentcb227dc0c28b1fc257913326341c5ba5fe8bb5a9 (diff)
downloadbinutils-cbb83bd1ee373467c9e76feca9ef98f3b0de9154.zip
binutils-cbb83bd1ee373467c9e76feca9ef98f3b0de9154.tar.gz
binutils-cbb83bd1ee373467c9e76feca9ef98f3b0de9154.tar.bz2
2003-10-08 Roland McGrath <roland@redhat.com>
* gcore.c (make_mem_sec): Function removed, folded into ... (gcore_create_callback): ... here. To omit a section, clear its SEC_LOAD bit rather than zeroing its size. Omit read-only sections only if they correspond to a known disk file. (gcore_copy_callback): Ignore sections without SEC_LOAD flag set.
Diffstat (limited to 'gdb/gcore.c')
-rw-r--r--gdb/gcore.c105
1 files changed, 61 insertions, 44 deletions
diff --git a/gdb/gcore.c b/gdb/gcore.c
index 709d469..d1525dd 100644
--- a/gdb/gcore.c
+++ b/gdb/gcore.c
@@ -62,7 +62,7 @@ gcore_command (char *args, int from_tty)
}
if (info_verbose)
- fprintf_filtered (gdb_stdout,
+ fprintf_filtered (gdb_stdout,
"Opening corefile '%s' for output.\n", corefilename);
/* Open the output file. */
@@ -84,11 +84,11 @@ gcore_command (char *args, int from_tty)
{
note_sec = bfd_make_section_anyway (obfd, "note0");
if (note_sec == NULL)
- error ("Failed to create 'note' section for corefile: %s",
+ 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_flags (obfd, note_sec,
+ bfd_set_section_flags (obfd, note_sec,
SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
bfd_set_section_alignment (obfd, note_sec, 0);
bfd_set_section_size (obfd, note_sec, note_size);
@@ -161,7 +161,7 @@ default_gcore_target (void)
and store its limits in *BOTTOM and *TOP. Return non-zero if
successful. */
-static int
+static int
derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
{
struct frame_info *fi, *tmp_fi;
@@ -209,7 +209,7 @@ derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
the static data sections. Store its limits in *BOTTOM and *TOP.
Return non-zero if successful. */
-static int
+static int
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
{
bfd_vma top_of_data_memory = 0;
@@ -306,55 +306,73 @@ make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
}
-static asection *
-make_mem_sec (bfd *obfd, bfd_vma addr, bfd_size_type size,
- unsigned int flags, unsigned int alignment)
+static int
+gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
+ int read, int write, int exec, void *data)
{
+ bfd *obfd = data;
asection *osec;
+ flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
+
+ if (write == 0)
+ {
+ /* 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. */
+ struct objfile *objfile;
+ struct obj_section *objsec;
+
+ ALL_OBJSECTIONS (objfile, objsec)
+ {
+ bfd *abfd = objfile->obfd;
+ asection *asec = objsec->the_bfd_section;
+ bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
+ asec);
+ bfd_vma start = objsec->addr & -align;
+ bfd_vma end = (objsec->endaddr + 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
+ (i.e. a mapping covering multiple small sections).
+
+ 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))
+ && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
+ {
+ flags &= ~SEC_LOAD;
+ goto keep; /* break out of two nested for loops */
+ }
+ }
+
+ keep:
+ flags |= SEC_READONLY;
+ }
+
+ if (exec)
+ flags |= SEC_CODE;
+ else
+ flags |= SEC_DATA;
osec = bfd_make_section_anyway (obfd, "load");
if (osec == NULL)
{
warning ("Couldn't make gcore segment: %s",
bfd_errmsg (bfd_get_error ()));
- return NULL;
+ return 1;
}
if (info_verbose)
{
fprintf_filtered (gdb_stdout, "Save segment, %lld bytes at 0x%s\n",
- (long long) size, paddr_nz (addr));
+ (long long) size, paddr_nz (vaddr));
}
bfd_set_section_size (obfd, osec, size);
- bfd_set_section_vma (obfd, osec, addr);
+ bfd_set_section_vma (obfd, osec, vaddr);
bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */
- bfd_set_section_alignment (obfd, osec, alignment);
- bfd_set_section_flags (obfd, osec,
- flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
- return osec;
-}
-
-static int
-gcore_create_callback (CORE_ADDR vaddr, unsigned long size,
- int read, int write, int exec, void *data)
-{
- flagword flags = 0;
-
- if (write == 0)
- {
- flags |= SEC_READONLY;
- /* Mark readonly sections as zero-sized, such that we can avoid
- copying their contents. */
- size = 0;
- }
-
- if (exec)
- flags |= SEC_CODE;
- else
- flags |= SEC_DATA;
-
- return ((make_mem_sec (data, vaddr, size, flags, 0)) == NULL);
+ bfd_set_section_flags (obfd, osec, flags);
+ return 0;
}
static int
@@ -380,7 +398,7 @@ objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
int size = bfd_section_size (ibfd, isec);
int ret;
- ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec),
+ ret = (*func) (objsec->addr, bfd_section_size (ibfd, isec),
1, /* All sections will be readable. */
(flags & SEC_READONLY) == 0, /* Writable. */
(flags & SEC_CODE) != 0, /* Executable. */
@@ -392,7 +410,7 @@ objfile_find_memory_regions (int (*func) (CORE_ADDR, unsigned long,
/* Make a stack segment. */
if (derive_stack_segment (&temp_bottom, &temp_top))
- (*func) (temp_bottom, temp_top - temp_bottom,
+ (*func) (temp_bottom, temp_top - temp_bottom,
1, /* Stack section will be readable. */
1, /* Stack section will be writable. */
0, /* Stack section will not be executable. */
@@ -416,9 +434,8 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
struct cleanup *old_chain = NULL;
void *memhunk;
- /* Read-only sections are marked as zero-size. We don't have to
- copy their contents. */
- if (size == 0)
+ /* Read-only sections are marked; we don't have to copy their contents. */
+ if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0)
return;
/* Only interested in "load" sections. */
@@ -431,12 +448,12 @@ gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
error ("Not enough memory to create corefile.");
old_chain = make_cleanup (xfree, memhunk);
- if (target_read_memory (bfd_section_vma (obfd, osec),
+ if (target_read_memory (bfd_section_vma (obfd, osec),
memhunk, size) != 0)
warning ("Memory read failed for corefile section, %ld bytes at 0x%s\n",
(long) size, paddr (bfd_section_vma (obfd, osec)));
if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
- warning ("Failed to write corefile contents (%s).",
+ warning ("Failed to write corefile contents (%s).",
bfd_errmsg (bfd_get_error ()));
do_cleanups (old_chain); /* Frees MEMHUNK. */