comparison packages/kernel/current/src/debug/dbg_gdb.cxx @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 /*==========================================================================
2 //
3 // dbg_gdb.c
4 //
5 // GDB Debugging Interface
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //==========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): nickg
33 // Contributors: nickg
34 // Date: 1998-08-22
35 // Purpose: GDB Debugging Interface
36 // Description: Interface for calls from GDB stubs into the OS. These
37 // currently mostly support thread awareness.
38 //
39 //####DESCRIPTIONEND####
40 //
41 //========================================================================*/
42
43 #include <pkgconf/kernel.h>
44 #include <pkgconf/hal.h> // CYG_HAL_USE_ROM_MONITOR_CYGMON
45
46 #ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
47
48 #include <cyg/kernel/ktypes.h>
49
50 #include <cyg/kernel/thread.hxx>
51 #include <cyg/kernel/sched.hxx>
52
53 #include <cyg/kernel/thread.inl>
54 #include <cyg/kernel/sched.inl>
55
56 #include <cyg/hal/hal_arch.h>
57
58 #if !defined(CYG_HAL_USE_ROM_MONITOR_CYGMON) \
59 && defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
60 // FIXME: This really needs to be handled in some other way.
61 #include <cyg/hal/hal_stub.h>
62 externC void __stub_copy_registers(target_register_t * dest,
63 target_register_t *src);
64 #endif
65
66 extern "C"
67 {
68 #include <cyg/hal/dbg-threads-api.h>
69 };
70
71 #define USE_ID 1
72
73 #if (CYG_BYTEORDER == CYG_LSBFIRST)
74
75 unsigned long swap32(unsigned long x)
76 {
77 unsigned long r = 0;
78
79 r |= (x>>24)&0xFF;
80 r |= ((x>>16)&0xFF)<<8;
81 r |= ((x>>8)&0xFF)<<16;
82 r |= ((x)&0xFF)<<24;
83
84 return r;
85 }
86
87 #else
88
89 #define swap32(x) ((unsigned long)(x))
90
91 #endif
92
93 //--------------------------------------------------------------------------
94
95 externC int dbg_thread_capabilities(struct dbg_capabilities * cpb)
96 {
97 cpb->mask1 = has_thread_current |
98 has_thread_registers |
99 has_thread_reg_change |
100 has_thread_list |
101 has_thread_info ;
102 return 1 ;
103 }
104
105 //--------------------------------------------------------------------------
106
107 static void dbg_make_threadref(Cyg_Thread *thread, threadref *ref )
108 {
109 cyg_uint16 id = thread->get_unique_id();
110
111 #if USE_ID
112 ((unsigned long *)ref)[0] = (unsigned long)thread;
113 ((unsigned long *)ref)[1] = (unsigned long)swap32(id);
114 #else
115 ((unsigned long *)ref)[1] = (unsigned long)thread;
116 ((unsigned long *)ref)[0] = (unsigned long)id;
117 #endif
118
119 }
120
121 static Cyg_Thread *dbg_get_thread( threadref *ref)
122 {
123 #if USE_ID
124
125 cyg_uint16 id = 0;
126
127 id = (cyg_uint16)swap32(((unsigned long *)ref)[1]);
128
129 Cyg_Thread *th = Cyg_Thread::get_list_head();
130 while( th != 0 )
131 {
132 if( th->get_unique_id() == id ) break;
133 th = th->get_list_next();
134 }
135
136 // if( thread->get_unique_id() != id ) th = 0;
137
138 #else
139
140 cyg_uint16 id = 0;
141
142 Cyg_Thread *thread = (Cyg_Thread *)(((unsigned long *)ref)[1]);
143 id = (cyg_uint16)(((unsigned long *)ref)[0]);
144
145 // Validate the thread.
146 Cyg_Thread *th = Cyg_Thread::get_list_head();
147 while( th != 0 )
148 {
149 if( th == thread ) break;
150 th = th->get_list_next();
151 }
152
153 // if( thread->get_unique_id() != id ) th = 0;
154
155 #endif
156
157 return th;
158 }
159
160 //--------------------------------------------------------------------------
161
162 externC int dbg_currthread(threadref * varparm)
163 {
164 Cyg_Thread *thread = Cyg_Scheduler::get_current_thread();
165
166 dbg_make_threadref(thread, varparm );
167
168 return 1 ;
169 }
170
171 //--------------------------------------------------------------------------
172
173 externC int dbg_currthread_id(void)
174 {
175 Cyg_Thread *thread = Cyg_Scheduler::get_current_thread();
176 return thread->get_unique_id ();
177 }
178
179 //--------------------------------------------------------------------------
180
181 externC int dbg_threadlist(int startflag,
182 threadref * lastthreadid,
183 threadref * next_thread)
184 {
185 Cyg_Thread *thread;
186 if( startflag )
187 {
188 thread = Cyg_Thread::get_list_head();
189 dbg_make_threadref(thread, next_thread);
190 }
191 else
192 {
193 thread = dbg_get_thread(lastthreadid);
194
195 if( thread == 0 ) return 0;
196 thread = thread->get_list_next();
197
198 if( thread == 0 ) return 0;
199 dbg_make_threadref(thread, next_thread);
200 }
201 return 1 ;
202 }
203
204 //--------------------------------------------------------------------------
205 // Some support routines for manufacturing thread info strings
206
207 static char *dbg_addstr(char *s, char *t)
208 {
209 while( (*s++ = *t++) != 0 );
210
211 return s-1;
212 }
213
214 static char *dbg_addint(char *s, int n, int base)
215 {
216 char buf[16];
217 char sign = '+';
218 cyg_count8 bpos;
219 char *digits = "0123456789ABCDEF";
220
221 if( n < 0 ) n = -n, sign = '-';
222
223 /* Set pos to start */
224 bpos = 0;
225
226 /* construct digits into buffer in reverse order */
227 if( n == 0 ) buf[bpos++] = '0';
228 else while( n != 0 )
229 {
230 cyg_ucount8 d = n % base;
231 buf[bpos++] = digits[d];
232 n /= base;
233 }
234
235 /* set sign if negative. */
236 if( sign == '-' )
237 {
238 buf[bpos] = sign;
239 }
240 else bpos--;
241
242 /* Now write it out in correct order. */
243 while( bpos >= 0 )
244 *s++ = buf[bpos--];
245
246 *s = 0;
247
248 return s;
249 }
250
251 static char *dbg_adddec(char *s, int x)
252 {
253 return dbg_addint(s, x, 10);
254 }
255
256 //--------------------------------------------------------------------------
257
258 externC int dbg_threadinfo(
259 threadref * threadid,
260 struct cygmon_thread_debug_info * info)
261 {
262 static char statebuf[60];
263
264 Cyg_Thread *thread = dbg_get_thread(threadid);
265 if( thread == 0 ) return 0;
266
267 info->context_exists = 1;
268
269 char *sbp = statebuf;
270 char *s;
271
272 if( thread->get_state() & Cyg_Thread::SUSPENDED )
273 {
274 sbp = dbg_addstr( sbp, "suspended+");
275 }
276
277 switch( thread->get_state() & ~Cyg_Thread::SUSPENDED )
278 {
279 case Cyg_Thread::RUNNING:
280 s = "running"; break;
281 case Cyg_Thread::SLEEPING:
282 s = "sleeping"; break;
283 case Cyg_Thread::COUNTSLEEP:
284 s = "counted sleep"; break;
285 case Cyg_Thread::CREATING:
286 s = "creating"; break;
287 case Cyg_Thread::EXITED:
288 s = "exited"; break;
289 default:
290 s = "unknown state"; break;
291 }
292
293 sbp = dbg_addstr( sbp, s );
294 sbp = dbg_addstr( sbp, ", Priority: " );
295 sbp = dbg_adddec( sbp, thread->get_priority() );
296
297 info->thread_display = statebuf;
298
299 #ifdef CYGVAR_KERNEL_THREADS_NAME
300 info->unique_thread_name = thread->get_name();
301 #else
302 info->unique_thread_name = 0;
303 #endif
304
305 info->more_display = 0;
306
307 return 1 ;
308 }
309
310 //--------------------------------------------------------------------------
311
312 externC int dbg_getthreadreg(
313 threadref * osthreadid,
314 int regcount, /* count of registers in the array */
315 void * regval) /* fillin this array */
316 {
317 Cyg_Thread *thread = dbg_get_thread(osthreadid);
318
319 if( thread == 0 ) return 0;
320
321 if( thread == Cyg_Scheduler::get_current_thread() )
322 {
323 #if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
324 // We have no state for the current thread, Cygmon has
325 // got that and we cannot get at it.
326 return 0;
327 #elif defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
328 // _registers hold the state of the current thread.
329 extern target_register_t * _registers;
330
331 __stub_copy_registers ((target_register_t *)regval, _registers);
332 #else
333 return 0;
334 #endif
335 }
336 else
337 {
338 HAL_SavedRegisters *regs = thread->get_saved_context();
339 if( regs == 0 ) return 0;
340
341 HAL_GET_GDB_REGISTERS (regval, regs);
342 }
343
344 return 1 ;
345 }
346
347 //--------------------------------------------------------------------------
348
349 externC int dbg_setthreadreg(
350 threadref * osthreadid,
351 int regcount , /* number of registers */
352 void * regval)
353 {
354 Cyg_Thread *thread = dbg_get_thread(osthreadid);
355
356 if( thread == 0 ) return 0;
357
358 if( thread == Cyg_Scheduler::get_current_thread() )
359 {
360 #if defined(CYG_HAL_USE_ROM_MONITOR_CYGMON)
361 // We have no state for the current thread, Cygmon has
362 // got that and we cannot get at it.
363 return 0;
364 #elif defined(CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS)
365 // _registers hold the state of the current thread.
366 extern target_register_t * _registers;
367
368 __stub_copy_registers (_registers, (target_register_t *)regval);
369 #else
370 return 0;
371 #endif
372 }
373 else
374 {
375 HAL_SavedRegisters *regs = thread->get_saved_context();
376 if( regs == 0 ) return 0;
377
378 HAL_SET_GDB_REGISTERS (regs, regval);
379 }
380
381
382 return 1;
383 }
384
385 #endif // CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
386
387 //--------------------------------------------------------------------------
388 // End of dbg_gdb.cxx