/[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

Contents of /src/debug/debugger.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 6 months ago) by dpavlin
File size: 19862 byte(s)
import upstream CVS
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