comparison debug.c @ 2170:ada3130b1396

Add memory indirection syntax to debugger parser/evaluator
author Michael Pavone <pavone@retrodev.com>
date Sat, 06 Aug 2022 14:50:41 -0700
parents cb9572145f8e
children 4b47155965c8
comparison
equal deleted inserted replaced
2169:cb9572145f8e 2170:ada3130b1396
67 typedef enum { 67 typedef enum {
68 TOKEN_NONE, 68 TOKEN_NONE,
69 TOKEN_NUM, 69 TOKEN_NUM,
70 TOKEN_NAME, 70 TOKEN_NAME,
71 TOKEN_OPER, 71 TOKEN_OPER,
72 TOKEN_SIZE 72 TOKEN_SIZE,
73 TOKEN_LBRACKET,
74 TOKEN_RBRACKET,
73 } token_type; 75 } token_type;
74 76
75 static const char *token_type_names[] = { 77 static const char *token_type_names[] = {
76 "TOKEN_NONE", 78 "TOKEN_NONE",
77 "TOKEN_NUM", 79 "TOKEN_NUM",
78 "TOKEN_NAME", 80 "TOKEN_NAME",
79 "TOKEN_OPER", 81 "TOKEN_OPER",
80 "TOKEN_SIZE" 82 "TOKEN_SIZE",
83 "TOKEN_LBRACKET",
84 "TOKEN_RBRACKET"
81 }; 85 };
82 86
83 typedef struct { 87 typedef struct {
84 token_type type; 88 token_type type;
85 union { 89 union {
151 .type = TOKEN_SIZE, 155 .type = TOKEN_SIZE,
152 .v = { 156 .v = {
153 .op = {start[1], 0} 157 .op = {start[1], 0}
154 } 158 }
155 }; 159 };
160 case '[':
161 *end = start + 1;
162 return (token) {
163 .type = TOKEN_LBRACKET
164 };
165 case ']':
166 *end = start + 1;
167 return (token) {
168 .type = TOKEN_RBRACKET
169 };
156 } 170 }
157 *end = start + 1; 171 *end = start + 1;
158 while (**end && !isblank(**end) && **end != '.') 172 while (**end && !isblank(**end) && **end != '.')
159 { 173 {
160 ++*end; 174 ++*end;
173 typedef enum { 187 typedef enum {
174 EXPR_NONE, 188 EXPR_NONE,
175 EXPR_SCALAR, 189 EXPR_SCALAR,
176 EXPR_UNARY, 190 EXPR_UNARY,
177 EXPR_BINARY, 191 EXPR_BINARY,
178 EXPR_SIZE 192 EXPR_SIZE,
193 EXPR_MEM
179 } expr_type; 194 } expr_type;
180 195
181 typedef struct expr expr; 196 typedef struct expr expr;
182 197
183 struct expr { 198 struct expr {
198 free(e->op.v.str); 213 free(e->op.v.str);
199 } 214 }
200 free(e); 215 free(e);
201 } 216 }
202 217
218 static expr *parse_scalar_or_muldiv(char *start, char **end);
219 static expr *parse_expression(char *start, char **end);
220
203 static expr *parse_scalar(char *start, char **end) 221 static expr *parse_scalar(char *start, char **end)
204 { 222 {
205 char *after_first; 223 char *after_first;
206 token first = parse_token(start, &after_first); 224 token first = parse_token(start, &after_first);
207 if (!first.type) { 225 if (!first.type) {
220 expr *ret = calloc(1, sizeof(expr)); 238 expr *ret = calloc(1, sizeof(expr));
221 ret->type = EXPR_UNARY; 239 ret->type = EXPR_UNARY;
222 ret->op = first; 240 ret->op = first;
223 ret->left = target; 241 ret->left = target;
224 *end = after_first; 242 *end = after_first;
243 return ret;
244 }
245 if (first.type == TOKEN_LBRACKET) {
246 expr *ret = calloc(1, sizeof(expr));
247 ret->type = EXPR_MEM;
248 ret->left = parse_expression(after_first, end);
249 if (!ret->left) {
250 fprintf(stderr, "Expression expected after `[`\n");
251 free(ret);
252 return NULL;
253 }
254 token rbrack = parse_token(*end, end);
255 if (rbrack.type != TOKEN_RBRACKET) {
256 fprintf(stderr, "Missing closing `]`");
257 free_expr(ret);
258 return NULL;
259 }
260 char *after_size;
261 token size = parse_token(*end, &after_size);
262 if (size.type == TOKEN_SIZE) {
263 *end = after_size;
264 ret->op = size;
265 }
225 return ret; 266 return ret;
226 } 267 }
227 token second = parse_token(after_first, end); 268 token second = parse_token(after_first, end);
228 if (second.type != TOKEN_SIZE) { 269 if (second.type != TOKEN_SIZE) {
229 expr *ret = calloc(1, sizeof(expr)); 270 expr *ret = calloc(1, sizeof(expr));
238 ret->left->type = EXPR_SCALAR; 279 ret->left->type = EXPR_SCALAR;
239 ret->left->op = second; 280 ret->left->op = second;
240 ret->op = first; 281 ret->op = first;
241 return ret; 282 return ret;
242 } 283 }
243
244 static expr *parse_scalar_or_muldiv(char *start, char **end);
245 static expr *parse_expression(char *start, char **end);
246 284
247 static expr *maybe_binary(expr *left, char *start, char **end) 285 static expr *maybe_binary(expr *left, char *start, char **end)
248 { 286 {
249 char *after_first; 287 char *after_first;
250 token first = parse_token(start, &after_first); 288 token first = parse_token(start, &after_first);
329 ret->type = EXPR_UNARY; 367 ret->type = EXPR_UNARY;
330 ret->op = first; 368 ret->op = first;
331 ret->left = target; 369 ret->left = target;
332 return ret; 370 return ret;
333 } 371 }
372 if (first.type == TOKEN_LBRACKET) {
373 expr *ret = calloc(1, sizeof(expr));
374 ret->type = EXPR_MEM;
375 ret->left = parse_expression(after_first, end);
376 if (!ret->left) {
377 fprintf(stderr, "Expression expected after `[`\n");
378 free(ret);
379 return NULL;
380 }
381 token rbrack = parse_token(*end, end);
382 if (rbrack.type != TOKEN_RBRACKET) {
383 fprintf(stderr, "Missing closing `]`");
384 free_expr(ret);
385 return NULL;
386 }
387 char *after_size;
388 token size = parse_token(*end, &after_size);
389 if (size.type == TOKEN_SIZE) {
390 *end = after_size;
391 ret->op = size;
392 }
393 return ret;
394 }
334 char *after_second; 395 char *after_second;
335 token second = parse_token(after_first, &after_second); 396 token second = parse_token(after_first, &after_second);
336 if (!second.type) {
337 expr *ret = calloc(1, sizeof(expr));
338 ret->type = EXPR_SCALAR;
339 ret->op = first;
340 *end = after_first;
341 return ret;
342 }
343 if (second.type == TOKEN_OPER) { 397 if (second.type == TOKEN_OPER) {
344 expr *ret; 398 expr *ret;
345 expr *bin = calloc(1, sizeof(expr)); 399 expr *bin = calloc(1, sizeof(expr));
346 bin->type = EXPR_BINARY; 400 bin->type = EXPR_BINARY;
347 bin->left = calloc(1, sizeof(expr)); 401 bin->left = calloc(1, sizeof(expr));
378 value->left = calloc(1, sizeof(expr)); 432 value->left = calloc(1, sizeof(expr));
379 value->left->type = EXPR_SCALAR; 433 value->left->type = EXPR_SCALAR;
380 value->left->op = first; 434 value->left->op = first;
381 return maybe_muldiv(value, after_second, end); 435 return maybe_muldiv(value, after_second, end);
382 } else { 436 } else {
383 fprintf(stderr, "Unexpected %s after scalar\n", token_type_names[second.type]); 437 expr *ret = calloc(1, sizeof(expr));
384 return NULL; 438 ret->type = EXPR_SCALAR;
439 ret->op = first;
440 *end = after_first;
441 return ret;
385 } 442 }
386 } 443 }
387 444
388 static expr *parse_expression(char *start, char **end) 445 static expr *parse_expression(char *start, char **end)
389 { 446 {
406 ret->type = EXPR_UNARY; 463 ret->type = EXPR_UNARY;
407 ret->op = first; 464 ret->op = first;
408 ret->left = target; 465 ret->left = target;
409 return ret; 466 return ret;
410 } 467 }
468 if (first.type == TOKEN_LBRACKET) {
469 expr *ret = calloc(1, sizeof(expr));
470 ret->type = EXPR_MEM;
471 ret->left = parse_expression(after_first, end);
472 if (!ret->left) {
473 fprintf(stderr, "Expression expected after `[`\n");
474 free(ret);
475 return NULL;
476 }
477 token rbrack = parse_token(*end, end);
478 if (rbrack.type != TOKEN_RBRACKET) {
479 fprintf(stderr, "Missing closing `]`");
480 free_expr(ret);
481 return NULL;
482 }
483 char *after_size;
484 token size = parse_token(*end, &after_size);
485 if (size.type == TOKEN_SIZE) {
486 *end = after_size;
487 ret->op = size;
488 }
489 return ret;
490 }
411 char *after_second; 491 char *after_second;
412 token second = parse_token(after_first, &after_second); 492 token second = parse_token(after_first, &after_second);
413 if (!second.type) {
414 expr *ret = calloc(1, sizeof(expr));
415 ret->type = EXPR_SCALAR;
416 ret->op = first;
417 *end = after_first;
418 return ret;
419 }
420 if (second.type == TOKEN_OPER) { 493 if (second.type == TOKEN_OPER) {
421 expr *bin = calloc(1, sizeof(expr)); 494 expr *bin = calloc(1, sizeof(expr));
422 bin->type = EXPR_BINARY; 495 bin->type = EXPR_BINARY;
423 bin->left = calloc(1, sizeof(expr)); 496 bin->left = calloc(1, sizeof(expr));
424 bin->left->type = EXPR_SCALAR; 497 bin->left->type = EXPR_SCALAR;
454 value->left = calloc(1, sizeof(expr)); 527 value->left = calloc(1, sizeof(expr));
455 value->left->type = EXPR_SCALAR; 528 value->left->type = EXPR_SCALAR;
456 value->left->op = first; 529 value->left->op = first;
457 return maybe_binary(value, after_second, end); 530 return maybe_binary(value, after_second, end);
458 } else { 531 } else {
459 fprintf(stderr, "Unexpected %s after scalar\n", token_type_names[second.type]); 532 expr *ret = calloc(1, sizeof(expr));
460 return NULL; 533 ret->type = EXPR_SCALAR;
534 ret->op = first;
535 *end = after_first;
536 return ret;
461 } 537 }
462 } 538 }
463 539
464 typedef struct debug_context debug_context; 540 typedef struct debug_context debug_context;
465 typedef uint8_t (*resolver)(debug_context *context, const char *name, uint32_t *out); 541 typedef uint8_t (*resolver)(debug_context *context, const char *name, uint32_t *out);
542 typedef uint8_t (*reader)(debug_context *context, uint32_t *out, char size);
466 543
467 struct debug_context { 544 struct debug_context {
468 resolver resolve; 545 resolver resolve;
546 reader read_mem;
469 void *system; 547 void *system;
470 }; 548 };
471 549
472 uint8_t eval_expr(debug_context *context, expr *e, uint32_t *out) 550 uint8_t eval_expr(debug_context *context, expr *e, uint32_t *out)
473 { 551 {
549 case 'w': 627 case 'w':
550 *out &= 0xFFFF; 628 *out &= 0xFFFF;
551 break; 629 break;
552 } 630 }
553 return 1; 631 return 1;
632 case EXPR_MEM:
633 if (!eval_expr(context, e->left, out)) {
634 return 0;
635 }
636 return context->read_mem(context, out, e->op.v.op[0]);
554 default: 637 default:
555 return 0; 638 return 0;
556 } 639 }
557 } 640 }
558 641
606 { 689 {
607 //TODO: share this implementation with GDB debugger 690 //TODO: share this implementation with GDB debugger
608 return read_byte(address, (void **)context->mem_pointers, &context->options->gen, context); 691 return read_byte(address, (void **)context->mem_pointers, &context->options->gen, context);
609 } 692 }
610 693
611 uint16_t m68k_read_word(uint32_t address, m68k_context *context) 694 static uint16_t m68k_read_word(uint32_t address, m68k_context *context)
612 { 695 {
613 return read_word(address, (void **)context->mem_pointers, &context->options->gen, context); 696 return read_word(address, (void **)context->mem_pointers, &context->options->gen, context);
614 } 697 }
615 698
616 uint32_t m68k_read_long(uint32_t address, m68k_context *context) 699 static uint32_t m68k_read_long(uint32_t address, m68k_context *context)
617 { 700 {
618 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context); 701 return m68k_read_word(address, context) << 16 | m68k_read_word(address + 2, context);
619 } 702 }
620 703
621 uint8_t resolve_m68k(m68k_context *context, const char *name, uint32_t *out) 704 static uint8_t read_m68k(m68k_context *context, uint32_t *out, char size)
705 {
706 if (size == 'b') {
707 *out = m68k_read_byte(*out, context);
708 } else if (size == 'l') {
709 *out = m68k_read_long(*out, context);
710 } else {
711 *out = m68k_read_word(*out, context);
712 }
713 return 1;
714 }
715
716 static uint8_t read_genesis(debug_context *context, uint32_t *out, char size)
717 {
718 genesis_context *gen = context->system;
719 return read_m68k(gen->m68k, out, size);
720 }
721
722 static uint8_t resolve_m68k(m68k_context *context, const char *name, uint32_t *out)
622 { 723 {
623 if (name[0] == 'd' && name[1] >= '0' && name[1] <= '7') { 724 if (name[0] == 'd' && name[1] >= '0' && name[1] <= '7') {
624 *out = context->dregs[name[1]-'0']; 725 *out = context->dregs[name[1]-'0'];
625 } else if (name[0] == 'a' && name[1] >= '0' && name[1] <= '7') { 726 } else if (name[0] == 'a' && name[1] >= '0' && name[1] <= '7') {
626 *out = context->aregs[name[1]-'0']; 727 *out = context->aregs[name[1]-'0'];
638 return 0; 739 return 0;
639 } 740 }
640 return 1; 741 return 1;
641 } 742 }
642 743
643 uint8_t resolve_genesis(debug_context *context, const char *name, uint32_t *out) 744 static uint8_t resolve_genesis(debug_context *context, const char *name, uint32_t *out)
644 { 745 {
645 genesis_context *gen = context->system; 746 genesis_context *gen = context->system;
646 if (resolve_m68k(gen->m68k, name, out)) { 747 if (resolve_m68k(gen->m68k, name, out)) {
647 return 1; 748 return 1;
648 } 749 }
672 default: 773 default:
673 fprintf(stderr, "Unrecognized format character: %c\n", format_char); 774 fprintf(stderr, "Unrecognized format character: %c\n", format_char);
674 } 775 }
675 debug_context c = { 776 debug_context c = {
676 .resolve = resolve_genesis, 777 .resolve = resolve_genesis,
778 .read_mem = read_genesis,
677 .system = context->system 779 .system = context->system
678 }; 780 };
679 char *after; 781 char *after;
680 expr *e = parse_expression(param, &after); 782 expr *e = parse_expression(param, &after);
681 if (e) { 783 if (e) {