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

Contents of /src/lisp/breakpoint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.14.2.2 - (show annotations)
Mon Dec 19 01:10:12 2005 UTC (8 years, 4 months ago) by rtoy
Branch: ppc_gencgc_branch
CVS Tags: ppc_gencgc_snap_2006-01-06, ppc_gencgc_snap_2005-12-17
Changes since 1.14.2.1: +98 -96 lines
File MIME type: text/plain
Merge code from main branch of 2005-12-17 to ppc gencgc branch.  Still
doesn't work of course.
1 /*
2
3 $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/breakpoint.c,v 1.14.2.2 2005/12/19 01:10:12 rtoy 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(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)
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 #if defined POSIX_SIGS
189 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
190 #else
191 sigsetmask(scp->sc_mask);
192 #endif
193 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
194 compute_offset(scp, code, 0), code, scp_sap);
195
196 undo_fake_foreign_function_call(scp);
197 }
198 #endif
199
200 #ifndef i386
201 void *
202 handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
203 {
204 lispobj code, lra;
205 struct code *codeptr;
206 int offset;
207
208 fake_foreign_function_call(scp);
209
210 code = find_code(scp);
211 codeptr = (struct code *) PTR(code);
212 offset = compute_offset(scp, code, 1);
213 #if 0
214 printf("handle_function_end:\n");
215 printf(" code = 0x%08x\n", code);
216 printf(" codeptr = %p\n", codeptr);
217 printf(" offset = %d\n", fixnum_value(offset));
218 fflush(stdout);
219 #endif
220
221 if (offset < 0) {
222 /*
223 * We were in the function end breakpoint. Which means we are
224 * in a bogus LRA, so compute where the code-component of this
225 * bogus lra object starts. Adjust code, and codeptr
226 * appropriately so the breakpoint handler can do the right
227 * thing.
228 */
229 unsigned int pc;
230
231 pc = SC_PC(scp);
232
233 offset = -offset;
234 /*
235 * Some magic here. pc points to the trap instruction. The
236 * offset gives us where the function_end_breakpoint_guts
237 * begins. But we need to back up some more to get to the
238 * code-component object. The magic 2 below is
239 */
240 code = pc - fixnum_value(offset);
241 code -= sizeof(struct code) + BOGUS_LRA_CONSTANTS * sizeof(lispobj);
242
243 code += type_OtherPointer;
244 codeptr = (struct code *) PTR(code);
245 #if 0
246 printf(" pc = 0x%08x\n", pc);
247 printf(" code = 0x%08x\n", code);
248 printf(" codeptr = %p\n", codeptr);
249 fflush(stdout);
250 #endif
251 }
252
253 funcall3(SymbolFunction(HANDLE_BREAKPOINT), offset, code, alloc_sap(scp));
254
255 /*
256 * Breakpoint handling done, so get the real LRA where we're
257 * supposed to return to so we can return there.
258 */
259 lra = codeptr->constants[REAL_LRA_SLOT];
260 #ifdef reg_CODE
261 /*
262 * With the known-return convention, we definitely do NOT want to
263 * mangle the CODE register because it isn't pointing to the bogus
264 * LRA but to the actual routine.
265 */
266 if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)
267 SC_REG(scp, reg_CODE) = lra;
268 #endif
269 undo_fake_foreign_function_call(scp);
270 return (void *) (lra - type_OtherPointer + sizeof(lispobj));
271 }
272 #else
273 void *
274 handle_function_end_breakpoint(int signal, int subcode, os_context_t * scp)
275 {
276 lispobj code, scp_sap = alloc_sap(scp);
277 struct code *codeptr;
278
279 fake_foreign_function_call(scp);
280
281 code = find_code(scp);
282 codeptr = (struct code *) PTR(code);
283
284 /*
285 * Don't disallow recursive breakpoint traps. Otherwise, we can't
286 * use debugger breakpoints anywhere in here.
287 */
288
289 #if defined POSIX_SIGS
290 sigprocmask(SIG_SETMASK, &scp->uc_sigmask, NULL);
291 #else
292 sigsetmask(scp->sc_mask);
293 #endif
294 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
295 compute_offset(scp, code, 1), code, scp_sap);
296
297 undo_fake_foreign_function_call(scp);
298
299 return compute_pc(codeptr->constants[REAL_LRA_SLOT],
300 fixnum_value(codeptr->constants[REAL_LRA_SLOT + 1]));
301 }
302 #endif

  ViewVC Help
Powered by ViewVC 1.1.5