📄 disassemble.c
字号:
}intmd_is_jr (adr) void *adr;{ const DISTBL *pt; u_int32_t inst; inst = load_word (adr); pt = get_distbl (inst); return (pt->type == JR);}void *md_branch_target(adr) void *adr;{ const DISTBL *pt; int32_t val; u_int32_t inst; inst = load_word (adr); pt = get_distbl (inst); switch (pt->type) { case OFF: case RS_RT_OFF: case RS_OFF: case CP_OFF: val = inst & 0xffff; if (val & 0x8000) val |= 0xffff0000; return(adr + 4 + (val << 2)); case TARGET: val = inst & 0x3ffffff; return ((void *)(((int)(adr + 4) & 0xf0000000) | (val << 2))); case JALR: case JR: val = RS_ (inst); return ((void *)(int)REGREG[val]); default: return (0); }}intmd_is_call (adr) void *adr;{ u_int32_t inst; inst = load_word(adr); switch (getfield(inst, 6, 26)) { case 0: /* special: jalr */ return (getfield (inst, 6, 0) == 9); case 1: /* regimm: bal */ return (getfield (inst, 2, 19) == 2); case 3: /* jal */ return (1); } return (0);}const DISTBL *get_distbl (bits) u_int32_t bits;{ const DISTBL *pt = distbl; static const DISTBL *lastpt = 0; static u_int32_t lastbits; /* simple cache for repeated lookups */ if (lastpt && bits == lastbits) return lastpt; while ((bits & pt->mask) != pt->code) ++pt; lastpt = pt; lastbits = bits; return (pt);}intmd_is_writeable (adr) void *adr;{ u_int32_t x; x = load_word (adr); store_word (adr, ~x); flush_cache(DCACHE, adr); if (load_word (adr) != ~x) return (0); store_word (adr, x); return (1);}const Optdesc l_opts[] ={ {"-b", "list only branches"}, {"-c", "list only calls"}, {"-t", "list trace buffer"}, {"-r", "show register values with trace"}, {0}};/************************************************************* * dis(ac,av) * the 'l' (disassemble) command */int rflag; /* Wanting effective addresses for load/store instructions */int rsvalue; /* Computed by rs() macro for displaying load/store effective addrs */int rtvalue;int do_rt;int do_rs;intmd_disassemble(ac, av) int ac; char *av[];{ void *adr; int siz, l; int bflag, cflag, i, j, n, tflag;static void *last_adr; /* For repeat of l command */ void *prev_adr; /* For figuring print of a0-a3 after jal type inst. */ rflag = bflag = cflag = n = tflag = 0; siz = moresz; adr = md_get_excpc; for (i = 1; i < ac; i++) { if (av[i][0] == '-') { for (j = 1; av[i][j] != 0; j++) { switch (av[i][j]) { case 'b': bflag = 1; break; case 'c': cflag = 1; break; case 't': tflag = 1; n++; break; case 'r': rflag = 1; break; default: printf ("%c: unknown option\n", av[i][j]); return (-1); } } } else { switch (n) { case 0: if (!get_rsa ((u_int32_t *)&adr, av[i])) return (-1); break; case 1: if (!get_rsa (&siz, av[i])) return (-1); break; default: printf ("%s: unknown option\n", av[i]); return (-1); } n++; } } if (repeating_cmd ) adr = last_adr - 4; if (matchenv ("regstyle")) { regname = regs_sw; c0reg = regs_c0; } else { regname = regs_hw; c0reg = regs_hw; } ioctl (STDIN, CBREAK, NULL); if (tflag) { dispchist (n, siz); rflag = 0; return (0); }#if 0 if (adr < K0BASE || adr >= K2BASE || ((int)adr & 3)) { printf ("%08x: illegal instruction address\n", adr); rflag = 0; return (1); }#endif if (n > 1 && siz == 1 && md_is_branch (adr)) siz = 2; /* include branch delay slot */ l = siz; if (cflag || bflag) printf ("%s", searching); while (1) { /* Enable this if you want a 'label' at the start of each * procedure. * if (adr2sym(prnbuf,adr)) { * strcat(prnbuf,":"); * if (more(prnbuf,&l,(n>1)?0:siz)) break; * } */ if (cflag || bflag) { int match; char *p; if (cflag) match = md_is_call (adr); else match = md_is_branch (adr); if (!match) { dotik (128, 0); adr += 4L; continue; } p = searching; while(*p++) printf("\b \b"); } prev_adr = adr; adr = md_disasm (prnbuf, adr); last_adr = adr; if (more (prnbuf, &l, (n > 1) ? 0 : siz)) break; if (rflag && ( md_is_call( prev_adr ) ) ) { /* * We're showing registers and we just displayed * a JAL type instruction. Show a0-a3 */ printf( "\t\t\t# a0=0x%x a1=0x%x a2=0x%x a3=0x%x\n", cpuinfotab[whatcpu]->a0, cpuinfotab[whatcpu]->a1, cpuinfotab[whatcpu]->a2, cpuinfotab[whatcpu]->a3); } if (cflag || bflag) printf ("%s", searching); } rflag = 0; return (0);}/**************************************************************/void * md_disasm (dest, addr) char *dest; void *addr;{ const DISTBL *pt; char tmp[40]; long v, v1, w; int i;#ifdef FLOATINGPT float *s_fs; /* For getting at FS argument via float */ float *s_ft; /* For getting at FT argument via float */ double *d_fs; /* For getting at FS argument via double */ double *d_ft; /* For getting at FT argument via double */ int *w_fs; /* For getting at FS argument via binary fixed single */ long long *l_fs; /* For getting at FS argument via binary fixed long */ int fpdis; /* Actually show the floating point values switch */#endif /* FLOATINGPT */ inst = load_word(addr);; if (regname == 0) regname = regs_sw; if (!adr2symoff (dest, (int)addr, 12)) sprintf (dest, "%08x", addr); sprintf (tmp, " %08x ", inst); strcat (dest, tmp); pt = get_distbl (inst); i = strlen (pt->str); strcat (dest, pt->str); do_rt = 0; do_rs = 0;#ifdef FLOATINGPT /* * It is possible the floating point values are bogus for printing * so give user a way to not show them. */ fpdis = matchenv ("fpdis"); /* * Get pointers to various ways of looking at floating point operands * as part of the rflag display rather than having do do these casts * over and over */ d_fs = (double *)&Fpr[(int)FS_(inst)]; d_ft = (double *)&Fpr[(int)FT_(inst)]; l_fs = (long long *)d_fs; s_fs = (float *)(((int *)d_fs)+1); s_ft = (float *)(((int *)d_ft)+1); w_fs = (int *)s_fs;#endif /* FLOATINGPT */ while (i++ < 8) strcat (dest, " "); switch (pt->type) { case FT_FS_FD_D: fd (); comma (); fs (); comma (); ft ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) { if (dpdenorm( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=0.0 (dp denorm)"); else if (dpnan( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *d_fs); strcat (dest, tmp); if (dpdenorm( (struct IEEEdp *)d_ft ) ) sprintf (tmp, " ft=0.0 (dp denorm)"); else if (dpnan( (struct IEEEdp *)d_ft ) ) sprintf (tmp, " ft=Nan"); else sprintf (tmp, " ft=%e", *d_ft); } else sprintf (tmp, " fs=%llx ft=%llx", *d_fs, *d_ft); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FT_FS_FD_S: fd (); comma (); fs (); comma (); ft ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) { if (spdenorm( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=0.0 (sp denorm)"); else if (spnan( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *s_fs); strcat (dest, tmp); if (spdenorm( (struct IEEEsp *)s_ft ) ) sprintf (tmp, " ft=0.0 (sp denorm)"); if (spnan( (struct IEEEsp *)s_ft ) ) sprintf (tmp, " ft=Nan"); else sprintf (tmp, " ft=%e", *s_ft); } else sprintf (tmp, " fs=0x%x ft=0x%x", *s_fs, *s_ft); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FS_FD_D: fd (); comma (); fs ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) if (dpdenorm( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=0.0 (dp denorm)"); else if (dpnan( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *d_fs); else sprintf (tmp, " fs=%llx", *d_fs); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FS_FD_S: fd (); comma (); fs ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) if (spdenorm( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=0.0 (sp denorm)"); else if (spnan( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *s_fs); else sprintf (tmp, " fs=0x%x", *s_fs); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FS_FD_W: fd (); comma (); fs ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "# ", 0); sprintf (tmp, "fs=0x%x", *w_fs); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FS_FD_L: fd (); comma (); fs ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "# ", 0); sprintf (tmp, "fs=%llx", *l_fs); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FT_FS_D: fs (); comma (); ft ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) { if (dpdenorm( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=0.0 (dp denorm)"); else if (dpnan( (struct IEEEdp *)d_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *d_fs); strcat (dest, tmp); if (dpdenorm( (struct IEEEdp *)d_ft ) ) sprintf (tmp, " ft=0.0 (dp denorm)"); else if (dpnan( (struct IEEEdp *)d_ft ) ) sprintf (tmp, " ft=Nan"); else sprintf (tmp, " ft=%e", *d_ft); } else sprintf (tmp, " fs=%llx ft=%llx", *d_fs, *d_ft); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case FT_FS_S: fs (); comma (); ft ();#ifdef FLOATINGPT if (rflag ) { mkcomment( dest, "#", 0); if (fpdis ) { if (spdenorm( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=0.0 (sp denorm)"); if (spnan( (struct IEEEsp *)s_fs ) ) sprintf (tmp, " fs=Nan"); else sprintf (tmp, " fs=%e", *s_fs); strcat (dest, tmp); if (spdenorm( (struct IEEEsp *)s_ft ) ) sprintf (tmp, " ft=0.0 (sp denorm)"); else if (spnan( (struct IEEEsp *)s_ft ) ) sprintf (tmp, " ft=Nan"); else sprintf (tmp, " ft=%e", *s_ft); } else sprintf (tmp, " fs=0x%x ft=0x%x", *s_fs, *s_ft); strcat (dest, tmp); }#endif /* FLOATINGPT */ break; case RT_RS_IMM: rt (); comma (); rs (); comma (); imm (dest); if (rflag ) { sprintf (tmp, " rs=0x%x", rsvalue); strcat (dest, tmp); } break; case RT_RS_SIMM: rt (); comma (); rs (); comma (); simm (dest); if (rflag ) { sprintf (tmp, " rs=0x%x", rsvalue); strcat (dest, tmp); } break; case RT_IMM: rt (); comma (); imm (dest); break; case RT_SIMM: rt (); comma (); simm (dest);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -