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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [corefile.c] - Blame information for rev 104

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

Line No. Rev Author Line
1 104 markom
/* Core dump and executable file functions above target vector, for GDB.
2
   Copyright 1986, 1987, 1989, 1991-1994, 2000
3
   Free Software Foundation, Inc.
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
9
   the Free Software Foundation; either version 2 of the License, or
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
18
   along with this program; if not, write to the Free Software
19
   Foundation, Inc., 59 Temple Place - Suite 330,
20
   Boston, MA 02111-1307, USA.  */
21
 
22
#include "defs.h"
23
#include "gdb_string.h"
24
#include <errno.h>
25
#include <signal.h>
26
#include <fcntl.h>
27
#include "frame.h"              /* required by inferior.h */
28
#include "inferior.h"
29
#include "symtab.h"
30
#include "command.h"
31
#include "gdbcmd.h"
32
#include "bfd.h"
33
#include "target.h"
34
#include "gdbcore.h"
35
#include "dis-asm.h"
36
#include "language.h"
37
#include "gdb_stat.h"
38
#include "symfile.h"
39
#include "objfiles.h"
40
 
41
/* Local function declarations.  */
42
 
43
extern void _initialize_core PARAMS ((void));
44
static void call_extra_exec_file_hooks PARAMS ((char *filename));
45
 
46
/* You can have any number of hooks for `exec_file_command' command to call.
47
   If there's only one hook, it is set in exec_file_display hook.
48
   If there are two or more hooks, they are set in exec_file_extra_hooks[],
49
   and exec_file_display_hook is set to a function that calls all of them.
50
   This extra complexity is needed to preserve compatibility with
51
   old code that assumed that only one hook could be set, and which called
52
   exec_file_display_hook directly.  */
53
 
54
typedef void (*hook_type) PARAMS ((char *));
55
 
56
hook_type exec_file_display_hook;       /* the original hook */
57
static hook_type *exec_file_extra_hooks;        /* array of additional hooks */
58
static int exec_file_hook_count = 0;     /* size of array */
59
 
60
/* Binary file diddling handle for the core file.  */
61
 
62
bfd *core_bfd = NULL;
63
 
64
 
65
/* Backward compatability with old way of specifying core files.  */
66
 
67
void
68
core_file_command (filename, from_tty)
69
     char *filename;
70
     int from_tty;
71
{
72
  struct target_ops *t;
73
 
74
  dont_repeat ();               /* Either way, seems bogus. */
75
 
76
  t = find_core_target ();
77
  if (t != NULL)
78
    if (!filename)
79
      (t->to_detach) (filename, from_tty);
80
    else
81
      {
82
        /* Yes, we were given the path of a core file.  Do we already
83
           have a symbol file?  If not, can we determine it from the
84
           core file?  If we can, do so.
85
         */
86
#ifdef HPUXHPPA
87
        if (symfile_objfile == NULL)
88
          {
89
            char *symfile;
90
            symfile = t->to_core_file_to_sym_file (filename);
91
            if (symfile)
92
              {
93
                char *symfile_copy = xstrdup (symfile);
94
 
95
                make_cleanup (free, symfile_copy);
96
                symbol_file_command (symfile_copy, from_tty);
97
              }
98
            else
99
              warning ("Unknown symbols for '%s'; use the 'symbol-file' command.", filename);
100
          }
101
#endif
102
        (t->to_open) (filename, from_tty);
103
      }
104
  else
105
    error ("GDB can't read core files on this machine.");
106
}
107
 
108
 
109
/* If there are two or more functions that wish to hook into exec_file_command,
110
 * this function will call all of the hook functions. */
111
 
112
static void
113
call_extra_exec_file_hooks (filename)
114
     char *filename;
115
{
116
  int i;
117
 
118
  for (i = 0; i < exec_file_hook_count; i++)
119
    (*exec_file_extra_hooks[i]) (filename);
120
}
121
 
