void show_lisp_register(ExceptionInformation *xp, char *label, int r) { extern char* print_lisp_object(LispObj); LispObj val = xpGPR(xp, r); #ifdef PPC fprintf(dbgout, "r%02d (%s) = %s\n", r, label, print_lisp_object(val)); #endif #ifdef X8664 fprintf(dbgout, "%%%s (%s) = %s\n",Iregnames[r], label, print_lisp_object(val)); #endif #ifdef X8632 { TCR *tcr = get_tcr(false); char *s; if (r == REG_EDX && (xpGPR(xp, REG_EFL) & EFL_DF)) s = "marked as unboxed (DF set)"; else if (tcr && (tcr->node_regs_mask & bit_for_regnum(r)) == 0) s = "marked as unboxed (node_regs_mask)"; else s = print_lisp_object(val); fprintf(dbgout, "%%%s (%s) = %s\n", Iregnames[r], label, s); } #endif #ifdef ARM fprintf(dbgout, "r%02d (%s) = %s\n", r, label, print_lisp_object(val)); #endif }
void describe_arm_uuo(ExceptionInformation *xp) { pc program_counter = xpPC(xp); opcode instruction = *program_counter; if (IS_UUO(instruction)) { unsigned format = UUO_FORMAT(instruction); switch(format) { case uuo_format_nullary: case uuo_format_nullary_error: switch UUOA_field(instruction) { case 0: fprintf(dbgout,"alloc_trap\n"); break; case 1: fprintf(dbgout,"wrong number of args (%d) to %s\n",xpGPR(xp,nargs)>>node_shift, print_lisp_object(xpGPR(xp,nfn))); break; case 2: fprintf(dbgout,"gc trap\n"); break; case 3: fprintf(dbgout,"debug trap\n"); break; case 4: fprintf(dbgout,"deferred interrupt\n"); break; case 5: fprintf(dbgout,"deferred suspend\n"); break; default: break; } break; case uuo_format_unary_error: switch (UUO_UNARY_field(instruction)) { case 0: case 1: fprintf(dbgout,"%s is unbound\n", print_lisp_object(xpGPR(xp,UUOA_field(instruction)))); break; default: break; } default: break; } } }
void describe_ppc_illegal(ExceptionInformation *xp) { pc where = xpPC(xp); opcode the_uuo = *where; Boolean described = false; if (IS_UUO(the_uuo)) { unsigned minor = UUO_MINOR(the_uuo), errnum = 0x3ff & (the_uuo >> 16); switch(minor) { case UUO_INTERR: switch (errnum) { case error_udf_call: fprintf(dbgout, "ERROR: undefined function call: %s\n", print_lisp_object(xpGPR(xp,fname))); described = true; break; default: fprintf(dbgout, "ERROR: lisp error %d\n", errnum); described = true; break; } break; default: break; } } if (!described) { fprintf(dbgout, "Illegal instruction (0x%08x) at 0x%lx\n", the_uuo, where); } }
debug_command_return debug_lisp_registers(ExceptionInformation *xp, siginfo_t *info, int arg) { if (lisp_debugger_in_foreign_code == false) { #ifdef PPC TCR *xpcontext = (TCR *)ptr_from_lispobj(xpGPR(xp, rcontext)); fprintf(dbgout, "rcontext = 0x%lX ", xpcontext); if (!active_tcr_p(xpcontext)) { fprintf(dbgout, "(INVALID)\n"); } else { fprintf(dbgout, "\nnargs = %d\n", xpGPR(xp, nargs) >> fixnumshift); show_lisp_register(xp, "fn", fn); show_lisp_register(xp, "arg_z", arg_z); show_lisp_register(xp, "arg_y", arg_y); show_lisp_register(xp, "arg_x", arg_x); show_lisp_register(xp, "temp0", temp0); show_lisp_register(xp, "temp1/next_method_context", temp1); show_lisp_register(xp, "temp2/nfn", temp2); show_lisp_register(xp, "temp3/fname", temp3); /* show_lisp_register(xp, "new_fn", new_fn); */ show_lisp_register(xp, "save0", save0); show_lisp_register(xp, "save1", save1); show_lisp_register(xp, "save2", save2); show_lisp_register(xp, "save3", save3); show_lisp_register(xp, "save4", save4); show_lisp_register(xp, "save5", save5); show_lisp_register(xp, "save6", save6); show_lisp_register(xp, "save7", save7); } #endif #ifdef X8664 show_lisp_register(xp, "arg_z", Iarg_z); show_lisp_register(xp, "arg_y", Iarg_y); show_lisp_register(xp, "arg_x", Iarg_x); fprintf(dbgout,"------\n"); show_lisp_register(xp, "fn", Ifn); fprintf(dbgout,"------\n"); show_lisp_register(xp, "save0", Isave0); show_lisp_register(xp, "save1", Isave1); show_lisp_register(xp, "save2", Isave2); show_lisp_register(xp, "save3", Isave3); fprintf(dbgout,"------\n"); show_lisp_register(xp, "temp0", Itemp0); show_lisp_register(xp, "temp1", Itemp1); show_lisp_register(xp, "temp2", Itemp2); fprintf(dbgout,"------\n"); if (tag_of(xpGPR(xp,Inargs)) == tag_fixnum) { fprintf(dbgout,"%%rcx (nargs) = %ld (maybe)\n", unbox_fixnum(xpGPR(xp,Inargs)&0xffff)); } #endif #ifdef X8632 show_lisp_register(xp, "arg_z", Iarg_z); show_lisp_register(xp, "arg_y", Iarg_y); fprintf(dbgout,"------\n"); show_lisp_register(xp, "fn", Ifn); fprintf(dbgout,"------\n"); show_lisp_register(xp, "temp0", Itemp0); show_lisp_register(xp, "temp1", Itemp1); fprintf(dbgout,"------\n"); if (tag_of(xpGPR(xp,Inargs)) == tag_fixnum) { fprintf(dbgout,"%%edx (nargs) = %d (maybe)\n", unbox_fixnum(xpGPR(xp,Inargs))); } #endif #ifdef ARM TCR *xpcontext = (TCR *)ptr_from_lispobj(xpGPR(xp, rcontext)); fprintf(dbgout, "rcontext = 0x%lX ", xpcontext); if (!active_tcr_p(xpcontext)) { fprintf(dbgout, "(INVALID)\n"); } else { fprintf(dbgout, "\nnargs = %d\n", xpGPR(xp, nargs) >> fixnumshift); show_lisp_register(xp, "fn", Rfn); show_lisp_register(xp, "arg_z", arg_z); show_lisp_register(xp, "arg_y", arg_y); show_lisp_register(xp, "arg_x", arg_x); show_lisp_register(xp, "temp0", temp0); show_lisp_register(xp, "temp1/fname/next_method_context", temp1); show_lisp_register(xp, "temp2/nfn", temp2); } #endif }
void describe_ppc_trap(ExceptionInformation *xp) { pc where = xpPC(xp); opcode the_trap = *where, instr; int err_arg2, ra, rs; Boolean identified = false; if ((the_trap & OP_MASK) == OP(major_opcode_TRI)) { /* TWI/TDI. If the RA field is "nargs", that means that the instruction is either a number-of-args check or an event-poll. Otherwise, the trap is some sort of typecheck. */ if (RA_field(the_trap) == nargs) { switch (TO_field(the_trap)) { case TO_NE: if (xpGPR(xp, nargs) < D_field(the_trap)) { fprintf(dbgout, "Too few arguments (no opt/rest)\n"); } else { fprintf(dbgout, "Too many arguments (no opt/rest)\n"); } identified = true; break; case TO_GT: fprintf(dbgout, "Event poll !\n"); identified = true; break; case TO_HI: fprintf(dbgout, "Too many arguments (with opt)\n"); identified = true; break; case TO_LT: fprintf(dbgout, "Too few arguments (with opt/rest/key)\n"); identified = true; break; default: /* some weird trap, not ours. */ identified = false; break; } } else { /* A type or boundp trap of some sort. */ switch (TO_field(the_trap)) { case TO_EQ: /* Boundp traps are of the form: treqi rX,unbound where some preceding instruction is of the form: lwz/ld rX,symbol.value(rY). The error message should try to say that rY is unbound. */ if (D_field(the_trap) == unbound) { #ifdef PPC64 instr = scan_for_instr(LD_instruction(RA_field(the_trap), unmasked_register, offsetof(lispsymbol,vcell)-fulltag_misc), D_RT_IMM_MASK, where); #else instr = scan_for_instr(LWZ_instruction(RA_field(the_trap), unmasked_register, offsetof(lispsymbol,vcell)-fulltag_misc), D_RT_IMM_MASK, where); #endif if (instr) { ra = RA_field(instr); if (lisp_reg_p(ra)) { fprintf(dbgout, "Unbound variable: %s\n", print_lisp_object(xpGPR(xp,ra))); identified = true; } } } break; case TO_NE: /* A type check. If the type (the immediate field of the trap instruction) is a header type, an "lbz rX,misc_header_offset(rY)" should precede it, in which case we say that "rY is not of header type <type>." If the type is not a header type, then rX should have been set by a preceding "clrlwi rX,rY,29/30". In that case, scan backwards for an RLWINM instruction that set rX and report that rY isn't of the indicated type. */ err_arg2 = D_field(the_trap); if (nodeheader_tag_p(err_arg2) || immheader_tag_p(err_arg2)) { instr = scan_for_instr(LBZ_instruction(RA_field(the_trap), unmasked_register, misc_subtag_offset), D_RT_IMM_MASK, where); if (instr) { ra = RA_field(instr); if (lisp_reg_p(ra)) { fprintf(dbgout, "value 0x%lX is not of the expected header type 0x%02X\n", xpGPR(xp, ra), err_arg2); identified = true; } } } else { /* Not a header type, look for rlwinm whose RA field matches the_trap's */ instr = scan_for_instr((OP(major_opcode_RLWINM) | (the_trap & RA_MASK)), (OP_MASK | RA_MASK), where); if (instr) { rs = RS_field(instr); if (lisp_reg_p(rs)) { fprintf(dbgout, "value 0x%lX is not of the expected type 0x%02X\n", xpGPR(xp, rs), err_arg2); identified = true; } } } break; } } } else { /* a "TW <to>,ra,rb" instruction." twltu sp,rN is stack-overflow on SP. twgeu rX,rY is subscript out-of-bounds, which was preceded by an "lwz rM,misc_header_offset(rN)" instruction. rM may or may not be the same as rY, but no other header would have been loaded before the trap. */ switch (TO_field(the_trap)) { case TO_LO: if (RA_field(the_trap) == sp) { fprintf(dbgout, "Stack overflow! Run away! Run away!\n"); identified = true; } break; case (TO_HI|TO_EQ): instr = scan_for_instr(OP(major_opcode_LWZ) | (D_MASK & misc_header_offset), (OP_MASK | D_MASK), where); if (instr) { ra = RA_field(instr); if (lisp_reg_p(ra)) { fprintf(dbgout, "Bad index %d for vector %lX length %d\n", unbox_fixnum(xpGPR(xp, RA_field(the_trap))), xpGPR(xp, ra), unbox_fixnum(xpGPR(xp, RB_field(the_trap)))); identified = true; } } break; } } if (!identified) { fprintf(dbgout, "Unknown trap: 0x%08x\n", the_trap); } }
void plbt(ExceptionInformation *xp) { plbt_sp(xpGPR(xp, sp)); }