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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [gdbserver/] [mem-break.c] - Blame information for rev 231

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

Line No. Rev Author Line
1 227 jeremybenn
/* Memory breakpoint operations for the remote server for GDB.
2
   Copyright (C) 2002, 2003, 2005, 2007, 2008, 2009, 2010
3
   Free Software Foundation, Inc.
4
 
5
   Contributed by MontaVista Software.
6
 
7
   This file is part of GDB.
8
 
9
   This program is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3 of the License, or
12
   (at your option) any later version.
13
 
14
   This program is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
 
22
#include "server.h"
23
 
24
const unsigned char *breakpoint_data;
25
int breakpoint_len;
26
 
27
#define MAX_BREAKPOINT_LEN 8
28
 
29
struct breakpoint
30
{
31
  struct breakpoint *next;
32
  CORE_ADDR pc;
33
  unsigned char old_data[MAX_BREAKPOINT_LEN];
34
 
35
  /* Non-zero iff we are stepping over this breakpoint.  */
36
  int reinserting;
37
 
38
  /* Non-NULL iff this breakpoint was inserted to step over
39
     another one.  Points to the other breakpoint (which is also
40
     in the *next chain somewhere).  */
41
  struct breakpoint *breakpoint_to_reinsert;
42
 
43
  /* Function to call when we hit this breakpoint.  If it returns 1,
44
     the breakpoint will be deleted; 0, it will be reinserted for
45
     another round.  */
46
  int (*handler) (CORE_ADDR);
47
};
48
 
49
void
50
set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
51
{
52
  struct process_info *proc = current_process ();
53
  struct breakpoint *bp;
54
 
55
  if (breakpoint_data == NULL)
56
    error ("Target does not support breakpoints.");
57
 
58
  bp = xmalloc (sizeof (struct breakpoint));
59
  memset (bp, 0, sizeof (struct breakpoint));
60
 
61
  (*the_target->read_memory) (where, bp->old_data,
62
                              breakpoint_len);
63
  (*the_target->write_memory) (where, breakpoint_data,
64
                               breakpoint_len);
65
 
66
  bp->pc = where;
67
  bp->handler = handler;
68
 
69
  bp->next = proc->breakpoints;
70
  proc->breakpoints = bp;
71
}
72
 
73
static void
74
delete_breakpoint (struct breakpoint *bp)
75
{
76
  struct process_info *proc = current_process ();
77
  struct breakpoint *cur;
78
 
79
  if (proc->breakpoints == bp)
80
    {
81
      proc->breakpoints = bp->next;
82
      (*the_target->write_memory) (bp->pc, bp->old_data,
83
                                   breakpoint_len);
84
      free (bp);
85
      return;
86
    }
87
  cur = proc->breakpoints;
88
  while (cur->next)
89
    {
90
      if (cur->next == bp)
91
        {
92
          cur->next = bp->next;
93
          (*the_target->write_memory) (bp->pc, bp->old_data,
94
                                       breakpoint_len);
95
          free (bp);
96
          return;
97
        }
98
    }
99
  warning ("Could not find breakpoint in list.");
100
}
101
 
102
static struct breakpoint *
103
find_breakpoint_at (CORE_ADDR where)
104
{
105
  struct process_info *proc = current_process ();
106
  struct breakpoint *bp = proc->breakpoints;
107
 
108
  while (bp != NULL)
109
    {
110
      if (bp->pc == where)
111
        return bp;
112
      bp = bp->next;
113
    }
114
 
115
  return NULL;
116
}
117
 
118
void
119
delete_breakpoint_at (CORE_ADDR addr)
120
{
121
  struct breakpoint *bp = find_breakpoint_at (addr);
122
  if (bp != NULL)
123
    delete_breakpoint (bp);
124
}
125
 
126
static int
127
reinsert_breakpoint_handler (CORE_ADDR stop_pc)
128
{
129
  struct breakpoint *stop_bp, *orig_bp;
130
 
131
  stop_bp = find_breakpoint_at (stop_pc);
132
  if (stop_bp == NULL)
133
    error ("lost the stopping breakpoint.");
134
 
135
  orig_bp = stop_bp->breakpoint_to_reinsert;
136
  if (orig_bp == NULL)
137
    error ("no breakpoint to reinsert");
138
 
139
  (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
140
                               breakpoint_len);
141
  orig_bp->reinserting = 0;
142
  return 1;
143
}
144
 
145
void
146
reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
147
{
148
  struct breakpoint *bp, *orig_bp;
149
 
150
  orig_bp = find_breakpoint_at (stop_pc);
151
  if (orig_bp == NULL)
152
    error ("Could not find original breakpoint in list.");
153
 
154
  set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
155
 
156
  bp = find_breakpoint_at (stop_at);
157
  if (bp == NULL)
158
    error ("Could not find breakpoint in list (reinserting by breakpoint).");
159
  bp->breakpoint_to_reinsert = orig_bp;
160
 
161
  (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data,
162
                               breakpoint_len);
163
  orig_bp->reinserting = 1;
164
}
165
 
