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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [gdb/] [corefile.c] - Blame information for rev 1771

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

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

powered by: WebSVN 2.1.0

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