LispObj find_symbol_in_range(LispObj *start, LispObj *end, char *name) { LispObj header, tag; int n = strlen(name); char *s = name; lisp_char_code *p; while (start < end) { header = *start; tag = fulltag_of(header); if (header_subtag(header) == subtag_symbol) { LispObj pname = deref(ptr_to_lispobj(start), 1), pname_header = header_of(pname); if ((header_subtag(pname_header) == subtag_simple_base_string) && (header_element_count(pname_header) == n)) { p = (lisp_char_code *) ptr_from_lispobj(pname + misc_data_offset); if (compare_lisp_string_to_c_string(p, s, n) == 0) { return (ptr_to_lispobj(start))+fulltag_misc; } } } if (nodeheader_tag_p(tag)) { start += (~1 & (2 + header_element_count(header))); } else if (immheader_tag_p(tag)) { start = (LispObj *) skip_over_ivector((natural)start, header); } else { start += 2; } } return (LispObj)NULL; }
void sprint_vector(LispObj o, int depth) { LispObj header = header_of(o); if (immheader_tag_p(fulltag_of(header))) { sprint_ivector(o); } else { sprint_gvector(o, depth); } }
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); } }