166
void
167
uninsert_breakpoint (CORE_ADDR stopped_at)
168
{
169
  struct breakpoint *bp;
170
 
171
  bp = find_breakpoint_at (stopped_at);
172
  if (bp == NULL)
173
    error ("Could not find breakpoint in list (uninserting).");
174
 
175
  (*the_target->write_memory) (bp->pc, bp->old_data,
176
                               breakpoint_len);
177
  bp->reinserting = 1;
178
}
179
 
180
void
181
reinsert_breakpoint (CORE_ADDR stopped_at)
182
{
183
  struct breakpoint *bp;
184
 
185
  bp = find_breakpoint_at (stopped_at);
186
  if (bp == NULL)
187
    error ("Could not find breakpoint in list (uninserting).");
188
  if (! bp->reinserting)
189
    error ("Breakpoint already inserted at reinsert time.");
190
 
191
  (*the_target->write_memory) (bp->pc, breakpoint_data,
192
                               breakpoint_len);
193
  bp->reinserting = 0;
194
}
195
 
196
int
197
check_breakpoints (CORE_ADDR stop_pc)
198
{
199
  struct breakpoint *bp;
200
 
201
  bp = find_breakpoint_at (stop_pc);
202
  if (bp == NULL)
203
    return 0;
204
  if (bp->reinserting)
205
    {
206
      warning ("Hit a removed breakpoint?");
207
      return 0;
208
    }
209
 
210
  if ((*bp->handler) (bp->pc))
211
    {
212
      delete_breakpoint (bp);
213
      return 2;
214
    }
215
  else
216
    return 1;
217
}
218
 
219
void
220
set_breakpoint_data (const unsigned char *bp_data, int bp_len)
221
{
222
  breakpoint_data = bp_data;
223
  breakpoint_len = bp_len;
224
}
225
 
226
void
227
check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
228
{
229
  struct process_info *proc = current_process ();
230
  struct breakpoint *bp = proc->breakpoints;
231
  CORE_ADDR mem_end = mem_addr + mem_len;
232
 
233
  for (; bp != NULL; bp = bp->next)
234
    {
235
      CORE_ADDR bp_end = bp->pc + breakpoint_len;
236
      CORE_ADDR start, end;
237
      int copy_offset, copy_len, buf_offset;
238
 
239
      if (mem_addr >= bp_end)
240
        continue;
241
      if (bp->pc >= mem_end)
242
        continue;
243
 
244
      start = bp->pc;
245
      if (mem_addr > start)
246
        start = mem_addr;
247
 
248
      end = bp_end;
249
      if (end > mem_end)
250
        end = mem_end;
251
 
252
      copy_len = end - start;
253
      copy_offset = start - bp->pc;
254
      buf_offset = start - mem_addr;
255
 
256
      memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
257
    }
258
}
259
 
260
void
261
check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
262
{
263
  struct process_info *proc = current_process ();
264
  struct breakpoint *bp = proc->breakpoints;
265
  CORE_ADDR mem_end = mem_addr + mem_len;
266
 
267
  for (; bp != NULL; bp = bp->next)
268
    {
269
      CORE_ADDR bp_end = bp->pc + breakpoint_len;
270
      CORE_ADDR start, end;
271
      int copy_offset, copy_len, buf_offset;
272
 
273
      if (mem_addr >= bp_end)
274
        continue;
275
      if (bp->pc >= mem_end)
276
        continue;
277
 
278
      start = bp->pc;
279
      if (mem_addr > start)
280
        start = mem_addr;
281
 
282
      end = bp_end;
283
      if (end > mem_end)
284
        end = mem_end;
285
 
286
      copy_len = end - start;
287
      copy_offset = start - bp->pc;
288
      buf_offset = start - mem_addr;
289
 
290
      memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
291
      if (bp->reinserting == 0)
292
        memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
293
    }
294
}
295
 
296
/* Delete all breakpoints, and un-insert them from the inferior.  */
297
 
298
void
299
delete_all_breakpoints (void)
300
{
301
  struct process_info *proc = current_process ();
302
 
303
  while (proc->breakpoints)
304
    delete_breakpoint (proc->breakpoints);
305
}
306
 
307
/* Release all breakpoints, but do not try to un-insert them from the
308
   inferior.  */
309
 
310
void
311
free_all_breakpoints (struct process_info *proc)
312
{
313
  struct breakpoint *bp;
314
 
315
  while (proc->breakpoints)
316
    {
317
      bp = proc->breakpoints;
318
      proc->breakpoints = bp->next;
319
      free (bp);
320
    }
321
}

powered by: WebSVN 2.1.0

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