]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gcore.c
Change all_objfiles adapter to be a method on program_space
[thirdparty/binutils-gdb.git] / gdb / gcore.c
CommitLineData
be4d1333 1/* Generate a core file for the inferior process.
1bac305b 2
42a4f53d 3 Copyright (C) 2001-2019 Free Software Foundation, Inc.
be4d1333
MS
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
be4d1333
MS
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
be4d1333
MS
19
20#include "defs.h"
d3420b2f
MK
21#include "elf-bfd.h"
22#include "infcall.h"
be4d1333
MS
23#include "inferior.h"
24#include "gdbcore.h"
be4d1333 25#include "objfiles.h"
de18c1d8 26#include "solib.h"
d3420b2f 27#include "symfile.h"
0156b218
MS
28#include "arch-utils.h"
29#include "completer.h"
30#include "gcore.h"
d3420b2f 31#include "cli/cli-decode.h"
0156b218
MS
32#include <fcntl.h>
33#include "regcache.h"
34#include "regset.h"
cbb099e8 35#include "gdb_bfd.h"
47ecca85 36#include "readline/tilde.h"
325fac50 37#include <algorithm>
bef155c3 38#include "common/gdb_unlinker.h"
26fcd5d7 39#include "byte-vector.h"
be4d1333 40
804e0f53
DJ
41/* The largest amount of memory to read from the target at once. We
42 must throttle it to limit the amount of memory used by GDB during
43 generate-core-file for programs with large resident data. */
44#define MAX_COPY_BYTES (1024 * 1024)
45
a78c2d62 46static const char *default_gcore_target (void);
d3420b2f
MK
47static enum bfd_architecture default_gcore_arch (void);
48static unsigned long default_gcore_mach (void);
49static int gcore_memory_sections (bfd *);
50
0156b218
MS
51/* create_gcore_bfd -- helper for gcore_command (exported).
52 Open a new bfd core file for output, and return the handle. */
be4d1333 53
192b62ce 54gdb_bfd_ref_ptr
85e1311a 55create_gcore_bfd (const char *filename)
be4d1333 56{
192b62ce 57 gdb_bfd_ref_ptr obfd (gdb_bfd_openw (filename, default_gcore_target ()));
d8734c88 58
192b62ce 59 if (obfd == NULL)
0156b218 60 error (_("Failed to open '%s' for output."), filename);
192b62ce
TT
61 bfd_set_format (obfd.get (), bfd_core);
62 bfd_set_arch_mach (obfd.get (), default_gcore_arch (), default_gcore_mach ());
0156b218
MS
63 return obfd;
64}
65
5fff78c4 66/* write_gcore_file_1 -- do the actual work of write_gcore_file. */
0156b218 67
5fff78c4
MM
68static void
69write_gcore_file_1 (bfd *obfd)
0156b218 70{
44287fd8 71 gdb::unique_xmalloc_ptr<char> note_data;
0156b218
MS
72 int note_size = 0;
73 asection *note_sec = NULL;
be4d1333 74
d3420b2f 75 /* An external target method must build the notes section. */
6432734d
UW
76 /* FIXME: uweigand/2011-10-06: All architectures that support core file
77 generation should be converted to gdbarch_make_corefile_notes; at that
78 point, the target vector method can be removed. */
f5656ead 79 if (!gdbarch_make_corefile_notes_p (target_gdbarch ()))
44287fd8 80 note_data.reset (target_make_corefile_notes (obfd, &note_size));
6432734d 81 else
44287fd8
TT
82 note_data.reset (gdbarch_make_corefile_notes (target_gdbarch (), obfd,
83 &note_size));
1d1f1ccb 84
6432734d
UW
85 if (note_data == NULL || note_size == 0)
86 error (_("Target does not support core file generation."));
be4d1333 87
d3420b2f 88 /* Create the note section. */
6432734d
UW
89 note_sec = bfd_make_section_anyway_with_flags (obfd, "note0",
90 SEC_HAS_CONTENTS
91 | SEC_READONLY
92 | SEC_ALLOC);
93 if (note_sec == NULL)
94 error (_("Failed to create 'note' section for corefile: %s"),
95 bfd_errmsg (bfd_get_error ()));
96
97 bfd_set_section_vma (obfd, note_sec, 0);
98 bfd_set_section_alignment (obfd, note_sec, 0);
99 bfd_set_section_size (obfd, note_sec, note_size);
be4d1333 100
d3420b2f 101 /* Now create the memory/load sections. */
be4d1333 102 if (gcore_memory_sections (obfd) == 0)
8a3fe4f8 103 error (_("gcore: failed to get corefile memory sections from target."));
be4d1333 104
d3420b2f 105 /* Write out the contents of the note section. */
44287fd8
TT
106 if (!bfd_set_section_contents (obfd, note_sec, note_data.get (), 0,
107 note_size))
6432734d 108 warning (_("writing note section (%s)"), bfd_errmsg (bfd_get_error ()));
0156b218
MS
109}
110
5fff78c4
MM
111/* write_gcore_file -- helper for gcore_command (exported).
112 Compose and write the corefile data to the core file. */
113
114void
115write_gcore_file (bfd *obfd)
116{
492d29ea 117 struct gdb_exception except = exception_none;
5fff78c4
MM
118
119 target_prepare_to_generate_core ();
120
492d29ea
PA
121 TRY
122 {
123 write_gcore_file_1 (obfd);
124 }
125 CATCH (e, RETURN_MASK_ALL)
126 {
127 except = e;
128 }
129 END_CATCH
5fff78c4
MM
130
131 target_done_generating_core ();
132
133 if (except.reason < 0)
134 throw_exception (except);
135}
136
0156b218
MS
137/* gcore_command -- implements the 'gcore' command.
138 Generate a core file from the inferior process. */
139
140static void
0b39b52e 141gcore_command (const char *args, int from_tty)
0156b218 142{
bef155c3 143 gdb::unique_xmalloc_ptr<char> corefilename;
0156b218
MS
144
145 /* No use generating a corefile without a target process. */
146 if (!target_has_execution)
147 noprocess ();
148
149 if (args && *args)
bef155c3 150 corefilename.reset (tilde_expand (args));
0156b218
MS
151 else
152 {
153 /* Default corefile name is "core.PID". */
e99b03dc 154 corefilename.reset (xstrprintf ("core.%d", inferior_ptid.pid ()));
be4d1333
MS
155 }
156
0156b218
MS
157 if (info_verbose)
158 fprintf_filtered (gdb_stdout,
bef155c3
TT
159 "Opening corefile '%s' for output.\n",
160 corefilename.get ());
0156b218
MS
161
162 /* Open the output file. */
bef155c3 163 gdb_bfd_ref_ptr obfd (create_gcore_bfd (corefilename.get ()));
0156b218 164
bef155c3
TT
165 /* Arrange to unlink the file on failure. */
166 gdb::unlinker unlink_file (corefilename.get ());
0156b218
MS
167
168 /* Call worker function. */
bef155c3 169 write_gcore_file (obfd.get ());
0156b218 170
d3420b2f 171 /* Succeeded. */
bef155c3 172 unlink_file.keep ();
1e351ed1 173
bef155c3 174 fprintf_filtered (gdb_stdout, "Saved corefile %s\n", corefilename.get ());
be4d1333
MS
175}
176
177static unsigned long
178default_gcore_mach (void)
179{
d3420b2f 180#if 1 /* See if this even matters... */
6dbdc4a3
MS
181 return 0;
182#else
1143fffb 183
f5656ead 184 const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ());
be4d1333
MS
185
186 if (bfdarch != NULL)
187 return bfdarch->mach;
be4d1333 188 if (exec_bfd == NULL)
8a3fe4f8 189 error (_("Can't find default bfd machine type (need execfile)."));
be4d1333
MS
190
191 return bfd_get_mach (exec_bfd);
6dbdc4a3 192#endif /* 1 */
be4d1333
MS
193}
194
195static enum bfd_architecture
196default_gcore_arch (void)
197{
f5656ead 198 const struct bfd_arch_info *bfdarch = gdbarch_bfd_arch_info (target_gdbarch ());
be4d1333
MS
199
200 if (bfdarch != NULL)
201 return bfdarch->arch;
be4d1333 202 if (exec_bfd == NULL)
8a3fe4f8 203 error (_("Can't find bfd architecture for corefile (need execfile)."));
be4d1333
MS
204
205 return bfd_get_arch (exec_bfd);
206}
207
a78c2d62 208static const char *
be4d1333
MS
209default_gcore_target (void)
210{
a78c2d62 211 /* The gdbarch may define a target to use for core files. */
f5656ead
TT
212 if (gdbarch_gcore_bfd_target_p (target_gdbarch ()))
213 return gdbarch_gcore_bfd_target (target_gdbarch ());
a78c2d62
UW
214
215 /* Otherwise, try to fall back to the exec_bfd target. This will probably
216 not work for non-ELF targets. */
be4d1333 217 if (exec_bfd == NULL)
6dbdc4a3
MS
218 return NULL;
219 else
220 return bfd_get_target (exec_bfd);
be4d1333
MS
221}
222
d3420b2f
MK
223/* Derive a reasonable stack segment by unwinding the target stack,
224 and store its limits in *BOTTOM and *TOP. Return non-zero if
225 successful. */
be4d1333 226
cbb83bd1 227static int
69db8bae 228derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
be4d1333 229{
be4d1333
MS
230 struct frame_info *fi, *tmp_fi;
231
d3420b2f
MK
232 gdb_assert (bottom);
233 gdb_assert (top);
be4d1333 234
d3420b2f 235 /* Can't succeed without stack and registers. */
be4d1333 236 if (!target_has_stack || !target_has_registers)
d3420b2f 237 return 0;
be4d1333 238
d3420b2f
MK
239 /* Can't succeed without current frame. */
240 fi = get_current_frame ();
241 if (fi == NULL)
242 return 0;
be4d1333 243
d3420b2f 244 /* Save frame pointer of TOS frame. */
8d357cca 245 *top = get_frame_base (fi);
d3420b2f 246 /* If current stack pointer is more "inner", use that instead. */
40a6adc1 247 if (gdbarch_inner_than (get_frame_arch (fi), get_frame_sp (fi), *top))
fb4443d8 248 *top = get_frame_sp (fi);
be4d1333 249
d3420b2f 250 /* Find prev-most frame. */
be4d1333
MS
251 while ((tmp_fi = get_prev_frame (fi)) != NULL)
252 fi = tmp_fi;
253
d3420b2f 254 /* Save frame pointer of prev-most frame. */
8d357cca 255 *bottom = get_frame_base (fi);
be4d1333 256
d3420b2f
MK
257 /* Now canonicalize their order, so that BOTTOM is a lower address
258 (as opposed to a lower stack frame). */
be4d1333
MS
259 if (*bottom > *top)
260 {
d3420b2f
MK
261 bfd_vma tmp_vma;
262
be4d1333
MS
263 tmp_vma = *top;
264 *top = *bottom;
265 *bottom = tmp_vma;
266 }
267
d3420b2f 268 return 1;
be4d1333
MS
269}
270
0156b218
MS
271/* call_target_sbrk --
272 helper function for derive_heap_segment. */
273
274static bfd_vma
275call_target_sbrk (int sbrk_arg)
276{
277 struct objfile *sbrk_objf;
278 struct gdbarch *gdbarch;
279 bfd_vma top_of_heap;
280 struct value *target_sbrk_arg;
281 struct value *sbrk_fn, *ret;
282 bfd_vma tmp;
283
3b7344d5 284 if (lookup_minimal_symbol ("sbrk", NULL, NULL).minsym != NULL)
0156b218
MS
285 {
286 sbrk_fn = find_function_in_inferior ("sbrk", &sbrk_objf);
287 if (sbrk_fn == NULL)
288 return (bfd_vma) 0;
289 }
3b7344d5 290 else if (lookup_minimal_symbol ("_sbrk", NULL, NULL).minsym != NULL)
0156b218
MS
291 {
292 sbrk_fn = find_function_in_inferior ("_sbrk", &sbrk_objf);
293 if (sbrk_fn == NULL)
294 return (bfd_vma) 0;
295 }
296 else
297 return (bfd_vma) 0;
298
299 gdbarch = get_objfile_arch (sbrk_objf);
300 target_sbrk_arg = value_from_longest (builtin_type (gdbarch)->builtin_int,
301 sbrk_arg);
302 gdb_assert (target_sbrk_arg);
e71585ff 303 ret = call_function_by_hand (sbrk_fn, NULL, target_sbrk_arg);
0156b218
MS
304 if (ret == NULL)
305 return (bfd_vma) 0;
306
307 tmp = value_as_long (ret);
308 if ((LONGEST) tmp <= 0 || (LONGEST) tmp == 0xffffffff)
309 return (bfd_vma) 0;
310
311 top_of_heap = tmp;
312 return top_of_heap;
313}
314
d3420b2f
MK
315/* Derive a reasonable heap segment for ABFD by looking at sbrk and
316 the static data sections. Store its limits in *BOTTOM and *TOP.
317 Return non-zero if successful. */
be4d1333 318
cbb83bd1 319static int
69db8bae 320derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
be4d1333
MS
321{
322 bfd_vma top_of_data_memory = 0;
323 bfd_vma top_of_heap = 0;
324 bfd_size_type sec_size;
be4d1333
MS
325 bfd_vma sec_vaddr;
326 asection *sec;
327
d3420b2f
MK
328 gdb_assert (bottom);
329 gdb_assert (top);
be4d1333 330
d3420b2f
MK
331 /* This function depends on being able to call a function in the
332 inferior. */
be4d1333 333 if (!target_has_execution)
d3420b2f
MK
334 return 0;
335
336 /* The following code assumes that the link map is arranged as
337 follows (low to high addresses):
be4d1333 338
d3420b2f
MK
339 ---------------------------------
340 | text sections |
341 ---------------------------------
342 | data sections (including bss) |
343 ---------------------------------
344 | heap |
345 --------------------------------- */
be4d1333
MS
346
347 for (sec = abfd->sections; sec; sec = sec->next)
348 {
d3420b2f
MK
349 if (bfd_get_section_flags (abfd, sec) & SEC_DATA
350 || strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
be4d1333
MS
351 {
352 sec_vaddr = bfd_get_section_vma (abfd, sec);
2c500098 353 sec_size = bfd_get_section_size (sec);
be4d1333
MS
354 if (sec_vaddr + sec_size > top_of_data_memory)
355 top_of_data_memory = sec_vaddr + sec_size;
356 }
357 }
d3420b2f 358
0156b218
MS
359 top_of_heap = call_target_sbrk (0);
360 if (top_of_heap == (bfd_vma) 0)
be4d1333 361 return 0;
be4d1333 362
d3420b2f 363 /* Return results. */
be4d1333
MS
364 if (top_of_heap > top_of_data_memory)
365 {
366 *bottom = top_of_data_memory;
367 *top = top_of_heap;
d3420b2f 368 return 1;
be4d1333 369 }
d3420b2f
MK
370
371 /* No additional heap space needs to be saved. */
372 return 0;
be4d1333
MS
373}
374
be4d1333
MS
375static void
376make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
377{
378 int p_flags = 0;
0156b218 379 int p_type = 0;
be4d1333
MS
380
381 /* FIXME: these constants may only be applicable for ELF. */
61012eef 382 if (startswith (bfd_section_name (obfd, osec), "load"))
be4d1333 383 p_type = PT_LOAD;
61012eef 384 else if (startswith (bfd_section_name (obfd, osec), "note"))
be4d1333 385 p_type = PT_NOTE;
0156b218
MS
386 else
387 p_type = PT_NULL;
be4d1333
MS
388
389 p_flags |= PF_R; /* Segment is readable. */
390 if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
391 p_flags |= PF_W; /* Segment is writable. */
392 if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
393 p_flags |= PF_X; /* Segment is executable. */
394
d3420b2f 395 bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0, 0, 0, 1, &osec);
be4d1333
MS
396}
397
4f69f4c2
JK
398/* find_memory_region_ftype implementation. DATA is 'bfd *' for the core file
399 GDB is creating. */
400
cbb83bd1 401static int
4f69f4c2
JK
402gcore_create_callback (CORE_ADDR vaddr, unsigned long size, int read,
403 int write, int exec, int modified, void *data)
be4d1333 404{
9a3c8263 405 bfd *obfd = (bfd *) data;
be4d1333 406 asection *osec;
cbb83bd1
RM
407 flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
408
86fbe6cc
EZ
409 /* If the memory segment has no permissions set, ignore it, otherwise
410 when we later try to access it for read/write, we'll get an error
411 or jam the kernel. */
4f69f4c2 412 if (read == 0 && write == 0 && exec == 0 && modified == 0)
86fbe6cc
EZ
413 {
414 if (info_verbose)
415 {
5af949e3 416 fprintf_filtered (gdb_stdout, "Ignore segment, %s bytes at %s\n",
f5656ead 417 plongest (size), paddress (target_gdbarch (), vaddr));
86fbe6cc
EZ
418 }
419
420 return 0;
421 }
422
4f69f4c2 423 if (write == 0 && modified == 0 && !solib_keep_data_in_core (vaddr, size))
cbb83bd1
RM
424 {
425 /* See if this region of memory lies inside a known file on disk.
426 If so, we can avoid copying its contents by clearing SEC_LOAD. */
cbb83bd1
RM
427 struct obj_section *objsec;
428
2030c079 429 for (objfile *objfile : current_program_space->objfiles ())
3b9d3ac2
TT
430 ALL_OBJFILE_OSECTIONS (objfile, objsec)
431 {
432 bfd *abfd = objfile->obfd;
433 asection *asec = objsec->the_bfd_section;
434 bfd_vma align = (bfd_vma) 1 << bfd_get_section_alignment (abfd,
435 asec);
436 bfd_vma start = obj_section_addr (objsec) & -align;
437 bfd_vma end = (obj_section_endaddr (objsec) + align - 1) & -align;
438
439 /* Match if either the entire memory region lies inside the
440 section (i.e. a mapping covering some pages of a large
441 segment) or the entire section lies inside the memory region
442 (i.e. a mapping covering multiple small sections).
443
444 This BFD was synthesized from reading target memory,
445 we don't want to omit that. */
446 if (objfile->separate_debug_objfile_backlink == NULL
447 && ((vaddr >= start && vaddr + size <= end)
448 || (start >= vaddr && end <= vaddr + size))
449 && !(bfd_get_file_flags (abfd) & BFD_IN_MEMORY))
450 {
451 flags &= ~(SEC_LOAD | SEC_HAS_CONTENTS);
452 goto keep; /* Break out of two nested for loops. */
453 }
454 }
cbb83bd1 455
4f69f4c2 456 keep:;
cbb83bd1
RM
457 }
458
4f69f4c2
JK
459 if (write == 0)
460 flags |= SEC_READONLY;
461
cbb83bd1
RM
462 if (exec)
463 flags |= SEC_CODE;
464 else
465 flags |= SEC_DATA;
be4d1333 466
52b57208 467 osec = bfd_make_section_anyway_with_flags (obfd, "load", flags);
d3420b2f 468 if (osec == NULL)
be4d1333 469 {
8a3fe4f8 470 warning (_("Couldn't make gcore segment: %s"),
be4d1333 471 bfd_errmsg (bfd_get_error ()));
cbb83bd1 472 return 1;
be4d1333
MS
473 }
474
475 if (info_verbose)
476 {
5af949e3 477 fprintf_filtered (gdb_stdout, "Save segment, %s bytes at %s\n",
f5656ead 478 plongest (size), paddress (target_gdbarch (), vaddr));
be4d1333
MS
479 }
480
481 bfd_set_section_size (obfd, osec, size);
cbb83bd1 482 bfd_set_section_vma (obfd, osec, vaddr);
d3420b2f 483 bfd_section_lma (obfd, osec) = 0; /* ??? bfd_set_section_lma? */
cbb83bd1 484 return 0;
be4d1333
MS
485}
486
b427c1bc
TT
487int
488objfile_find_memory_regions (struct target_ops *self,
489 find_memory_region_ftype func, void *obfd)
be4d1333 490{
d3420b2f 491 /* Use objfile data to create memory sections. */
be4d1333
MS
492 struct obj_section *objsec;
493 bfd_vma temp_bottom, temp_top;
494
d3420b2f 495 /* Call callback function for each objfile section. */
2030c079 496 for (objfile *objfile : current_program_space->objfiles ())
3b9d3ac2
TT
497 ALL_OBJFILE_OSECTIONS (objfile, objsec)
498 {
499 bfd *ibfd = objfile->obfd;
500 asection *isec = objsec->the_bfd_section;
501 flagword flags = bfd_get_section_flags (ibfd, isec);
502
503 /* Separate debug info files are irrelevant for gcore. */
504 if (objfile->separate_debug_objfile_backlink != NULL)
505 continue;
506
507 if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
508 {
509 int size = bfd_section_size (ibfd, isec);
510 int ret;
511
512 ret = (*func) (obj_section_addr (objsec), size,
513 1, /* All sections will be readable. */
514 (flags & SEC_READONLY) == 0, /* Writable. */
515 (flags & SEC_CODE) != 0, /* Executable. */
516 1, /* MODIFIED is unknown, pass it as true. */
517 obfd);
518 if (ret != 0)
519 return ret;
520 }
521 }
be4d1333 522
d3420b2f 523 /* Make a stack segment. */
be4d1333 524 if (derive_stack_segment (&temp_bottom, &temp_top))
cbb83bd1 525 (*func) (temp_bottom, temp_top - temp_bottom,
d3420b2f
MK
526 1, /* Stack section will be readable. */
527 1, /* Stack section will be writable. */
528 0, /* Stack section will not be executable. */
4f69f4c2 529 1, /* Stack section will be modified. */
be4d1333
MS
530 obfd);
531
0963b4bd 532 /* Make a heap segment. */
be4d1333 533 if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
d3420b2f
MK
534 (*func) (temp_bottom, temp_top - temp_bottom,
535 1, /* Heap section will be readable. */
536 1, /* Heap section will be writable. */
537 0, /* Heap section will not be executable. */
4f69f4c2 538 1, /* Heap section will be modified. */
be4d1333 539 obfd);
d3420b2f 540
be4d1333
MS
541 return 0;
542}
543
544static void
545gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
546{
804e0f53
DJ
547 bfd_size_type size, total_size = bfd_section_size (obfd, osec);
548 file_ptr offset = 0;
be4d1333 549
cbb83bd1
RM
550 /* Read-only sections are marked; we don't have to copy their contents. */
551 if ((bfd_get_section_flags (obfd, osec) & SEC_LOAD) == 0)
d3420b2f
MK
552 return;
553
554 /* Only interested in "load" sections. */
61012eef 555 if (!startswith (bfd_section_name (obfd, osec), "load"))
d3420b2f 556 return;
be4d1333 557
325fac50 558 size = std::min (total_size, (bfd_size_type) MAX_COPY_BYTES);
26fcd5d7 559 gdb::byte_vector memhunk (size);
be4d1333 560
804e0f53
DJ
561 while (total_size > 0)
562 {
563 if (size > total_size)
564 size = total_size;
565
566 if (target_read_memory (bfd_section_vma (obfd, osec) + offset,
26fcd5d7 567 memhunk.data (), size) != 0)
804e0f53 568 {
3e43a32a
MS
569 warning (_("Memory read failed for corefile "
570 "section, %s bytes at %s."),
5af949e3 571 plongest (size),
f5656ead 572 paddress (target_gdbarch (), bfd_section_vma (obfd, osec)));
804e0f53
DJ
573 break;
574 }
26fcd5d7
TT
575 if (!bfd_set_section_contents (obfd, osec, memhunk.data (),
576 offset, size))
804e0f53
DJ
577 {
578 warning (_("Failed to write corefile contents (%s)."),
579 bfd_errmsg (bfd_get_error ()));
580 break;
581 }
582
583 total_size -= size;
584 offset += size;
585 }
be4d1333
MS
586}
587
588static int
589gcore_memory_sections (bfd *obfd)
590{
35c2fab7 591 /* Try gdbarch method first, then fall back to target method. */
f5656ead
TT
592 if (!gdbarch_find_memory_regions_p (target_gdbarch ())
593 || gdbarch_find_memory_regions (target_gdbarch (),
35c2fab7
UW
594 gcore_create_callback, obfd) != 0)
595 {
596 if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
597 return 0; /* FIXME: error return/msg? */
598 }
be4d1333 599
d3420b2f 600 /* Record phdrs for section-to-segment mapping. */
be4d1333
MS
601 bfd_map_over_sections (obfd, make_output_phdrs, NULL);
602
d3420b2f 603 /* Copy memory region contents. */
be4d1333
MS
604 bfd_map_over_sections (obfd, gcore_copy_callback, NULL);
605
d3420b2f 606 return 1;
be4d1333
MS
607}
608
609void
610_initialize_gcore (void)
611{
1bedd215 612 add_com ("generate-core-file", class_files, gcore_command, _("\
d3420b2f 613Save a core file with the current state of the debugged process.\n\
0cab2f1e
TT
614Usage: generate-core-file [FILENAME]\n\
615Argument is optional filename. Default filename is 'core.PROCESS_ID'."));
be4d1333
MS
616
617 add_com_alias ("gcore", "generate-core-file", class_files, 1);
be4d1333 618}