]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/ia64/ia64/db_trace.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / sys / ia64 / ia64 / db_trace.c
1 /*-
2  * Copyright (c) 2003, 2004 Marcel Moolenaar
3  * Copyright (c) 2000-2001 Doug Rabson
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *      $FreeBSD$
28  */
29
30 #include <sys/param.h>
31 #include <sys/kdb.h>
32 #include <sys/proc.h>
33 #include <sys/stack.h>
34
35 #include <machine/db_machdep.h>
36 #include <machine/frame.h>
37 #include <machine/md_var.h>
38 #include <machine/pcb.h>
39 #include <machine/unwind.h>
40 #include <machine/vmparam.h>
41
42 #include <ddb/ddb.h>
43 #include <ddb/db_sym.h> 
44 #include <ddb/db_access.h>
45 #include <ddb/db_variables.h>
46 #include <ddb/db_output.h>
47
48 int  db_md_set_watchpoint(db_expr_t addr, db_expr_t size);
49 int  db_md_clr_watchpoint(db_expr_t addr, db_expr_t size);
50 void db_md_list_watchpoints(void);
51
52 static int
53 db_backtrace(struct thread *td, struct pcb *pcb, int count)
54 {
55         struct unw_regstate rs;
56         struct trapframe *tf;
57         const char *name;
58         db_expr_t offset;
59         uint64_t bsp, cfm, ip, pfs, reg, sp;
60         c_db_sym_t sym;
61         int args, error, i, quit;
62
63         quit = 0;
64         db_setup_paging(db_simple_pager, &quit, db_lines_per_page);
65         error = unw_create_from_pcb(&rs, pcb);
66         while (!error && count-- && !quit) {
67                 error = unw_get_cfm(&rs, &cfm);
68                 if (!error)
69                         error = unw_get_bsp(&rs, &bsp);
70                 if (!error)
71                         error = unw_get_ip(&rs, &ip);
72                 if (!error)
73                         error = unw_get_sp(&rs, &sp);
74                 if (error)
75                         break;
76
77                 args = IA64_CFM_SOL(cfm);
78                 if (args > 8)
79                         args = 8;
80
81                 error = unw_step(&rs);
82                 if (!error) {
83                         if (!unw_get_cfm(&rs, &pfs)) {
84                                 i = IA64_CFM_SOF(pfs) - IA64_CFM_SOL(pfs);
85                                 if (args > i)
86                                         args = i;
87                         }
88                 }
89
90                 sym = db_search_symbol(ip, DB_STGY_ANY, &offset);
91                 db_symbol_values(sym, &name, NULL);
92                 db_printf("%s(", name);
93                 if (bsp >= IA64_RR_BASE(5)) {
94                         for (i = 0; i < args; i++) {
95                                 if ((bsp & 0x1ff) == 0x1f8)
96                                         bsp += 8;
97                                 db_read_bytes(bsp, sizeof(reg), (void*)&reg);
98                                 if (i > 0)
99                                         db_printf(", ");
100                                 db_printf("0x%lx", reg);
101                                 bsp += 8;
102                         }
103                 } else
104                         db_printf("...");
105                 db_printf(") at ");
106
107                 db_printsym(ip, DB_STGY_PROC);
108                 db_printf("\n");
109
110                 if (error != ERESTART)
111                         continue;
112                 if (sp < IA64_RR_BASE(5))
113                         break;
114
115                 tf = (struct trapframe *)(sp + 16);
116                 if ((tf->tf_flags & FRAME_SYSCALL) != 0 ||
117                     tf->tf_special.iip < IA64_RR_BASE(5))
118                         break;
119
120                 /* XXX ask if we should unwind across the trapframe. */
121                 db_printf("--- trapframe at %p\n", tf);
122                 unw_delete(&rs);
123                 error = unw_create_from_frame(&rs, tf);
124         }
125
126         unw_delete(&rs);
127         /*
128          * EJUSTRETURN and ERESTART signal the end of a trace and
129          * are not really errors.
130          */
131         return ((error > 0) ? error : 0);
132 }
133
134 void
135 db_trace_self(void)
136 {
137         struct pcb pcb;
138
139         savectx(&pcb);
140         db_backtrace(curthread, &pcb, -1);
141 }
142
143 int
144 db_trace_thread(struct thread *td, int count)
145 {
146         struct pcb *ctx;
147
148         ctx = kdb_thr_ctx(td);
149         return (db_backtrace(td, ctx, count));
150 }
151
152 void
153 stack_save(struct stack *st)
154 {
155
156         stack_zero(st);
157         /*
158          * Nothing for now.
159          * Is libuwx reentrant?
160          * Can unw_create* sleep?
161          */
162 }
163
164 int
165 db_md_set_watchpoint(addr, size)
166         db_expr_t addr;
167         db_expr_t size;
168 {
169         return (-1);
170 }
171
172
173 int
174 db_md_clr_watchpoint(addr, size)
175         db_expr_t addr;
176         db_expr_t size;
177 {
178         return (-1);
179 }
180
181
182 void
183 db_md_list_watchpoints()
184 {
185         return;
186 }