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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [gdb/] [gdbserver/] [mem-break.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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