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/systm.h>
32174195Srwatson#include <sys/proc.h>
33174195Srwatson#include <sys/stack.h>
34174195Srwatson
35174195Srwatson#include <machine/pcb.h>
36174195Srwatson#include <machine/stack.h>
37174195Srwatson
38174195Srwatson#include <vm/vm.h>
39174195Srwatson#include <vm/vm_param.h>
40174195Srwatson#include <vm/pmap.h>
41174195Srwatson
42174195Srwatsonstatic void
43286396Skibstack_capture(struct thread *td, struct stack *st, register_t rbp)
44174195Srwatson{
45174195Srwatson	struct amd64_frame *frame;
46174195Srwatson	vm_offset_t callpc;
47174195Srwatson
48174195Srwatson	stack_zero(st);
49174195Srwatson	frame = (struct amd64_frame *)rbp;
50174195Srwatson	while (1) {
51174195Srwatson		if (!INKERNEL((long)frame))
52174195Srwatson			break;
53174195Srwatson		callpc = frame->f_retaddr;
54174195Srwatson		if (!INKERNEL(callpc))
55174195Srwatson			break;
56174195Srwatson		if (stack_put(st, callpc) == -1)
57174195Srwatson			break;
58174195Srwatson		if (frame->f_frame <= frame ||
59286396Skib		    (vm_offset_t)frame->f_frame >= td->td_kstack +
60286396Skib		    td->td_kstack_pages * PAGE_SIZE)
61174195Srwatson			break;
62174195Srwatson		frame = frame->f_frame;
63174195Srwatson	}
64174195Srwatson}
65174195Srwatson
66174195Srwatsonvoid
67174195Srwatsonstack_save_td(struct stack *st, struct thread *td)
68174195Srwatson{
69174195Srwatson	register_t rbp;
70174195Srwatson
71174195Srwatson	if (TD_IS_SWAPPED(td))
72174195Srwatson		panic("stack_save_td: swapped");
73174195Srwatson	if (TD_IS_RUNNING(td))
74174195Srwatson		panic("stack_save_td: running");
75174195Srwatson
76174195Srwatson	rbp = td->td_pcb->pcb_rbp;
77286396Skib	stack_capture(td, st, rbp);
78174195Srwatson}
79174195Srwatson
80174195Srwatsonvoid
81174195Srwatsonstack_save(struct stack *st)
82174195Srwatson{
83174195Srwatson	register_t rbp;
84174195Srwatson
85174195Srwatson	__asm __volatile("movq %%rbp,%0" : "=r" (rbp));
86286396Skib	stack_capture(curthread, st, rbp);
87174195Srwatson}
88