/[cmucl]/src/lisp/breakpoint.c
ViewVC logotype

Contents of /src/lisp/breakpoint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (hide annotations)
Fri Jul 6 08:04:39 2007 UTC (6 years, 9 months ago) by cshapiro
Branch: MAIN
CVS Tags: snapshot-2007-09, snapshot-2007-08, snapshot-2008-08, snapshot-2008-09, snapshot-2008-05, snapshot-2008-06, snapshot-2008-07, snapshot-2008-01, snapshot-2008-02, snapshot-2008-03, release-19e, unicode-utf16-sync-2008-07, unicode-utf16-sync-2008-09, snapshot-2008-04, unicode-utf16-extfmts-pre-sync-2008-11, release-19e-pre1, release-19e-pre2, unicode-utf16-string-support, release-19e-base, unicode-utf16-base, snapshot-2007-12, snapshot-2007-10, snapshot-2007-11, pre-telent-clx
Branch point for: unicode-utf16-branch, release-19e-branch, unicode-utf16-extfmt-branch
Changes since 1.19: +3 -3 lines
File MIME type: text/plain
Import x86 Darwin port.
1 ram 1.6 /*
2    
3 cshapiro 1.20 $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/breakpoint.c,v 1.20 2007/07/06 08:04:39 cshapiro Exp $
4 ram 1.6
5     This code was written as part of the CMU Common Lisp project at
6     Carnegie Mellon University, and has been placed in the public domain.
7    
8     */
9    
10 wlott 1.1 #include <stdio.h>
11     #include <signal.h>
12    
13     #include "lisp.h"
14     #include "os.h"
15     #include "internals.h"
16 ram 1.5 #include "interrupt.h"
17 wlott 1.1 #include "arch.h"
18     #include "lispregs.h"
19     #include "globals.h"
20     #include "alloc.h"
21     #include "breakpoint.h"
22 dtc 1.12 #if defined GENCGC
23     #include "gencgc.h"
24     #endif
25 wlott 1.1
26 rtoy 1.15 /*
27     * See MAKE-BOGUS-LRA in code/debug-int.lisp for these values. (We
28     * really should generate these from the Lisp code.)
29     */
30 wlott 1.1 #define REAL_LRA_SLOT 0
31 dtc 1.8 #ifndef i386
32 wlott 1.1 #define KNOWN_RETURN_P_SLOT 1
33     #define BOGUS_LRA_CONSTANTS 2
34 dtc 1.8 #else
35     #define KNOWN_RETURN_P_SLOT 2
36     #define BOGUS_LRA_CONSTANTS 3
37     #endif
38 wlott 1.1
39 rtoy 1.18 static void *
40     compute_pc(lispobj code_obj, int pc_offset)
41 wlott 1.1 {
42     struct code *code;
43    
44 rtoy 1.18 code = (struct code *) PTR(code_obj);
45     return (void *) ((char *) code + HeaderValue(code->header) * sizeof(lispobj)
46     + pc_offset);
47 wlott 1.1 }
48    
49 rtoy 1.18 unsigned long
50     breakpoint_install(lispobj code_obj, int pc_offset)
51 wlott 1.1 {
52     return arch_install_breakpoint(compute_pc(code_obj, pc_offset));
53     }
54    
55 rtoy 1.18 void
56     breakpoint_remove(lispobj code_obj, int pc_offset, unsigned long orig_inst)
57 wlott 1.1 {
58     arch_remove_breakpoint(compute_pc(code_obj, pc_offset), orig_inst);
59     }
60    
61 rtoy 1.18 void
62     breakpoint_do_displaced_inst(os_context_t * scp, unsigned long orig_inst)
63 wlott 1.1 {
64 dtc 1.7 #if !defined(hpux) && !defined(irix) && !defined(i386)
65 wlott 1.2 undo_fake_foreign_function_call(scp);
66 wlott 1.3 #endif
67 wlott 1.1 arch_do_displaced_inst(scp, orig_inst);
68     }
69    
70 rtoy 1.17 #if !defined(i386)
71 rtoy 1.18 static lispobj
72     find_code(os_context_t * scp)
73 wlott 1.1 {
74 wlott 1.2 #ifdef reg_CODE
75     lispobj code = SC_REG(scp, reg_CODE), header;
76 wlott 1.1
77     if (LowtagOf(code) != type_OtherPointer)
78     return NIL;
79    
80 rtoy 1.18 header = *(lispobj *) (code - type_OtherPointer);
81 wlott 1.1
82     if (TypeOf(header) == type_CodeHeader)
83     return code;
84     else
85 rtoy 1.18 return code - HeaderValue(header) * sizeof(lispobj);
86 wlott 1.1 #else
87     return NIL;
88     #endif
89     }
90 dtc 1.7 #endif
91    
92 rtoy 1.17 #if defined(i386)
93 rtoy 1.18 static lispobj
94     find_code(os_context_t * scp)
95 dtc 1.7 {
96 cshapiro 1.20 lispobj *codeptr = component_ptr_from_pc((lispobj *) SC_PC(scp));
97 dtc 1.7
98 rtoy 1.18 if (codeptr == NULL)
99     return NIL;
100     else
101     return (lispobj) codeptr | type_OtherPointer;
102 dtc 1.7 }
103     #endif
104 wlott 1.1
105 rtoy 1.18 static int
106     compute_offset(os_context_t * scp, lispobj code, boolean function_end)
107 wlott 1.1 {
108     if (code == NIL)
109 wlott 1.2 return 0;
110 wlott 1.1 else {
111     unsigned long code_start;
112 rtoy 1.18 struct code *codeptr = (struct code *) PTR(code);
113    
114 wlott 1.3 #ifdef parisc
115     unsigned long pc = SC_PC(scp) & ~3;
116     #else
117     unsigned long pc = SC_PC(scp);
118     #endif
119 wlott 1.1
120 rtoy 1.18 code_start = (unsigned long) codeptr
121     + HeaderValue(codeptr->header) * sizeof(lispobj);
122 wlott 1.3 if (pc < code_start)
123 wlott 1.2 return 0;
124 wlott 1.1 else {
125 wlott 1.3 int offset = pc - code_start;
126 rtoy 1.18
127 rtoy 1.15 if (offset >= codeptr->code_size) {
128 rtoy 1.18 if (function_end) {
129 cshapiro 1.20 #if defined(sparc) || (defined(DARWIN) && defined(__ppc__))
130 rtoy 1.18 /*
131     * We're in a function end breakpoint. Compute the
132     * offset from the (known) breakpoint location and the
133     * beginning of the breakpoint guts. (See *-assem.S.)
134     *
135     * Then make the offset negative so the caller knows
136     * that the offset is not from the code object.
137     */
138     extern char function_end_breakpoint_trap;
139     extern char function_end_breakpoint_guts;
140    
141     offset =
142     &function_end_breakpoint_trap -
143     &function_end_breakpoint_guts;
144     return make_fixnum(-offset);
145 rtoy 1.15 #else
146 rtoy 1.18 return 0;
147     #endif
148     } else {
149     return 0;
150     }
151 rtoy 1.15 } else {
152 rtoy 1.18 return make_fixnum(offset);
153     }
154 wlott 1.1 }
155     }
156 wlott 1.2 }
157 wlott 1.1
158 dtc 1.9 #ifndef i386
159 rtoy 1.18 void
160     handle_breakpoint(int signal, int subcode, os_context_t * scp)
161 dtc 1.9 {
162     lispobj code;
163    
164     fake_foreign_function_call(scp);
165    
166     code = find_code(scp);
167    
168     funcall3(SymbolFunction(HANDLE_BREAKPOINT),
169 rtoy 1.18 compute_offset(scp, code, 0), code, alloc_sap(scp));
170 dtc 1.9
171     undo_fake_foreign_function_call(scp);
172     }
173     #else
174 rtoy 1.18 void
175     handle_breakpoint(int signal, int subcode, os_context_t * scp)
176 wlott 1.2 {
177 rtoy 1.18 lispobj code, scp_sap = alloc_sap(scp);
178 wlott 1.2
179     fake_foreign_function_call(scp);
180    
181     code = find_code(scp);
182 dtc 1.7
183 dtc 1.11 /*
184     * Don't disallow recursive breakpoint traps. Otherwise, we can't
185     * use debugger breakpoints anywhere in here.
186     */
187    
188 rtoy 1.18 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
189 wlott 1.1 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
190 rtoy 1.18 compute_offset(scp, code, 0), code, scp_sap);
191 wlott 1.1
192 wlott 1.2 undo_fake_foreign_function_call(scp);
193 wlott 1.1 }
194 dtc 1.9 #endif
195 wlott 1.1
196 dtc 1.8 #ifndef i386
197 rtoy 1.18 void *
198     handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
199 wlott 1.1 {
200 dtc 1.9 lispobj code, lra;
201 wlott 1.2 struct code *codeptr;
202 rtoy 1.15 int offset;
203 rtoy 1.18
204 wlott 1.2 fake_foreign_function_call(scp);
205 wlott 1.1
206 wlott 1.2 code = find_code(scp);
207 rtoy 1.18 codeptr = (struct code *) PTR(code);
208 rtoy 1.15 offset = compute_offset(scp, code, 1);
209 rtoy 1.16 #if 0
210     printf("handle_function_end:\n");
211     printf(" code = 0x%08x\n", code);
212     printf(" codeptr = %p\n", codeptr);
213     printf(" offset = %d\n", fixnum_value(offset));
214     fflush(stdout);
215     #endif
216 wlott 1.2
217 rtoy 1.18 if (offset < 0) {
218     /*
219     * We were in the function end breakpoint. Which means we are
220     * in a bogus LRA, so compute where the code-component of this
221     * bogus lra object starts. Adjust code, and codeptr
222     * appropriately so the breakpoint handler can do the right
223     * thing.
224     */
225     unsigned int pc;
226    
227     pc = SC_PC(scp);
228    
229     offset = -offset;
230     /*
231     * Some magic here. pc points to the trap instruction. The
232     * offset gives us where the function_end_breakpoint_guts
233     * begins. But we need to back up some more to get to the
234     * code-component object. The magic 2 below is
235     */
236     code = pc - fixnum_value(offset);
237     code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS * sizeof(lispobj);
238    
239     code += type_OtherPointer;
240     codeptr = (struct code *) PTR(code);
241 rtoy 1.16 #if 0
242     printf(" pc = 0x%08x\n", pc);
243     printf(" code = 0x%08x\n", code);
244     printf(" codeptr = %p\n", codeptr);
245     fflush(stdout);
246     #endif
247 rtoy 1.18 }
248    
249     funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp));
250 wlott 1.2
251 rtoy 1.15 /*
252     * Breakpoint handling done, so get the real LRA where we're
253     * supposed to return to so we can return there.
254     */
255 wlott 1.1 lra = codeptr->constants[REAL_LRA_SLOT];
256 wlott 1.2 #ifdef reg_CODE
257 rtoy 1.15 /*
258     * With the known-return convention, we definitely do NOT want to
259     * mangle the CODE register because it isn't pointing to the bogus
260     * LRA but to the actual routine.
261     */
262 wlott 1.1 if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)
263 wlott 1.2 SC_REG(scp, reg_CODE) = lra;
264 wlott 1.1 #endif
265 dtc 1.8 undo_fake_foreign_function_call(scp);
266 rtoy 1.18 return (void *) (lra - type_OtherPointer + sizeof(lispobj));
267 dtc 1.8 }
268     #else
269 rtoy 1.18 void *
270     handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
271 dtc 1.8 {
272 rtoy 1.18 lispobj code, scp_sap = alloc_sap(scp);
273 dtc 1.8 struct code *codeptr;
274    
275     fake_foreign_function_call(scp);
276    
277     code = find_code(scp);
278 dtc 1.11 codeptr = (struct code *) PTR(code);
279    
280     /*
281     * Don't disallow recursive breakpoint traps. Otherwise, we can't
282     * use debugger breakpoints anywhere in here.
283     */
284 dtc 1.8
285 rtoy 1.18 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
286 dtc 1.8 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
287 rtoy 1.18 compute_offset(scp, code, 1), code, scp_sap);
288 wlott 1.2
289     undo_fake_foreign_function_call(scp);
290    
291 dtc 1.8 return compute_pc(codeptr->constants[REAL_LRA_SLOT],
292 dtc 1.11 fixnum_value(codeptr->constants[REAL_LRA_SLOT + 1]));
293 dtc 1.8 }
294 dtc 1.7 #endif

  ViewVC Help
Powered by ViewVC 1.1.5