- bfd_size_type size = bfd_section_size (obfd, osec);
- struct cleanup *old_chain = NULL;
- void *memhunk;
-
- if (size == 0)
- return; /* Read-only sections are marked as zero-size.
- We don't have to copy their contents. */
- if (strncmp ("load", bfd_get_section_name (obfd, osec), 4) != 0)
- return; /* Only interested in "load" sections. */
-
- if ((memhunk = xmalloc (size)) == NULL)
- error ("Not enough memory to create corefile.");
- old_chain = make_cleanup (xfree, memhunk);
-
- 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).",
- bfd_errmsg (bfd_get_error ()));
-
- do_cleanups (old_chain); /* frees the xmalloc buffer */
+ bfd_size_type size, total_size = bfd_section_size (obfd, osec);
+ file_ptr offset = 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. */
+ if (!startswith (bfd_section_name (obfd, osec), "load"))
+ return;
+
+ size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES);
+ gdb::byte_vector memhunk (size);
+
+ while (total_size > 0)
+ {
+ if (size > total_size)
+ size = total_size;
+
+ if (target_read_memory (bfd_section_vma (obfd, osec) + offset,
+ memhunk.data (), size) != 0)
+ {
+ warning (_("Memory read failed for corefile "
+ "section, %s bytes at %s."),
+ plongest (size),
+ paddress (target_gdbarch (), bfd_section_vma (obfd, osec)));
+ break;
+ }
+ if (!bfd_set_section_contents (obfd, osec, memhunk.data (),
+ offset, size))
+ {
+ warning (_("Failed to write corefile contents (%s)."),
+ bfd_errmsg (bfd_get_error ()));
+ break;
+ }
+
+ total_size -= size;
+ offset += size;
+ }