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

4.104.114.84.95
Last change on this file since 4e36a2f was 981b99f, checked in by Joel Sherrill <joel.sherrill@…>, on 08/10/99 at 16:41:44

Patch from Eric Valette <valette@…> and Emmanuel Raguet
<raguet@…>:

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