📄 5db.c
字号:
if((v & (1U<<31)) == 0) return 0; return 0xFFFFFFFF; } return ASR(v, s); case 6: /* RORIMM */ if(s == 0) { ulong c = (rget(map, "PSR") >> 29) & 1; return (c << 31) | LSR(v, 1); } return ROR(v, s); case 7: /* RORREG */ sprint(buf, "R%ld", (s>>1)&0xF); s = rget(map, buf); if(s == 0 || (s & 0xF) == 0) return v; return ROR(v, s & 0xF); } }}static intnbits(ulong v){ int n = 0; int i; for(i=0; i < 32 ; i++) { if(v & 1) ++n; v >>= 1; } return n;}static ulongarmmaddr(Map *map, Rgetter rget, Instr *i){ ulong v; ulong nb; char buf[8]; ulong rn; rn = (i->w >> 16) & 0xf; sprint(buf,"R%ld", rn); v = rget(map, buf); nb = nbits(i->w & ((1 << 15) - 1)); switch((i->w >> 23) & 3) { default: case 0: return (v - (nb*4)) + 4; case 1: return v; case 2: return v - (nb*4); case 3: return v + 4; }}static uvlongarmaddr(Map *map, Rgetter rget, Instr *i){ char buf[8]; ulong rn; sprint(buf, "R%ld", (i->w >> 16) & 0xf); rn = rget(map, buf); if((i->w & (1<<24)) == 0) { /* POSTIDX */ sprint(buf, "R%ld", rn); return rget(map, buf); } if((i->w & (1<<25)) == 0) { /* OFFSET */ sprint(buf, "R%ld", rn); if(i->w & (1U<<23)) return rget(map, buf) + (i->w & BITS(0,11)); return rget(map, buf) - (i->w & BITS(0,11)); } else { /* REGOFF */ ulong index = 0; uchar c; uchar rm; sprint(buf, "R%ld", i->w & 0xf); rm = rget(map, buf); switch((i->w & BITS(5,6)) >> 5) { case 0: index = rm << ((i->w & BITS(7,11)) >> 7); break; case 1: index = LSR(rm, ((i->w & BITS(7,11)) >> 7)); break; case 2: index = ASR(rm, ((i->w & BITS(7,11)) >> 7)); break; case 3: if((i->w & BITS(7,11)) == 0) { c = (rget(map, "PSR") >> 29) & 1; index = c << 31 | LSR(rm, 1); } else { index = ROR(rm, ((i->w & BITS(7,11)) >> 7)); } break; } if(i->w & (1<<23)) return rn + index; return rn - index; }}static uvlongarmfadd(Map *map, Rgetter rget, Instr *i, uvlong pc){ char buf[8]; int r; r = (i->w >> 12) & 0xf; if(r != 15 || !armcondpass(map, rget, (i->w >> 28) & 0xf)) return pc+4; r = (i->w >> 16) & 0xf; sprint(buf, "R%d", r); return rget(map, buf) + armshiftval(map, rget, i);}static uvlongarmfmovm(Map *map, Rgetter rget, Instr *i, uvlong pc){ ulong v; ulong addr; v = i->w & 1<<15; if(!v || !armcondpass(map, rget, (i->w>>28)&0xf)) return pc+4; addr = armmaddr(map, rget, i) + nbits(i->w & BITS(0,15)); if(get4(map, addr, &v) < 0) { werrstr("can't read addr: %r"); return -1; } return v;}static uvlongarmfbranch(Map *map, Rgetter rget, Instr *i, uvlong pc){ if(!armcondpass(map, rget, (i->w >> 28) & 0xf)) return pc+4; return pc + (((signed long)i->w << 8) >> 6) + 8;}static uvlongarmfmov(Map *map, Rgetter rget, Instr *i, uvlong pc){ ulong rd, v; rd = (i->w >> 12) & 0xf; if(rd != 15 || !armcondpass(map, rget, (i->w>>28)&0xf)) return pc+4; /* LDR */ /* BUG: Needs LDH/B, too */ if(((i->w>>26)&0x3) == 1) { if(get4(map, armaddr(map, rget, i), &v) < 0) { werrstr("can't read instruction: %r"); return pc+4; } return v; } /* MOV */ v = armshiftval(map, rget, i); return v;}static Opcode opcodes[] ={ "AND%C%S", armdps, 0, "R%s,R%n,R%d", "EOR%C%S", armdps, 0, "R%s,R%n,R%d", "SUB%C%S", armdps, 0, "R%s,R%n,R%d", "RSB%C%S", armdps, 0, "R%s,R%n,R%d", "ADD%C%S", armdps, armfadd, "R%s,R%n,R%d", "ADC%C%S", armdps, 0, "R%s,R%n,R%d", "SBC%C%S", armdps, 0, "R%s,R%n,R%d", "RSC%C%S", armdps, 0, "R%s,R%n,R%d", "TST%C%S", armdps, 0, "R%s,R%n", "TEQ%C%S", armdps, 0, "R%s,R%n", "CMP%C%S", armdps, 0, "R%s,R%n", "CMN%C%S", armdps, 0, "R%s,R%n", "ORR%C%S", armdps, 0, "R%s,R%n,R%d", "MOVW%C%S", armdps, armfmov, "R%s,R%d", "BIC%C%S", armdps, 0, "R%s,R%n,R%d", "MVN%C%S", armdps, 0, "R%s,R%d",/* 16 */ "AND%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "EOR%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "SUB%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "RSB%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "ADD%C%S", armdps, armfadd, "(R%s%h%m),R%n,R%d", "ADC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "SBC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "RSC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "TST%C%S", armdps, 0, "(R%s%h%m),R%n", "TEQ%C%S", armdps, 0, "(R%s%h%m),R%n", "CMP%C%S", armdps, 0, "(R%s%h%m),R%n", "CMN%C%S", armdps, 0, "(R%s%h%m),R%n", "ORR%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "MOVW%C%S", armdps, armfmov, "(R%s%h%m),R%d", "BIC%C%S", armdps, 0, "(R%s%h%m),R%n,R%d", "MVN%C%S", armdps, 0, "(R%s%h%m),R%d",/* 32 */ "AND%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "EOR%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "SUB%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "RSB%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "ADD%C%S", armdps, armfadd, "(R%s%hR%M),R%n,R%d", "ADC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "SBC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "RSC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "TST%C%S", armdps, 0, "(R%s%hR%M),R%n", "TEQ%C%S", armdps, 0, "(R%s%hR%M),R%n", "CMP%C%S", armdps, 0, "(R%s%hR%M),R%n", "CMN%C%S", armdps, 0, "(R%s%hR%M),R%n", "ORR%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "MOVW%C%S", armdps, armfmov, "(R%s%hR%M),R%d", "BIC%C%S", armdps, 0, "(R%s%hR%M),R%n,R%d", "MVN%C%S", armdps, 0, "(R%s%hR%M),R%d",/* 48 */ "AND%C%S", armdpi, 0, "$#%i,R%n,R%d", "EOR%C%S", armdpi, 0, "$#%i,R%n,R%d", "SUB%C%S", armdpi, 0, "$#%i,R%n,R%d", "RSB%C%S", armdpi, 0, "$#%i,R%n,R%d", "ADD%C%S", armdpi, armfadd, "$#%i,R%n,R%d", "ADC%C%S", armdpi, 0, "$#%i,R%n,R%d", "SBC%C%S", armdpi, 0, "$#%i,R%n,R%d", "RSC%C%S", armdpi, 0, "$#%i,R%n,R%d", "TST%C%S", armdpi, 0, "$#%i,R%n", "TEQ%C%S", armdpi, 0, "$#%i,R%n", "CMP%C%S", armdpi, 0, "$#%i,R%n", "CMN%C%S", armdpi, 0, "$#%i,R%n", "ORR%C%S", armdpi, 0, "$#%i,R%n,R%d", "MOVW%C%S", armdpi, armfmov, "$#%i,R%d", "BIC%C%S", armdpi, 0, "$#%i,R%n,R%d", "MVN%C%S", armdpi, 0, "$#%i,R%d",/* 48+16 */ "MUL%C%S", armdpi, 0, "R%M,R%s,R%n", "MULA%C%S", armdpi, 0, "R%M,R%s,R%n,R%d", "SWPW", armdpi, 0, "R%s,(R%n),R%d", "SWPB", armdpi, 0, "R%s,(R%n),R%d",/* 48+16+4 */ "MOV%u%C%p", armhwby, 0, "R%d,(R%n%UR%M)", "MOV%u%C%p", armhwby, 0, "R%d,%I", "MOV%u%C%p", armhwby, armfmov, "(R%n%UR%M),R%d", "MOV%u%C%p", armhwby, armfmov, "%I,R%d",/* 48+24 */ "MOVW%C%p", armsdti, 0, "R%d,%I", "MOVB%C%p", armsdti, 0, "R%d,%I", "MOVW%C%p", armsdti, armfmov, "%I,R%d", "MOVBU%C%p", armsdti, armfmov, "%I,R%d", "MOVW%C%p", armsdts, 0, "R%d,(R%s%h%m)(R%n)", "MOVB%C%p", armsdts, 0, "R%d,(R%s%h%m)(R%n)", "MOVW%C%p", armsdts, armfmov, "(R%s%h%m)(R%n),R%d", "MOVBU%C%p", armsdts, armfmov, "(R%s%h%m)(R%n),R%d", "MOVM%C%P%a", armbdt, armfmovm, "[%r],(R%n)", "MOVM%C%P%a", armbdt, armfmovm, "(R%n),[%r]", "B%C", armb, armfbranch, "%b", "BL%C", armb, armfbranch, "%b", "CDP%C", armco, 0, "", "CDP%C", armco, 0, "", "MCR%C", armco, 0, "", "MRC%C", armco, 0, "",/* 48+24+4+4+2+2+4 */ "MULLU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", "MULALU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", "MULL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)", "MULAL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",/* 48+24+4+4+2+2+4+4 */ "UNK", armunk, 0, "",};static voidgaddr(Instr *i){ *i->curr++ = '$'; i->curr += gsymoff(i->curr, i->end-i->curr, i->imm, CANY);}static char *mode[] = { 0, "IA", "DB", "IB" };static char *pw[] = { "P", "PW", 0, "W" };static char *sw[] = { 0, "W", "S", "SW" };static voidformat(char *mnemonic, Instr *i, char *f){ int j, k, m, n; int g; char *fmt; if(mnemonic) format(0, i, mnemonic); if(f == 0) return; if(mnemonic) if(i->curr < i->end) *i->curr++ = '\t'; for ( ; *f && i->curr < i->end; f++) { if(*f != '%') { *i->curr++ = *f; continue; } switch (*++f) { case 'C': /* .CONDITION */ if(cond[i->cond]) bprint(i, ".%s", cond[i->cond]); break; case 'S': /* .STORE */ if(i->store) bprint(i, ".S"); break; case 'P': /* P & U bits for block move */ n = (i->w >>23) & 0x3; if (mode[n]) bprint(i, ".%s", mode[n]); break; case 'p': /* P & W bits for single data xfer*/ if (pw[i->store]) bprint(i, ".%s", pw[i->store]); break; case 'a': /* S & W bits for single data xfer*/ if (sw[i->store]) bprint(i, ".%s", sw[i->store]); break; case 's': bprint(i, "%d", i->rs & 0xf); break; case 'M': bprint(i, "%lud", (i->w>>8) & 0xf); break; case 'm': bprint(i, "%lud", (i->w>>7) & 0x1f); break; case 'h': bprint(i, shtype[(i->w>>5) & 0x3]); break; case 'u': /* Signed/unsigned Byte/Halfword */ bprint(i, hb[(i->w>>5) & 0x3]); break; case 'I': if (i->rn == 13) { if (plocal(i)) break; } g = 0; fmt = "#%lx(R%d)"; if (i->rn == 15) { /* convert load of offset(PC) to a load immediate */ if (get4(i->map, i->addr+i->imm+8, (ulong*)&i->imm) > 0) { g = 1; fmt = ""; } } if (mach->sb) { if (i->rd == 11) { ulong nxti; if (get4(i->map, i->addr+4, &nxti) > 0) { if ((nxti & 0x0e0f0fff) == 0x060c000b) { i->imm += mach->sb; g = 1; fmt = "-SB"; } } } if (i->rn == 12) { i->imm += mach->sb; g = 1; fmt = "-SB(SB)"; } } if (g) { gaddr(i); bprint(i, fmt, i->rn); } else bprint(i, fmt, i->imm, i->rn); break; case 'U': /* Add/subtract from base */ bprint(i, addsub[(i->w >> 23) & 1]); break; case 'n': bprint(i, "%d", i->rn); break; case 'd': bprint(i, "%d", i->rd); break; case 'i': bprint(i, "%lux", i->imm); break; case 'b': i->curr += symoff(i->curr, i->end-i->curr, i->imm, CTEXT); break; case 'g': i->curr += gsymoff(i->curr, i->end-i->curr, i->imm, CANY); break; case 'r': n = i->imm&0xffff; j = 0; k = 0; while(n) { m = j; while(n&0x1) { j++; n >>= 1; } if(j != m) { if(k) bprint(i, ","); if(j == m+1) bprint(i, "R%d", m); else bprint(i, "R%d-R%d", m, j-1); k = 1; } j++; n >>= 1; } break; case '\0': *i->curr++ = '%'; return; default: bprint(i, "%%%c", *f); break; } } *i->curr = 0;}static intprintins(Map *map, uvlong pc, char *buf, int n){ Instr i; i.curr = buf; i.end = buf+n-1; if(decode(map, pc, &i) < 0) return -1; (*opcodes[i.op].fmt)(&opcodes[i.op], &i); return 4;}static intarminst(Map *map, uvlong pc, char modifier, char *buf, int n){ USED(modifier); return printins(map, pc, buf, n);}static intarmdas(Map *map, uvlong pc, char *buf, int n){ Instr i; i.curr = buf; i.end = buf+n; if(decode(map, pc, &i) < 0) return -1; if(i.end-i.curr > 8) i.curr = _hexify(buf, i.w, 7); *i.curr = 0; return 4;}static intarminstlen(Map *map, uvlong pc){ Instr i; if(decode(map, pc, &i) < 0) return -1; return 4;}static intarmfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll){ uvlong d; Instr i; if(decode(map, pc, &i) < 0) return -1; if(opcodes[i.op].foll) { d = (*opcodes[i.op].foll)(map, rget, &i, pc); if(d == -1) return -1; } else d = pc+4; foll[0] = d; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -