#help_index "Debugging/Dump" Bool ClassRep2(CDoc *doc, U8 *_d, U8 *class_name=lastclass, Bool u8_chars, Bool force, I64 depth, I64 max_depth, Bool dynamic, I64 types=HTT_CLASS, I64 offset=0) {//See ::/Demo/LastClass.ZC. I64 i, j, stars, *ptr; CMemberList *ml; CDocEntry *doc_e; Bool unlock; CHashClass *tmpc, *tmpc2; if (depth >= max_depth) return TRUE; if (!(tmpc = HashFind(class_name, Fs->hash_table, types))) { DocPrint(doc, "Class Not Found.\n"); return FALSE; } if (!force && (!CheckPtr(_d) || !CheckPtr(_d(U8 *) + tmpc->size))) { DocPrint(doc, "Bad Pointer:%016X\n", _d); return FALSE; } if (tmpc->base_class && !ClassRep2(doc, _d, tmpc->base_class->str, depth, max_depth, dynamic, types, offset)) return FALSE; unlock = DocLock(doc); DocPrint(doc, "Class:\"%s\"\n", class_name); ml = tmpc->member_list_and_root; while (ml) { tmpc2 = ml->member_class; ptr = _d(U8 *) + ml->offset; DocPrint(doc, "%08X ", ptr(U8 *) + offset); stars = tmpc2->ptr_stars_count; tmpc2 = OptClassFwd(tmpc2); tmpc2 -= tmpc2->ptr_stars_count; if (tmpc2->type & HTT_INTERNAL_TYPE) { DocPrint(doc, "$GREEN$%-20ts:$FG$", ml->str); if (stars == 1 && (tmpc2->raw_type == RT_I8 || tmpc2->raw_type == RT_U8)) { ptr = *ptr; if (CheckPtr(ptr)) { if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n"); doc_e->data = ptr; DocDataFormat(doc, doc_e); } else DocPrint(doc, "%40ts\n", ptr); } } else if (!stars) { j = MinI64(ml->dim.total_count, 32); if ((tmpc2->raw_type == RT_I8 || tmpc2->raw_type == RT_U8) && u8_chars) { if (j == 1) { if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=U8,A=\"%%c\"$\n"); doc_e->data = ptr; } else DocPrint(doc, "%c\n", *ptr(U8 *)); } else { if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$\n"); doc_e->data = ptr; DocDataFormat(doc, doc_e); } else DocPrint(doc, "%40ts\n", ptr); } } for (i = 0; i < j; i++) { switch (tmpc2->raw_type) { case RT_I0: case RT_U0: break; case RT_I8: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=I8,A=\"%%02X\"$ "); doc_e->data = ptr(I8 *)++; } else DocPrint(doc, "%02X ", *ptr(I8 *)++); break; case RT_U8: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=U8,A=\"%%02X\"$ "); doc_e->data = ptr(U8 *)++; } else DocPrint(doc, "%02X ", *ptr(U8 *)++); break; case RT_I16: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=I16,A=\"%%04X\"$ "); doc_e->data = ptr(I16 *)++; } else DocPrint(doc, "%04X ", *ptr(I16 *)++); break; case RT_U16: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=U16,A=\"%%04X\"$ "); doc_e->data = ptr(U16 *)++; } else DocPrint(doc, "%04X ", *ptr(U16 *)++); break; case RT_I32: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=I32,A=\"%%08X\"$ "); doc_e->data = ptr(I32 *)++; } else DocPrint(doc, "%08X ", *ptr(I32 *)++); break; case RT_U32: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=U32,A=\"%%08X\"$ "); doc_e->data = ptr(U32 *)++; } else DocPrint(doc, "%08X ", *ptr(U32 *)++); break; case RT_U64: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=U64,A=\"%%08X\"$ "); doc_e->data = ptr(U64 *)++; } else DocPrint(doc, "%08X ", *ptr(U64 *)++); break; case RT_F64: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,RT=F64,A=\"%%16g\"$ "); doc_e->data = ptr(F64 *)++; } else DocPrint(doc, "%16g ", *ptr(I64 *)++); break; default: if (dynamic) { doc_e = DocPrint(doc, "$DA-TRM+RD+UD,A=\"%%016X\"$ "); doc_e->data = ptr(I64 *)++; } else DocPrint(doc, "%016X ", *ptr(I64 *)++); } if (dynamic) DocDataFormat(doc, doc_e); } if (j < ml->dim.total_count) DocPrint(doc, "..."); } else DocPrint(doc, "%016X", *ptr); DocPrint(doc,"\n"); } else { if (depth < 2) { if (stars == 1 && !CheckPtr(*ptr)) DocPrint(doc, "%-20ts:%016X\n", ml->str, *ptr); else { DocPrint(doc, "$TR,\"%s\"$\n", ml->str); DocPrint(doc, "$ID,2$"); if (!stars) ClassRep2(doc, ptr, tmpc2->str, u8_chars, force, depth + 1, max_depth, dynamic); else if (stars == 1) ClassRep2(doc, *ptr, tmpc2->str, u8_chars, force, depth + 1, max_depth, dynamic); DocPrint(doc, "$ID,-2$"); } } else DocPrint(doc, "%-20ts\n", ml->str); } ml = ml->next; } if (unlock) DocUnlock(doc); return TRUE; } public U0 ClassRep(U8 *_d, U8 *class_name=lastclass, I64 max_depth=2, Bool u8_chars=FALSE, Bool force=FALSE, Bool fun=FALSE, I64 offset=0) {//Displays members of a record by using the compiler's info. CDoc *doc; I64 type; if (IsRaw) doc = DocNew; else { DocMax; doc = DocPut; } if (fun) type = HTT_FUN; else type = HTT_CLASS; ClassRep2(doc, _d, class_name, u8_chars, force, 0, max_depth, FALSE, type, offset); DocPrint(doc, "\n"); DocRecalc(doc); if (IsRaw) { DocDumpLines(doc, 100000); DocDel(doc); } } public U0 ClassRepD(U8 *_d, U8 *class_name=lastclass, I64 max_depth=2, Bool u8_chars=FALSE, Bool force=FALSE, Bool fun=FALSE, I64 offset=0) {//Dynamic ClassRep. Uses hex_ed widget for live changes. CDoc *doc; if (IsRaw) doc = DocNew; else { DocMax; doc = DocPut; } if (fun) ClassRep2(doc, _d, class_name, u8_chars, force, 0, max_depth, TRUE, HTT_FUN, offset); else ClassRep2(doc, _d, class_name, u8_chars, force, 0, max_depth, TRUE, HTT_CLASS, offset); DocPrint(doc, "\n"); DocRecalc(doc); if (IsRaw) { DocDumpLines(doc, 100000); DocDel(doc); } } U0 UpdateRegVarImg(CHashFun *tmpf, U8 *_b, CTask *task) { CMemberList *ml; CHashClass *tmpc; ml = tmpf->member_list_and_root; while (ml) { if (ml->reg != REG_NONE) { tmpc = OptClassFwd(ml->member_class); MemCopy(_b + ml->offset, TaskRegAddr(task, ml->reg), tmpc->size); } ml = ml->next; } } public U0 FunRep(U8 *st, U8 *rbp=NULL, I64 max_depth=2, CTask *task=NULL) {//Shows names and values of a function's local variables using compiler's info. I64 size; U8 *img; CHashFun *tmpf = HashFind(st, Fs->hash_table, HTT_FUN); CMemberList *tmpm; if (tmpf) { if (rbp) { if (task) { //tmpf->size is negative. It's the bottom //of the function local variable space relative to RBP. size = tmpf->arg_count * 8 - tmpf->size + 16; img = MAlloc(size); MemCopy(img, rbp + tmpf->size, size); UpdateRegVarImg(tmpf, img - tmpf->size, task); ClassRep(img - tmpf->size, st, max_depth, FALSE, FALSE, TRUE, rbp - img + tmpf->size); Free(img); } else ClassRep(rbp, st, max_depth, FALSE, FALSE, TRUE); } else { tmpm = tmpf->member_list_and_root; if (!IsRaw) "$LTCYAN$Reg/Offset Symbol$FG$\n"; else "Reg/Offset Symbol\n"; while (tmpm) { if (0 <= tmpm->reg < REG_REGS_NUM) "%010Z %s\n", tmpm->reg, "ST_U64_REGS", tmpm->str; else "%010tX %s\n", tmpm->offset, tmpm->str; tmpm = tmpm->next; } "%010tX Stack Size\n", tmpf->size; } } } #help_index "Debugging/Unassemble" public U0 Uf(U8 *st) {//Unassembles a named function. I64 i; CHashSrcSym *tmpf; CDebugInfo *debug_info; if (tmpf = HashFind(st, Fs->hash_table, HTT_FUN | HTT_EXPORT_SYS_SYM)) { if (tmpf->type & HTT_FUN) FunRep(st); if (debug_info = tmpf->debug_info) { i = debug_info->body[debug_info->max_line + 1 - debug_info->min_line] - debug_info->body[0]; Un(debug_info->body[0], i); "Code Size:%04X\n", i; } else U(HashVal(tmpf)); } }