X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FDisassembler.c;h=41b66f146ca39a7c6b77278631fd2d58c870f2b9;hb=423d477bfecd490de1449c59325c8776f91d7aac;hp=63de39d3f4d51e5c54d3fc6663502c5999181588;hpb=8931116063aaf06ed2759e2b2ca2e554cfa7124f;p=ghc-hetmet.git diff --git a/ghc/rts/Disassembler.c b/ghc/rts/Disassembler.c index 63de39d..41b66f1 100644 --- a/ghc/rts/Disassembler.c +++ b/ghc/rts/Disassembler.c @@ -1,351 +1,283 @@ - /* ----------------------------------------------------------------------------- * Bytecode disassembler * - * Copyright (c) 1994-1998. + * Copyright (c) 1994-2002. * * $RCSfile: Disassembler.c,v $ - * $Revision: 1.4 $ - * $Date: 1999/03/01 14:47:05 $ + * $Revision: 1.28 $ + * $Date: 2004/08/13 13:09:46 $ * ---------------------------------------------------------------------------*/ -#include "Rts.h" - -#ifdef INTERPRETER +#ifdef DEBUG +#include "PosixSource.h" +#include "Rts.h" +#include "RtsAPI.h" #include "RtsUtils.h" +#include "Closures.h" +#include "TSO.h" +#include "Schedule.h" + #include "Bytecodes.h" -#include "Assembler.h" #include "Printer.h" #include "Disassembler.h" +#include "Interpreter.h" + +#include /* -------------------------------------------------------------------------- * Disassembler * ------------------------------------------------------------------------*/ -static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i ); -static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i ); - -static InstrPtr disNone ( StgBCO *bco, InstrPtr pc, char* i ) +int +disInstr ( StgBCO *bco, int pc ) { - fprintf(stderr,"%s",i); - return pc; -} + int i; -static InstrPtr disInt ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInt x = bcoInstr(bco,pc++); - ASSERT(pc < bco->n_instrs); - fprintf(stderr,"%s %d",i,x); - return pc; -} + StgWord16* instrs = (StgWord16*)(bco->instrs->payload); -static InstrPtr disIntInt ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInt x = bcoInstr(bco,pc++); - StgInt y = bcoInstr(bco,pc++); - fprintf(stderr,"%s %d %d",i,x,y); - return pc; -} + StgArrWords* literal_arr = bco->literals; + StgWord* literals = (StgWord*)(&literal_arr->payload[0]); -static InstrPtr disIntPC ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInt x = bcoInstr(bco,pc++); - StgWord y = bcoInstr(bco,pc++); - fprintf(stderr,"%s %d %d",i,x,pc+y); - return pc; -} + StgMutArrPtrs* ptrs_arr = bco->ptrs; + StgPtr* ptrs = (StgPtr*)(&ptrs_arr->payload[0]); -static InstrPtr disPC ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgWord y = bcoInstr(bco,pc++); - fprintf(stderr,"%s %d",i,pc+y); - return pc; -} - -static InstrPtr disInfo ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInfoTable* info = bcoConstInfoPtr(bco,bcoInstr(bco,pc++)); - /* ToDo: print contents of infotable */ - fprintf(stderr,"%s ",i); - printPtr(stgCast(StgPtr,info)); - return pc; -} + StgArrWords* itbls_arr = bco->itbls; + StgInfoTable** itbls = (StgInfoTable**)(&itbls_arr->payload[0]); -static InstrPtr disConstPtr ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInt o = bcoInstr(bco,pc++); - StgPtr x = bcoConstPtr(bco,o); - fprintf(stderr,"%s [%d]=",i,o); - printPtr(x); /* bad way to print it... */ - return pc; -} + switch (instrs[pc++]) { + case bci_SWIZZLE: + fprintf(stderr, "SWIZZLE stkoff %d by %d\n", + instrs[pc], (signed int)instrs[pc+1]); + pc += 2; break; + case bci_CCALL: + fprintf(stderr, "CCALL marshaller at 0x%x\n", + literals[instrs[pc]] ); + pc += 1; break; + case bci_STKCHECK: + fprintf(stderr, "STKCHECK %d\n", instrs[pc] ); + pc += 1; break; + case bci_PUSH_L: + fprintf(stderr, "PUSH_L %d\n", instrs[pc] ); + pc += 1; break; + case bci_PUSH_LL: + fprintf(stderr, "PUSH_LL %d %d\n", instrs[pc], instrs[pc+1] ); + pc += 2; break; + case bci_PUSH_LLL: + fprintf(stderr, "PUSH_LLL %d %d %d\n", instrs[pc], instrs[pc+1], + instrs[pc+2] ); + pc += 3; break; + case bci_PUSH_G: + fprintf(stderr, "PUSH_G " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n" ); + pc += 1; break; -static InstrPtr disConst2Ptr ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgWord o1 = bcoInstr(bco,pc++); - StgWord o2 = bcoInstr(bco,pc++); - StgWord o = o1*256 + o2; - StgPtr x = bcoConstPtr(bco,o); - fprintf(stderr,"%s [%d]=",i,o); - printPtr(x); /* bad way to print it... */ - return pc; -} + case bci_PUSH_ALTS: + fprintf(stderr, "PUSH_ALTS " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_P: + fprintf(stderr, "PUSH_ALTS_P " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_N: + fprintf(stderr, "PUSH_ALTS_N " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_F: + fprintf(stderr, "PUSH_ALTS_F " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_D: + fprintf(stderr, "PUSH_ALTS_D " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_L: + fprintf(stderr, "PUSH_ALTS_L " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; + case bci_PUSH_ALTS_V: + fprintf(stderr, "PUSH_ALTS_V " ); printPtr( ptrs[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 1; break; -static InstrPtr disConstInt ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgInt x = bcoConstInt(bco,bcoInstr(bco,pc++)); - fprintf(stderr,"%s %d",i,x); - return pc; -} + case bci_PUSH_UBX: + fprintf(stderr, "PUSH_UBX "); + for (i = 0; i < instrs[pc+1]; i++) + fprintf(stderr, "0x%x ", literals[i + instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 2; break; + case bci_PUSH_APPLY_N: + fprintf(stderr, "PUSH_APPLY_N\n"); + break; + case bci_PUSH_APPLY_V: + fprintf(stderr, "PUSH_APPLY_V\n"); + break; + case bci_PUSH_APPLY_F: + fprintf(stderr, "PUSH_APPLY_F\n"); + break; + case bci_PUSH_APPLY_D: + fprintf(stderr, "PUSH_APPLY_D\n"); + break; + case bci_PUSH_APPLY_L: + fprintf(stderr, "PUSH_APPLY_L\n"); + break; + case bci_PUSH_APPLY_P: + fprintf(stderr, "PUSH_APPLY_P\n"); + break; + case bci_PUSH_APPLY_PP: + fprintf(stderr, "PUSH_APPLY_PP\n"); + break; + case bci_PUSH_APPLY_PPP: + fprintf(stderr, "PUSH_APPLY_PPP\n"); + break; + case bci_PUSH_APPLY_PPPP: + fprintf(stderr, "PUSH_APPLY_PPPP\n"); + break; + case bci_PUSH_APPLY_PPPPP: + fprintf(stderr, "PUSH_APPLY_PPPPP\n"); + break; + case bci_PUSH_APPLY_PPPPPP: + fprintf(stderr, "PUSH_APPLY_PPPPPP\n"); + break; + case bci_SLIDE: + fprintf(stderr, "SLIDE %d down by %d\n", instrs[pc], instrs[pc+1] ); + pc += 2; break; + case bci_ALLOC_AP: + fprintf(stderr, "ALLOC_AP %d words\n", instrs[pc] ); + pc += 1; break; + case bci_ALLOC_PAP: + fprintf(stderr, "ALLOC_PAP %d words, %d arity\n", + instrs[pc], instrs[pc+1] ); + pc += 2; break; + case bci_MKAP: + fprintf(stderr, "MKAP %d words, %d stkoff\n", instrs[pc+1], + instrs[pc] ); + pc += 2; break; + case bci_UNPACK: + fprintf(stderr, "UNPACK %d\n", instrs[pc] ); + pc += 1; break; + case bci_PACK: + fprintf(stderr, "PACK %d words with itbl ", instrs[pc+1] ); + printPtr( (StgPtr)itbls[instrs[pc]] ); + fprintf(stderr, "\n"); + pc += 2; break; -static InstrPtr disConstAddr ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgAddr x = bcoConstAddr(bco,bcoInstr(bco,pc++)); - fprintf(stderr,"%s ",i); - printPtr(x); - return pc; -} + case bci_TESTLT_I: + fprintf(stderr, "TESTLT_I %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; + case bci_TESTEQ_I: + fprintf(stderr, "TESTEQ_I %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; -static InstrPtr disConstChar ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgChar x = bcoConstChar(bco,bcoInstr(bco,pc++)); - if (isprint((int)x)) - fprintf(stderr,"%s '%c'",i,x); else - fprintf(stderr,"%s 0x%x",i,(int)x); - return pc; -} + case bci_TESTLT_F: + fprintf(stderr, "TESTLT_F %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; + case bci_TESTEQ_F: + fprintf(stderr, "TESTEQ_F %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; -static InstrPtr disConstFloat ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgFloat x = bcoConstFloat(bco,bcoInstr(bco,pc++)); - fprintf(stderr,"%s %f",i,x); - return pc; -} + case bci_TESTLT_D: + fprintf(stderr, "TESTLT_D %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; + case bci_TESTEQ_D: + fprintf(stderr, "TESTEQ_D %d, fail to %d\n", literals[instrs[pc]], + instrs[pc+1]); + pc += 2; break; -static InstrPtr disConstDouble ( StgBCO *bco, InstrPtr pc, char* i ) -{ - StgDouble x = bcoConstDouble(bco,bcoInstr(bco,pc++)); - fprintf(stderr,"%s %f",i,x); - return pc; -} + case bci_TESTLT_P: + fprintf(stderr, "TESTLT_P %d, fail to %d\n", instrs[pc], + instrs[pc+1]); + pc += 2; break; + case bci_TESTEQ_P: + fprintf(stderr, "TESTEQ_P %d, fail to %d\n", instrs[pc], + instrs[pc+1]); + pc += 2; break; + case bci_CASEFAIL: + fprintf(stderr, "CASEFAIL\n" ); + break; + case bci_JMP: + fprintf(stderr, "JMP to %d\n", instrs[pc]); + pc += 1; break; -InstrPtr disInstr( StgBCO *bco, InstrPtr pc ) -{ - Instr in; - ASSERT(pc < bco->n_instrs); - in = bcoInstr(bco,pc++); - switch (in) { - case i_INTERNAL_ERROR: - return disNone(bco,pc,"INTERNAL_ERROR"); - case i_PANIC: - return disNone(bco,pc,"PANIC"); - case i_HP_CHECK: - return disInt(bco,pc,"HP_CHECK"); - case i_STK_CHECK: - return disInt(bco,pc,"STK_CHECK"); - case i_ARG_CHECK: - return disInt(bco,pc,"ARG_CHECK"); - case i_ALLOC_AP: - return disInt(bco,pc,"ALLOC_AP"); - case i_ALLOC_PAP: - return disInt(bco,pc,"ALLOC_PAP"); - case i_ALLOC_CONSTR: - return disInfo(bco,pc,"ALLOC_CONSTR"); - case i_MKAP: - return disIntInt(bco,pc,"MKAP"); - case i_MKPAP: - return disIntInt(bco,pc,"MKPAP"); - case i_PACK: - return disInt(bco,pc,"PACK"); - case i_SLIDE: - return disIntInt(bco,pc,"SLIDE"); - case i_ENTER: - return disNone(bco,pc,"ENTER"); - case i_RETADDR: - return disConstPtr(bco,pc,"RETADDR"); - case i_TEST: - return disIntPC(bco,pc,"TEST"); - case i_UNPACK: - return disNone(bco,pc,"UNPACK"); - case i_VAR: - return disInt(bco,pc,"VAR"); - case i_CONST: - return disConstPtr(bco,pc,"CONST"); - case i_CONST2: - return disConst2Ptr(bco,pc,"CONST2"); + case bci_ENTER: + fprintf(stderr, "ENTER\n"); + break; - case i_VOID: - return disNone(bco,pc,"VOID"); - case i_RETURN_GENERIC: - return disNone(bco,pc,"RETURN_GENERIC"); + case bci_RETURN: + fprintf(stderr, "RETURN\n" ); + break; + case bci_RETURN_P: + fprintf(stderr, "RETURN_P\n" ); + break; + case bci_RETURN_N: + fprintf(stderr, "RETURN_N\n" ); + break; + case bci_RETURN_F: + fprintf(stderr, "RETURN_F\n" ); + break; + case bci_RETURN_D: + fprintf(stderr, "RETURN_D\n" ); + break; + case bci_RETURN_L: + fprintf(stderr, "RETURN_L\n" ); + break; + case bci_RETURN_V: + fprintf(stderr, "RETURN_V\n" ); + break; - case i_VAR_INT: - return disInt(bco,pc,"VAR_INT"); - case i_CONST_INT: - return disConstInt(bco,pc,"CONST_INT"); - case i_RETURN_INT: - return disNone(bco,pc,"RETURN_INT"); - case i_PACK_INT: - return disNone(bco,pc,"PACK_INT"); - case i_UNPACK_INT: - return disNone(bco,pc,"UNPACK_INT"); - case i_TEST_INT: - return disPC(bco,pc,"TEST_INT"); + default: + barf("disInstr: unknown opcode"); + } + return pc; +} -#ifdef PROVIDE_INT64 - case i_VAR_INT64: - return disInt(bco,pc,"VAR_INT64"); - case i_CONST_INT64: - return disConstInt(bco,pc,"CONST_INT64"); - case i_RETURN_INT64: - return disNone(bco,pc,"RETURN_INT64"); - case i_PACK_INT64: - return disNone(bco,pc,"PACK_INT64"); - case i_UNPACK_INT64: - return disNone(bco,pc,"UNPACK_INT64"); -#endif -#ifdef PROVIDE_INTEGER - case i_CONST_INTEGER: - return disConstAddr(bco,pc,"CONST_INTEGER"); -#endif -#ifdef PROVIDE_WORD - case i_VAR_WORD: - return disInt(bco,pc,"VAR_WORD"); - case i_CONST_WORD: - return disConstInt(bco,pc,"CONST_WORD"); - case i_RETURN_WORD: - return disNone(bco,pc,"RETURN_WORD"); - case i_PACK_WORD: - return disNone(bco,pc,"PACK_WORD"); - case i_UNPACK_WORD: - return disNone(bco,pc,"UNPACK_WORD"); -#endif -#ifdef PROVIDE_ADDR - case i_VAR_ADDR: - return disInt(bco,pc,"VAR_ADDR"); - case i_CONST_ADDR: - return disConstAddr(bco,pc,"CONST_ADDR"); - case i_RETURN_ADDR: - return disNone(bco,pc,"RETURN_ADDR"); - case i_PACK_ADDR: - return disNone(bco,pc,"PACK_ADDR"); - case i_UNPACK_ADDR: - return disNone(bco,pc,"UNPACK_ADDR"); -#endif - case i_VAR_CHAR: - return disInt(bco,pc,"VAR_CHAR"); - case i_CONST_CHAR: - return disConstChar(bco,pc,"CONST_CHAR"); - case i_RETURN_CHAR: - return disNone(bco,pc,"RETURN_CHAR"); - case i_PACK_CHAR: - return disNone(bco,pc,"PACK_CHAR"); - case i_UNPACK_CHAR: - return disNone(bco,pc,"UNPACK_CHAR"); - case i_VAR_FLOAT: - return disInt(bco,pc,"VAR_FLOAT"); - case i_CONST_FLOAT: - return disConstFloat(bco,pc,"CONST_FLOAT"); - case i_RETURN_FLOAT: - return disNone(bco,pc,"RETURN_FLOAT"); - case i_PACK_FLOAT: - return disNone(bco,pc,"PACK_FLOAT"); - case i_UNPACK_FLOAT: - return disNone(bco,pc,"UNPACK_FLOAT"); +/* Something of a kludge .. how do we know where the end of the insn + array is, since it isn't recorded anywhere? Answer: the first + short is the number of bytecodes which follow it. + See ByteCodeGen.linkBCO.insns_arr for construction ... +*/ +void disassemble( StgBCO *bco ) +{ + nat i, j; + StgWord16* instrs = (StgWord16*)(bco->instrs->payload); + StgMutArrPtrs* ptrs = bco->ptrs; + nat nbcs = (int)instrs[0]; + nat pc = 1; - case i_VAR_DOUBLE: - return disInt(bco,pc,"VAR_DOUBLE"); - case i_CONST_DOUBLE: - return disConstDouble(bco,pc,"CONST_DOUBLE"); - case i_RETURN_DOUBLE: - return disNone(bco,pc,"RETURN_DOUBLE"); - case i_PACK_DOUBLE: - return disNone(bco,pc,"PACK_DOUBLE"); - case i_UNPACK_DOUBLE: - return disNone(bco,pc,"UNPACK_DOUBLE"); + fprintf(stderr, "BCO\n" ); + pc = 1; + while (pc <= nbcs) { + fprintf(stderr, "\t%2d: ", pc ); + pc = disInstr ( bco, pc ); + } -#ifdef PROVIDE_STABLE - case i_VAR_STABLE: - return disInt(bco,pc,"VAR_STABLE"); - case i_RETURN_STABLE: - return disNone(bco,pc,"RETURN_STABLE"); - case i_PACK_STABLE: - return disNone(bco,pc,"PACK_STABLE"); - case i_UNPACK_STABLE: - return disNone(bco,pc,"UNPACK_STABLE"); -#endif + fprintf(stderr, "INSTRS:\n " ); + j = 16; + for (i = 0; i < nbcs; i++) { + fprintf(stderr, "%3d ", (int)instrs[i] ); + j--; + if (j == 0) { j = 16; fprintf(stderr, "\n "); }; + } + fprintf(stderr, "\n"); - case i_PRIMOP1: - { - Primop1 op = bcoInstr(bco,pc++); - switch (op) { - case i_INTERNAL_ERROR1: - return disNone(bco,pc,"INTERNAL_ERROR1"); - case i_pushseqframe: - return disNone(bco,pc,"i_pushseqframe"); - case i_pushcatchframe: - return disNone(bco,pc,"i_pushcatchframe"); - default: - { - const AsmPrim* p = asmFindPrimop(i_PRIMOP1,op); - if (p) { - return disNone(bco,pc,p->name); - } - barf("Unrecognised primop1 %d\n",op); - } - } - } - case i_PRIMOP2: - { - Primop2 op = bcoInstr(bco,pc++); - switch (op) { - case i_INTERNAL_ERROR2: - return disNone(bco,pc,"INTERNAL_ERROR2"); - case i_ccall_Id: - return disNone(bco,pc,"ccall_Id"); - case i_ccall_IO: - return disNone(bco,pc,"ccall_IO"); - case i_raise: - return disNone(bco,pc,"primRaise"); - default: - { - const AsmPrim* p = asmFindPrimop(i_PRIMOP2,op); - if (p) { - return disNone(bco,pc,p->name); - } - barf("Unrecognised primop2 %d\n",op); - } - } - } - default: - barf("Unrecognised instruction %d\n",in); - } -} + fprintf(stderr, "PTRS:\n " ); + j = 8; + for (i = 0; i < ptrs->ptrs; i++) { + fprintf(stderr, "%8p ", ptrs->payload[i] ); + j--; + if (j == 0) { j = 8; fprintf(stderr, "\n "); }; + } + fprintf(stderr, "\n"); -void disassemble( StgBCO *bco, char* prefix ) -{ - int pc = 0; - int pcLim = bco->n_instrs; - ASSERT( get_itbl(bco)->type == BCO); - while (pc < pcLim) { - fprintf(stderr,"%s%d:\t",prefix,pc); - pc = disInstr(bco,pc); - fprintf(stderr,"\n"); - } - if (bco->stgexpr) { - ppStgExpr(bco->stgexpr); - fprintf(stderr, "\n"); - } - else - fprintf(stderr, "\t(handwritten bytecode)\n" ); + fprintf(stderr, "\n"); + ASSERT(pc == nbcs+1); } -#endif /* INTERPRETER */ +#endif /* DEBUG */