OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [gcore.c] - Blame information for rev 1775

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* Generate a core file for the inferior process.
2
   Copyright 2001, 2002 Free Software Foundation, Inc.
3
 
4
   This file is part of GDB.
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License as published by
8
   the Free Software Foundation; either version 2 of the License, or
9
   (at your option) any later version.
10
 
11
   This program is distributed in the hope that it will be useful,
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
   GNU General Public License for more details.
15
 
16
   You should have received a copy of the GNU General Public License
17
   along with this program; if not, write to the Free Software
18
   Foundation, Inc., 59 Temple Place - Suite 330,
19
   Boston, MA 02111-1307, USA.  */
20
 
21
#include "defs.h"
22
#include "cli/cli-decode.h"
23
#include "inferior.h"
24
#include "gdbcore.h"
25
#include "elf-bfd.h"
26
#include "symfile.h"
27
#include "objfiles.h"
28
 
29
static char                  *default_gcore_target (void);
30
static enum bfd_architecture  default_gcore_arch (void);
31
static unsigned long          default_gcore_mach (void);
32
static int                    gcore_memory_sections (bfd *);
33
 
34
/* Function: gcore_command
35
   Generate a core file from the inferior process.  */
36
 
37
static void
38
gcore_command (char *args, int from_tty)
39
{
40
  struct cleanup *old_chain;
41
  char *corefilename, corefilename_buffer[40];
42
  asection *note_sec = NULL;
43
  bfd *obfd;
44
  void *note_data = NULL;
45
  int note_size = 0;
46
 
47
  /* No use generating a corefile without a target process.  */
48
  if (!(target_has_execution))
49
    noprocess ();
50
 
51
  if (args && *args)
52
    corefilename = args;
53
  else
54
    {
55
      /* Default corefile name is "core.PID".  */
56
      sprintf (corefilename_buffer, "core.%d", PIDGET (inferior_ptid));
57
      corefilename = corefilename_buffer;
58
    }
59
 
60
  if (info_verbose)
61
    fprintf_filtered (gdb_stdout,
62
                      "Opening corefile '%s' for output.\n", corefilename);
63
 
64
  /* Open the output file. */
65
  if (!(obfd = bfd_openw (corefilename, default_gcore_target ())))
66
    {
67
      error ("Failed to open '%s' for output.", corefilename);
68
    }
69
 
70
  /* Need a cleanup that will close the file (FIXME: delete it?). */
71
  old_chain = make_cleanup_bfd_close (obfd);
72
 
73
  bfd_set_format (obfd, bfd_core);
74
  bfd_set_arch_mach (obfd, default_gcore_arch (), default_gcore_mach ());
75
 
76
  /* An external target method must build the notes section. */
77
  note_data = (char *) target_make_corefile_notes (obfd, &note_size);
78
 
79
  /* Create the note section. */
80
  if (note_data != NULL && note_size != 0)
81
    {
82
      if ((note_sec = bfd_make_section_anyway (obfd, "note0")) == NULL)
83
        error ("Failed to create 'note' section for corefile: %s",
84
               bfd_errmsg (bfd_get_error ()));
85
 
86
      bfd_set_section_vma (obfd, note_sec, 0);
87
      bfd_set_section_flags (obfd, note_sec,
88
                             SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC);
89
      bfd_set_section_alignment (obfd, note_sec, 0);
90
      bfd_set_section_size (obfd, note_sec, note_size);
91
    }
92
 
93
  /* Now create the memory/load sections. */
94
  if (gcore_memory_sections (obfd) == 0)
95
    error ("gcore: failed to get corefile memory sections from target.");
96
 
97
  /* Write out the contents of the note section. */
98
  if (note_data != NULL && note_size != 0)
99
    {
100
      if (!bfd_set_section_contents (obfd, note_sec, note_data, 0, note_size))
101
        {
102
          warning ("writing note section (%s)",
103
                   bfd_errmsg (bfd_get_error ()));
104
        }
105
    }
106
 
107
  /* Succeeded. */
108
  fprintf_filtered (gdb_stdout,
109
                    "Saved corefile %s\n", corefilename);
110
 
111
  /* Clean-ups will close the output file and free malloc memory. */
112
  do_cleanups (old_chain);
113
  return;
114
}
115
 
