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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [reverse.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 jeremybenn
/* Reverse execution and reverse debugging.
2
 
3
   Copyright (C) 2006, 2007, 2008, 2009, 2010 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 3 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, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
#include "gdb_string.h"
22
#include "target.h"
23
#include "top.h"
24
#include "cli/cli-cmds.h"
25
#include "cli/cli-decode.h"
26
#include "inferior.h"
27
#include "regcache.h"
28
 
29
/* User interface:
30
   reverse-step, reverse-next etc.  */
31
 
32
static void
33
exec_direction_default (void *notused)
34
{
35
  /* Return execution direction to default state.  */
36
  execution_direction = EXEC_FORWARD;
37
}
38
 
39
/* exec_reverse_once -- accepts an arbitrary gdb command (string),
40
   and executes it with exec-direction set to 'reverse'.
41
 
42
   Used to implement reverse-next etc. commands.  */
43
 
44
static void
45
exec_reverse_once (char *cmd, char *args, int from_tty)
46
{
47
  char *reverse_command;
48
  enum exec_direction_kind dir = execution_direction;
49
  struct cleanup *old_chain;
50
 
51
  if (dir == EXEC_ERROR)
52
    error (_("Target %s does not support this command."), target_shortname);
53
 
54
  if (dir == EXEC_REVERSE)
55
    error (_("Already in reverse mode.  Use '%s' or 'set exec-dir forward'."),
56
           cmd);
57
 
58
  if (!target_can_execute_reverse)
59
    error (_("Target %s does not support this command."), target_shortname);
60
 
61
  reverse_command = xstrprintf ("%s %s", cmd, args ? args : "");
62
  old_chain = make_cleanup (exec_direction_default, NULL);
63
  make_cleanup (xfree, reverse_command);
64
  execution_direction = EXEC_REVERSE;
65
  execute_command (reverse_command, from_tty);
66
  do_cleanups (old_chain);
67
}
68
 
69
static void
70
reverse_step (char *args, int from_tty)
71
{
72
  exec_reverse_once ("step", args, from_tty);
73
}
74
 
75
static void
76
reverse_stepi (char *args, int from_tty)
77
{
78
  exec_reverse_once ("stepi", args, from_tty);
79
}
80
 
81
static void
82
reverse_next (char *args, int from_tty)
83
{
84
  exec_reverse_once ("next", args, from_tty);
85
}
86
 
87
static void
88
reverse_nexti (char *args, int from_tty)
89
{
90
  exec_reverse_once ("nexti", args, from_tty);
91
}
92
 
93
static void
94
reverse_continue (char *args, int from_tty)
95
{
96
  exec_reverse_once ("continue", args, from_tty);
97
}
98
 
99
static void
100
reverse_finish (char *args, int from_tty)
101
{
102
  exec_reverse_once ("finish", args, from_tty);
103
}
104
 
105
/* Data structures for a bookmark list.  */
106
 
107
struct bookmark {
108
  struct bookmark *next;
109
  int number;
110
  CORE_ADDR pc;
111
  struct symtab_and_line sal;
112
  gdb_byte *opaque_data;
113
};
114
 
115
static struct bookmark *bookmark_chain;
116
static int bookmark_count;
117
 
118
#define ALL_BOOKMARKS(B) for ((B) = bookmark_chain; (B); (B) = (B)->next)
119
 
120
#define ALL_BOOKMARKS_SAFE(B,TMP)           \
121
     for ((B) = bookmark_chain;             \
122
          (B) ? ((TMP) = (B)->next, 1) : 0; \
123
          (B) = (TMP))
124
 
125
/* save_bookmark_command -- implement "bookmark" command.
126
   Call target method to get a bookmark identifier.
127
   Insert bookmark identifier into list.
128
 
129
   Identifier will be a malloc string (gdb_byte *).
130
   Up to us to free it as required.  */
131
 
132
static void
133
save_bookmark_command (char *args, int from_tty)
134
{
135
  /* Get target's idea of a bookmark.  */
136
  gdb_byte *bookmark_id = target_get_bookmark (args, from_tty);
137
  struct bookmark *b, *b1;
138
  struct gdbarch *gdbarch = get_regcache_arch (get_current_regcache ());
139
 
140
  /* CR should not cause another identical bookmark.  */
141
  dont_repeat ();
142
 
143
  if (bookmark_id == NULL)
144
    error (_("target_get_bookmark failed."));
145
 
146
  /* Set up a bookmark struct.  */
147
  b = xcalloc (1, sizeof (struct bookmark));
148
  b->number = ++bookmark_count;
149
  init_sal (&b->sal);
150
  b->pc = regcache_read_pc (get_current_regcache ());
151
  b->sal = find_pc_line (b->pc, 0);
152
  b->sal.pspace = get_frame_program_space (get_current_frame ());
153
  b->opaque_data = bookmark_id;
154
  b->next = NULL;
155
 
156
  /* Add this bookmark to the end of the chain, so that a list
157
     of bookmarks will come out in order of increasing numbers.  */
158
 
159
  b1 = bookmark_chain;
160
  if (b1 == 0)
161
    bookmark_chain = b;
162
  else
163
    {
164
      while (b1->next)
165
        b1 = b1->next;
166
      b1->next = b;
167
    }
168
  printf_filtered (_("Saved bookmark %d at %s\n"), b->number,
169
                     paddress (gdbarch, b->sal.pc));
170
}
171
 
172
/* Implement "delete bookmark" command.  */
173
 
174
static int
175
delete_one_bookmark (struct bookmark *b)
176
{
177
  struct bookmark *b1;
178
 
179
  /* Special case, first item in list.  */
180
  if (b == bookmark_chain)
181
    bookmark_chain = b->next;
182
 
183
  /* Find bookmark preceeding "marked" one, so we can unlink.  */
184
  if (b)
185
    {
186
      ALL_BOOKMARKS (b1)
187
        if (b1->next == b)
188
          {
189
            /* Found designated bookmark.  Unlink and delete.  */
190
            b1->next = b->next;
191
            break;
192
          }
193
      xfree (b->opaque_data);
194
      xfree (b);
195
      return 1;         /* success */
196
    }
197
  return 0;              /* failure */
198
}
199
 
200
static void
201
delete_all_bookmarks (void)
202
{
203
  struct bookmark *b, *b1;
204
 
205
  ALL_BOOKMARKS_SAFE (b, b1)
206
    {
207
      xfree (b->opaque_data);
208
      xfree (b);
209
    }
210
  bookmark_chain = NULL;
211
}
212
 
213
static void
214
delete_bookmark_command (char *args, int from_tty)
215
{
216
  struct bookmark *b, *b1;
217
  unsigned long num;
218
 
219
  if (bookmark_chain == NULL)
220
    {
221
      warning (_("No bookmarks."));
222
      return;
223
    }
224
 
225
  if (args == NULL || args[0] == '\0')
226
    {
227
      if (from_tty && !query (_("Delete all bookmarks? ")))
228
        return;
229
      delete_all_bookmarks ();
230
      return;
231
    }
232
 
233
  num = strtoul (args, NULL, 0);
234
  /* Find bookmark with corresponding number.  */
235
  ALL_BOOKMARKS (b)
236
    if (b->number == num)
237
      break;
238
 
239
  if (!delete_one_bookmark (b))
240
    /* Not found.  */
241
    error (_("delete bookmark: no bookmark found for '%s'."), args);
242
}
243
 
244
/* Implement "goto-bookmark" command.  */
245
 
246
static void
247
goto_bookmark_command (char *args, int from_tty)
248
{
249
  struct bookmark *b;
250
  unsigned long num;
251
 
252
  if (args == NULL || args[0] == '\0')
253
    error (_("Command requires an argument."));
254
 
255
  if (strncmp (args, "start", strlen ("start")) == 0
256
      || strncmp (args, "begin", strlen ("begin")) == 0
257
      || strncmp (args, "end",   strlen ("end")) == 0)
258
    {
259
      /* Special case.  Give target opportunity to handle.  */
260
      target_goto_bookmark (args, from_tty);
261
      return;
262
    }
263
 
264
  if (args[0] == '\'' || args[0] == '\"')
265
    {
266
      /* Special case -- quoted string.  Pass on to target.  */
267
      if (args[strlen (args) - 1] != args[0])
268
        error (_("Unbalanced quotes: %s"), args);
269
      target_goto_bookmark (args, from_tty);
270
      return;
271
    }
272
 
273
  /* General case.  Bookmark identified by bookmark number.  */
274
  num = strtoul (args, NULL, 0);
275
  ALL_BOOKMARKS (b)
276
    if (b->number == num)
277
      break;
278
 
279
  if (b)
280
    {
281
      /* Found.  Send to target method.  */
282
      target_goto_bookmark (b->opaque_data, from_tty);
283
      return;
284
    }
285
  /* Not found.  */
286
  error (_("goto-bookmark: no bookmark found for '%s'."), args);
287
}
288
 
289
/* Implement "info bookmarks" command.  */
290
 
291
static void
292
bookmarks_info (char *args, int from_tty)
293
{
294
  struct bookmark *b;
295
  int bnum = -1;
296
  struct gdbarch *gdbarch;
297
 
298
  if (args)
299
    bnum = parse_and_eval_long (args);
300
 
301
  if (!bookmark_chain)
302
    {
303
      printf_filtered (_("No bookmarks.\n"));
304
      return;
305
    }
306
 
307
  gdbarch = get_regcache_arch (get_current_regcache ());
308
  printf_filtered (_("Bookmark    Address     Opaque\n"));
309
  printf_filtered (_("   ID                    Data \n"));
310
 
311
  ALL_BOOKMARKS (b)
312
    printf_filtered ("   %d       %s    '%s'\n",
313
                     b->number,
314
                     paddress (gdbarch, b->pc),
315
                     b->opaque_data);
316
}
317
 
318
 
319
/* Provide a prototype to silence -Wmissing-prototypes.  */
320
extern initialize_file_ftype _initialize_reverse;
321
 
322
void
323
_initialize_reverse (void)
324
{
325
  add_com ("reverse-step", class_run, reverse_step, _("\
326
Step program backward until it reaches the beginning of another source line.\n\
327
Argument N means do this N times (or till program stops for another reason).")
328
           );
329
  add_com_alias ("rs", "reverse-step", class_alias, 1);
330
 
331
  add_com ("reverse-next", class_run, reverse_next, _("\
332
Step program backward, proceeding through subroutine calls.\n\
333
Like the \"reverse-step\" command as long as subroutine calls do not happen;\n\
334
when they do, the call is treated as one instruction.\n\
335
Argument N means do this N times (or till program stops for another reason).")
336
           );
337
  add_com_alias ("rn", "reverse-next", class_alias, 1);
338
 
339
  add_com ("reverse-stepi", class_run, reverse_stepi, _("\
340
Step backward exactly one instruction.\n\
341
Argument N means do this N times (or till program stops for another reason).")
342
           );
343
  add_com_alias ("rsi", "reverse-stepi", class_alias, 0);
344
 
345
  add_com ("reverse-nexti", class_run, reverse_nexti, _("\
346
Step backward one instruction, but proceed through called subroutines.\n\
347
Argument N means do this N times (or till program stops for another reason).")
348
           );
349
  add_com_alias ("rni", "reverse-nexti", class_alias, 0);
350
 
351
  add_com ("reverse-continue", class_run, reverse_continue, _("\
352
Continue program being debugged but run it in reverse.\n\
353
If proceeding from breakpoint, a number N may be used as an argument,\n\
354
which means to set the ignore count of that breakpoint to N - 1 (so that\n\
355
the breakpoint won't break until the Nth time it is reached)."));
356
  add_com_alias ("rc", "reverse-continue", class_alias, 0);
357
 
358
  add_com ("reverse-finish", class_run, reverse_finish, _("\
359
Execute backward until just before selected stack frame is called."));
360
 
361
  add_com ("bookmark", class_bookmark, save_bookmark_command, _("\
362
Set a bookmark in the program's execution history.\n\
363
A bookmark represents a point in the execution history \n\
364
that can be returned to at a later point in the debug session."));
365
  add_info ("bookmarks", bookmarks_info, _("\
366
Status of user-settable bookmarks.\n\
367
Bookmarks are user-settable markers representing a point in the \n\
368
execution history that can be returned to later in the same debug \n\
369
session."));
370
  add_cmd ("bookmark", class_bookmark, delete_bookmark_command, _("\
371
Delete a bookmark from the bookmark list.\n\
372
Argument is a bookmark number, or no argument to delete all bookmarks.\n"),
373
           &deletelist);
374
  add_com ("goto-bookmark", class_bookmark, goto_bookmark_command, _("\
375
Go to an earlier-bookmarked point in the program's execution history.\n\
376
Argument is the bookmark number of a bookmark saved earlier by using \n\
377
the 'bookmark' command, or the special arguments:\n\
378
  start (beginning of recording)\n\
379
  end   (end of recording)\n"));
380
}

powered by: WebSVN 2.1.0

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