source: rtems/c/src/lib/librdbg/ptrace.c @ 08b5f55

4.104.114.84.95
Last change on this file since 08b5f55 was 4721cf1, checked in by Joel Sherrill <joel.sherrill@…>, on 12/03/98 at 23:54:14

Patch from Emmanuel Raguet <raguet@…> to add remote debug server
and RPC support to RTEMS. Thanks. :) Email follows:

Hello,

For Xmas, here is the Remote Debugger on RTEMS !

Here are 2 patches for the Remote Debugger on RTEMS for pc386 from Linux
host :

  • one for RTEMS it self,
  • one for GDB-4.17.

1/ RTEMS patch
--------------

This patch adds 2 libraries :

  • a simplified SUN RPC library
  • the Remote Debugger library

The configuration command is the following :
../rtems4/configure --target=i386-rtemself --enable-rtemsbsp=pc386
--enable-rdbg

The SUN RPC library is built only if networking is set.
The RDBG library is built if networking and enable-rdbg are set.

The function used to initialize the debugger is :

rtems_rdbg_initialize ();

A special function has been created to force a task to be
in a "debug" state : enterRdbg().
The use of this function is not mandatory.

2/ GDB-4.17 patch
-----------------

This patch create a new RTEMS target for GDB-4.17.

The configuration command is the following :
./configure --enable-shared --target=i386RTEMS

To connect to a target, use :

target rtems [your_site_address]

Then, attach the target using : attach 1

And... Debug ;)

You can obtain the original GDB-4.17 on
ftp://ftp.debian.org/debian/dists/stable/main/source/devel/gdb_4.17.orig.tar.gz

This has been tested from a Debian 2.0.1 linux host.

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