116
static unsigned long
117
default_gcore_mach (void)
118
{
119
#if 1   /* See if this even matters... */
120
  return 0;
121
#else
122
#ifdef TARGET_ARCHITECTURE
123
  const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
124
 
125
  if (bfdarch != NULL)
126
    return bfdarch->mach;
127
#endif /* TARGET_ARCHITECTURE */
128
  if (exec_bfd == NULL)
129
    error ("Can't find default bfd machine type (need execfile).");
130
 
131
  return bfd_get_mach (exec_bfd);
132
#endif /* 1 */
133
}
134
 
135
static enum bfd_architecture
136
default_gcore_arch (void)
137
{
138
#ifdef TARGET_ARCHITECTURE
139
  const struct bfd_arch_info * bfdarch = TARGET_ARCHITECTURE;
140
 
141
  if (bfdarch != NULL)
142
    return bfdarch->arch;
143
#endif
144
  if (exec_bfd == NULL)
145
    error ("Can't find bfd architecture for corefile (need execfile).");
146
 
147
  return bfd_get_arch (exec_bfd);
148
}
149
 
150
static char *
151
default_gcore_target (void)
152
{
153
  /* FIXME -- this may only work for ELF targets.  */
154
  if (exec_bfd == NULL)
155
    return NULL;
156
  else
157
    return bfd_get_target (exec_bfd);
158
}
159
 
160
/* Function: derive_stack_segment
161
 
162
   Derive a reasonable stack segment by unwinding the target stack.
163
 
164
   Returns 0 for failure, 1 for success.  */
165
 
166
static int
167
derive_stack_segment (bfd_vma *bottom, bfd_vma *top)
168
{
169
  bfd_vma tmp_vma;
170
  struct frame_info *fi, *tmp_fi;
171
 
172
  if (bottom == NULL || top == NULL)
173
    return 0;    /* Paranoia. */
174
 
175
  if (!target_has_stack || !target_has_registers)
176
    return 0;    /* Can't succeed without stack and registers. */
177
 
178
  if ((fi = get_current_frame ()) == NULL)
179
    return 0;    /* Can't succeed without current frame. */
180
 
181
  /* Save frame pointer of TOS frame. */
182
  *top = fi->frame;
183
  /* If current stack pointer is more "inner", use that instead. */
184
  if (INNER_THAN (read_sp (), *top))
185
    *top = read_sp ();
186
 
187
  /* Find prev-most frame. */
188
  while ((tmp_fi = get_prev_frame (fi)) != NULL)
189
    fi = tmp_fi;
190
 
191
  /* Save frame pointer of prev-most frame. */
192
  *bottom = fi->frame;
193
 
194
  /* Now canonicalize their order, so that 'bottom' is a lower address
195
   (as opposed to a lower stack frame). */
196
  if (*bottom > *top)
197
    {
198
      tmp_vma = *top;
199
      *top = *bottom;
200
      *bottom = tmp_vma;
201
    }
202
 
203
  return 1;     /* success */
204
}
205
 
206
/* Function: derive_heap_segment
207
 
208
   Derive a reasonable heap segment by looking at sbrk and
209
   the static data sections.
210
 
211
   Returns 0 for failure, 1 for success.  */
212
 
