1174195Srwatson/*- 2174195Srwatson * Copyright (c) 2005 Antoine Brodin 3174195Srwatson * All rights reserved. 4174195Srwatson * 5174195Srwatson * Redistribution and use in source and binary forms, with or without 6174195Srwatson * modification, are permitted provided that the following conditions 7174195Srwatson * are met: 8174195Srwatson * 1. Redistributions of source code must retain the above copyright 9174195Srwatson * notice, this list of conditions and the following disclaimer. 10174195Srwatson * 2. Redistributions in binary form must reproduce the above copyright 11174195Srwatson * notice, this list of conditions and the following disclaimer in the 12174195Srwatson * documentation and/or other materials provided with the distribution. 13174195Srwatson * 14174195Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15174195Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16174195Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17174195Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18174195Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19174195Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20174195Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21174195Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22174195Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23174195Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24174195Srwatson * SUCH DAMAGE. 25174195Srwatson */ 26174195Srwatson 27174195Srwatson#include <sys/cdefs.h> 28174195Srwatson__FBSDID("$FreeBSD$"); 29174195Srwatson 30174195Srwatson#include <sys/param.h> 31174195Srwatson#include <sys/proc.h> 32174195Srwatson#include <sys/stack.h> 33174195Srwatson#include <sys/systm.h> 34174195Srwatson 35174195Srwatson#include <machine/pcb.h> 36174195Srwatson#include <machine/stack.h> 37174195Srwatson#include <machine/vmparam.h> 38174195Srwatson 39200272Smariusstatic void stack_capture(struct stack *st, struct frame *frame); 40184376Smarius 41174195Srwatsonstatic void 42200272Smariusstack_capture(struct stack *st, struct frame *frame) 43174195Srwatson{ 44200272Smarius struct frame *fp; 45174195Srwatson vm_offset_t callpc; 46174195Srwatson 47174195Srwatson stack_zero(st); 48200272Smarius fp = frame; 49200272Smarius for (;;) { 50200272Smarius if (!INKERNEL((vm_offset_t)fp) || 51200272Smarius !ALIGNED_POINTER(fp, uint64_t)) 52200272Smarius break; 53184376Smarius callpc = fp->fr_pc; 54174195Srwatson if (!INKERNEL(callpc)) 55174195Srwatson break; 56174195Srwatson /* Don't bother traversing trap frames. */ 57174195Srwatson if ((callpc > (uint64_t)tl_trap_begin && 58174195Srwatson callpc < (uint64_t)tl_trap_end) || 59174195Srwatson (callpc > (uint64_t)tl_text_begin && 60174195Srwatson callpc < (uint64_t)tl_text_end)) 61174195Srwatson break; 62174195Srwatson if (stack_put(st, callpc) == -1) 63174195Srwatson break; 64200272Smarius if (v9next_frame(fp) <= fp || 65200272Smarius v9next_frame(fp) >= frame + KSTACK_PAGES * PAGE_SIZE) 66200272Smarius break; 67184376Smarius fp = v9next_frame(fp); 68174195Srwatson } 69174195Srwatson} 70174195Srwatson 71174195Srwatsonvoid 72174195Srwatsonstack_save_td(struct stack *st, struct thread *td) 73174195Srwatson{ 74174195Srwatson 75174195Srwatson if (TD_IS_SWAPPED(td)) 76174195Srwatson panic("stack_save_td: swapped"); 77174195Srwatson if (TD_IS_RUNNING(td)) 78174195Srwatson panic("stack_save_td: running"); 79174195Srwatson 80184376Smarius stack_capture(st, (struct frame *)(td->td_pcb->pcb_sp + SPOFF)); 81174195Srwatson} 82174195Srwatson 83174195Srwatsonvoid 84174195Srwatsonstack_save(struct stack *st) 85174195Srwatson{ 86174195Srwatson 87184376Smarius stack_capture(st, (struct frame *)__builtin_frame_address(1)); 88174195Srwatson} 89