remove const from TPL_OpenTPLFromMemory since the memory is altered
[libogc.git] / libdb / debug_supp.c
blob5ac1df4c92db837224e57253056fab505aef869e
1 #include <stdlib.h>
2 #include <string.h>
3 #include <stdio.h>
4 #include <gccore.h>
6 #include "lwp_threads.h"
7 #include "debug_supp.h"
9 extern lwp_objinfo _lwp_cond_objects;
10 extern lwp_objinfo _lwp_thr_objects;
11 extern lwp_objinfo _lwp_tqueue_objects;
12 extern lwp_objinfo _lwp_mqbox_objects;
13 extern lwp_objinfo _lwp_mutex_objects;
14 extern lwp_objinfo _lwp_sema_objects;
16 extern const u8 hexchars[];
18 extern u8 __text_start[],__data_start[],__bss_start[];
19 extern u8 __text_fstart[],__data_fstart[],__bss_fstart[];
21 s32 hstr2nibble(const char *buf,s32 *nibble)
23 s32 ch;
25 ch = *buf;
26 if(ch>='0' && ch<='9') {
27 *nibble = ch - '0';
28 return 1;
30 if(ch>='a' && ch<='f') {
31 *nibble = ch - 'a' + 10;
32 return 1;
34 if(ch>='A' && ch<='F') {
35 *nibble = ch - 'A' + 10;
36 return 1;
38 return 0;
41 s32 hstr2byte(const char *buf,s32 *bval)
43 s32 hnib,lnib;
45 if(!hstr2nibble(buf,&hnib) || !hstr2nibble(buf+1,&lnib)) return 0;
47 *bval = (hnib<<4)|lnib;
48 return 1;
51 const char* vhstr2int(const char *buf,s32 *ival)
53 s32 i,val,nibble;
54 s32 found0,lim;
56 found0 = 0;
57 for(i=0;i<8;i++,buf++) {
58 if(*buf!='0') break;
60 found0 = 1;
63 val = 0;
64 lim = 8 - i;
65 for(i=0;i<lim;i++,buf++) {
66 if(!hstr2nibble(buf,&nibble)) {
67 if(i==0 && !found0) return NULL;
69 *ival = val;
70 return buf;
72 val = (val<<4)|nibble;
74 if(hstr2nibble(buf,&nibble)) return NULL;
76 *ival = val;
77 return buf;
80 const char* fhstr2int(const char *buf,s32 *ival)
82 s32 i,val,nibble;
84 val = 0;
85 for(i=0;i<8;i++,buf++) {
86 if(!hstr2nibble(buf,&nibble)) return NULL;
88 val = (val<<4)|nibble;
91 *ival = val;
92 return buf;
95 char* int2fhstr(char *buf,s32 val)
97 s32 i,nibble,shift;
99 for(i=0,shift=28;i<8;i++,shift-=4,buf++) {
100 nibble = (val>>shift)&0x0f;
101 *buf = hexchars[nibble];
103 return buf;
106 char* int2vhstr(char *buf,s32 val)
108 s32 i,nibble,shift;
110 for(i=0,shift=28;i<8;i++,shift-=4) {
111 nibble = (val>>shift)&0x0f;
112 if(nibble) break;
114 if(i==8) {
115 *buf++ = '0';
116 return buf;
119 *buf++ = hexchars[nibble];
120 for(i++,shift-=4;i<8;i++,shift-=4,buf++) {
121 nibble = (val>>shift)&0x0f;
122 *buf = hexchars[nibble];
124 return buf;
127 char* mem2hstr(char *buf,const char *mem,s32 count)
129 s32 i;
130 char ch;
132 for(i=0;i<count;i++,mem++) {
133 ch = *mem;
134 *buf++ = hexchars[ch>>4];
135 *buf++ = hexchars[ch&0x0f];
137 *buf = 0;
138 return buf;
140 char* thread2fhstr(char *buf,s32 thread)
142 s32 i,nibble,shift;
144 for(i=0;i<8;i++,buf++) *buf = '0';
145 for(i=0,shift=28;i<8;i++,shift-=4,buf++) {
146 nibble = (thread>>shift)&0x0f;
147 *buf = hexchars[nibble];
149 return buf;
152 char* thread2vhstr(char *buf,s32 thread)
154 s32 i,nibble,shift;
156 for(i=0,shift=28;i<8;i++,shift-=4) {
157 nibble = (thread>>shift)&0x0f;
158 if(nibble) break;
160 if(i==8) {
161 *buf++ = '0';
162 return buf;
165 *buf++ = hexchars[nibble];
166 for(i++,shift-=4;i<8;i++,shift-=4,buf++) {
167 nibble = (thread>>shift)&0x0f;
168 *buf = hexchars[nibble];
170 return buf;
173 const char* fhstr2thread(const char *buf,s32 *thread)
175 s32 i,nibble,val;
177 for(i=0;i<8;i++,buf++)
178 if(*buf!='0') return NULL;
180 val = 0;
181 for(i=0;i<8;i++,buf++) {
182 if(!hstr2nibble(buf,&nibble)) return NULL;
184 val = (val<<4)|nibble;
187 *thread = val;
188 return buf;
191 const char* vhstr2thread(const char *buf,s32 *thread)
193 s32 i,val,nibble;
194 s32 found0,lim;
196 found0 = 0;
197 for(i=0;i<16;i++,buf++) {
198 if(*buf!='0') break;
200 found0 = 1;
203 val = 0;
204 lim = 16 - i;
205 for(i=0;i<lim;i++,buf++) {
206 if(!hstr2nibble(buf,&nibble)) {
207 if(i==0 && found0) return NULL;
209 *thread = val;
210 return buf;
213 val = (val<<4)|nibble;
215 if(hstr2nibble(buf,&nibble)) return NULL;
217 *thread = val;
218 return buf;
221 s32 gdbstub_idtoindex(s32 objid)
223 s32 min_id,max_id;
224 s32 first_id;
226 if(_thr_executing==_thr_idle) return 1;
228 first_id = 1;
229 min_id = _lwp_thr_objects.min_id;
230 max_id = _lwp_thr_objects.max_id;
231 if(objid>=min_id && objid<max_id) return first_id + (objid - min_id);
233 return 1;
236 lwp_cntrl* gdbstub_indextoid(s32 thread)
238 s32 objid;
239 s32 min_id,max_id,first_id;
240 lwp_cntrl *th;
242 if(thread<=0) return NULL;
244 if(thread==1) return _thr_idle;
246 first_id = 1;
247 objid = _thr_executing->object.id;
248 min_id = _lwp_thr_objects.min_id;
249 max_id = _lwp_thr_objects.max_id;
250 if(thread<(first_id + (max_id - min_id))) {
251 th = (lwp_cntrl*)_lwp_thr_objects.local_table[thread - first_id];
252 return th;
254 return NULL;
257 s32 gdbstub_getcurrentthread()
259 return gdbstub_idtoindex(_thr_executing->object.id);
262 s32 gdbstub_getnextthread(s32 athread)
264 s32 id,start;
265 s32 first_id,min_id,max_id,lim;
267 if(athread<1) return 1;
269 first_id = 1;
270 min_id = _lwp_thr_objects.min_id;
271 max_id = _lwp_thr_objects.max_id;
272 lim = first_id + max_id - min_id;
273 if(athread<lim) {
274 if(athread<first_id)
275 start = first_id;
276 else
277 start = athread+1;
279 for(id=start;id<lim;id++)
280 if(_lwp_thr_objects.local_table[id - first_id]!=NULL) return id;
283 return 0;
286 s32 gdbstub_getoffsets(char **textaddr,char **dataaddr,char **bssaddr)
288 *textaddr = (char*)((u32)__text_fstart - (u32)__text_fstart);
289 *dataaddr = (char*)((u32)__data_fstart - (u32)__text_fstart);
290 *bssaddr = (char*)((u32)__bss_fstart - (u32)__text_fstart);
292 return 1;
295 s32 gdbstub_getthreadinfo(s32 thread,struct gdbstub_threadinfo *info)
297 s32 first_id,min_id,max_id;
298 lwp_cntrl *th;
299 char tmp_buf[20];
301 if(thread<=0) return 0;
303 if(thread==1) {
304 strcpy(info->display,"idle thread");
305 strcpy(info->name,"IDLE");
306 info->more_display[0] = 0;
307 return 1;
310 first_id = 1;
311 min_id = _lwp_thr_objects.min_id;
312 max_id = _lwp_thr_objects.max_id;
313 if(thread<=(first_id + (max_id - min_id))){
314 th = (lwp_cntrl*)_lwp_thr_objects.local_table[thread - first_id];
315 if(th==NULL) return 0;
317 strcpy(info->display,"libogc task: control at: 0x");
318 tmp_buf[0] = hexchars[(((int)th)>>28)&0x0f];
319 tmp_buf[1] = hexchars[(((int)th)>>24)&0x0f];
320 tmp_buf[2] = hexchars[(((int)th)>>20)&0x0f];
321 tmp_buf[3] = hexchars[(((int)th)>>16)&0x0f];
322 tmp_buf[4] = hexchars[(((int)th)>>12)&0x0f];
323 tmp_buf[5] = hexchars[(((int)th)>>8)&0x0f];
324 tmp_buf[6] = hexchars[(((int)th)>>4)&0x0f];
325 tmp_buf[7] = hexchars[((int)th)&0x0f];
326 tmp_buf[8] = 0;
327 strcat(info->display,tmp_buf);
329 info->name[0] = 0;
330 info->name[1] = 0;
331 info->name[2] = 0;
332 info->name[3] = 0;
333 info->name[4] = 0;
335 info->more_display[0] = 0;
336 return 1;
338 return 0;
341 s32 parsezbreak(const char *in,int *type,char **addr,int *len)
343 s32 ttmp,atmp,ltmp;
345 in++;
346 if(!hstr2nibble(in,&ttmp) || *(in+1)!=',') return 0;
348 in += 2;
349 in = vhstr2int(in,&atmp);
350 if(in==NULL || *in!=',') return 0;
352 in++;
353 in = vhstr2int(in,&ltmp);
354 if(in==NULL || ltmp<1) return 0;
356 *type = ttmp;
357 *addr = (char*)atmp;
358 *len = ltmp;
360 return 1;
363 s32 parseqp(const char *in,s32 *mask,s32 *thread)
365 const char *ptr;
367 ptr = fhstr2int(in+2,mask);
368 if(ptr==NULL) return 0;
370 ptr = fhstr2thread(ptr,thread);
371 if(ptr==NULL) return 0;
373 return 1;
376 void packqq(char *out,s32 mask,s32 thread,struct gdbstub_threadinfo *info)
378 s32 len;
380 *out++ = 'q';
381 *out++ = 'Q';
382 out = int2fhstr(out,mask);
383 out = thread2fhstr(out,thread);
385 if(mask&0x01) {
386 memcpy(out,"00000001",8);
387 out += 8;
388 *out++ = '1';
389 *out++ = '0';
390 out = thread2fhstr(out,thread);
392 if(mask&0x02) {
393 memcpy(out,"00000002",8);
394 out += 8;
395 *out++ = '0';
396 *out++ = '1';
397 *out++ = '1';
399 if(mask&0x04) {
400 memcpy(out,"00000004",8);
401 out += 8;
403 info->display[sizeof(info->display)-1] = 0; //for god sake
404 len = strlen(info->display);
406 *out++ = hexchars[(len>>4)&0x0f];
407 *out++ = hexchars[len&0x0f];
409 memcpy(out,info->display,len);
410 out += len;
412 if(mask&0x08) {
413 memcpy(out,"00000008",8);
414 out += 8;
416 info->display[sizeof(info->name)-1] = 0; //for god sake
417 len = strlen(info->name);
419 *out++ = hexchars[(len>>4)&0x0f];
420 *out++ = hexchars[len&0x0f];
422 memcpy(out,info->name,len);
423 out += len;
425 if(mask&0x10) {
426 memcpy(out,"00000010",8);
427 out += 8;
429 info->display[sizeof(info->more_display)-1] = 0; //for god sake
430 len = strlen(info->more_display);
432 *out++ = hexchars[(len>>4)&0x0f];
433 *out++ = hexchars[len&0x0f];
435 memcpy(out,info->more_display,len);
436 out += len;
438 *out = 0;
441 s32 parseql(const char *in,s32 *first,s32 *max_cnt,s32 *athread)
443 const char *ptr;
445 ptr = in+2;
446 if(!hstr2nibble(ptr,first)) return 0;
448 ptr++;
449 if(!hstr2byte(ptr,max_cnt)) return 0;
451 ptr += 2;
452 ptr = fhstr2thread(ptr,athread);
453 if(ptr==NULL) return 0;
455 return 1;
458 char* reserve_qmheader(char *out)
460 return (out+21);
463 char* packqmthread(char *out,s32 thread)
465 return thread2fhstr(out,thread);
468 void packqmheader(char *out,s32 count,s32 done,s32 athread)
470 *out++ = 'q';
471 *out++ = 'M';
472 *out++ = hexchars[(count>>4)&0x0f];
473 *out++ = hexchars[count&0x0f];
475 if(done) *out++ = '1';
476 else *out++ = '0';
478 thread2fhstr(out,athread);