/[pearpc]/src/debug/debugger.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /src/debug/debugger.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Wed Sep 5 17:11:21 2007 UTC (12 years, 3 months ago) by dpavlin
File size: 19862 byte(s)
import upstream CVS
1 dpavlin 1 /*
2     * HT Editor
3     * debugger.cc
4     *
5     * Copyright (C) 2003 Stefan Weyergraf
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License version 2 as
9     * published by the Free Software Foundation.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20     #define HAVE_DEBUGGER
21    
22     #include <stdio.h>
23    
24     #include "system/display.h"
25     #include "tools/except.h"
26     #include "tools/snprintf.h"
27     #include "tools/debug.h"
28     #include "debugger.h"
29     #include "parsehelper.h"
30     #include "stdfuncs.h"
31     #include "cpu/cpu.h"
32    
33     #include "debug/ppcdis.h"
34    
35     #ifdef HAVE_DEBUGGER
36     #include "cpu/cpu_generic/ppc_mmu.h"
37     #endif
38    
39     /*
40     * A function
41     */
42     SInt64 *Function::evalInteger() const
43     {
44     EvalType type = getReturnType();
45     switch (type) {
46     case ET_INTEGER: throw NotImplementedException(HERE);
47     case ET_FLOAT: {
48     Float *f = evalFloat();
49     SInt64 *i = new SInt64((sint64)f->value);
50     delete f;
51     return i;
52     break;
53     }
54     case ET_STRING: {
55     String *s = evalString();
56     uint64 u;
57     SInt64 *i;
58     if (s->toInt64(u, 10)) {
59     i = new SInt64(u);
60     } else {
61     i = new SInt64(0);
62     }
63     delete s;
64     return i;
65     break;
66     }
67     case ET_VARARGS: /* may-not-happen */
68     ASSERT(0);
69     break;
70     }
71     return NULL;
72     }
73    
74     Float *Function::evalFloat() const
75     {
76     EvalType type = getReturnType();
77     switch (type) {
78     case ET_INTEGER: {
79     SInt64 *u = evalInteger();
80     Float *f = new Float(u->value);
81     delete u;
82     return f;
83     }
84     case ET_FLOAT: throw NotImplementedException(HERE);
85     case ET_STRING: {
86     throw NotImplementedException(HERE);
87     // but it should be
88     break;
89     }
90     case ET_VARARGS: /* may-not-happen */
91     ASSERT(0);
92     break;
93     }
94     return NULL;
95     }
96    
97     String *Function::evalString() const
98     {
99     EvalType type = getReturnType();
100     switch (type) {
101     case ET_INTEGER: {
102     SInt64 *u = evalInteger();
103     String *s = new String();
104     s->assignFormat("%qd", u->value);
105     delete u;
106     return s;
107     }
108     case ET_FLOAT: {
109     Float *f = evalFloat();
110     String *s = new String();
111     s->assignFormat("%f", f->value);
112     delete f;
113     return s;
114     }
115     case ET_STRING: throw NotImplementedException(HERE);
116     case ET_VARARGS: /* may-not-happen */
117     ASSERT(0);
118     break;
119     }
120     return NULL;
121     }
122    
123     uint Function::getArgCount() const
124     {
125     return 0;
126     }
127    
128     Function *Function::getArg(uint i) const
129     {
130     throw IllegalArgumentException(HERE);
131     }
132    
133     void Function::setArg(uint i, Function *f)
134     {
135     throw IllegalArgumentException(HERE);
136     }
137    
138     /*
139     * A constant integer function
140     */
141     SInt64Function::SInt64Function(sint64 v)
142     {
143     value = v;
144     }
145    
146     EvalType SInt64Function::getReturnType() const
147     {
148     return ET_INTEGER;
149     }
150    
151     SInt64 *SInt64Function::evalInteger() const
152     {
153     return new SInt64(value);
154     }
155    
156     /*
157     * A GPR
158     */
159     GPRFunction::GPRFunction(int number)
160     {
161     mNumber = number;
162     }
163    
164     EvalType GPRFunction::getReturnType() const
165     {
166     return ET_INTEGER;
167     }
168    
169     SInt64 *GPRFunction::evalInteger() const
170     {
171     #ifdef HAVE_DEBUGGER
172     return new SInt64(gCPU.gpr[mNumber]);
173     #else
174     return NULL;
175     #endif
176     }
177    
178     FPRFunction::FPRFunction(int number)
179     {
180     mNumber = number;
181     }
182    
183     EvalType FPRFunction::getReturnType() const
184     {
185     return ET_FLOAT;
186     }
187    
188     Float *FPRFunction::evalFloat() const
189     {
190     #ifdef HAVE_DEBUGGER
191     double_uint64 du = { gCPU.fpr[mNumber] };
192     return new Float(du.d);
193     #else
194     return NULL;
195     #endif
196     }
197    
198     UInt32PFunction::UInt32PFunction(uint32 *aValue)
199     {
200     mValue = aValue;
201     }
202    
203     EvalType UInt32PFunction::getReturnType() const
204     {
205     return ET_INTEGER;
206     }
207    
208     SInt64 *UInt32PFunction::evalInteger() const
209     {
210     return new SInt64(*mValue);
211     }
212    
213     /*
214     * A constant float function
215     */
216     FloatFunction::FloatFunction(double v)
217     {
218     value = v;
219     }
220    
221     EvalType FloatFunction::getReturnType() const
222     {
223     return ET_FLOAT;
224     }
225    
226     Float *FloatFunction::evalFloat() const
227     {
228     return new Float(value);
229     }
230    
231     /*
232     * A constant string function
233     */
234     StringFunction::StringFunction(const byte *str, int len)
235     : value(str, len)
236     {
237     }
238    
239     EvalType StringFunction::getReturnType() const
240     {
241     return ET_STRING;
242     }
243    
244     String *StringFunction::evalString() const
245     {
246     return value.clone();
247     }
248    
249     /**
250     * A parametrized function (implementation helper)
251     */
252    
253     PFunction::PFunction()
254     : mArgs(true)
255     {
256     }
257    
258     uint PFunction::getArgCount() const
259     {
260     return mArgs.count();
261     }
262    
263     Function *PFunction::getArg(uint i) const
264     {
265     Function *r = (Function*)mArgs[i];
266     if (!r) throw IllegalArgumentException(HERE);
267     return r;
268     }
269    
270     void PFunction::setArg(uint i, Function *f)
271     {
272     mArgs.forceSetByIdx(i, f);
273     }
274    
275     /*
276     * An expression parser
277     */
278    
279     enum protoMatchQuality {
280     PMQ_EXACT,
281     PMQ_OK,
282     PMQ_NOT_OK
283     };
284    
285     static bool convertsInto(EvalType from, EvalType to)
286     {
287     switch (from) {
288     case ET_INTEGER:
289     return true;
290     case ET_FLOAT:
291     return (to != ET_INTEGER);
292     case ET_STRING:
293     return (to == ET_STRING);
294     case ET_VARARGS:
295     /* may-not-happen */
296     break;
297     }
298     return false;
299     }
300    
301     static protoMatchQuality matchFunctionPrototype(const Enumerator &params, uint count, EvalType *decl)
302     {
303     if (params.count() < count) return PMQ_NOT_OK;
304     uint pcount = params.count();
305     if (count && (decl[count-1] == ET_VARARGS)) {
306     count--;
307     pcount = count;
308     }
309     if (count == pcount) {
310     protoMatchQuality r = PMQ_EXACT;
311     for (uint i=0; i<count; i++) {
312     Function *f = (Function*)params[i];
313     if (!convertsInto(f->getReturnType(), decl[i])) return PMQ_NOT_OK;
314     if (f->getReturnType() != decl[i]) r = PMQ_OK;
315     }
316     return r;
317     }
318     return PMQ_NOT_OK;
319     }
320    
321     static Function *matchFunctionByDesc(const String &name, const Enumerator &params, FunctionDesc *descs)
322     {
323     protoMatchQuality bestPMQ = PMQ_NOT_OK;
324     FunctionDesc *bestMatch = NULL;
325     while (descs->name) {
326     if (strcmp(descs->name, name.contentChar()) == 0) {
327     protoMatchQuality pmq = matchFunctionPrototype(params, descs->declparam_count, descs->declparam);
328     if (pmq == PMQ_EXACT) {
329     // if its exact take it immediately
330     bestPMQ = PMQ_EXACT;
331     bestMatch = descs;
332     break;
333     } else if ((bestPMQ == PMQ_NOT_OK) && (pmq == PMQ_OK)) {
334     // try to take the first thats ok
335     bestPMQ = PMQ_OK;
336     bestMatch = descs;
337     }
338     }
339     descs++;
340     }
341     if (bestPMQ != PMQ_NOT_OK) {
342     Function *r = bestMatch->creator();
343     for (uint i=0; i<params.count(); i++) {
344     r->setArg(i, (Function*)params[i]);
345     }
346     return r;
347     }
348     return NULL;
349     }
350    
351     Watch::Watch(String *aName, Function *aFunc)
352     {
353     mName = aName->clone();
354     f = aFunc;
355     }
356    
357     Watch::~Watch()
358     {
359     delete mName;
360     delete f;
361     }
362    
363     int Watch::toString(char *buf, int buflen) const
364     {
365     SInt64 *sint = f->evalInteger();
366     String *s = f->evalString();
367     int ret = ht_snprintf(buf, buflen, "watch: '%y' = %y (0x%08x)", mName, s, (uint32)sint->value);
368     delete sint;
369     delete s;
370     return ret;
371     }
372    
373     Debugger::Debugger()
374     {
375     mWatches = new LinkedList(true);
376     #ifdef HAVE_DEBUGGER
377     savedCPUState = gCPU;
378     #endif
379     mUseColors = true;
380     }
381    
382     Debugger::~Debugger()
383     {
384     delete mWatches;
385     }
386    
387     Function *Debugger::eval_scalarToFunction(eval_scalar &s)
388     {
389     switch (s.type) {
390     case SCALAR_INT:
391     return new SInt64Function(s.scalar.integer.value);
392     case SCALAR_FLOAT:
393     return new FloatFunction(s.scalar.floatnum.value);
394     case SCALAR_REG:
395     switch (s.scalar.reg.type) {
396     case REG_GPR:
397     return new GPRFunction(s.scalar.reg.num);
398     case REG_FPR:
399     return new FPRFunction(s.scalar.reg.num);
400     #ifdef HAVE_DEBUGGER
401     case REG_PC:
402     return new UInt32PFunction(&gCPU.pc);
403     case REG_LR:
404     return new UInt32PFunction(&gCPU.lr);
405     case REG_CR:
406     return new UInt32PFunction(&gCPU.cr);
407     case REG_CTR:
408     return new UInt32PFunction(&gCPU.ctr);
409     case REG_XER:
410     return new UInt32PFunction(&gCPU.xer);
411     case REG_MSR:
412     return new UInt32PFunction(&gCPU.msr);
413     case REG_SRR0:
414     return new UInt32PFunction(&gCPU.srr[0]);
415     case REG_SRR1:
416     return new UInt32PFunction(&gCPU.srr[1]);
417     #endif
418     }
419     break;
420     case SCALAR_STR:
421     return new StringFunction((byte*)s.scalar.str.value, s.scalar.str.len);
422     case SCALAR_FUNCTION: {
423     Array p(false);
424     for (int i=0; i<s.scalar.function.param_count; i++) {
425     p += eval_scalarToFunction(s.scalar.function.params[i]);
426     }
427     return matchFunction(s.scalar.function.name, p);
428     }
429     case SCALAR_EMPTY:
430     return NULL;
431     case SCALAR_ANY:
432     case SCALAR_VARARGS:
433     /* may-not-happen */
434     break;
435     }
436     /* may-not-happen */
437     ASSERT(0);
438     return NULL;
439     }
440    
441     Function *Debugger::matchFunction(const String &name, const Enumerator &params)
442     {
443     Function *r = matchFunctionByDesc(name, params, gStdEvalFunctions);
444     if (!r) {
445     String msg;
446     msg.assignFormat("parse/eval: no function matching signature '%y(", &name);
447     for (uint i=0; i<params.count(); i++) {
448     Function *f = (Function*)params[i];
449     switch (f->getReturnType()) {
450     case ET_INTEGER:
451     msg.append("integer");
452     break;
453     case ET_FLOAT:
454     msg.append("float");
455     break;
456     case ET_STRING:
457     msg.append("string");
458     break;
459     case ET_VARARGS:
460     /* may-not-happen */
461     ASSERT(0);
462     break;
463     }
464     if (i+1<params.count()) msg.append(",");
465     }
466     msg.append(")'");
467     throw MsgException(msg.contentChar());
468     }
469     return r;
470     }
471    
472     inline static void disasm(uint32 code, uint32 ea, char *result)
473     {
474     PPCDisassembler dis;
475     CPU_ADDR addr;
476     addr.addr32.offset = ea;
477     strcpy(result, dis.str(dis.decode((byte*)&code, 4, addr), 0));
478     }
479    
480     void Debugger::dump()
481     {
482     #ifdef HAVE_DEBUGGER
483     int r = 0;
484     const char *hiColor, *loColor;
485     if (mUseColors) {
486     hiColor = "\e[33;1m";
487     loColor = "\e[37;1m";
488     } else {
489     hiColor = "";
490     loColor = "";
491     }
492     for (int i=0; i<8; i++) {
493     for (int j=0; j<4; j++) {
494     ht_printf("r%02d: %s%08x%s ", r, (savedCPUState.gpr[r] != gCPU.gpr[r])?hiColor:loColor , gCPU.gpr[r], loColor);
495     r++;
496     }
497     ht_printf("\n");
498     }
499     /* ht_printf("dbatu0: %08x dbatl0: %08x\n", gCPU.dbatu[0], gCPU.dbatl[0]);
500     ht_printf("dbatu1: %08x dbatl1: %08x\n", gCPU.dbatu[1], gCPU.dbatl[1]);
501     ht_printf("dbatu2: %08x dbatl2: %08x\n", gCPU.dbatu[2], gCPU.dbatl[2]);
502     ht_printf("dbatu3: %08x dbatl3: %08x\n", gCPU.dbatu[3], gCPU.dbatl[3]);*/
503     ht_printf("cr: %s%08x%s xer: %s%08x%s lr: %s%08x%s ctr: %s%08x%s\n",
504     (savedCPUState.cr != gCPU.cr)?hiColor:loColor, gCPU.cr, loColor,
505     (savedCPUState.xer != gCPU.xer)?hiColor:loColor, gCPU.xer, loColor,
506     (savedCPUState.lr != gCPU.lr)?hiColor:loColor, gCPU.lr, loColor,
507     (savedCPUState.ctr != gCPU.ctr)?hiColor:loColor, gCPU.ctr, loColor);
508     // ht_printf("msr: %08x sv: %d srr1: %08x\n", gCPU.msr, (gCPU.msr & MSR_PR) ? 0 : 1, gCPU.srr[1]);
509    
510     foreach(Watch, w, *mWatches, {
511     ht_printf("%y\n", w);
512     });
513    
514     char disstr[256];
515     disasm(gCPU.current_opc, gCPU.pc, disstr);
516     ht_printf("@%08x: %08x %s\n", gCPU.pc, gCPU.current_opc, disstr);
517    
518     if (disstr[0] == 'b') {
519     int i = 1;
520     while (disstr[i] && disstr[i] != ' ') i++;
521     if (disstr[i-1] != 'l') {
522     mForceSinglestep = true;
523     }
524     }
525     #endif
526     }
527    
528     static void displayFPRs()
529     {
530     #if 0
531     for (int i=0; i<32; i++) {
532     ppc_double dd;
533     ppc_fpu_unpack_double(dd, gCPU.fpr[i]);
534     double d = ppc_fpu_get_double(dd);
535     ht_printf("fr%02d: ", i);
536     switch (dd.type) {
537     case ppc_fpr_norm:
538     ht_printf("%c%qb * 2^%d = %f", dd.s?'-':'+', &dd.m, dd.e, d);
539     break;
540     case ppc_fpr_zero:
541     ht_printf("%c0.0", dd.s?'-':'+');
542     break;
543     case ppc_fpr_Inf:
544     ht_printf("%cInf", dd.s?'-':'+');
545     break;
546     case ppc_fpr_NaN:
547     ht_printf("%cNaN", dd.s?'-':'+');
548     break;
549     }
550     ht_printf("\n");
551     ht_printf(" = %qx\n", &gCPU.fpr[i]);
552     }
553     #endif
554     }
555    
556     static bool translateAddress(uint32 ea, uint32 &pa, bool error)
557     {
558     #ifdef HAVE_DEBUGGER
559     if (ppc_effective_to_physical(ea, PPC_MMU_READ|PPC_MMU_NO_EXC|PPC_MMU_SV, pa)) {
560     if (error) ht_printf("cant translate effective address %08x\n", ea);
561     return false;
562     } else {
563     return true;
564     }
565     #endif
566     }
567    
568     bool Debugger::parse(const String &str)
569     {
570     eval_command s;
571     bool ret = false;
572     memset(&s, 0, sizeof s);
573     if (!eval_parse(&s, str.contentChar())) {
574     char *str2;
575     int pos;
576     if (!get_eval_error(&str2, &pos)) {
577     str2 = "internal error! please report!";
578     pos = 0;
579     }
580     throw MsgfException("error: %s at %d", str2, pos);
581     } else {
582     Function *params[3];
583     for (int i=0; i<s.paramcount; i++) {
584     params[i] = eval_scalarToFunction(s.param[i]);
585     }
586     switch (s.type) {
587     case COMMAND_NOP: break;
588     case COMMAND_PRINT: {
589     String *s = params[0]->evalString();
590     SInt64 *sint = params[0]->evalInteger();
591     ht_printf("= %y (0x%08x)\n", s, sint->value);
592     delete s;
593     delete sint;
594     break;
595     }
596     case COMMAND_REGS:
597     dump();
598     break;
599     case COMMAND_FLOATS:
600     displayFPRs();
601     break;
602     case COMMAND_SETREG: {
603     SInt64 *sint = params[1]->evalInteger();
604     switch (s.param[0].scalar.reg.type) {
605     #ifdef HAVE_DEBUGGER
606     case REG_GPR:
607     gCPU.gpr[s.param[0].scalar.reg.num] = sint->value;
608     break;
609     case REG_FPR: {
610     Float *f = params[1]->evalFloat();
611     double_uint64 du;
612     du.d = f->value;
613     gCPU.fpr[s.param[0].scalar.reg.num] = du.u;
614     delete f;
615     break;
616     }
617     case REG_PC:
618     gCPU.pc = gCPU.npc = sint->value;
619     break;
620     case REG_CR:
621     gCPU.cr = sint->value;
622     break;
623     case REG_LR:
624     gCPU.lr = sint->value;
625     break;
626     case REG_CTR:
627     gCPU.ctr = sint->value;
628     break;
629     case REG_XER:
630     gCPU.xer = sint->value;
631     break;
632     case REG_MSR:
633     gCPU.msr = sint->value;
634     break;
635     case REG_SRR0:
636     gCPU.srr[0] = sint->value;
637     break;
638     case REG_SRR1:
639     gCPU.srr[1] = sint->value;
640     break;
641     #endif
642     }
643     delete sint;
644     break;
645     }
646     #ifdef HAVE_DEBUGGER
647     case COMMAND_LIST_BREAK:
648     ht_printf("Breakpoint %d at %08x\n", 1, gBreakpoint);
649     ht_printf("Breakpoint %d at %08x\n", 2, gBreakpoint2);
650     break;
651     case COMMAND_BREAK: {
652     SInt64 *sint = params[0]->evalInteger();
653     gBreakpoint2 = sint->value;
654     ht_printf("Breakpoint %d at %08x\n", 2, gBreakpoint2);
655     break;
656     }
657     case COMMAND_STEP:
658     ppc_set_singlestep_nonverbose(true);
659     ret = true;
660     break;
661     case COMMAND_NEXT:
662     gBreakpoint = gCPU.npc;
663     if (mForceSinglestep) {
664     ppc_set_singlestep_nonverbose(true);
665     } else {
666     gBreakpoint = gCPU.npc;
667     ppc_set_singlestep_nonverbose(false);
668     }
669     ret = true;
670     break;
671     case COMMAND_CONTINUE:
672     ppc_set_singlestep_nonverbose(false);
673     ret = true;
674     break;
675     case COMMAND_QUIT:
676     ppc_cpu_stop();
677     ppc_set_singlestep_nonverbose(false);
678     ret = true;
679     break;
680     #endif
681     case COMMAND_E2P: {
682     SInt64 *sint = params[0]->evalInteger();
683     uint32 pa, ea = sint->value;
684     if (translateAddress(ea, pa, true)) {
685     ht_printf("effective: %08x, physical: %08x\n", ea, pa);
686     }
687     delete sint;
688     break;
689     }
690     case COMMAND_INSPECT_BYTE: {
691     SInt64 *sint = params[0]->evalInteger();
692     uint32 pa, ea = sint->value;
693     uint8 v;
694     if (translateAddress(ea, pa, true)) {
695     #ifdef HAVE_DEBUGGER
696     if (ppc_read_physical_byte(pa, v)) {
697     ht_printf("cant read at physical address %08x\n", pa);
698     } else {
699     ht_printf("@%08x: %02x (physical: %08x)\n", ea, v, pa);
700     }
701     #endif
702     }
703     delete sint;
704     break;
705     }
706     case COMMAND_INSPECT_HALF: {
707     SInt64 *sint = params[0]->evalInteger();
708     uint32 pa, ea = sint->value;
709     uint16 v;
710     if (translateAddress(ea, pa, true)) {
711     #ifdef HAVE_DEBUGGER
712     if (ppc_read_physical_half(pa, v)) {
713     ht_printf("cant read at physical address %08x\n", pa);
714     } else {
715     ht_printf("@%08x: %04x (physical: %08x)\n", ea, v, pa);
716     }
717     #endif
718     }
719     delete sint;
720     break;
721     }
722     case COMMAND_INSPECT_WORD: {
723     SInt64 *sint = params[0]->evalInteger();
724     uint32 pa, ea = sint->value;
725     delete sint;
726     uint32 v;
727     if (translateAddress(ea, pa, true)) {
728     #ifdef HAVE_DEBUGGER
729     if (ppc_read_physical_word(pa, v)) {
730     ht_printf("cant read at physical address %08x\n", pa);
731     } else {
732     ht_printf("@%08x: %08x (physical: %08x)\n", ea, v, pa);
733     }
734     #endif
735     }
736     break;
737     }
738     case COMMAND_INSPECT_DWORD: {
739     SInt64 *sint = params[0]->evalInteger();
740     uint32 pa, ea = sint->value;
741     delete sint;
742     uint64 v;
743     if (translateAddress(ea, pa, true)) {
744     #ifdef HAVE_DEBUGGER
745     if (ppc_read_physical_dword(pa, v)) {
746     ht_printf("cant read at physical address %08x\n", pa);
747     } else {
748     ht_printf("@%08x: %016x (physical: %08x)\n", ea, v, pa);
749     }
750     #endif
751     }
752     break;
753     }
754     case COMMAND_INSPECT_STRING: {
755     SInt64 *sint = params[0]->evalInteger();
756     uint32 pa, ea = sint->value;
757     delete sint;
758     byte *v;
759     if (translateAddress(ea, pa, true)) {
760     #ifdef HAVE_DEBUGGER
761     if (ppc_direct_physical_memory_handle(pa, v)) {
762     ht_printf("cant read at physical address %08x\n", pa);
763     } else {
764     ht_printf("@%08x: '%s' (physical: %08x)\n", ea, v, pa);
765     }
766     #endif
767     }
768     break;
769     }
770     case COMMAND_INSPECT_MEM: {
771     SInt64 *sint = params[0]->evalInteger();
772     uint32 pa, ea = sint->value;
773     uint32 count = 0x100;
774     delete sint;
775     byte v;
776     int x = 0;
777     char buf[80];
778     memset(buf, ' ', sizeof buf);
779     buf[79] = 0;
780     buf[sprintf(buf, "@%08x", ea)] = ' ';
781     while (count) {
782     if (translateAddress(ea, pa, true)) {
783     #ifdef HAVE_DEBUGGER
784     if (ppc_read_physical_byte(pa, v)) {
785     ht_printf("cant read at physical address %08x\n", pa);
786     break;
787     } else {
788     // ht_printf("@%08x: '%s' (physical: %08x)\n", ea, v, pa);
789     sprintf(buf+10+(x%16)*3, "%02x", v);
790     buf[10+(x%16)*3+2] = ' ';
791     sprintf(buf+10+16*3+x%16, "%c", (v>=32 && v<=127)?v:' ');
792     buf[10+16*3+x%16+1] = ' ';
793     }
794     #endif
795     } else {
796     break;
797     }
798     count--;
799     ea++;
800     x++;
801     if (x % 16 == 0) {
802     ht_printf("%s\n", buf);
803     memset(buf, ' ', sizeof buf);
804     buf[79] = 0;
805     buf[sprintf(buf, "@%08x", ea)] = ' ';
806     }
807     }
808     if (x % 16) ht_printf("%s\n", buf);
809     break;
810     }
811     case COMMAND_WATCH: {
812     String *name;
813     if (params[1]) {
814     name = params[1]->evalString();
815     } else {
816     name = new String("noname");
817     }
818     mWatches->insert(new Watch(name, eval_scalarToFunction(s.param[0])));
819     break;
820     }
821     case COMMAND_WATCH_BYTE:
822     case COMMAND_WATCH_HALF:
823     case COMMAND_WATCH_WORD:
824     case COMMAND_WATCH_DWORD:
825     case COMMAND_DELETE_WATCH:
826     case COMMAND_DUMP:
827     case COMMAND_DISASM: {
828     #ifdef HAVE_DEBUGGER
829     uint32 ea, pa;
830     if (params[0]) {
831     SInt64 *sint;
832     sint = params[0]->evalInteger();
833     ea = sint->value & ~3;
834     delete sint;
835     } else {
836     ea = gCPU.pc;
837     }
838     uint32 count;
839     if (params[1]) {
840     SInt64 *sint;
841     sint = params[1]->evalInteger();
842     count = sint->value;
843     delete sint;
844     } else {
845     count = 16;
846     }
847     while (count) {
848     uint32 opc;
849     if (translateAddress(ea, pa, true)) {
850     if (ppc_read_physical_word(pa, opc)) {
851     ht_printf("cant read at physical address %08x\n", pa);
852     break;
853     }
854     } else {
855     break;
856     }
857     char disstr[256];
858     disasm(opc, gCPU.pc, disstr);
859     ht_printf("@%08x: %08x %s\n", ea, opc, disstr);
860     count--;
861     ea+=4;
862     }
863     #endif
864     break;
865     }
866     case COMMAND_HELP:
867     ht_printf("bist du jeck?\n");
868     break;
869     }
870     for (int i=0; i<s.paramcount; i++) {
871     delete params[i];
872     }
873     }
874     return ret;
875     }
876    
877     void Debugger::enter()
878     {
879     char buf[1024];
880     bool quit = false;
881     if (mAlwaysShowRegs) dump();
882    
883     /*
884     * If current instruction is a branch instruction
885     * which doesnt set LR we force single step
886     */
887     mForceSinglestep = false;
888     char disstr[256];
889     #ifdef HAVE_DEBUGGER
890     disasm(gCPU.current_opc, gCPU.pc, disstr);
891     #endif
892     if (disstr[0] == 'b') {
893     int i = 1;
894     while (disstr[i] && disstr[i] != ' ') i++;
895     if (disstr[i-1] != 'l') {
896     mForceSinglestep = true;
897     }
898     }
899     #ifdef HAVE_DEBUGGER
900     gBreakpoint = 0;
901     #endif
902    
903     while (!quit) {
904     printf("> ");
905     fgets(buf, sizeof buf, stdin);
906     try {
907     quit = parse(buf);
908     } catch (const Exception &e) {
909     String s;
910     ht_printf("%y\n", &e.reason(s));
911     continue;
912     }
913     }
914     #ifdef HAVE_DEBUGGER
915     savedCPUState = gCPU;
916     #endif
917     }
918    
919     #include "configparser.h"
920     void debugger_init_config()
921     {
922     gConfig->acceptConfigEntryString("debugger_exec", false);
923     }

  ViewVC Help
Powered by ViewVC 1.1.26