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