213
static int
214
derive_heap_segment (bfd *abfd, bfd_vma *bottom, bfd_vma *top)
215
{
216
  bfd_vma top_of_data_memory = 0;
217
  bfd_vma top_of_heap = 0;
218
  bfd_size_type sec_size;
219
  struct value *zero, *sbrk;
220
  bfd_vma sec_vaddr;
221
  asection *sec;
222
 
223
  if (bottom == NULL || top == NULL)
224
    return 0;            /* Paranoia. */
225
 
226
  if (!target_has_execution)
227
    return 0;            /* This function depends on being able
228
                           to call a function in the inferior.  */
229
 
230
  /* Assumption: link map is arranged as follows (low to high addresses):
231
     text sections
232
     data sections (including bss)
233
     heap
234
  */
235
 
236
  for (sec = abfd->sections; sec; sec = sec->next)
237
    {
238
      if (bfd_get_section_flags (abfd, sec) & SEC_DATA ||
239
          strcmp (".bss", bfd_section_name (abfd, sec)) == 0)
240
        {
241
          sec_vaddr = bfd_get_section_vma (abfd, sec);
242
          sec_size = bfd_get_section_size_before_reloc (sec);
243
          if (sec_vaddr + sec_size > top_of_data_memory)
244
            top_of_data_memory = sec_vaddr + sec_size;
245
        }
246
    }
247
  /* Now get the top-of-heap by calling sbrk in the inferior.  */
248
  if (lookup_minimal_symbol ("sbrk", NULL, NULL) != NULL)
249
    {
250
      if ((sbrk = find_function_in_inferior ("sbrk")) == NULL)
251
        return 0;
252
    }
253
  else if (lookup_minimal_symbol ("_sbrk", NULL, NULL) != NULL)
254
    {
255
      if ((sbrk = find_function_in_inferior ("_sbrk")) == NULL)
256
        return 0;
257
    }
258
  else
259
    return 0;
260
 
261
  if ((zero = value_from_longest (builtin_type_int, (LONGEST) 0)) == NULL)
262
    return 0;
263
  if ((sbrk = call_function_by_hand (sbrk, 1, &zero)) == NULL)
264
    return 0;
265
  top_of_heap = value_as_long (sbrk);
266
 
267
  /* Return results. */
268
  if (top_of_heap > top_of_data_memory)
269
    {
270
      *bottom = top_of_data_memory;
271
      *top = top_of_heap;
272
      return 1; /* success */
273
    }
274
  else
275
    return 0;    /* No additional heap space needs to be saved. */
276
}
277
 
278
/* ARGSUSED */
279
static void
280
make_output_phdrs (bfd *obfd, asection *osec, void *ignored)
281
{
282
  int p_flags = 0;
283
  int p_type;
284
 
285
  /* FIXME: these constants may only be applicable for ELF.  */
286
  if (strncmp (bfd_section_name (obfd, osec), "load", 4) == 0)
287
    p_type = PT_LOAD;
288
  else
289
    p_type = PT_NOTE;
290
 
291
  p_flags |= PF_R;      /* Segment is readable.  */
292
  if (!(bfd_get_section_flags (obfd, osec) & SEC_READONLY))
293
    p_flags |= PF_W;    /* Segment is writable.  */
294
  if (bfd_get_section_flags (obfd, osec) & SEC_CODE)
295
    p_flags |= PF_X;    /* Segment is executable.  */
296
 
297
  bfd_record_phdr (obfd, p_type, 1, p_flags, 0, 0,
298
                   0, 0, 1, &osec);
299
}
300
 
301
static asection *
302
make_mem_sec (bfd *obfd,
303
              bfd_vma addr,
304
              bfd_size_type size,
305
              unsigned int flags,
306
              unsigned int alignment)
307
{
308
  asection *osec;
309
 
310
  if ((osec = bfd_make_section_anyway (obfd, "load")) == NULL)
311
    {
312
      warning ("Couldn't make gcore segment: %s",
313
               bfd_errmsg (bfd_get_error ()));
314
      return NULL;
315
    }
316
 
317
  if (info_verbose)
318
    {
319
      fprintf_filtered (gdb_stdout,
320
                        "Save segment, %lld bytes at 0x%s\n",
321
                        (long long) size, paddr_nz (addr));
322
    }
323
 
324
  bfd_set_section_size (obfd, osec, size);
325
  bfd_set_section_vma (obfd, osec, addr);
326
  osec->lma = 0; /* FIXME: there should be a macro for this! */
327
  bfd_set_section_alignment (obfd, osec, alignment);
328
  bfd_set_section_flags (obfd, osec,
329
                         flags | SEC_LOAD | SEC_ALLOC | SEC_HAS_CONTENTS);
330
  return osec;
331
}
332
 
333
static int
334
gcore_create_callback (CORE_ADDR vaddr,
335
                       unsigned long size,
336
                       int read, int write, int exec,
337
                       void *data)
338
{
339
  flagword flags = 0;
340
 
341
  if (write == 0)
342
    {
343
      flags |= SEC_READONLY;
344
      /* Set size == zero for readonly sections. */
345
      size = 0;
346
    }
347
  if (exec)
348
    {
349
      flags |= SEC_CODE;
350
    }
351
  else
352
    {
353
      flags |= SEC_DATA;
354
    }
355
 
356
  return ((make_mem_sec ((bfd *) data, vaddr, size, flags, 0)) == NULL);
357
}
358
 
359
static int
360
objfile_find_memory_regions (int (*func) (CORE_ADDR,
361
                                          unsigned long,
362
                                          int, int, int,
363
                                           void *),
364
                             void *obfd)
365
{
366
  /* Use objfile data to create memory sections. */
367
  struct objfile *objfile;
368
  struct obj_section *objsec;
369
  bfd_vma temp_bottom, temp_top;
370
 
371
  /* Call callback function for each objfile section. */
372
  ALL_OBJSECTIONS (objfile, objsec)
373
    {
374
      bfd *ibfd = objfile->obfd;
375
      asection *isec = objsec->the_bfd_section;
376
      flagword flags = bfd_get_section_flags (ibfd, isec);
377
      int ret;
378
 
379
      if ((flags & SEC_ALLOC) || (flags & SEC_LOAD))
380
        {
381
          int size = bfd_section_size (ibfd, isec);
382
          int ret;
383
 
384
          if ((ret = (*func) (objsec->addr,
385
                              bfd_section_size (ibfd, isec),
386
                              1, /* All sections will be readable.  */
387
                              (flags & SEC_READONLY) == 0, /* writable */
388
                              (flags & SEC_CODE) != 0, /* executable */
389
                              obfd)) != 0)
390
            return ret;
391
        }
392
    }
393
 
394
  /* Make a stack segment. */
395
  if (derive_stack_segment (&temp_bottom, &temp_top))
396
    (*func) (temp_bottom,
397
             temp_top - temp_bottom,
398
             1, /* Stack section will be readable */
399
             1, /* Stack section will be writable */
400
             0, /* Stack section will not be executable */
401
             obfd);
402
 
403
  /* Make a heap segment. */
404
  if (derive_heap_segment (exec_bfd, &temp_bottom, &temp_top))
405
    (*func) (temp_bottom,
406
             temp_top - temp_bottom,
407
             1, /* Heap section will be readable */
408
             1, /* Heap section will be writable */
409
             0, /* Heap section will not be executable */
410
             obfd);
411
  return 0;
412
}
413
 
414
static void
415
gcore_copy_callback (bfd *obfd, asection *osec, void *ignored)
416
{
417
  bfd_size_type size = bfd_section_size (obfd, osec);
418
  struct cleanup *old_chain = NULL;
419
  void *memhunk;
420
 
421
  if (size == 0)
422
    return;     /* Read-only sections are marked as zero-size.
423
                   We don't have to copy their contents. */
424
  if (strncmp ("load", bfd_section_name (obfd, osec), 4) != 0)
425
    return;     /* Only interested in "load" sections. */
426
 
427
  if ((memhunk = xmalloc (size)) == NULL)
428
    error ("Not enough memory to create corefile.");
429
  old_chain = make_cleanup (xfree, memhunk);
430
 
431
  if (target_read_memory (bfd_section_vma (obfd, osec),
432
                          memhunk, size) != 0)
433
    warning ("Memory read failed for corefile section, %ld bytes at 0x%s\n",
434
             (long) size, paddr (bfd_section_vma (obfd, osec)));
435
  if (!bfd_set_section_contents (obfd, osec, memhunk, 0, size))
436
    warning ("Failed to write corefile contents (%s).",
437
             bfd_errmsg (bfd_get_error ()));
438
 
439
  do_cleanups (old_chain);      /* frees the xmalloc buffer */
440
}
441
 
442
static int
443
gcore_memory_sections (bfd *obfd)
444
{
445
  if (target_find_memory_regions (gcore_create_callback, obfd) != 0)
446
    return 0;    /* FIXME error return/msg? */
447
 
448
  /* Record phdrs for section-to-segment mapping. */
449
  bfd_map_over_sections (obfd, make_output_phdrs, NULL);
450
 
451
  /* Copy memory region contents. */
452
  bfd_map_over_sections (obfd, gcore_copy_callback, NULL);
453
 
454
  return 1;     /* success */
455
}
456
 
457
void
458
_initialize_gcore (void)
459
{
460
  add_com ("generate-core-file", class_files, gcore_command,
461
           "Save a core file with the current state of the debugged process.\n\
462
Argument is optional filename.  Default filename is 'core.<process_id>'.");
463
 
464
  add_com_alias ("gcore", "generate-core-file", class_files, 1);
465
  exec_set_find_memory_regions (objfile_find_memory_regions);
466
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.