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

Contents of /src/lisp/breakpoint.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations)
Tue Nov 25 15:53:30 1997 UTC (16 years, 4 months ago) by dtc
Branch: MAIN
Changes since 1.6: +45 -6 lines
File MIME type: text/plain
Breakpoint and single stepping support for the x86 port. This has been
tested in the experimental code and works on both FreeBSD and Linux.
Plus a few improvements to the interrupt safety for the x86 port.
1 /*
2
3 $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/breakpoint.c,v 1.7 1997/11/25 15:53:30 dtc 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
23 #define REAL_LRA_SLOT 0
24 #define KNOWN_RETURN_P_SLOT 1
25 #define BOGUS_LRA_CONSTANTS 2
26
27 static void *compute_pc(lispobj code_obj, int pc_offset)
28 {
29 struct code *code;
30
31 code = (struct code *)PTR(code_obj);
32 return (void *)((char *)code + HeaderValue(code->header)*sizeof(lispobj)
33 + pc_offset);
34 }
35
36 unsigned long breakpoint_install(lispobj code_obj, int pc_offset)
37 {
38 return arch_install_breakpoint(compute_pc(code_obj, pc_offset));
39 }
40
41 void breakpoint_remove(lispobj code_obj, int pc_offset,
42 unsigned long orig_inst)
43 {
44 arch_remove_breakpoint(compute_pc(code_obj, pc_offset), orig_inst);
45 }
46
47 void breakpoint_do_displaced_inst(struct sigcontext *scp,
48 unsigned long orig_inst)
49 {
50 #if !defined(hpux) && !defined(irix) && !defined(i386)
51 undo_fake_foreign_function_call(scp);
52 #endif
53 arch_do_displaced_inst(scp, orig_inst);
54 }
55
56 #ifndef i386
57 static lispobj find_code(struct sigcontext *scp)
58 {
59 #ifdef reg_CODE
60 lispobj code = SC_REG(scp, reg_CODE), header;
61
62 if (LowtagOf(code) != type_OtherPointer)
63 return NIL;
64
65 header = *(lispobj *)(code-type_OtherPointer);
66
67 if (TypeOf(header) == type_CodeHeader)
68 return code;
69 else
70 return code - HeaderValue(header)*sizeof(lispobj);
71 #else
72 return NIL;
73 #endif
74 }
75 #endif
76
77 #ifdef i386
78 static lispobj find_code(struct sigcontext *scp)
79 {
80 lispobj codeptr = component_ptr_from_pc(SC_PC(scp));
81
82 if (codeptr==NULL)
83 return NIL;
84 return (codeptr+type_OtherPointer);
85 }
86 #endif
87
88 static int compute_offset(struct sigcontext *scp, lispobj code)
89 {
90 if (code == NIL)
91 return 0;
92 else {
93 unsigned long code_start;
94 struct code *codeptr = (struct code *)PTR(code);
95 #ifdef parisc
96 unsigned long pc = SC_PC(scp) & ~3;
97 #else
98 unsigned long pc = SC_PC(scp);
99 #endif
100
101 code_start = (unsigned long)codeptr
102 + HeaderValue(codeptr->header)*sizeof(lispobj);
103 if (pc < code_start)
104 return 0;
105 else {
106 int offset = pc - code_start;
107 if (offset >= codeptr->code_size)
108 return 0;
109 else
110 return make_fixnum(offset);
111 }
112 }
113 }
114
115 void handle_breakpoint(int signal, int subcode, struct sigcontext *scp)
116 {
117 lispobj code, scp_sap=alloc_sap(scp);
118
119 fake_foreign_function_call(scp);
120
121 code = find_code(scp);
122
123 #ifdef i386
124 /* Don't disallow recursive breakpoint traps. Otherwise, we can't */
125 /* use debugger breakpoints anywhere in here. */
126 sigsetmask(scp->sc_mask);
127 #endif
128
129 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
130 compute_offset(scp, code),
131 code,
132 scp_sap);
133
134 undo_fake_foreign_function_call(scp);
135 }
136
137 void *handle_function_end_breakpoint(int signal, int subcode,
138 struct sigcontext *scp)
139 {
140 lispobj code, lra, scp_sap=alloc_sap(scp);
141 struct code *codeptr;
142
143 fake_foreign_function_call(scp);
144
145 code = find_code(scp);
146 codeptr = (struct code *)PTR(code);
147
148 #ifdef i386
149 /* Don't disallow recursive breakpoint traps. Otherwise, we can't */
150 /* use debugger breakpoints anywhere in here. */
151 sigsetmask(scp->sc_mask);
152 #endif
153
154 funcall3(SymbolFunction(HANDLE_BREAKPOINT),
155 compute_offset(scp, code),
156 code,
157 scp_sap);
158
159 lra = codeptr->constants[REAL_LRA_SLOT];
160 #ifdef reg_CODE
161 if (codeptr->constants[KNOWN_RETURN_P_SLOT] == NIL)
162 SC_REG(scp, reg_CODE) = lra;
163 #endif
164
165 undo_fake_foreign_function_call(scp);
166
167 #ifdef i386
168 /* On the x86 the saved lra is a SAP; extract the return
169 address. */
170 if (!Pointerp(lra) || !(LowtagOf(lra)==type_OtherPointer))
171 fprintf(stderr,"* Return address not a SAP!\n");
172 {
173 struct sap *sap = (struct sap *)PTR(lra);
174 if (TypeOf(sap->header)!=type_Sap)
175 fprintf(stderr,"* Return address not a SAP!\n");
176 return (void *)(sap->pointer);
177 }
178 #else
179 return (void *)(lra-type_OtherPointer+sizeof(lispobj));
180 #endif
181 }

  ViewVC Help
Powered by ViewVC 1.1.5