122
/* Call this to specify the hook for exec_file_command to call back.
123
   This is called from the x-window display code.  */
124
 
125
void
126
specify_exec_file_hook (hook)
127
     void (*hook) PARAMS ((char *));
128
{
129
  hook_type *new_array;
130
 
131
  if (exec_file_display_hook != NULL)
132
    {
133
      /* There's already a hook installed.  Arrange to have both it
134
       * and the subsequent hooks called. */
135
      if (exec_file_hook_count == 0)
136
        {
137
          /* If this is the first extra hook, initialize the hook array. */
138
          exec_file_extra_hooks = (hook_type *) xmalloc (sizeof (hook_type));
139
          exec_file_extra_hooks[0] = exec_file_display_hook;
140
          exec_file_display_hook = call_extra_exec_file_hooks;
141
          exec_file_hook_count = 1;
142
        }
143
 
144
      /* Grow the hook array by one and add the new hook to the end.
145
         Yes, it's inefficient to grow it by one each time but since
146
         this is hardly ever called it's not a big deal.  */
147
      exec_file_hook_count++;
148
      new_array =
149
        (hook_type *) xrealloc (exec_file_extra_hooks,
150
                                exec_file_hook_count * sizeof (hook_type));
151
      exec_file_extra_hooks = new_array;
152
      exec_file_extra_hooks[exec_file_hook_count - 1] = hook;
153
    }
154
  else
155
    exec_file_display_hook = hook;
156
}
157
 
158
/* The exec file must be closed before running an inferior.
159
   If it is needed again after the inferior dies, it must
160
   be reopened.  */
161
 
162
void
163
close_exec_file ()
164
{
165
#if 0                           /* FIXME */
166
  if (exec_bfd)
167
    bfd_tempclose (exec_bfd);
168
#endif
169
}
170
 
171
void
172
reopen_exec_file ()
173
{
174
#if 0                           /* FIXME */
175
  if (exec_bfd)
176
    bfd_reopen (exec_bfd);
177
#else
178
  char *filename;
179
  int res;
180
  struct stat st;
181
  long mtime;
182
 
183
  /* Don't do anything if the current target isn't exec. */
184
  if (exec_bfd == NULL || strcmp (target_shortname, "exec") != 0)
185
    return;
186
 
187
  /* If the timestamp of the exec file has changed, reopen it. */
188
  filename = xstrdup (bfd_get_filename (exec_bfd));
189
  make_cleanup (free, filename);
190
  mtime = bfd_get_mtime (exec_bfd);
191
  res = stat (filename, &st);
192
 
193
  if (mtime && mtime != st.st_mtime)
194
    exec_file_command (filename, 0);
195
#endif
196
}
197
 
198
/* If we have both a core file and an exec file,
199
   print a warning if they don't go together.  */
200
 
201
void
202
validate_files ()
203
{
204
  if (exec_bfd && core_bfd)
205
    {
206
      if (!core_file_matches_executable_p (core_bfd, exec_bfd))
207
        warning ("core file may not match specified executable file.");
208
      else if (bfd_get_mtime (exec_bfd) > bfd_get_mtime (core_bfd))
209
        warning ("exec file is newer than core file.");
210
    }
211
}
212
 
213
/* Return the name of the executable file as a string.
214
   ERR nonzero means get error if there is none specified;
215
   otherwise return 0 in that case.  */
216
 
217
char *
218
get_exec_file (err)
219
     int err;
220
{
221
  if (exec_bfd)
222
    return bfd_get_filename (exec_bfd);
223
  if (!err)
224
    return NULL;
225
 
226
  error ("No executable file specified.\n\
227
Use the \"file\" or \"exec-file\" command.");
228
  return NULL;
229
}
230
 
231
 
232
/* Report a memory error with error().  */
233
 
234
void
235
memory_error (status, memaddr)
236
     int status;
237
     CORE_ADDR memaddr;
