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

Contents of /src/lisp/breakpoint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.20 - (show 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 /*
2
3 $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/breakpoint.c,v 1.20 2007/07/06 08:04:39 cshapiro Exp $
4
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 #include <stdio.h>
11 #include <signal.h>
12
13 #include "lisp.h"
14 #include "os.h"
15 #include "internals.h"
16 #include "interrupt.h"
17 #include "arch.h"
18 #include "lispregs.h"
19 #include "globals.h"
20 #include "alloc.h"
21 #include "breakpoint.h"
22 #if defined GENCGC
23 #include "gencgc.h"
24 #endif
25
26 /*
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 #define REAL_LRA_SLOT 0
31 #ifndef i386
32 #define KNOWN_RETURN_P_SLOT 1
33 #define BOGUS_LRA_CONSTANTS 2
34 #else
35 #define KNOWN_RETURN_P_SLOT 2
36 #define BOGUS_LRA_CONSTANTS 3
37 #endif
38
39 static void *
40 compute_pc(lispobj code_obj, int pc_offset)
41 {
42 struct code *code;
43
44 code = (struct code *) PTR(code_obj);
45 return (void *) ((char *) code + HeaderValue(code->header) * sizeof(lispobj)
46 + pc_offset);
47 }
48
49 unsigned long
50 breakpoint_install(lispobj code_obj, int pc_offset)
51 {
52 return arch_install_breakpoint(compute_pc(code_obj, pc_offset));
53 }
54
55 void
56 breakpoint_remove(lispobj code_obj, int pc_offset, unsigned long orig_inst)
57 {
58 arch_remove_breakpoint(compute_pc(code_obj, pc_offset), orig_inst);
59 }
60
61 void
62 breakpoint_do_displaced_inst(os_context_t * scp, unsigned long orig_inst)
63 {
64 #if !defined(hpux) && !defined(irix) && !defined(i386)
65 undo_fake_foreign_function_call(scp);
66 #endif
67 arch_do_displaced_inst(scp, orig_inst);
68 }
69
70 #if !defined(i386)
71 static lispobj
72 find_code(os_context_t * scp)
73 {
74 #ifdef reg_CODE
75 lispobj code = SC_REG(scp, reg_CODE), header;
76
77 if (LowtagOf(code) != type_OtherPointer)
78 return NIL;
79
80 header = *(lispobj *) (code - type_OtherPointer);
81
82 if (TypeOf(header) == type_CodeHeader)
83 return code;
84 else
85 return code - HeaderValue(header) * sizeof(lispobj);
86 #else
87 return NIL;
88 #endif
89 }
90 #endif
91
92 #if defined(i386)
93 static lispobj
94 find_code(os_context_t * scp)
95 {
96 lispobj *codeptr = component_ptr_from_pc((lispobj *) SC_PC(scp));
97
98 if (codeptr == NULL)
99 return NIL;
100 else
101 return (lispobj) codeptr | type_OtherPointer;
102 }
103 #endif
104
105 static int
106 compute_offset(os_context_t * scp, lispobj code, boolean function_end)
107 {
108 if (code == NIL)
109 return 0;
110 else {
111 unsigned long code_start;
112 struct code *codeptr = (struct code *) PTR(code);
113
114 #ifdef parisc
115 unsigned long pc = SC_PC(scp) & ~3;
116 #else
117 unsigned long pc = SC_PC(scp);
118 #endif
119
120 code_start = (unsigned long) codeptr
121 + HeaderValue(codeptr->header) * sizeof(lispobj);
122 if (pc < code_start)
123 return 0;
124 else {
125 int offset = pc - code_start;
126
127 if (offset >= codeptr->code_size) {
128 if (function_end) {
129 #if defined(sparc) || (defined(DARWIN) && defined(__ppc__))
130 /*
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 #else
146 return 0;
147 #endif
148 } else {
149 return 0;
150 }
151 } else {
152 return make_fixnum(offset);
153 }
154 }
155 }
156 }
157
158 #ifndef i386
159 void
160 handle_breakpoint(int signal, int subcode, os_context_t * scp)
161 {
162 lispobj code;
163
164 fake_foreign_function_call(scp);
165
166 code = find_code(scp);
167
168 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
169 compute_offset(scp, code, 0), code, alloc_sap(scp));
170
171 undo_fake_foreign_function_call(scp);
172 }
173 #else
174 void
175 handle_breakpoint(int signal, int subcode, os_context_t * scp)
176 {
177 lispobj code, scp_sap = alloc_sap(scp);
178
179 fake_foreign_function_call(scp);
180
181 code = find_code(scp);
182
183 /*
184 * Don't disallow recursive breakpoint traps. Otherwise, we can't
185 * use debugger breakpoints anywhere in here.
186 */
187
188 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
189 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
190 compute_offset(scp, code, 0), code, scp_sap);
191
192 undo_fake_foreign_function_call(scp);
193 }
194 #endif
195
196 #ifndef i386
197 void *
198 handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
199 {
200 lispobj code, lra;
201 struct code *codeptr;
202 int offset;
203
204 fake_foreign_function_call(scp);
205
206 code = find_code(scp);
207 codeptr = (struct code *) PTR(code);
208 offset = compute_offset(scp, code, 1);
209 #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
217 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 #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 }
248
249 funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp));
250
251 /*
252 * Breakpoint handling done, so get the real LRA where we're
253 * supposed to return to so we can return there.
254 */
255 lra = codeptr->constants[REAL_LRA_SLOT];
256 #ifdef reg_CODE
257 /*
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 if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)
263 SC_REG(scp, reg_CODE) = lra;
264 #endif
265 undo_fake_foreign_function_call(scp);
266 return (void *) (lra - type_OtherPointer + sizeof(lispobj));
267 }
268 #else
269 void *
270 handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
271 {
272 lispobj code, scp_sap = alloc_sap(scp);
273 struct code *codeptr;
274
275 fake_foreign_function_call(scp);
276
277 code = find_code(scp);
278 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
285 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
286 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
287 compute_offset(scp, code, 1), code, scp_sap);
288
289 undo_fake_foreign_function_call(scp);
290
291 return compute_pc(codeptr->constants[REAL_LRA_SLOT],
292 fixnum_value(codeptr->constants[REAL_LRA_SLOT + 1]));
293 }
294 #endif

  ViewVC Help
Powered by ViewVC 1.1.5