X-Git-Url: https://git.gag.com/?p=fw%2Fsdcc;a=blobdiff_plain;f=debugger%2Fmcs51%2Fcmd.c;h=cd038fffea32bcf9665469ffdfa2ba1671a79186;hp=4cae0c91c5ec1284ef09a7437c965a3744e58e3b;hb=HEAD;hpb=31264d72ca126a7ad645192145c94daf4d72e2a7 diff --git a/debugger/mcs51/cmd.c b/debugger/mcs51/cmd.c index 4cae0c91..cd038fff 100644 --- a/debugger/mcs51/cmd.c +++ b/debugger/mcs51/cmd.c @@ -1053,7 +1053,16 @@ static int stack_change(unsigned addr) } } -static int pc_change(unsigned addr, unsigned addrs[2]) +static void +do_indent(int indent); + +#if 1 +#define DPC(x) +#else +#define DPC(x) do { do_indent(indent); printf x; } while (0); +#endif + +static int pc_change(unsigned addr, unsigned addrs[2], int indent) { unsigned char insn; unsigned new_addr; @@ -1072,6 +1081,7 @@ static int pc_change(unsigned addr, unsigned addrs[2]) if (insn == LJMP_addr16) { addrs[0] = ((simGetValue(addr+1, 'C', 1) << 8) | (simGetValue(addr+2, 'C', 1))); + DPC(("0x%04x LJMP 0x%04x\n", addr, addrs[0])); return 1; } @@ -1080,6 +1090,7 @@ static int pc_change(unsigned addr, unsigned addrs[2]) unsigned char direct = simGetValue(addr+1,'C', 1); addrs[0] = ((addr + 2) & 0xf800) | ((insn & 0xe0) << 3) | direct; + DPC(("0x%04x AJMP 0x%04x\n", addr, addrs[0])); return 1; } @@ -1089,23 +1100,44 @@ static int pc_change(unsigned addr, unsigned addrs[2]) delta = (signed char) simGetValue(addr+len-1, 'C', 1); new_addr = (addr + len) + delta; - if (insn == SJMP_rel) { + if (insn == SJMP_rel || (addr + len) == new_addr) { addrs[0] = new_addr; + DPC(("0x%04x SJMP 0x%04x\n", addr, addrs[0])); return 1; } + addrs[0] = (addr + len) & 0xffff; + addrs[1] = new_addr & 0xffff; - addrs[0] = addr + len; - addrs[1] = new_addr; + DPC(("0x%04x SJMP 0x%04x 0x%04x\n", addr, addrs[0], addrs[1])); return 2; } -#define SEARCH_FAILED 0x8000 +#define SEARCH_LOOP 0x8000 +#define SEARCH_EXPIRED 0x8001 + +#define MAX_STACK_BRANCH_TRACE 8192 +static unsigned stack_branch_trace[MAX_STACK_BRANCH_TRACE]; static int -stack_depth(unsigned pc, int search) +been_here(unsigned pc, int ntrace) +{ + int t; + + for (t = 0; t < ntrace; t++) + if (stack_branch_trace[t] == pc) + return 1; + return 0; +} + +#define MAX_SEARCH 100 + +#define indent (MAX_SEARCH - search) + +static int +stack_depth(unsigned pc, int search, int ntrace) { unsigned new_pc[2]; - unsigned max_pc = pc; + int d[2]; int n; int s; int change; @@ -1113,35 +1145,62 @@ stack_depth(unsigned pc, int search) change = 0; for (;;) { change += stack_change(pc); - n = pc_change(pc, new_pc); + n = pc_change(pc, new_pc, MAX_SEARCH - search); if (n == 0) return change; if (n != 1) break; + if (new_pc[0] <= pc) { + if (been_here(pc, ntrace)) { + DPC(("0x%04x loop 1\n", pc)); + return SEARCH_LOOP; + } + stack_branch_trace[ntrace++] = pc; + } pc = new_pc[0]; - /* detect infinite loop */ - if (pc == max_pc) - return change; - if (pc > max_pc) - max_pc = pc; } - if (search == 0) - return SEARCH_FAILED; + if (search == 0) { + DPC(("0x%04x max depth\n", pc)); + return SEARCH_EXPIRED; + } + if (been_here(pc, ntrace)) + { + DPC(("0x%04x loop 2\n", pc)); + return SEARCH_LOOP; + } + stack_branch_trace[ntrace++] = pc; + for (s = 0; s < search - 1; s++) { - int d; - int i; - d = SEARCH_FAILED; - for (i = 0; i < n; i++) { - d = stack_depth(new_pc[i], search-1); - if (d != SEARCH_FAILED) + int i, j, d; + + i = 0; + while (i < n) { + d = stack_depth(new_pc[i], search-1, ntrace); + if (d == SEARCH_LOOP) { + for (j = i; j < n-1; j++) + new_pc[j] = new_pc[j+1]; + n--; + continue; + } + if (d != SEARCH_EXPIRED) { + DPC(("success %d\n", d + change)); return d + change; + } + i++; + } + if (n == 0) { + DPC(("0x%04x loop 3\n", pc)); + return SEARCH_LOOP; } } - return SEARCH_FAILED; + DPC(("search expired\n")); + return SEARCH_EXPIRED; } +#undef indent + unsigned int stack_start(void) { @@ -1162,10 +1221,11 @@ frameStart(unsigned int *bpp, unsigned int *pcp) pc = simGetPC(); sp = simGetValue(0x81,'I',1); - depth = stack_depth(pc, 100); - bp = sp + depth; - if (bp < stack_start()) - return 0; + depth = stack_depth(pc, MAX_SEARCH, 0); + if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED) + bp = 0; + else + bp = sp + depth; *bpp = bp; *pcp = pc; return 1; @@ -1182,8 +1242,13 @@ frameNext(unsigned int *bpp, unsigned int *pcp) if (bp < stack_start()) return 0; pc = simGetValue(bp - 1, 'B', 2); - depth = stack_depth(pc, 100); - bp = bp - 2 + depth; + if (pc == 0xffff) + return 0; + depth = stack_depth(pc, MAX_SEARCH, 0); + if (depth == SEARCH_LOOP || depth == SEARCH_EXPIRED) + bp = 0; + else + bp = bp - 2 + depth; *bpp = bp; *pcp = pc; return 1;