238
{
239
  struct ui_file *tmp_stream = mem_fileopen ();
240
  make_cleanup_ui_file_delete (tmp_stream);
241
 
242
  if (status == EIO)
243
    {
244
      /* Actually, address between memaddr and memaddr + len
245
         was out of bounds. */
246
      fprintf_unfiltered (tmp_stream, "Cannot access memory at address ");
247
      print_address_numeric (memaddr, 1, tmp_stream);
248
    }
249
  else
250
    {
251
      fprintf_filtered (tmp_stream, "Error accessing memory address ");
252
      print_address_numeric (memaddr, 1, tmp_stream);
253
      fprintf_filtered (tmp_stream, ": %s.",
254
                       safe_strerror (status));
255
    }
256
 
257
  error_stream (tmp_stream);
258
}
259
 
260
/* Same as target_read_memory, but report an error if can't read.  */
261
void
262
read_memory (memaddr, myaddr, len)
263
     CORE_ADDR memaddr;
264
     char *myaddr;
265
     int len;
266
{
267
  int status;
268
  status = target_read_memory (memaddr, myaddr, len);
269
  if (status != 0)
270
    memory_error (status, memaddr);
271
}
272
 
273
void
274
read_memory_section (memaddr, myaddr, len, bfd_section)
275
     CORE_ADDR memaddr;
276
     char *myaddr;
277
     int len;
278
     asection *bfd_section;
279
{
280
  int status;
281
  status = target_read_memory_section (memaddr, myaddr, len, bfd_section);
282
  if (status != 0)
283
    memory_error (status, memaddr);
284
}
285
 
286
/* Like target_read_memory, but slightly different parameters.  */
287
 
288
int
289
dis_asm_read_memory (memaddr, myaddr, len, info)
290
     bfd_vma memaddr;
291
     bfd_byte *myaddr;
292
     unsigned int len;
293
     disassemble_info *info;
294
{
295
  return target_read_memory (memaddr, (char *) myaddr, len);
296
}
297
 
298
/* Like memory_error with slightly different parameters.  */
299
void
300
dis_asm_memory_error (status, memaddr, info)
301
     int status;
302
     bfd_vma memaddr;
303
     disassemble_info *info;
304
{
305
  memory_error (status, memaddr);
306
}
307
 
308
/* Like print_address with slightly different parameters.  */
309
void
310
dis_asm_print_address (addr, info)
311
     bfd_vma addr;
312
     struct disassemble_info *info;
313
{
314
  print_address (addr, info->stream);
315
}
316
 
317
/* Same as target_write_memory, but report an error if can't write.  */
318
void
319
write_memory (memaddr, myaddr, len)
320
     CORE_ADDR memaddr;
321
     char *myaddr;
322
     int len;
323
{
324
  int status;
325
 
326
  status = target_write_memory (memaddr, myaddr, len);
327
  if (status != 0)
328
    memory_error (status, memaddr);
329
}
330
 
331
/* Read an integer from debugged memory, given address and number of bytes.  */
332
 
333
LONGEST
334
read_memory_integer (memaddr, len)
335
     CORE_ADDR memaddr;
336
     int len;
337
{
338
  char buf[sizeof (LONGEST)];
339
 
340
  read_memory (memaddr, buf, len);
341
  return extract_signed_integer (buf, len);
342
}
343
 
344
ULONGEST
345
read_memory_unsigned_integer (memaddr, len)
346
     CORE_ADDR memaddr;
347
     int len;
348
{
349
  char buf[sizeof (ULONGEST)];
350
 
351
  read_memory (memaddr, buf, len);
352
  return extract_unsigned_integer (buf, len);
353
}
354
 
355
void
356
read_memory_string (memaddr, buffer, max_len)
357
     CORE_ADDR memaddr;
358
     char *buffer;
359
     int max_len;
