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

Subversion Repositories openrisc_me

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

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

Line No. Rev Author Line
1 24 jeremybenn
/* Memory breakpoint operations for the remote server for GDB.
2
   Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc.
3
 
4
   Contributed by MontaVista Software.
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 3 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, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "server.h"
22
 
23
const unsigned char *breakpoint_data;
24
int breakpoint_len;
25
 
26
#define MAX_BREAKPOINT_LEN 8
27
 
28
struct breakpoint
29
{
30
  struct breakpoint *next;
31
  CORE_ADDR pc;
32
  unsigned char old_data[MAX_BREAKPOINT_LEN];
33
 
34
  /* Non-zero iff we are stepping over this breakpoint.  */
35
  int reinserting;
36
 
37
  /* Non-NULL iff this breakpoint was inserted to step over
38
     another one.  Points to the other breakpoint (which is also
39
     in the *next chain somewhere).  */
40
  struct breakpoint *breakpoint_to_reinsert;
41
 
42
  /* Function to call when we hit this breakpoint.  If it returns 1,
43
     the breakpoint will be deleted; 0, it will be reinserted for
44
     another round.  */
45
  int (*handler) (CORE_ADDR);
46
};
47
 
48
struct breakpoint *breakpoints;
49
 
50
void
51
set_breakpoint_at (CORE_ADDR where, int (*handler) (CORE_ADDR))
52
{
53
  struct breakpoint *bp;
54
 
55
  if (breakpoint_data == NULL)
56
    error ("Target does not support breakpoints.");
57
 
58
  bp = malloc (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 = breakpoints;
70
  breakpoints = bp;
71
}
72
 
73
static void
74
delete_breakpoint (struct breakpoint *bp)
75
{
76
  struct breakpoint *cur;
77
 
78
  if (breakpoints == bp)
79
    {
80
      breakpoints = bp->next;
81
      (*the_target->write_memory) (bp->pc, bp->old_data,
82
                                   breakpoint_len);
83
      free (bp);
84
      return;
85
    }
86
  cur = breakpoints;
87
  while (cur->next)
88
    {
89
      if (cur->next == bp)
90
        {
91
          cur->next = bp->next;
92
          (*the_target->write_memory) (bp->pc, bp->old_data,
93
                                       breakpoint_len);
94
          free (bp);
95
          return;
96
        }
97
    }
98
  warning ("Could not find breakpoint in list.");
99
}
100
 
101
static struct breakpoint *
102
find_breakpoint_at (CORE_ADDR where)
103
{
104
  struct breakpoint *bp = breakpoints;
105
 
106
  while (bp != NULL)
107
    {
108
      if (bp->pc == where)
109
        return bp;
110
      bp = bp->next;
111
    }
112
 
113
  return NULL;
114
}
115
 
116
void
117
delete_breakpoint_at (CORE_ADDR addr)
118
{
119
  struct breakpoint *bp = find_breakpoint_at (addr);
120
  if (bp != NULL)
121
    delete_breakpoint (bp);
122
}
123
 
124
static int
125
reinsert_breakpoint_handler (CORE_ADDR stop_pc)
126
{
127
  struct breakpoint *stop_bp, *orig_bp;
128
 
129
  stop_bp = find_breakpoint_at (stop_pc);
130
  if (stop_bp == NULL)
131
    error ("lost the stopping breakpoint.");
132
 
133
  orig_bp = stop_bp->breakpoint_to_reinsert;
134
  if (orig_bp == NULL)
135
    error ("no breakpoint to reinsert");
136
 
137
  (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
138
                               breakpoint_len);
139
  orig_bp->reinserting = 0;
140
  return 1;
141
}
142
 
143
void
144
reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
145
{
146
  struct breakpoint *bp, *orig_bp;
147
 
148
  orig_bp = find_breakpoint_at (stop_pc);
149
  if (orig_bp == NULL)
150
    error ("Could not find original breakpoint in list.");
151
 
152
  set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
153
 
154
  bp = find_breakpoint_at (stop_at);
155
  if (bp == NULL)
156
    error ("Could not find breakpoint in list (reinserting by breakpoint).");
157
  bp->breakpoint_to_reinsert = orig_bp;
158
 
159
  (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data,
160
                               breakpoint_len);
161
  orig_bp->reinserting = 1;
162
}
163
 
164
void
165
uninsert_breakpoint (CORE_ADDR stopped_at)
166
{
167
  struct breakpoint *bp;
168
 
169
  bp = find_breakpoint_at (stopped_at);
170
  if (bp == NULL)
171
    error ("Could not find breakpoint in list (uninserting).");
172
 
173
  (*the_target->write_memory) (bp->pc, bp->old_data,
174
                               breakpoint_len);
175
  bp->reinserting = 1;
176
}
177
 
178
void
179
reinsert_breakpoint (CORE_ADDR stopped_at)
180
{
181
  struct breakpoint *bp;
182
 
183
  bp = find_breakpoint_at (stopped_at);
184
  if (bp == NULL)
185
    error ("Could not find breakpoint in list (uninserting).");
186
  if (! bp->reinserting)
187
    error ("Breakpoint already inserted at reinsert time.");
188
 
189
  (*the_target->write_memory) (bp->pc, breakpoint_data,
190
                               breakpoint_len);
191
  bp->reinserting = 0;
192
}
193
 
194
int
195
check_breakpoints (CORE_ADDR stop_pc)
196
{
197
  struct breakpoint *bp;
198
 
199
  bp = find_breakpoint_at (stop_pc);
200
  if (bp == NULL)
201
    return 0;
202
  if (bp->reinserting)
203
    {
204
      warning ("Hit a removed breakpoint?");
205
      return 0;
206
    }
207
 
208
  if ((*bp->handler) (bp->pc))
209
    {
210
      delete_breakpoint (bp);
211
      return 2;
212
    }
213
  else
214
    return 1;
215
}
216
 
217
void
218
set_breakpoint_data (const unsigned char *bp_data, int bp_len)
219
{
220
  breakpoint_data = bp_data;
221
  breakpoint_len = bp_len;
222
}
223
 
224
void
225
check_mem_read (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
226
{
227
  struct breakpoint *bp = breakpoints;
228
  CORE_ADDR mem_end = mem_addr + mem_len;
229
 
230
  for (; bp != NULL; bp = bp->next)
231
    {
232
      CORE_ADDR bp_end = bp->pc + breakpoint_len;
233
      CORE_ADDR start, end;
234
      int copy_offset, copy_len, buf_offset;
235
 
236
      if (mem_addr >= bp_end)
237
        continue;
238
      if (bp->pc >= mem_end)
239
        continue;
240
 
241
      start = bp->pc;
242
      if (mem_addr > start)
243
        start = mem_addr;
244
 
245
      end = bp_end;
246
      if (end > mem_end)
247
        end = mem_end;
248
 
249
      copy_len = end - start;
250
      copy_offset = start - bp->pc;
251
      buf_offset = start - mem_addr;
252
 
253
      memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
254
    }
255
}
256
 
257
void
258
check_mem_write (CORE_ADDR mem_addr, unsigned char *buf, int mem_len)
259
{
260
  struct breakpoint *bp = breakpoints;
261
  CORE_ADDR mem_end = mem_addr + mem_len;
262
 
263
  for (; bp != NULL; bp = bp->next)
264
    {
265
      CORE_ADDR bp_end = bp->pc + breakpoint_len;
266
      CORE_ADDR start, end;
267
      int copy_offset, copy_len, buf_offset;
268
 
269
      if (mem_addr >= bp_end)
270
        continue;
271
      if (bp->pc >= mem_end)
272
        continue;
273
 
274
      start = bp->pc;
275
      if (mem_addr > start)
276
        start = mem_addr;
277
 
278
      end = bp_end;
279
      if (end > mem_end)
280
        end = mem_end;
281
 
282
      copy_len = end - start;
283
      copy_offset = start - bp->pc;
284
      buf_offset = start - mem_addr;
285
 
286
      memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
287
      if (bp->reinserting == 0)
288
        memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
289
    }
290
}
291
 
292
/* Delete all breakpoints.  */
293
 
294
void
295
delete_all_breakpoints (void)
296
{
297
  while (breakpoints)
298
    delete_breakpoint (breakpoints);
299
}

powered by: WebSVN 2.1.0

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