static void stack_capture(struct stack *st, vm_offset_t frame) { vm_offset_t callpc; stack_zero(st); if (frame < PAGE_SIZE) return; while (1) { frame = *(vm_offset_t *)frame; if (frame < PAGE_SIZE) break; #ifdef __powerpc64__ callpc = *(vm_offset_t *)(frame + 16) - 4; #else callpc = *(vm_offset_t *)(frame + 4) - 4; #endif if ((callpc & 3) || (callpc < 0x100)) break; /* * Don't bother traversing trap-frames - there should * be enough info down to the frame to work out where * things are going wrong. Plus, prevents this shortened * version of code from accessing user-space frames */ if (callpc + CALLOFFSET == (vm_offset_t) &trapexit || callpc + CALLOFFSET == (vm_offset_t) &asttrapexit) break; if (stack_put(st, callpc) == -1) break; } }
static void stack_capture(struct stack *st, struct frame *frame) { struct frame *fp; vm_offset_t callpc; stack_zero(st); fp = frame; for (;;) { if (!INKERNEL((vm_offset_t)fp) || !ALIGNED_POINTER(fp, uint64_t)) break; callpc = fp->fr_pc; if (!INKERNEL(callpc)) break; /* Don't bother traversing trap frames. */ if ((callpc > (uint64_t)tl_trap_begin && callpc < (uint64_t)tl_trap_end) || (callpc > (uint64_t)tl_text_begin && callpc < (uint64_t)tl_text_end)) break; if (stack_put(st, callpc) == -1) break; if (v9next_frame(fp) <= fp || v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) break; fp = v9next_frame(fp); } }
int main() { int elt; // element to be pushed and poped char c; // 'switch(c)' of the main loop // display management const char *prompt = "> "; int prompt_count = 1; print_usage(); printf("%i%s", prompt_count++, prompt); /*--------------------------- Main loop of the test program ---------------------------*/ while ( (c = getchar()) != 'Q') { switch(c) { case 'p': // put if (scanf("%i", &elt) != 1) goto error_scanf; stack_put(elt); printf("%i\n", elt); break; case 'g': // get elt = stack_get(); printf("%i\n", elt); break; case 'r': // retrieve, cannot use p for peek :-( elt = stack_peek(); printf("%i\n", elt); break; default: print_usage(); break; } while (getchar() != '\n') {} /* skip end of line */ printf("%i%s", prompt_count++, prompt); continue; // all is ok, go to the beginning of the main loop /*----- ERROR TREATMENT -----*/ error_scanf: while (getchar() != '\n') {} /* skip end of line */ printf("ERROR: wrong scanf argument\n"); printf("%i%s", prompt_count++, prompt); continue; /*----- END ERROR TREATMENT -----*/ } /*-------------------------------------- End of the main loop of the test program --------------------------------------*/ printf("Quit\n"); return 0; }
static void stack_capture(struct stack *st, u_int32_t *frame) { #if !defined(__ARM_EABI__) && !defined(__clang__) vm_offset_t callpc; while (INKERNEL(frame)) { callpc = frame[FR_SCP]; if (stack_put(st, callpc) == -1) break; frame = (u_int32_t *)(frame[FR_RFP]); } #endif }
static void stack_capture(struct stack *st, u_int32_t *frame) { vm_offset_t callpc; stack_zero(st); while (1) { if (!INKERNEL(frame)) break; callpc = frame[FR_SCP]; if (stack_put(st, callpc) == -1) break; frame = (u_int32_t *)(frame[FR_RFP]); } }
static void stack_capture(struct stack *st, u_register_t pc, u_register_t sp) { u_register_t ra = 0, i, stacksize; short ra_stack_pos = 0; InstFmt insn; stack_zero(st); for (;;) { stacksize = 0; if (pc <= (u_register_t)(intptr_t)btext) break; for (i = pc; i >= (u_register_t)(intptr_t)btext; i -= sizeof (insn)) { bcopy((void *)(intptr_t)i, &insn, sizeof insn); switch (insn.IType.op) { case OP_ADDI: case OP_ADDIU: case OP_DADDI: case OP_DADDIU: if (insn.IType.rs != SP || insn.IType.rt != SP) break; stacksize = -(short)insn.IType.imm; break; case OP_SW: case OP_SD: if (insn.IType.rs != SP || insn.IType.rt != RA) break; ra_stack_pos = (short)insn.IType.imm; break; default: break; } if (stacksize) break; } if (stack_put(st, pc) == -1) break; for (i = pc; !ra; i += sizeof (insn)) { bcopy((void *)(intptr_t)i, &insn, sizeof insn); switch (insn.IType.op) { case OP_SPECIAL: if((insn.RType.func == OP_JR)) { if (ra >= (u_register_t)(intptr_t)btext) break; if (insn.RType.rs != RA) break; ra = stack_register_fetch(sp, ra_stack_pos); if (!ra) goto done; ra -= 8; } break; default: break; } /* eret */ if (insn.word == 0x42000018) goto done; } if (pc == ra && stacksize == 0) break; sp += stacksize; pc = ra; ra = 0; } done: return; }