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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [corefile.c] - Blame information for rev 1777

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

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

powered by: WebSVN 2.1.0

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