/* This file is in the public domain. */ #include #include #include "fnprintf.h" #include "machine.h" #define CF_RELOC (CF_MSPEC+0) #define CF_STAB (CF_MSPEC+1) static const char *regs[] = { "g0","g1","g2","g3","g4","g5","g6","g7", "o0","o1","o2","o3","o4","o5","sp","o7", "l0","l1","l2","l3","l4","l5","l6","l7", "i0","i1","i2","i3","i4","i5","fp","i7" }; static const char *icc[] = { "n", "e", "le", "l", "leu", "lu/cs", "neg", "vs", "a", "ne", "g", "ge", "gu", "geu/cc", "pos", "vc" }; static const char *fcc[] = { "n", "ne", "lg", "ul", "l", "ug", "g", "u", "a", "e", "ue", "ge", "uge", "le", "ule", "o" }; static const char *ccc[] = { "n", "123", "12", "13", "1", "23", "2", "3", "a", "0", "03", "02", "023", "01", "013", "012" }; static int prev_sethi; static unsigned long int sethi_val; static int sethi_suf; static unsigned long int sethi_sufval; #define REP4(x) x, x, x, x #define REP8(x) REP4(x), REP4(x) #define REP16(x) REP8(x), REP8(x) #define REP32(x) REP16(x), REP16(x) #define REP64(x) REP32(x), REP32(x) #define REP128(x) REP64(x), REP64(x) #define REP256(x) REP128(x), REP128(x) #define REP2b(x) REP4(x) #define REP3b(x) REP8(x) #define REP4b(x) REP16(x) #define REP5b(x) REP32(x) #define REP6b(x) REP64(x) #define REP7b(x) REP128(x) #define REP8b(x) REP256(x) #define OPC(opc) (((opc)>>30)&3) /* format select bits */ #define OP2(opc) (((opc)>>22)&7) /* opcode bits, format 2 */ #define DREG(opc) (((opc)>>25)&31) /* dest reg bits, formats 2 and 3 */ #define A(opc) (((opc)>>29)&1) /* annul bit, format 2 */ #define COND(opc) (((opc)>>25)&15) /* condition code bits, format 2 */ #define IMM22(opc) ((opc)&0x003fffff) /* immediate data, format 2 */ #define DISP22(opc) signextend(IMM22(opc),22) /* displacement, format 2 */ #define OP3(opc) (((opc)>>19)&0x3f) /* opcode bits, format 3 */ #define SREG1(opc) (((opc)>>14)&31) /* source reg 1 bits, format 3 */ #define SREG2(opc) ((opc)&31) /* source reg 2 bits, format 3 */ #define I(opc) (((opc)>>13)&1) /* immediate bit, format 3 */ #define ASI(opc) (((opc)>>5)&0xff) /* alternative space bits, format 3 */ #define SIMM13(opc) signextend((opc)&0x1fff,13) /* immediate data, format 3 */ #define OPF(opc) (((opc)>>5)&0x1ff) /* FPU opcode bits, format 3 */ static signed long int signextend(unsigned long int ul, int nbits) { return( (ul&(1UL<<(nbits-1))) ? -(signed long int)((((1UL<= 4) { unsigned long int prevopc; prevopc = corefetchu(addr-4,4); if ( (OPC(prevopc) == 0) && (OP2(prevopc) == 4) && (DREG(prevopc) == reg) ) { prev_sethi = 1; sethi_val = IMM22(prevopc) << 10; } } } static void print_address(void (*fn)(char), ADDR addr, unsigned long int opc) { int anything; anything = 0; if (SREG1(opc) != 0) { fnprintf(fn,"%%%s",regs[SREG1(opc)]); anything = 1; } if (I(opc)) { signed long int off; sethi_check(addr,SREG1(opc)); off = SIMM13(opc); if (prev_sethi) { sethi_suf = 1; sethi_sufval = sethi_val + off; } if (off || !anything) { if (off < 0) fnprintf(fn,"-%#lx",-off); else fnprintf(fn,"%s%#lx",anything?"+":"",off); } } else { if (SREG2(opc) || !anything) { fnprintf(fn,"%s%%%s",anything?"+":"",regs[SREG2(opc)]); } } } static int do_dis_inst(ADDR addr, void (*fn)(char), CFLAG flg) { unsigned long int opc; prev_sethi = -1; sethi_suf = 0; addr -= corebase; if (addr+4 > coresize) return(-1); opc = corefetchu(addr,4); switch (OPC(opc)) { case 1: /* format 1 */ /* 01oo oooo oooo oooo oooo oooo oooo oooo */ /* o = offset, in longword units */ fnprintf(fn,"call "); print_symbol_or_hex(fn,addr+corebase+((opc&0x3fffffff)<<2)); break; case 0: /* format 2 */ /* 00rr rrro ooii iiii iiii iiii iiii iiii */ /* 00ac ccco oodd dddd dddd dddd dddd dddd */ /* r = dreg, a = annul, c = cond, o = opcode */ /* i = immediate data, d = displacement */ switch (OP2(opc)) { case 0: fnprintf(fn,"unimp 0x%lx",IMM22(opc)); break; case 4: if (opc == 0x01000000) { fnprintf(fn,"nop"); } else { fnprintf(fn,"sethi %%hi(0x%08lx), %%%s",IMM22(opc)<<10,regs[DREG(opc)]); } break; { int n; const char **ccvec; const char *pref; case 2: ccvec = &icc[0]; pref = "b"; if (0) { case 6: ccvec = &fcc[0]; pref = "fb"; } if (0) { case 7: ccvec = &ccc[0]; pref = "cb"; } fnprintf(fn,"%s%s",pref,ccvec[COND(opc)]); n = strlen(pref) + strlen(ccvec[COND(opc)]); if (A(opc)) { fnprintf(fn,",a"); n += 2; } fnprintf(fn,"%*s",12-n,""); print_symbol_or_hex(fn,addr+corebase+(DISP22(opc)<<2)); } break; case 1: case 3: case 5: fnprintf(fn,"",OP2(opc),DREG(opc),IMM22(opc)); break; } break; case 2: /* format 3 */ { static const char *rs1_ri_rd_opc[] = { "Dadd", "Xand", "Xor", "Xxor", /* 0000xx */ "Dsub", "Xandn", "Xorn", "Xxnor", /* 0001xx */ "Daddx", 0, 0, 0, "Dsubx", 0, 0, 0, /* 001xxx */ "Daddcc", "Xandcc", "Xorcc", "Xxorcc", /* 0100xx */ "Dsubcc", "Xandncc", "Xorncc", "Xxnorcc", /* 0101xx */ "Daddxcc", 0, 0, 0, "Dsubxcc", 0, 0, 0, /* 011xxx */ "Dtaddcc", "Dtsubcc", "Dtaddcctv", "Dtsubcctv", /* 1000xx */ "Dmulscc", "5sll", "5srl", "5sra", /* 1001xx */ REP3b(0), /* 101xxx */ REP3b(0), /* 110xxx */ 0, 0, 0, 0, "Dsave", "Drestore", 0, 0 }; /* 111xxx */ static const char *rdreg[] = { REP5b(0), /* 0xxxxx */ REP3b(0), /* 100xxx */ "y", "psr", "wim", "tbr", 0, 0, 0, 0, /* 101xxx */ REP4b(0) }; /* 11xxxx */ static const char *wrreg[] = { REP5b(0), /* 0xxxxx */ REP4b(0), /* 10xxxx */ "y", "psr", "wim", "tbr", 0, 0, 0, 0, /* 110xxx */ REP3b(0) }; /* 111xxx */ const char *os; int op3; int opf; op3 = OP3(opc); if ((os = rs1_ri_rd_opc[op3])) { if (opc == 0x81e80000) { /* restore %g0, %g0, %g0 -> restore */ fnprintf(fn,"restore"); } else if (opc == 0x81e00000) { /* save %g0, %g0, %g0 -> save */ fnprintf(fn,"save"); } else if ((op3 == 20) && (DREG(opc) == 0)) { /* subcc x, y, %g0 -> cmp x, y */ fnprintf(fn,"cmp %%%s, ",regs[SREG1(opc)]); if (I(opc)) fnprintf(fn,"%ld",SIMM13(opc)); else fnprintf(fn,"%%%s",regs[SREG2(opc)]); } else if ( (op3 == 18) && !I(opc) && (SREG2(opc) == 0) && (DREG(opc) == 0) ) { /* orcc x, %g0, %g0 -> tst x */ fnprintf(fn,"tst %%%s",regs[SREG1(opc)]); } else if ( (op3 == 18) && !I(opc) && (SREG1(opc) == 0) && (DREG(opc) == 0) ) { /* orcc %g0, x, %g0 -> tst x */ fnprintf(fn,"tst %%%s",regs[SREG2(opc)]); } else if ((op3 == 7) && !I(opc) && (SREG2(opc) == 0)) { /* xnor x, %g0, y -> not x, y */ /* xnor x, %g0, x -> not x */ fnprintf(fn,"not %%%s",regs[SREG1(opc)]); if (DREG(opc) != SREG1(opc)) fnprintf(fn,", %%%s",regs[DREG(opc)]); } else if ((op3 == 4) && !I(opc) && (SREG1(opc) == 0)) { /* sub %g0, x, y -> neg x, y */ /* sub %g0, x, x -> neg x */ fnprintf(fn,"neg %%%s",regs[SREG2(opc)]); if (DREG(opc) != SREG2(opc)) fnprintf(fn,", %%%s",regs[DREG(opc)]); } else if ((op3 == 0) && I(opc) && (SREG1(opc) == DREG(opc))) { /* add x, y, x -> inc y, x */ /* add x, 1, x -> inc x */ fnprintf(fn,"inc "); if (SIMM13(opc) != 1) fnprintf(fn,"%ld, ",SIMM13(opc)); fnprintf(fn,"%%%s",regs[SREG1(opc)]); sethi_check(addr,SREG1(opc)); if (prev_sethi) { sethi_suf = 1; sethi_sufval = sethi_val + SIMM13(opc); } } else if ((op3 == 4) && I(opc) && (SREG1(opc) == DREG(opc))) { /* sub x, y, x -> dec y, x */ /* sub x, 1, x -> dec x */ fnprintf(fn,"dec "); if (SIMM13(opc) != 1) fnprintf(fn,"%ld, ",SIMM13(opc)); fnprintf(fn,"%%%s",regs[SREG1(opc)]); sethi_check(addr,SREG1(opc)); if (prev_sethi) { sethi_suf = 1; sethi_sufval = sethi_val - SIMM13(opc); } } else if ( (op3 == 16) && I(opc) && (SREG1(opc) == DREG(opc)) && (SIMM13(opc) == 1) ) { /* addcc x, 1, x -> inccc x */ fnprintf(fn,"inccc %%%s",regs[SREG1(opc)]); } else if ( (op3 == 20) && I(opc) && (SREG1(opc) == DREG(opc)) && (SIMM13(opc) == 1) ) { /* subcc x, 1, x -> deccc x */ fnprintf(fn,"deccc %%%s",regs[SREG1(opc)]); } else if ((op3 == 17) && (DREG(opc) == 0)) { /* andcc x, y, %g0 -> btst y, x */ fnprintf(fn,"btst "); if (I(opc)) fnprintf(fn,"%#lx",SIMM13(opc)); else fnprintf(fn,"%%%s",regs[SREG2(opc)]); fnprintf(fn,", %%%s",regs[SREG1(opc)]); } else if ( (op3 == 2) && !I(opc) && (SREG1(opc) == 0) && (SREG2(opc) == 0) ) { /* or %g0, %g0, x -> clr x */ fnprintf(fn,"clr %%%s",regs[DREG(opc)]); } else if ( (op3 == 2) && (SREG1(opc) == 0) ) { /* or %g0, x, y -> mov x, y */ fnprintf(fn,"mov "); if (I(opc)) fnprintf(fn,"%#lx",SIMM13(opc)); else fnprintf(fn,"%%%s",regs[SREG2(opc)]); fnprintf(fn,", %%%s",regs[DREG(opc)]); } else { fnprintf(fn,"%s%*s%%%s, ",os+1,12-(int)strlen(os+1),"",regs[SREG1(opc)]); if (I(opc)) { switch (os[0]) { case 'D': fnprintf(fn,"%ld",SIMM13(opc)); break; case 'X': fnprintf(fn,"0x%lx",SIMM13(opc)); break; case '5': fnprintf(fn,"%ld",SIMM13(opc)&31); break; } } else { fnprintf(fn,"%%%s",regs[SREG2(opc)]); } fnprintf(fn,", %%%s",regs[DREG(opc)]); sethi_check(addr,SREG1(opc)); if (prev_sethi && I(opc)) { switch (op3) { case 0: /* add */ sethi_suf = 1; sethi_sufval = sethi_val + SIMM13(opc); break; case 2: /* or */ sethi_suf = 1; sethi_sufval = sethi_val | SIMM13(opc); break; case 4: /* sub */ sethi_suf = 1; sethi_sufval = sethi_val - SIMM13(opc); break; } } } } else if ((os = rdreg[op3])) { fnprintf(fn,"rd %%%s, %%%s",os,regs[DREG(opc)]); } else if ((os = wrreg[op3])) { fnprintf(fn,"wr %%%s, ",regs[SREG1(opc)]); if (I(opc)) fnprintf(fn,"0x%lx",SIMM13(opc)); else fnprintf(fn,"%%%s",regs[SREG2(opc)]); fnprintf(fn,", %%%s",os); } else { switch (op3) { case 52: /* 110100 - fpop1 */ { static const char *fs1_fs2_fd[] = { REP6b(0), /*000xxxxxx*/ REP3b(0), /*001000xxx*/ 0, "fmuls", "fmuld", "fmulx", /*0010010xx*/ 0, "fdivs", "fdivd", "fdivx", /*0010011xx*/ REP4b(0), /*00101xxxx*/ REP5b(0), /*0011xxxxx*/ REP7b(0), /*01xxxxxxx*/ REP8b(0) }; /*1xxxxxxxx*/ static const char *fs2_fd[] = { 0, "fmovs", 0, 0, /*0000000xx*/ 0, "fnegs", 0, 0, /*0000001xx*/ 0, "fabss", 0, 0, /*0000010xx*/ REP2b(0), /*0000011xx*/ REP4b(0), /*00001xxxx*/ REP3b(0), /*000100xxx*/ 0, "fsqrts", "fsqrtd", "fsqrtx", /*0001010xx*/ REP2b(0), /*0001011xx*/ REP4b(0), /*00011xxxx*/ REP6b(0), /*001xxxxxx*/ REP6b(0), /*010xxxxxx*/ 0, "fstoir", "fdtoir", "fxtoir", /*0110000xx*/ "fitos", 0, "fdtos", "fxtos", /*0110001xx*/ "fitod", "fstod", 0, "fxtod", /*0110010xx*/ "fitox", "fstox", "fdtox", 0, /*0110011xx*/ 0, "fstoi", "fdtoi", "fxtoi", /*0110100xx*/ REP2b(0), /*0110101xx*/ REP3b(0), /*011011xxx*/ REP5b(0), /*0111xxxxx*/ REP8b(0) }; /*1xxxxxxxx*/ opf = OPF(opc); if ((os = fs1_fs2_fd[opf])) { fnprintf(fn,"%s%*s%%f%lu, %%f%lu, %%f%lu",os,12-(int)strlen(os),"",SREG1(opc),SREG2(opc),DREG(opc)); } else if ((os = fs2_fd[opf])) { fnprintf(fn,"%s%*s%%f%lu, %%f%lu",os,12-(int)strlen(os),"",SREG2(opc),DREG(opc)); } else { fnprintf(fn,"",OPF(opc),SREG1(opc),SREG2(opc),DREG(opc)); } } break; case 53: /* 110101 - fpop2 */ { static const char *cmps[] = { REP6b(0), /*000xxxxxx*/ REP4b(0), /*00100xxxx*/ 0, "fcmps", "fcmpd", "fcmpx", /*0010100xx*/ 0, "fcmpes", "fcmped", "fcmpex", /*0010101xx*/ REP3b(0), /*001011xxx*/ REP5b(0), /*0011xxxxx*/ REP7b(0), /*01xxxxxxx*/ REP8b(0) }; /*1xxxxxxxx*/ opf = OPF(opc); if ((os = cmps[opf])) { fnprintf(fn,"%s%*s%%f%lu, %%f%lu",os,12-(int)strlen(os),"",SREG1(opc),SREG2(opc)); } else { fnprintf(fn,"",OPF(opc),SREG1(opc),SREG2(opc),DREG(opc)); } } break; case 54: /* 110110 - cpop1 */ fnprintf(fn,"",OPF(opc),SREG1(opc),SREG2(opc),DREG(opc)); break; case 55: /* 110111 - cpop2 */ fnprintf(fn,"",OPF(opc),SREG1(opc),SREG2(opc),DREG(opc)); break; case 56: /* 111000 */ if (opc == 0x81c7e008) /* jmpl %i7+8, %g0 */ { fnprintf(fn,"ret"); } else if (opc == 0x81c3e008) /* jmpl %o7+8, %g0 */ { fnprintf(fn,"retl"); } else if (DREG(opc) == 0) /* jmpl x, %g0 */ { fnprintf(fn,"jmp "); print_address(fn,addr,opc); } else if (DREG(opc) == 15) /* jmpl x, %o7 */ { fnprintf(fn,"call "); print_address(fn,addr,opc); } else { fnprintf(fn,"jmpl "); print_address(fn,addr,opc); fnprintf(fn,", %%%s",regs[DREG(opc)]); } break; case 57: /* 111001 */ fnprintf(fn,"rett "); print_address(fn,addr,opc); break; case 58: /* 111010 */ os = icc[DREG(opc)&15]; fnprintf(fn,"t%s%*s",os,11-(int)strlen(os),""); print_address(fn,addr,opc); break; case 59: /* 111011 */ fnprintf(fn,"iflush "); print_address(fn,addr,opc); break; default: fnprintf(fn,"",OP3(opc),DREG(opc),SREG1(opc),I(opc),ASI(opc),OPF(opc),SIMM13(opc),SREG2(opc)); break; } } } break; case 3: /* format 3 */ { static const char *addr_rd[] = { "ld", "ldub", "lduh", "ldd", 0, 0, 0, 0, /* 000xxx */ 0, "ldsb", "ldsh", 0, 0, "ldstub", 0, "swap", /* 001xxx */ REP4b(0), /* 01xxxx */ REP5b(0) }; /* 1xxxxx */ static const char *addr_asi_rd[] = { REP4b(0), /* 00xxxx */ "lda", "lduba", "lduha", "ldda", 0, 0, 0, 0, /* 010xxx */ 0, "ldsba", "ldsha", 0, 0, "ldstuba", 0, "swapa", /* 011xxx */ REP5b(0) }; /* 1xxxxx */ static const char *rd_addr[] = { 0, 0, 0, 0, "st", "stb", "sth", "std", /* 000xxx */ REP3b(0), /* 001xxx */ REP4b(0), /* 01xxxx */ REP5b(0) }; /* 1xxxxx */ static const char *rd_addr_asi[] = { REP4b(0), /* 00xxxx */ 0, 0, 0, 0, "sta", "stba", "stha", "stda", /* 010xxx */ REP3b(0), /* 011xxx */ REP5b(0) }; /* 1xxxxx */ static const char *ld[] = { REP5b(0), /* 0xxxxx */ "frld", "fsld", 0, "frldd", 0, 0, 0, 0, /* 100xxx */ REP3b(0), /* 101xxx */ "crld", "csld", 0, "crldd", 0, 0, 0, 0, /* 110xxx */ REP3b(0) }; /* 111xxx */ static const char *st[] = { REP5b(0), /* 0xxxxx */ 0, 0, 0, 0, "frst", "fsst", "fqst", "frstd", /* 100xxx */ REP3b(0), /* 101xxx */ 0, 0, 0, 0, "crst", "csst", "cqst", "crstd", /* 110xxx */ REP3b(0) }; /* 111xxx */ int op3; const char *os; op3 = OP3(opc); if ((os = addr_rd[op3])) { fnprintf(fn,"%s%*s[",os,12-(int)strlen(os),""); print_address(fn,addr,opc); fnprintf(fn,"], %%%s",regs[DREG(opc)]); } else if ((os = addr_asi_rd[op3]) && !I(opc)) { fnprintf(fn,"%s%*s[%%%s+%%%s], %%%s",os,12-(int)strlen(os),"",regs[SREG1(opc)],regs[SREG2(opc)],regs[DREG(opc)]); } else if ((os = rd_addr[op3])) { if (DREG(opc) == 0) { fnprintf(fn,"clr%s%*s[",os+2,9-(int)strlen(os+2),""); } else { fnprintf(fn,"%s%*s%%%s, [",os,12-(int)strlen(os),"",regs[DREG(opc)]); } print_address(fn,addr,opc); fnprintf(fn,"]"); } else if ((os = rd_addr_asi[op3]) && !I(opc)) { fnprintf(fn,"%s%*s%%%s, [%%%s+%%%s]",os,12-(int)strlen(os),"",regs[DREG(opc)],regs[SREG1(opc)],regs[SREG2(opc)]); } else if ((os = ld[op3])) { fnprintf(fn,"%s%*s[",os+2,12-(int)strlen(os+2),""); print_address(fn,addr,opc); switch (os[1]) { case 'r': fnprintf(fn,"], %%%c%lu",os[0],DREG(opc)); break; case 's': fnprintf(fn,"], %%%csr",os[0]); break; } } else if ((os = st[op3])) { fnprintf(fn,"%s%*s",os+2,12-(int)strlen(os+2),""); switch (os[1]) { case 'r': fnprintf(fn,"%%%c%lu",os[0],DREG(opc)); break; case 's': fnprintf(fn,"%%%csr",os[0]); break; case 'q': fnprintf(fn,"%%%cq",os[0]); break; } fnprintf(fn,", ["); print_address(fn,addr,opc); fnprintf(fn,"]"); } else { fnprintf(fn,"",OP3(opc),DREG(opc),SREG1(opc),I(opc),ASI(opc),OPF(opc),SIMM13(opc),SREG2(opc)); } } break; } if (sethi_suf) { fnprintf(fn," ! "); print_symbol_or_hex(fn,sethi_sufval); } if (addr & 3) { fnprintf(fn," {unaligned}"); return(1); } if (flg & CFF_INST_PARALLEL) { fnprintf(fn," {parallel}"); return(1); } flags[addr+1] = CF_PREV; flags[addr+2] = CF_PREV; flags[addr+3] = CF_PREV; return(4); } static int do_dis_reloc(ADDR addr, void (*fn)(char)) { unsigned long int r_address; unsigned long int r_sym_ext_type; unsigned long int r_addend; int i; if (addr+12 > coresize) return(-1); r_address = corefetchu(addr,4); r_sym_ext_type = corefetchu(addr+4,4); r_addend = corefetchu(addr+8,4); fnprintf(fn,"reloc: @"); print_symbol_or_hex(fn,r_address); fnprintf(fn," #%lu %s ",r_sym_ext_type>>8,(r_sym_ext_type&0x80)?"ext":"lcl"); switch (r_sym_ext_type & 0x1f) { case 0: fnprintf(fn,"8"); break; case 1: fnprintf(fn,"16"); break; case 2: fnprintf(fn,"32"); break; case 3: fnprintf(fn,"DISP8"); break; case 4: fnprintf(fn,"DISP16"); break; case 5: fnprintf(fn,"DISP32"); break; case 6: fnprintf(fn,"WDISP30"); break; case 7: fnprintf(fn,"WDISP22"); break; case 8: fnprintf(fn,"HI22"); break; case 9: fnprintf(fn,"22"); break; case 10: fnprintf(fn,"13"); break; case 11: fnprintf(fn,"LO10"); break; case 12: fnprintf(fn,"UNUSED1"); break; case 13: fnprintf(fn,"UNUSED2"); break; case 14: fnprintf(fn,"BASE10"); break; case 15: fnprintf(fn,"BASE13"); break; case 16: fnprintf(fn,"BASE22"); break; case 17: fnprintf(fn,"PC10"); break; case 18: fnprintf(fn,"PC22"); break; case 19: fnprintf(fn,"JMP_TBL"); break; case 20: fnprintf(fn,"UNUSED3"); break; case 21: fnprintf(fn,"GLOB_DAT"); break; case 22: fnprintf(fn,"JMP_SLOT"); break; case 23: fnprintf(fn,"RELATIVE"); break; default: fnprintf(fn,"(?%d)",(int)(r_sym_ext_type&0x1f)); break; } if (r_addend & 0x80000000) { r_addend = - r_addend; fnprintf(fn," -%lu (-%#lx)",r_addend,r_addend); } else { fnprintf(fn," +%lu (+%#lx)",r_addend,r_addend); } for (i=1;i<12;i++) flags[addr+i] = CF_PREV; return(12); } static int do_dis_stab(ADDR addr, void (*fn)(char)) { unsigned long int n_strx; unsigned long int n_type_pad_desc; unsigned char n_type; unsigned long int n_value; int i; if (addr+12 > coresize) return(-1); n_strx = corefetchu(addr,4); n_type_pad_desc = corefetchu(addr+4,4); n_value = corefetchu(addr+8,4); fnprintf(fn,"sym: "); n_type = n_type_pad_desc >> 24; if (n_type & ~0x1f) { fnprintf(fn,"(type %02x, desc %04lx) ",n_type,n_type_pad_desc&0xffff); } else { fnprintf(fn,"%.2s ","u U a A t T d D b B i I z Z c C aeAEteTEdeDEbeBEsvSVfnwm"+(n_type<<1)); if (n_type_pad_desc & 0xffffff) fnprintf(fn,"[%06lx] ",n_type_pad_desc&0xffffff); } fnprintf(fn,"%08lx %08lx",n_value,n_strx); for (i=1;i<12;i++) flags[addr+i] = CF_PREV; return(12); } static void r_command(void) { if (changecur_()) return; flags[loc.u.on.aoff] = CF_RELOC; } static void y_command(void) { if (changecur_()) return; flags[loc.u.on.aoff] = CF_STAB; } static void sparc_init(void) { } static int sparc_cmd(char ch) { switch (ch) { case 'r': r_command(); return(1); break; case 'y': y_command(); return(1); break; } return(0); } static int sparc_dis(ADDR addr, void (*fn)(char)) { int rv; switch (flags[addr-corebase]) { default: if (ISINST(flags[addr-corebase])) { rv = do_dis_inst(addr,fn,flags[addr-corebase]); } else { fnprintf(fn,"",(unsigned long int)flags[addr-corebase]); rv = 1; } break; case CF_RELOC: rv = do_dis_reloc(addr,fn); break; case CF_STAB: rv = do_dis_stab(addr,fn); break; } return(rv); } static unsigned long int sparc_fetch(const void *base, int size) #define bp(n) ((unsigned long int)(((const unsigned char *)base)[(n)])) { switch (size) { case 1: return(bp(0)); break; case 2: return((bp(0)<<8)|bp(1)); break; case 4: return((bp(0)<<24)|(bp(1)<<16)|(bp(2)<<8)|bp(3)); break; } abort(); } #undef bp static const char *sparc_names[] = { "SPARC", "Sparc", "sparc", 0 }; MACHINE machine_sparc = { &sparc_names[0], 4, &sparc_init, &sparc_cmd, &sparc_dis, &sparc_fetch, 0 };