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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [corelow.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/* Core dump and executable file functions below target vector, for GDB.
2
   Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
3
   1998, 1999, 2000, 2001
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 2 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program; if not, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "gdb_string.h"
25
#include <errno.h>
26
#include <signal.h>
27
#include <fcntl.h>
28
#ifdef HAVE_SYS_FILE_H
29
#include <sys/file.h>           /* needed for F_OK and friends */
30
#endif
31
#include "frame.h"              /* required by inferior.h */
32
#include "inferior.h"
33
#include "symtab.h"
34
#include "command.h"
35
#include "bfd.h"
36
#include "target.h"
37
#include "gdbcore.h"
38
#include "gdbthread.h"
39
#include "regcache.h"
40
 
41
#ifndef O_BINARY
42
#define O_BINARY 0
43
#endif
44
 
45
/* List of all available core_fns.  On gdb startup, each core file register
46
   reader calls add_core_fns() to register information on each core format it
47
   is prepared to read. */
48
 
49
static struct core_fns *core_file_fns = NULL;
50
 
51
/* The core_fns for a core file handler that is prepared to read the core
52
   file currently open on core_bfd. */
53
 
54
static struct core_fns *core_vec = NULL;
55
 
56
static void core_files_info (struct target_ops *);
57
 
58
#ifdef SOLIB_ADD
59
static int solib_add_stub (PTR);
60
#endif
61
 
62
static struct core_fns *sniff_core_bfd (bfd *);
63
 
64
static boolean gdb_check_format (bfd *);
65
 
66
static void core_open (char *, int);
67
 
68
static void core_detach (char *, int);
69
 
70
static void core_close (int);
71
 
72
static void core_close_cleanup (void *ignore);
73
 
74
static void get_core_registers (int);
75
 
76
static void add_to_thread_list (bfd *, asection *, PTR);
77
 
78
static int ignore (CORE_ADDR, char *);
79
 
80
static int core_file_thread_alive (ptid_t tid);
81
 
82
static void init_core_ops (void);
83
 
84
void _initialize_corelow (void);
85
 
86
struct target_ops core_ops;
87
 
88
/* Link a new core_fns into the global core_file_fns list.  Called on gdb
89
   startup by the _initialize routine in each core file register reader, to
90
   register information about each format the the reader is prepared to
91
   handle. */
92
 
93
void
94
add_core_fns (struct core_fns *cf)
95
{
96
  cf->next = core_file_fns;
97
  core_file_fns = cf;
98
}
99
 
100
/* The default function that core file handlers can use to examine a
101
   core file BFD and decide whether or not to accept the job of
102
   reading the core file. */
103
 
104
int
105
default_core_sniffer (struct core_fns *our_fns, bfd *abfd)
106
{
107
  int result;
108
 
109
  result = (bfd_get_flavour (abfd) == our_fns -> core_flavour);
110
  return (result);
111
}
112
 
113
/* Walk through the list of core functions to find a set that can
114
   handle the core file open on ABFD.  Default to the first one in the
115
   list if nothing matches.  Returns pointer to set that is
116
   selected. */
117
 
118
static struct core_fns *
119
sniff_core_bfd (bfd *abfd)
120
{
121
  struct core_fns *cf;
122
  struct core_fns *yummy = NULL;
123
  int matches = 0;;
124
 
125
  for (cf = core_file_fns; cf != NULL; cf = cf->next)
126
    {
127
      if (cf->core_sniffer (cf, abfd))
128
        {
129
          yummy = cf;
130
          matches++;
131
        }
132
    }
133
  if (matches > 1)
134
    {
135
      warning ("\"%s\": ambiguous core format, %d handlers match",
136
               bfd_get_filename (abfd), matches);
137
    }
138
  else if (matches == 0)
139
    {
140
      warning ("\"%s\": no core file handler recognizes format, using default",
141
               bfd_get_filename (abfd));
142
    }
143
  if (yummy == NULL)
144
    {
145
      yummy = core_file_fns;
146
    }
147
  return (yummy);
148
}
149
 
150
/* The default is to reject every core file format we see.  Either
151
   BFD has to recognize it, or we have to provide a function in the
152
   core file handler that recognizes it. */
153
 
154
int
155
default_check_format (bfd *abfd)
156
{
157
  return (0);
158
}
159
 
160
/* Attempt to recognize core file formats that BFD rejects. */
161
 
162
static boolean
163
gdb_check_format (bfd *abfd)
164
{
165
  struct core_fns *cf;
166
 
167
  for (cf = core_file_fns; cf != NULL; cf = cf->next)
168
    {
169
      if (cf->check_format (abfd))
170
        {
171
          return (true);
172
        }
173
    }
174
  return (false);
175
}
176
 
177
/* Discard all vestiges of any previous core file and mark data and stack
178
   spaces as empty.  */
179
 
180
/* ARGSUSED */
181
static void
182
core_close (int quitting)
183
{
184
  char *name;
185
 
186
  if (core_bfd)
187
    {
188
      inferior_ptid = null_ptid;        /* Avoid confusion from thread stuff */
189
 
190
      /* Clear out solib state while the bfd is still open. See
191
         comments in clear_solib in solib.c. */
192
#ifdef CLEAR_SOLIB
193
      CLEAR_SOLIB ();
194
#endif
195
 
196
      name = bfd_get_filename (core_bfd);
197
      if (!bfd_close (core_bfd))
198
        warning ("cannot close \"%s\": %s",
199
                 name, bfd_errmsg (bfd_get_error ()));
200
      xfree (name);
201
      core_bfd = NULL;
202
      if (core_ops.to_sections)
203
        {
204
          xfree (core_ops.to_sections);
205
          core_ops.to_sections = NULL;
206
          core_ops.to_sections_end = NULL;
207
        }
208
    }
209
  core_vec = NULL;
210
}
211
 
212
static void
213
core_close_cleanup (void *ignore)
214
{
215
  core_close (0/*ignored*/);
216
}
217
 
218
#ifdef SOLIB_ADD
219
/* Stub function for catch_errors around shared library hacking.  FROM_TTYP
220
   is really an int * which points to from_tty.  */
221
 
222
static int
223
solib_add_stub (PTR from_ttyp)
224
{
225
  SOLIB_ADD (NULL, *(int *) from_ttyp, &current_target);
226
  re_enable_breakpoints_in_shlibs ();
227
  return 0;
228
}
229
#endif /* SOLIB_ADD */
230
 
231
/* Look for sections whose names start with `.reg/' so that we can extract the
232
   list of threads in a core file.  */
233
 
234
static void
235
add_to_thread_list (bfd *abfd, asection *asect, PTR reg_sect_arg)
236
{
237
  int thread_id;
238
  asection *reg_sect = (asection *) reg_sect_arg;
239
 
240
  if (strncmp (bfd_section_name (abfd, asect), ".reg/", 5) != 0)
241
    return;
242
 
243
  thread_id = atoi (bfd_section_name (abfd, asect) + 5);
244
 
245
  add_thread (pid_to_ptid (thread_id));
246
 
247
/* Warning, Will Robinson, looking at BFD private data! */
248
 
249
  if (reg_sect != NULL
250
      && asect->filepos == reg_sect->filepos)   /* Did we find .reg? */
251
    inferior_ptid = pid_to_ptid (thread_id);    /* Yes, make it current */
252
}
253
 
254
/* This routine opens and sets up the core file bfd.  */
255
 
256
static void
257
core_open (char *filename, int from_tty)
258
{
259
  const char *p;
260
  int siggy;
261
  struct cleanup *old_chain;
262
  char *temp;
263
  bfd *temp_bfd;
264
  int ontop;
265
  int scratch_chan;
266
 
267
  target_preopen (from_tty);
268
  if (!filename)
269
    {
270
      error (core_bfd ?
271
             "No core file specified.  (Use `detach' to stop debugging a core file.)"
272
             : "No core file specified.");
273
    }
274
 
275
  filename = tilde_expand (filename);
276
  if (filename[0] != '/')
277
    {
278
      temp = concat (current_directory, "/", filename, NULL);
279
      xfree (filename);
280
      filename = temp;
281
    }
282
 
283
  old_chain = make_cleanup (xfree, filename);
284
 
285
  scratch_chan = open (filename, O_BINARY | ( write_files ? O_RDWR : O_RDONLY ), 0);
286
  if (scratch_chan < 0)
287
    perror_with_name (filename);
288
 
289
  temp_bfd = bfd_fdopenr (filename, gnutarget, scratch_chan);
290
  if (temp_bfd == NULL)
291
    perror_with_name (filename);
292
 
293
  if (!bfd_check_format (temp_bfd, bfd_core) &&
294
      !gdb_check_format (temp_bfd))
295
    {
296
      /* Do it after the err msg */
297
      /* FIXME: should be checking for errors from bfd_close (for one thing,
298
         on error it does not free all the storage associated with the
299
         bfd).  */
300
      make_cleanup_bfd_close (temp_bfd);
301
      error ("\"%s\" is not a core dump: %s",
302
             filename, bfd_errmsg (bfd_get_error ()));
303
    }
304
 
305
  /* Looks semi-reasonable.  Toss the old core file and work on the new.  */
306
 
307
  discard_cleanups (old_chain); /* Don't free filename any more */
308
  unpush_target (&core_ops);
309
  core_bfd = temp_bfd;
310
  old_chain = make_cleanup (core_close_cleanup, 0 /*ignore*/);
311
 
312
  /* Find a suitable core file handler to munch on core_bfd */
313
  core_vec = sniff_core_bfd (core_bfd);
314
 
315
  validate_files ();
316
 
317
  /* Find the data section */
318
  if (build_section_table (core_bfd, &core_ops.to_sections,
319
                           &core_ops.to_sections_end))
320
    error ("\"%s\": Can't find sections: %s",
321
           bfd_get_filename (core_bfd), bfd_errmsg (bfd_get_error ()));
322
 
323
  set_gdbarch_from_file (core_bfd);
324
 
325
  ontop = !push_target (&core_ops);
326
  discard_cleanups (old_chain);
327
 
328
  p = bfd_core_file_failing_command (core_bfd);
329
  if (p)
330
    printf_filtered ("Core was generated by `%s'.\n", p);
331
 
332
  siggy = bfd_core_file_failing_signal (core_bfd);
333
  if (siggy > 0)
334
    /* NOTE: target_signal_from_host() converts a target signal value
335
       into gdb's internal signal value.  Unfortunately gdb's internal
336
       value is called ``target_signal'' and this function got the
337
       name ..._from_host(). */
338
    printf_filtered ("Program terminated with signal %d, %s.\n", siggy,
339
                     target_signal_to_string (target_signal_from_host (siggy)));
340
 
341
  /* Build up thread list from BFD sections. */
342
 
343
  init_thread_list ();
344
  bfd_map_over_sections (core_bfd, add_to_thread_list,
345
                         bfd_get_section_by_name (core_bfd, ".reg"));
346
 
347
  if (ontop)
348
    {
349
      /* Fetch all registers from core file.  */
350
      target_fetch_registers (-1);
351
 
352
      /* Add symbols and section mappings for any shared libraries.  */
353
#ifdef SOLIB_ADD
354
      catch_errors (solib_add_stub, &from_tty, (char *) 0,
355
                    RETURN_MASK_ALL);
356
#endif
357
 
358
      /* Now, set up the frame cache, and print the top of stack.  */
359
      flush_cached_frames ();
360
      select_frame (get_current_frame (), 0);
361
      print_stack_frame (selected_frame, selected_frame_level, 1);
362
    }
363
  else
364
    {
365
      warning (
366
                "you won't be able to access this core file until you terminate\n\
367
your %s; do ``info files''", target_longname);
368
    }
369
}
370
 
371
static void
372
core_detach (char *args, int from_tty)
373
{
374
  if (args)
375
    error ("Too many arguments");
376
  unpush_target (&core_ops);
377
  reinit_frame_cache ();
378
  if (from_tty)
379
    printf_filtered ("No core file now.\n");
380
}
381
 
382
 
383
/* Try to retrieve registers from a section in core_bfd, and supply
384
   them to core_vec->core_read_registers, as the register set numbered
385
   WHICH.
386
 
387
   If inferior_ptid is zero, do the single-threaded thing: look for a
388
   section named NAME.  If inferior_ptid is non-zero, do the
389
   multi-threaded thing: look for a section named "NAME/PID", where
390
   PID is the shortest ASCII decimal representation of inferior_ptid.
391
 
392
   HUMAN_NAME is a human-readable name for the kind of registers the
393
   NAME section contains, for use in error messages.
394
 
395
   If REQUIRED is non-zero, print an error if the core file doesn't
396
   have a section by the appropriate name.  Otherwise, just do nothing.  */
397
 
398
static void
399
get_core_register_section (char *name,
400
                           int which,
401
                           char *human_name,
402
                           int required)
403
{
404
  char section_name[100];
405
  sec_ptr section;
406
  bfd_size_type size;
407
  char *contents;
408
 
409
  if (PIDGET (inferior_ptid))
410
    sprintf (section_name, "%s/%d", name, PIDGET (inferior_ptid));
411
  else
412
    strcpy (section_name, name);
413
 
414
  section = bfd_get_section_by_name (core_bfd, section_name);
415
  if (! section)
416
    {
417
      if (required)
418
        warning ("Couldn't find %s registers in core file.\n", human_name);
419
      return;
420
    }
421
 
422
  size = bfd_section_size (core_bfd, section);
423
  contents = alloca (size);
424
  if (! bfd_get_section_contents (core_bfd, section, contents,
425
                                  (file_ptr) 0, size))
426
    {
427
      warning ("Couldn't read %s registers from `%s' section in core file.\n",
428
               human_name, name);
429
      return;
430
    }
431
 
432
  core_vec->core_read_registers (contents, size, which,
433
                                 ((CORE_ADDR)
434
                                  bfd_section_vma (core_bfd, section)));
435
}
436
 
437
 
438
/* Get the registers out of a core file.  This is the machine-
439
   independent part.  Fetch_core_registers is the machine-dependent
440
   part, typically implemented in the xm-file for each architecture.  */
441
 
442
/* We just get all the registers, so we don't use regno.  */
443
 
444
/* ARGSUSED */
445
static void
446
get_core_registers (int regno)
447
{
448
  int status;
449
 
450
  if (core_vec == NULL
451
      || core_vec->core_read_registers == NULL)
452
    {
453
      fprintf_filtered (gdb_stderr,
454
                     "Can't fetch registers from this type of core file\n");
455
      return;
456
    }
457
 
458
  get_core_register_section (".reg", 0, "general-purpose", 1);
459
  get_core_register_section (".reg2", 2, "floating-point", 0);
460
  get_core_register_section (".reg-xfp", 3, "extended floating-point", 0);
461
 
462
  registers_fetched ();
463
}
464
 
465
static void
466
core_files_info (struct target_ops *t)
467
{
468
  print_section_info (t, core_bfd);
469
}
470
 
471
/* If mourn is being called in all the right places, this could be say
472
   `gdb internal error' (since generic_mourn calls breakpoint_init_inferior).  */
473
 
474
static int
475
ignore (CORE_ADDR addr, char *contents)
476
{
477
  return 0;
478
}
479
 
480
 
481
/* Okay, let's be honest: threads gleaned from a core file aren't
482
   exactly lively, are they?  On the other hand, if we don't claim
483
   that each & every one is alive, then we don't get any of them
484
   to appear in an "info thread" command, which is quite a useful
485
   behaviour.
486
 */
487
static int
488
core_file_thread_alive (ptid_t tid)
489
{
490
  return 1;
491
}
492
 
493
/* Fill in core_ops with its defined operations and properties.  */
494
 
495
static void
496
init_core_ops (void)
497
{
498
  core_ops.to_shortname = "core";
499
  core_ops.to_longname = "Local core dump file";
500
  core_ops.to_doc =
501
    "Use a core file as a target.  Specify the filename of the core file.";
502
  core_ops.to_open = core_open;
503
  core_ops.to_close = core_close;
504
  core_ops.to_attach = find_default_attach;
505
  core_ops.to_require_attach = find_default_require_attach;
506
  core_ops.to_detach = core_detach;
507
  core_ops.to_require_detach = find_default_require_detach;
508
  core_ops.to_fetch_registers = get_core_registers;
509
  core_ops.to_xfer_memory = xfer_memory;
510
  core_ops.to_files_info = core_files_info;
511
  core_ops.to_insert_breakpoint = ignore;
512
  core_ops.to_remove_breakpoint = ignore;
513
  core_ops.to_create_inferior = find_default_create_inferior;
514
  core_ops.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior;
515
  core_ops.to_thread_alive = core_file_thread_alive;
516
  core_ops.to_stratum = core_stratum;
517
  core_ops.to_has_memory = 1;
518
  core_ops.to_has_stack = 1;
519
  core_ops.to_has_registers = 1;
520
  core_ops.to_magic = OPS_MAGIC;
521
}
522
 
523
/* non-zero if we should not do the add_target call in
524
   _initialize_corelow; not initialized (i.e., bss) so that
525
   the target can initialize it (i.e., data) if appropriate.
526
   This needs to be set at compile time because we don't know
527
   for sure whether the target's initialize routine is called
528
   before us or after us. */
529
int coreops_suppress_target;
530
 
531
void
532
_initialize_corelow (void)
533
{
534
  init_core_ops ();
535
 
536
  if (!coreops_suppress_target)
537
    add_target (&core_ops);
538
}

powered by: WebSVN 2.1.0

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