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