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