source: rtems/c/src/librdbg/src/ptrace.c @ 4a501bd

4.104.114.84.95
Last change on this file since 4a501bd was ce8e6a8, checked in by Joel Sherrill <joel.sherrill@…>, on 07/01/02 at 22:14:25

2002-07-01 Joel Sherrill <joel@…>

  • src/_servtgt.c, src/ptrace.c: Corrected use of _Objects_Information_table now that it is a two dimensional array based upon API and class.
  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 **************************************************************************
3 *
4 * Component =   
5 *
6 * Synopsis  =   rkdb/rkdb.c
7 *
8 * $Id$
9 *
10 **************************************************************************
11 */
12
13#include <assert.h>
14#include <errno.h>
15#include <rdbg/rdbg.h>
16#include <rdbg/rdbg_f.h>
17#include <rdbg/servrpc.h>
18
19extern rtems_id serializeSemId;
20extern rtems_id wakeupEventSemId;
21extern rtems_id eventTaskId;
22extern rtems_id debugId;
23extern Exception_context *FirstCtx;
24extern Exception_context *LastCtx;
25extern CPU_Exception_frame SavedContext;
26extern unsigned int NbExceptCtx;
27
28/*
29 * return a pointer to the Thread Control structure of the specified
30 * Id
31 */
32
33  Thread_Control *
34Thread_Get_RDBG (Objects_Id Id)
35{
36  unsigned index;
37
38  if (Id < _Objects_Information_table[OBJECTS_CLASSIC_API][1]->maximum_id &&
39      Id > _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id) {
40
41    index = Id - _Objects_Information_table[OBJECTS_CLASSIC_API][1]->minimum_id;
42    if (_Objects_Information_table[OBJECTS_CLASSIC_API][1]->local_table[1 + index] != NULL) {
43      return (Thread_Control*) (_Objects_Information_table[OBJECTS_CLASSIC_API][1]->local_table[1 + index]);
44    }
45  }
46
47  if (Id < _Objects_Information_table[OBJECTS_POSIX_API][1]->maximum_id &&
48      Id > _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id) {
49
50    index = Id - _Objects_Information_table[OBJECTS_POSIX_API][1]->minimum_id;
51    if (_Objects_Information_table[OBJECTS_POSIX_API][1]->
52        local_table[1 + index] != NULL)
53      return (Thread_Control*) (_Objects_Information_table[OBJECTS_POSIX_API][1]->local_table[1 + index]);
54  }
55
56  return 0;
57
58}
59
60  int
61safeMemRead (void *src, void *dest, int nbBytes)
62{
63
64  /*
65   * safe because if it generates an exception,
66   * it must return normally
67   * TBD
68   */
69
70  memcpy (dest, src, nbBytes);
71  return 0;
72}
73
74  int
75safeMemWrite (void *src, void *dest, int nbBytes)
76{
77
78  /*
79   * safe because if it generates an exception,
80   * it must return normally
81   * TBD
82   */
83
84  memcpy (dest, src, nbBytes);
85  return 0;
86}
87
88  int
89ptrace (int request, int pid, char *addr, int data, char *addr2)
90{
91  int diag;
92  errno = 0;
93  if (pid != 1) {
94    errno = ESRCH;
95    return -1;
96  }
97  switch (request) {
98
99  case RPT_SINGLESTEP:{
100      Exception_context *ctx;
101
102      if (CannotRestart == 1) {
103        setErrno (EIO);
104        return -1;
105      }
106
107      if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
108        Single_Step (ctx->ctx);
109        rtems_semaphore_release (ctx->semaphoreId);
110        return 0;
111      }
112      break;
113    }
114
115  case RPT_PEEKTEXT:
116  case RPT_PEEKDATA:{
117      diag = safeMemRead (addr, &data, sizeof data);
118      if (diag == 0)
119        return data;
120    mem_error:
121      return -1;
122    }
123
124  case RPT_POKETEXT:{
125      diag = safeMemWrite (&data, addr, sizeof data);
126
127      /*
128       * We must flush the INSTR and DATA cache to be sure the
129       * opcode modification is taken into account, because
130       * the breakpoint opcode is written via the data cache
131       * while execution code is fetched via the instruction
132       * cache
133       */
134
135      if (diag == 0) {
136        copyback_data_cache_and_invalidate_instr_cache (addr, sizeof data);
137        return 0;
138      }
139      goto mem_error;
140    }
141  case RPT_POKEDATA:{
142      diag = safeMemWrite (&data, addr, sizeof data);
143      if (diag == 0)
144        return 0;
145      goto mem_error;
146    }
147  case RPT_CONT:{
148      Exception_context *ctx;
149
150      if (CannotRestart == 1) {
151        setErrno (EIO);
152        return -1;
153      }
154
155      ctx = GetExceptCtx (currentTargetThread);
156      if (ctx == NULL)
157        ctx = GetExceptCtx (debugId);
158
159      if (ctx != NULL) {
160
161        if (!isRdbgException (ctx)) {
162          CannotRestart = 1;
163          setErrno (EIO);
164          return -1;
165        }
166
167        assert (data == 0);
168        assert (ExitForSingleStep == 0);
169
170        rtems_semaphore_release (ctx->semaphoreId);
171      }
172      rtems_semaphore_release (serializeSemId);
173      return 0;
174    }
175
176  case RPT_ATTACH:
177    return 0;
178
179  case RPT_DETACH:{
180      Exception_context *ctx;
181
182      if (NbExceptCtx || NbSerializedCtx) {
183        ctx = FirstCtx;
184        rtems_task_delete (eventTaskId);
185        rtems_semaphore_delete (serializeSemId);
186        rtems_semaphore_delete (wakeupEventSemId);
187      }
188      return 0;
189    }
190
191  case RPT_GETREGS:{
192      Exception_context *ctx;
193
194      if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
195        CtxToRegs (ctx->ctx, (xdr_regs *) addr);
196        return 0;
197      }
198      break;
199    }
200
201  case RPT_SETREGS:{
202      Exception_context *ctx;
203
204      if ((ctx = GetExceptCtx (currentTargetThread)) != NULL) {
205        RegsToCtx ((xdr_regs *) addr, ctx->ctx);
206        return 0;
207      }
208      break;
209    }
210
211  case RPT_READTEXT:
212  case RPT_READDATA:{
213      diag = safeMemRead (addr, addr2, data);
214      if (diag == 0)
215        return 0;
216      goto mem_error;
217    }
218  case RPT_WRITETEXT:
219  case RPT_WRITEDATA:{
220      diag = safeMemWrite (addr2, addr, data);
221      if (diag == 0)
222        return 0;
223      goto mem_error;
224    }
225
226  case RPT_GETTARGETTHREAD:
227    if (!NbExceptCtx) {
228      errno = EBUSY;
229      return -1;
230    }
231    return currentTargetThread;
232
233  case RPT_SETTARGETTHREAD:
234    if (!NbExceptCtx) {
235      errno = EBUSY;
236      return -1;
237    }
238    currentTargetThread = data;
239    return 0;
240
241  case RPT_GETTHREADNAME:{
242      return TgtGetThreadName (NULL, (unsigned) (data), (char *) addr);
243    }
244
245  case RPT_THREADLIST:{
246      int count = TgtThreadList (NULL, (unsigned *) addr, UTHREAD_MAX
247                                 * sizeof (unsigned));
248      if (count < 0) {
249        errno = EINVAL;
250        return -1;
251      }
252      return count;
253    }
254
255  case RPT_SETTHREADREGS:{
256      Exception_context *ctx;
257      CPU_Exception_frame Ectx;
258      Thread_Control *thread;
259      rtems_id id;
260
261      rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
262      if (data == (unsigned) id)
263        break;
264
265      if ((ctx = GetExceptCtx (data)) != NULL) {
266        RegsToCtx ((xdr_regs *) addr, ctx->ctx);
267        return 0;
268      }
269      thread = Thread_Get_RDBG ((Objects_Id) (data));
270      if (thread != NULL) {
271        RegsToCtx ((xdr_regs *) addr, &Ectx);
272        set_ctx_thread (thread, &Ectx);
273        return 0;
274      }
275      break;
276    }
277
278  case RPT_GETTHREADREGS:{
279      Exception_context *ctx;
280      CPU_Exception_frame Ectx;
281      Thread_Control *thread;
282      rtems_id id;
283
284      rtems_task_ident (RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &id);
285      if (data == (unsigned) id) {
286        justSaveContext = 1;
287        enterRdbg ();
288        CtxToRegs (&(SavedContext), (xdr_regs *) addr);
289        return 0;
290      }
291
292      if ((ctx = GetExceptCtx (data)) != NULL) {
293        CtxToRegs (ctx->ctx, (xdr_regs *) addr);
294        return 0;
295      }
296      thread = Thread_Get_RDBG ((Objects_Id) (data));
297      if (thread != NULL) {
298        get_ctx_thread (thread, &Ectx);
299        CtxToRegs (&Ectx, (xdr_regs *) addr);
300        return 0;
301      }
302      break;
303    }
304
305  case RPT_KILL:
306    TotalReboot = 1;
307    return 0;
308
309  case RPT_TRACEME:
310  case RPT_PEEKUSER:
311  case RPT_POKEUSER:
312  case RPT_GETFPREGS:
313  case RPT_SETFPREGS:
314  case RPT_GETFPAREGS:
315  case RPT_SETFPAREGS:
316  case RPT_SYSCALL:
317  case RPT_DUMPCORE:
318  case RPT_GETUCODE:
319  case RPT_THREADSUSPEND:
320  case RPT_THREADRESUME:
321  case RPT_SETTHREADNAME:
322  default:
323    break;
324  }
325  errno = EINVAL;
326  return -1;
327}
Note: See TracBrowser for help on using the repository browser.