360
{
361
  register char *cp;
362
  register int i;
363
  int cnt;
364
 
365
  cp = buffer;
366
  while (1)
367
    {
368
      if (cp - buffer >= max_len)
369
        {
370
          buffer[max_len - 1] = '\0';
371
          break;
372
        }
373
      cnt = max_len - (cp - buffer);
374
      if (cnt > 8)
375
        cnt = 8;
376
      read_memory (memaddr + (int) (cp - buffer), cp, cnt);
377
      for (i = 0; i < cnt && *cp; i++, cp++)
378
        ;                       /* null body */
379
 
380
      if (i < cnt && !*cp)
381
        break;
382
    }
383
}
384
 
385
 
386
#if 0
387
/* Enable after 4.12.  It is not tested.  */
388
 
389
/* Search code.  Targets can just make this their search function, or
390
   if the protocol has a less general search function, they can call this
391
   in the cases it can't handle.  */
392
void
393
generic_search (len, data, mask, startaddr, increment, lorange, hirange
394
                addr_found, data_found)
395
     int len;
396
     char *data;
397
     char *mask;
398
     CORE_ADDR startaddr;
399
     int increment;
400
     CORE_ADDR lorange;
401
     CORE_ADDR hirange;
402
     CORE_ADDR *addr_found;
403
     char *data_found;
404
{
405
  int i;
406
  CORE_ADDR curaddr = startaddr;
407
 
408
  while (curaddr >= lorange && curaddr < hirange)
409
    {
410
      read_memory (curaddr, data_found, len);
411
      for (i = 0; i < len; ++i)
412
        if ((data_found[i] & mask[i]) != data[i])
413
          goto try_again;
414
      /* It matches.  */
415
      *addr_found = curaddr;
416
      return;
417
 
418
    try_again:
419
      curaddr += increment;
420
    }
421
  *addr_found = (CORE_ADDR) 0;
422
  return;
423
}
424
#endif /* 0 */
425
 
426
/* The current default bfd target.  Points to storage allocated for
427
   gnutarget_string.  */
428
char *gnutarget;
429
 
430
/* Same thing, except it is "auto" not NULL for the default case.  */
431
static char *gnutarget_string;
432
 
433
static void set_gnutarget_command
434
  PARAMS ((char *, int, struct cmd_list_element *));
435
 
436
static void
437
set_gnutarget_command (ignore, from_tty, c)
438
     char *ignore;
439
     int from_tty;
440
     struct cmd_list_element *c;
441
{
442
  if (STREQ (gnutarget_string, "auto"))
443
    gnutarget = NULL;
444
  else
445
    gnutarget = gnutarget_string;
446
}
447
 
448
/* Set the gnutarget.  */
449
void
450
set_gnutarget (newtarget)
451
     char *newtarget;
452
{
453
  if (gnutarget_string != NULL)
454
    free (gnutarget_string);
455
  gnutarget_string = savestring (newtarget, strlen (newtarget));
456
  set_gnutarget_command (NULL, 0, NULL);
457
}
458
 
459
void
460
_initialize_core ()
461
{
462
  struct cmd_list_element *c;
463
  c = add_cmd ("core-file", class_files, core_file_command,
464
               "Use FILE as core dump for examining memory and registers.\n\
465
No arg means have no core file.  This command has been superseded by the\n\
466
`target core' and `detach' commands.", &cmdlist);
467
  c->completer = filename_completer;
468
 
469
  c = add_set_cmd ("gnutarget", class_files, var_string_noescape,
470
                   (char *) &gnutarget_string,
471
                   "Set the current BFD target.\n\
472
Use `set gnutarget auto' to specify automatic detection.",
473
                   &setlist);
474
  c->function.sfunc = set_gnutarget_command;
475
  add_show_from_set (c, &showlist);
476
 
477
  if (getenv ("GNUTARGET"))
478
    set_gnutarget (getenv ("GNUTARGET"));
479
  else
480
    set_gnutarget ("auto");
481
}

powered by: WebSVN 2.1.0

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