Rev 444 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 444 | Rev 459 | ||
---|---|---|---|
1 | $Revision: 431 $ |
1 | $Revision: 431 $ |
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
3 | ;; ;; |
3 | ;; ;; |
4 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
4 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
6 | ;; ;; |
6 | ;; ;; |
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | 8 | ||
9 | ; diamond, 2006 |
9 | ; diamond, 2006 |
10 | sys_debug_services: |
10 | sys_debug_services: |
11 | cmp eax, 9 |
11 | cmp eax, 9 |
12 | ja @f |
12 | ja @f |
13 | jmp dword [sys_debug_services_table+eax*4] |
13 | jmp dword [sys_debug_services_table+eax*4] |
14 | @@: ret |
14 | @@: ret |
15 | sys_debug_services_table: |
15 | sys_debug_services_table: |
16 | dd debug_set_event_data |
16 | dd debug_set_event_data |
17 | dd debug_getcontext |
17 | dd debug_getcontext |
18 | dd debug_setcontext |
18 | dd debug_setcontext |
19 | dd debug_detach |
19 | dd debug_detach |
20 | dd debug_suspend |
20 | dd debug_suspend |
21 | dd debug_resume |
21 | dd debug_resume |
22 | dd debug_read_process_memory |
22 | dd debug_read_process_memory |
23 | dd debug_write_process_memory |
23 | dd debug_write_process_memory |
24 | dd debug_terminate |
24 | dd debug_terminate |
25 | dd debug_set_drx |
25 | dd debug_set_drx |
26 | 26 | ||
27 | debug_set_event_data: |
27 | debug_set_event_data: |
28 | ; in: ebx = pointer |
28 | ; in: ebx = pointer |
29 | ; destroys eax |
29 | ; destroys eax |
30 | mov eax, [current_slot] |
30 | mov eax, [current_slot] |
31 | mov [eax+APPDATA.dbg_event_mem], ebx |
31 | mov [eax+APPDATA.dbg_event_mem], ebx |
32 | ret |
32 | ret |
33 | 33 | ||
34 | get_debuggee_slot: |
34 | get_debuggee_slot: |
35 | ; in: ebx=PID |
35 | ; in: ebx=PID |
36 | ; out: CF=1 if error |
36 | ; out: CF=1 if error |
37 | ; CF=0 and eax=slot*0x20 if ok |
37 | ; CF=0 and eax=slot*0x20 if ok |
38 | ; out: interrupts disabled |
38 | ; out: interrupts disabled |
39 | cli |
39 | cli |
40 | mov eax, ebx |
40 | mov eax, ebx |
41 | call pid_to_slot |
41 | call pid_to_slot |
42 | test eax, eax |
42 | test eax, eax |
43 | jz .ret_bad |
43 | jz .ret_bad |
44 | shl eax, 5 |
44 | shl eax, 5 |
45 | push ebx |
45 | push ebx |
46 | mov ebx, [CURRENT_TASK] |
46 | mov ebx, [CURRENT_TASK] |
47 | cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx |
47 | cmp [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx |
48 | pop ebx |
48 | pop ebx |
49 | jnz .ret_bad |
49 | jnz .ret_bad |
50 | ; clc ; automatically |
50 | ; clc ; automatically |
51 | ret |
51 | ret |
52 | .ret_bad: |
52 | .ret_bad: |
53 | stc |
53 | stc |
54 | ret |
54 | ret |
55 | 55 | ||
56 | debug_detach: |
56 | debug_detach: |
57 | ; in: ebx=pid |
57 | ; in: ebx=pid |
58 | ; destroys eax,ebx |
58 | ; destroys eax,ebx |
59 | call get_debuggee_slot |
59 | call get_debuggee_slot |
60 | jc .ret |
60 | jc .ret |
61 | and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 |
61 | and dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0 |
62 | call do_resume |
62 | call do_resume |
63 | .ret: |
63 | .ret: |
64 | sti |
64 | sti |
65 | ret |
65 | ret |
66 | 66 | ||
67 | debug_terminate: |
67 | debug_terminate: |
68 | ; in: ebx=pid |
68 | ; in: ebx=pid |
69 | call get_debuggee_slot |
69 | call get_debuggee_slot |
70 | jc debug_detach.ret |
70 | jc debug_detach.ret |
71 | mov ebx, eax |
71 | mov ebx, eax |
72 | shr ebx, 5 |
72 | shr ebx, 5 |
73 | push 2 |
73 | push 2 |
74 | pop eax |
74 | pop eax |
75 | jmp sys_system |
75 | jmp sys_system |
76 | 76 | ||
77 | debug_suspend: |
77 | debug_suspend: |
78 | ; in: ebx=pid |
78 | ; in: ebx=pid |
79 | ; destroys eax,ebx |
79 | ; destroys eax,ebx |
80 | call get_debuggee_slot |
80 | call get_debuggee_slot |
81 | jc .ret |
81 | jc .ret |
82 | mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state |
82 | mov bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state |
83 | test bl, bl |
83 | test bl, bl |
84 | jz .1 |
84 | jz .1 |
85 | cmp bl, 5 |
85 | cmp bl, 5 |
86 | jnz .ret |
86 | jnz .ret |
87 | mov bl, 2 |
87 | mov bl, 2 |
88 | .2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
88 | .2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
89 | .ret: |
89 | .ret: |
90 | sti |
90 | sti |
91 | ret |
91 | ret |
92 | .1: |
92 | .1: |
93 | inc ebx |
93 | inc ebx |
94 | jmp .2 |
94 | jmp .2 |
95 | 95 | ||
96 | do_resume: |
96 | do_resume: |
97 | mov bl, [CURRENT_TASK+eax+TASKDATA.state] |
97 | mov bl, [CURRENT_TASK+eax+TASKDATA.state] |
98 | cmp bl, 1 |
98 | cmp bl, 1 |
99 | jz .1 |
99 | jz .1 |
100 | cmp bl, 2 |
100 | cmp bl, 2 |
101 | jnz .ret |
101 | jnz .ret |
102 | mov bl, 5 |
102 | mov bl, 5 |
103 | .2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
103 | .2: mov [CURRENT_TASK+eax+TASKDATA.state], bl |
104 | .ret: ret |
104 | .ret: ret |
105 | .1: dec ebx |
105 | .1: dec ebx |
106 | jmp .2 |
106 | jmp .2 |
107 | 107 | ||
108 | debug_resume: |
108 | debug_resume: |
109 | ; in: ebx=pid |
109 | ; in: ebx=pid |
110 | ; destroys eax,ebx |
110 | ; destroys eax,ebx |
111 | call get_debuggee_slot |
111 | call get_debuggee_slot |
112 | jc .ret |
112 | jc .ret |
113 | call do_resume |
113 | call do_resume |
114 | .ret: sti |
114 | .ret: sti |
115 | ret |
115 | ret |
116 | 116 | ||
117 | debug_getcontext: |
117 | debug_getcontext: |
118 | ; in: |
118 | ; in: |
119 | ; ebx=pid |
119 | ; ebx=pid |
120 | ; ecx=sizeof(CONTEXT) |
120 | ; ecx=sizeof(CONTEXT) |
121 | ; edx->CONTEXT |
121 | ; edx->CONTEXT |
122 | ; destroys eax,ecx,edx,esi,edi |
122 | ; destroys eax,ecx,edx,esi,edi |
123 | cmp ecx, 28h |
123 | cmp ecx, 28h |
124 | jnz .ret |
124 | jnz .ret |
125 | ; add edx, std_application_base_address |
- | |
126 | push ebx |
125 | push ebx |
127 | mov ebx, edx |
126 | mov ebx, edx |
128 | call check_region |
127 | call check_region |
129 | pop ebx |
128 | pop ebx |
130 | dec eax |
129 | dec eax |
131 | jnz .ret |
130 | jnz .ret |
132 | call get_debuggee_slot |
131 | call get_debuggee_slot |
133 | jc .ret |
132 | jc .ret |
134 | ; imul eax, tss_step/32 |
133 | mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
135 | ; add eax, tss_data |
134 | lea esi, [eax+RING0_STACK_SIZE] |
136 | mov edi, edx |
135 | mov edi, edx |
137 | ; cmp [eax+TSS._cs], app_code |
- | |
138 | ; jnz .ring0 |
- | |
139 | ; lea esi, [eax+TSS._eip] |
- | |
140 | ; shr ecx, 2 |
- | |
141 | ; rep movsd |
- | |
142 | ; jmp .ret |
- | |
143 | .ring0: |
136 | .ring0: |
144 | ; note that following code assumes that all interrupt/exception handlers |
137 | ; note that following code assumes that all interrupt/exception handlers |
145 | ; saves ring-3 context by pushad in this order |
138 | ; saves ring-3 context by pushad in this order |
146 | mov esi, [tss._esp0] |
- | |
147 | ; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad |
139 | ; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), pushad |
148 | sub esi, 8+12+20h |
140 | sub esi, 8+12+20h |
149 | lodsd ;edi |
141 | lodsd ;edi |
150 | mov [edi+24h], eax |
142 | mov [edi+24h], eax |
151 | lodsd ;esi |
143 | lodsd ;esi |
152 | mov [edi+20h], eax |
144 | mov [edi+20h], eax |
153 | lodsd ; ebp |
145 | lodsd ; ebp |
154 | mov [edi+1Ch], eax |
146 | mov [edi+1Ch], eax |
155 | lodsd ;esp |
147 | lodsd ;esp |
156 | lodsd ;ebx |
148 | lodsd ;ebx |
157 | mov [edi+14h], eax |
149 | mov [edi+14h], eax |
158 | lodsd ;edx |
150 | lodsd ;edx |
159 | mov [edi+10h], eax |
151 | mov [edi+10h], eax |
160 | lodsd ;ecx |
152 | lodsd ;ecx |
161 | mov [edi+0Ch], eax |
153 | mov [edi+0Ch], eax |
162 | lodsd ;eax |
154 | lodsd ;eax |
163 | mov [edi+8], eax |
155 | mov [edi+8], eax |
164 | ;;; add esi, 8 ;ds es |
- | |
165 | lodsd ;eip |
156 | lodsd ;eip |
166 | mov [edi], eax |
157 | mov [edi], eax |
167 | lodsd ;cs |
158 | lodsd ;cs |
168 | lodsd ;eflags |
159 | lodsd ;eflags |
169 | mov [edi+4], eax |
160 | mov [edi+4], eax |
170 | lodsd ;esp |
161 | lodsd ;esp |
171 | mov [edi+18h], eax |
162 | mov [edi+18h], eax |
172 | .ret: |
163 | .ret: |
173 | sti |
164 | sti |
174 | ret |
165 | ret |
175 | 166 | ||
176 | debug_setcontext: |
167 | debug_setcontext: |
177 | ; in: |
168 | ; in: |
178 | ; ebx=pid |
169 | ; ebx=pid |
179 | ; ecx=sizeof(CONTEXT) |
170 | ; ecx=sizeof(CONTEXT) |
180 | ; edx->CONTEXT |
171 | ; edx->CONTEXT |
181 | ; destroys eax,ecx,edx,esi,edi |
172 | ; destroys eax,ecx,edx,esi,edi |
182 | cmp ecx, 28h |
173 | cmp ecx, 28h |
183 | jnz .ret |
174 | jnz .ret |
184 | ; add edx, std_application_base_address |
- | |
185 | push ebx |
175 | push ebx |
186 | mov ebx, edx |
176 | mov ebx, edx |
187 | call check_region |
177 | call check_region |
188 | pop ebx |
178 | pop ebx |
189 | dec eax |
179 | dec eax |
190 | jnz .ret |
180 | jnz .ret |
191 | call get_debuggee_slot |
181 | call get_debuggee_slot |
192 | jc .stiret |
182 | jc .stiret |
193 | ; imul eax, tss_step/32 |
183 | mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack] |
194 | ; add eax, tss_data |
184 | lea edi, [eax+RING0_STACK_SIZE] |
195 | mov esi, edx |
185 | mov esi, edx |
196 | ; cmp [eax+TSS._cs], app_code |
- | |
197 | ; jnz .ring0 |
- | |
198 | ; lea edi, [eax+TSS._eip] |
- | |
199 | ; shr ecx, 2 |
- | |
200 | ; rep movsd |
- | |
201 | ; jmp .stiret |
- | |
202 | .ring0: |
186 | .ring0: |
203 | mov edi, [tss._esp0] |
- | |
204 | sub edi, 8+12+20h |
187 | sub edi, 8+12+20h |
205 | mov eax, [esi+24h] ;edi |
188 | mov eax, [esi+24h] ;edi |
206 | stosd |
189 | stosd |
207 | mov eax, [esi+20h] ;esi |
190 | mov eax, [esi+20h] ;esi |
208 | stosd |
191 | stosd |
209 | mov eax, [esi+1Ch] ;ebp |
192 | mov eax, [esi+1Ch] ;ebp |
210 | stosd |
193 | stosd |
211 | scasd |
194 | scasd |
212 | mov eax, [esi+14h] ;ebx |
195 | mov eax, [esi+14h] ;ebx |
213 | stosd |
196 | stosd |
214 | mov eax, [esi+10h] ;edx |
197 | mov eax, [esi+10h] ;edx |
215 | stosd |
198 | stosd |
216 | mov eax, [esi+0Ch] ;ecx |
199 | mov eax, [esi+0Ch] ;ecx |
217 | stosd |
200 | stosd |
218 | mov eax, [esi+8] ;eax |
201 | mov eax, [esi+8] ;eax |
219 | stosd |
202 | stosd |
220 | ;;; add edi, 8 ;ds es |
- | |
221 | mov eax, [esi] ;eip |
203 | mov eax, [esi] ;eip |
222 | stosd |
204 | stosd |
223 | scasd |
205 | scasd |
224 | mov eax, [esi+4] ;eflags |
206 | mov eax, [esi+4] ;eflags |
225 | stosd |
207 | stosd |
226 | mov eax, [esi+18h] ;esp |
208 | mov eax, [esi+18h] ;esp |
227 | stosd |
209 | stosd |
228 | .stiret: |
210 | .stiret: |
229 | sti |
211 | sti |
230 | .ret: |
212 | .ret: |
231 | ret |
213 | ret |
232 | 214 | ||
233 | debug_set_drx: |
215 | debug_set_drx: |
234 | call get_debuggee_slot |
216 | call get_debuggee_slot |
235 | jc .errret |
217 | jc .errret |
236 | mov ebp, eax |
218 | mov ebp, eax |
237 | lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] |
219 | lea eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs] |
238 | ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
220 | ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3 |
239 | ; [eax+10]=dr7 |
221 | ; [eax+10]=dr7 |
240 | ; add edx, std_application_base_address |
222 | cmp edx, OS_BASE |
241 | jc .errret |
223 | jae .errret |
242 | cmp cl, 3 |
224 | cmp cl, 3 |
243 | ja .errret |
225 | ja .errret |
244 | mov ebx, dr7 |
226 | mov ebx, dr7 |
245 | shr ebx, cl |
227 | shr ebx, cl |
246 | shr ebx, cl |
228 | shr ebx, cl |
247 | test ebx, 2 ; bit 1+2*index = G0..G3, global break enable |
229 | test ebx, 2 ; bit 1+2*index = G0..G3, global break enable |
248 | jnz .errret2 |
230 | jnz .errret2 |
249 | test ch, ch |
231 | test ch, ch |
250 | jns .new |
232 | jns .new |
251 | ; clear breakpoint |
233 | ; clear breakpoint |
252 | movzx ecx, cl |
234 | movzx ecx, cl |
253 | add ecx, ecx |
235 | add ecx, ecx |
254 | and dword [eax+ecx*2], 0 ; clear DR |
236 | and dword [eax+ecx*2], 0 ; clear DR |
255 | btr dword [eax+10h], ecx ; clear L bit |
237 | btr dword [eax+10h], ecx ; clear L bit |
256 | test byte [eax+10h], 55h |
238 | test byte [eax+10h], 55h |
257 | jnz .okret |
239 | jnz .okret |
258 | ; imul eax, ebp, tss_step/32 |
240 | ; imul eax, ebp, tss_step/32 |
259 | ; and byte [eax + tss_data + TSS._trap], not 1 |
241 | ; and byte [eax + tss_data + TSS._trap], not 1 |
- | 242 | and [ebp*8 + SLOT_BASE+APPDATA.dbg_state], not 1 |
|
260 | .okret: |
243 | .okret: |
261 | and dword [esp+36], 0 |
244 | and dword [esp+36], 0 |
262 | sti |
245 | sti |
263 | ret |
246 | ret |
264 | .errret: |
247 | .errret: |
265 | sti |
248 | sti |
266 | mov dword [esp+36], 1 |
249 | mov dword [esp+36], 1 |
267 | ret |
250 | ret |
268 | .errret2: |
251 | .errret2: |
269 | sti |
252 | sti |
270 | mov dword [esp+36], 2 |
253 | mov dword [esp+36], 2 |
271 | ret |
254 | ret |
272 | .new: |
255 | .new: |
273 | ; add new breakpoint |
256 | ; add new breakpoint |
274 | ; cl=index; ch=flags; edx=address |
257 | ; cl=index; ch=flags; edx=address |
275 | test ch, 0xF0 |
258 | test ch, 0xF0 |
276 | jnz .errret |
259 | jnz .errret |
277 | mov bl, ch |
260 | mov bl, ch |
278 | and bl, 3 |
261 | and bl, 3 |
279 | cmp bl, 2 |
262 | cmp bl, 2 |
280 | jz .errret |
263 | jz .errret |
281 | mov bl, ch |
264 | mov bl, ch |
282 | shr bl, 2 |
265 | shr bl, 2 |
283 | cmp bl, 2 |
266 | cmp bl, 2 |
284 | jz .errret |
267 | jz .errret |
285 | test dl, bl |
268 | test dl, bl |
286 | jnz .errret |
269 | jnz .errret |
287 | or byte [eax+10h+1], 3 ; set GE and LE flags |
270 | or byte [eax+10h+1], 3 ; set GE and LE flags |
288 | movzx ebx, ch |
271 | movzx ebx, ch |
289 | movzx ecx, cl |
272 | movzx ecx, cl |
290 | add ecx, ecx |
273 | add ecx, ecx |
291 | bts dword [eax+10h], ecx ; set L flag |
274 | bts dword [eax+10h], ecx ; set L flag |
292 | add ecx, ecx |
275 | add ecx, ecx |
293 | mov [eax+ecx], edx ; set DR |
276 | mov [eax+ecx], edx ; set DR |
294 | shl ebx, cl |
277 | shl ebx, cl |
295 | mov edx, 0xF |
278 | mov edx, 0xF |
296 | shl edx, cl |
279 | shl edx, cl |
297 | not edx |
280 | not edx |
298 | and [eax+10h+2], dx |
281 | and [eax+10h+2], dx |
299 | or [eax+10h+2], bx ; set R/W and LEN fields |
282 | or [eax+10h+2], bx ; set R/W and LEN fields |
300 | ; imul eax, ebp, tss_step/32 |
283 | ; imul eax, ebp, tss_step/32 |
301 | ; or byte [eax + tss_data + TSS._trap], 1 |
284 | ; or byte [eax + tss_data + TSS._trap], 1 |
- | 285 | or [ebp*8 + SLOT_BASE+APPDATA.dbg_state], 1 |
|
302 | jmp .okret |
286 | jmp .okret |
303 | 287 | ||
304 | debug_read_process_memory: |
288 | debug_read_process_memory: |
305 | ; in: |
289 | ; in: |
306 | ; ebx=pid |
290 | ; ebx=pid |
307 | ; ecx=length |
291 | ; ecx=length |
308 | ; esi->buffer in debugger |
292 | ; esi->buffer in debugger |
309 | ; edx=address in debuggee |
293 | ; edx=address in debuggee |
310 | ; out: [esp+36]=sizeof(read) |
294 | ; out: [esp+36]=sizeof(read) |
311 | ; destroys all |
295 | ; destroys all |
312 | ; add esi, std_application_base_address |
- | |
313 | push ebx |
296 | push ebx |
314 | mov ebx, esi |
297 | mov ebx, esi |
315 | call check_region |
298 | call check_region |
316 | pop ebx |
299 | pop ebx |
317 | dec eax |
300 | dec eax |
318 | jnz .err |
301 | jnz .err |
319 | call get_debuggee_slot |
302 | call get_debuggee_slot |
320 | jc .err |
303 | jc .err |
321 | shr eax, 5 |
304 | shr eax, 5 |
322 | mov ebx, esi |
305 | mov ebx, esi |
323 | call read_process_memory |
306 | call read_process_memory |
324 | sti |
307 | sti |
325 | mov dword [esp+36], eax |
308 | mov dword [esp+36], eax |
326 | ret |
309 | ret |
327 | .err: |
310 | .err: |
328 | or dword [esp+36], -1 |
311 | or dword [esp+36], -1 |
329 | ret |
312 | ret |
330 | 313 | ||
331 | debug_write_process_memory: |
314 | debug_write_process_memory: |
332 | ; in: |
315 | ; in: |
333 | ; ebx=pid |
316 | ; ebx=pid |
334 | ; ecx=length |
317 | ; ecx=length |
335 | ; esi->buffer in debugger |
318 | ; esi->buffer in debugger |
336 | ; edx=address in debuggee |
319 | ; edx=address in debuggee |
337 | ; out: [esp+36]=sizeof(write) |
320 | ; out: [esp+36]=sizeof(write) |
338 | ; destroys all |
321 | ; destroys all |
339 | ; add esi, std_application_base_address |
- | |
340 | push ebx |
322 | push ebx |
341 | mov ebx, esi |
323 | mov ebx, esi |
342 | call check_region |
324 | call check_region |
343 | pop ebx |
325 | pop ebx |
344 | dec eax |
326 | dec eax |
345 | jnz debug_read_process_memory.err |
327 | jnz debug_read_process_memory.err |
346 | call get_debuggee_slot |
328 | call get_debuggee_slot |
347 | jc debug_read_process_memory.err |
329 | jc debug_read_process_memory.err |
348 | shr eax, 5 |
330 | shr eax, 5 |
349 | mov ebx, esi |
331 | mov ebx, esi |
350 | call write_process_memory |
332 | call write_process_memory |
351 | sti |
333 | sti |
352 | mov [esp+36], eax |
334 | mov [esp+36], eax |
353 | ret |
335 | ret |
354 | 336 | ||
355 | debugger_notify: |
337 | debugger_notify: |
356 | ; in: eax=debugger slot |
338 | ; in: eax=debugger slot |
357 | ; ecx=size of debug message |
339 | ; ecx=size of debug message |
358 | ; [esp+4]..[esp+4+ecx]=message |
340 | ; [esp+4]..[esp+4+ecx]=message |
359 | ; interrupts must be disabled! |
341 | ; interrupts must be disabled! |
360 | ; destroys all general registers |
342 | ; destroys all general registers |
361 | ; interrupts remain disabled |
343 | ; interrupts remain disabled |
362 | xchg ebp, eax |
344 | xchg ebp, eax |
363 | mov edi, [timer_ticks] |
345 | mov edi, [timer_ticks] |
364 | add edi, 500 ; 5 sec timeout |
346 | add edi, 500 ; 5 sec timeout |
365 | .1: |
347 | .1: |
366 | mov eax, ebp |
348 | mov eax, ebp |
367 | shl eax, 8 |
349 | shl eax, 8 |
368 | mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
350 | mov edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem] |
369 | test edx, edx |
351 | test edx, edx |
370 | jz .ret |
352 | jz .ret |
371 | ; read buffer header |
353 | ; read buffer header |
372 | push ecx |
354 | push ecx |
373 | push eax |
355 | push eax |
374 | push eax |
356 | push eax |
375 | mov eax, ebp |
357 | mov eax, ebp |
376 | mov ebx, esp |
358 | mov ebx, esp |
377 | mov ecx, 8 |
359 | mov ecx, 8 |
378 | call read_process_memory |
360 | call read_process_memory |
379 | cmp eax, ecx |
361 | cmp eax, ecx |
380 | jz @f |
362 | jz @f |
381 | add esp, 12 |
363 | add esp, 12 |
382 | jmp .ret |
364 | jmp .ret |
383 | @@: |
365 | @@: |
384 | cmp dword [ebx], 0 |
366 | cmp dword [ebx], 0 |
385 | jg @f |
367 | jg @f |
386 | .2: |
368 | .2: |
387 | pop ecx |
369 | pop ecx |
388 | pop ecx |
370 | pop ecx |
389 | pop ecx |
371 | pop ecx |
390 | cmp dword [CURRENT_TASK], 1 |
372 | cmp dword [CURRENT_TASK], 1 |
391 | jnz .notos |
373 | jnz .notos |
392 | cmp [timer_ticks], edi |
374 | cmp [timer_ticks], edi |
393 | jae .ret |
375 | jae .ret |
394 | .notos: |
376 | .notos: |
395 | sti |
377 | sti |
396 | call change_task |
378 | call change_task |
397 | cli |
379 | cli |
398 | jmp .1 |
380 | jmp .1 |
399 | @@: |
381 | @@: |
400 | mov ecx, [ebx+8] |
382 | mov ecx, [ebx+8] |
401 | add ecx, [ebx+4] |
383 | add ecx, [ebx+4] |
402 | cmp ecx, [ebx] |
384 | cmp ecx, [ebx] |
403 | ja .2 |
385 | ja .2 |
404 | ; advance buffer position |
386 | ; advance buffer position |
405 | push ecx |
387 | push ecx |
406 | mov ecx, 4 |
388 | mov ecx, 4 |
407 | sub ebx, ecx |
389 | sub ebx, ecx |
408 | mov eax, ebp |
390 | mov eax, ebp |
409 | add edx, ecx |
391 | add edx, ecx |
410 | call write_process_memory |
392 | call write_process_memory |
411 | pop eax |
393 | pop eax |
412 | ; write message |
394 | ; write message |
413 | mov eax, ebp |
395 | mov eax, ebp |
414 | add edx, ecx |
396 | add edx, ecx |
415 | add edx, [ebx+8] |
397 | add edx, [ebx+8] |
416 | add ebx, 20 |
398 | add ebx, 20 |
417 | pop ecx |
399 | pop ecx |
418 | pop ecx |
400 | pop ecx |
419 | pop ecx |
401 | pop ecx |
420 | call write_process_memory |
402 | call write_process_memory |
421 | ; new debug event |
403 | ; new debug event |
422 | mov eax, ebp |
404 | mov eax, ebp |
423 | shl eax, 8 |
405 | shl eax, 8 |
424 | or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
406 | or byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1 ; set flag 100h |
425 | .ret: |
407 | .ret: |
426 | ret |
408 | ret |
427 | 409 | ||
428 | debug_exc: |
410 | debug_exc: |
429 | ; int 1 = #DB |
411 | ; int 1 = #DB |
430 | save_ring3_context |
412 | save_ring3_context |
431 | cld |
413 | cld |
432 | mov ax, app_data ;os_data |
414 | mov ax, app_data ;os_data |
433 | mov ds, ax |
415 | mov ds, ax |
434 | mov es, ax |
416 | mov es, ax |
435 | mov eax, dr6 |
417 | mov eax, dr6 |
436 | test ax, ax |
- | |
437 | jns @f |
- | |
438 | ; this is exception from task switch |
- | |
439 | ; set DRx registers for task and continue |
- | |
440 | mov eax, [CURRENT_TASK] |
- | |
441 | shl eax, 8 |
- | |
442 | add eax, SLOT_BASE+APPDATA.dbg_regs |
- | |
443 | mov ecx, [eax+0] |
- | |
444 | mov dr0, ecx |
- | |
445 | mov ecx, [eax+4] |
- | |
446 | mov dr1, ecx |
- | |
447 | mov ecx, [eax+8] |
- | |
448 | mov dr2, ecx |
- | |
449 | mov ecx, [eax+0Ch] |
- | |
450 | mov dr3, ecx |
- | |
451 | xor ecx, ecx |
- | |
452 | mov dr6, ecx |
- | |
453 | mov ecx, [eax+10h] |
- | |
454 | mov dr7, ecx |
- | |
455 | restore_ring3_context |
- | |
456 | iretd |
- | |
457 | @@: |
- | |
458 | push eax |
418 | push eax |
459 | xor eax, eax |
419 | xor eax, eax |
460 | mov dr6, eax |
420 | mov dr6, eax |
461 | ; test if debugging |
421 | ; test if debugging |
462 | cli |
422 | cli |
463 | mov eax, [current_slot] |
423 | mov eax, [current_slot] |
464 | mov eax, [eax+APPDATA.debugger_slot] |
424 | mov eax, [eax+APPDATA.debugger_slot] |
465 | test eax, eax |
425 | test eax, eax |
466 | jnz .debug |
426 | jnz .debug |
467 | sti |
427 | sti |
468 | ; not debuggee => say error and terminate |
428 | ; not debuggee => say error and terminate |
469 | add esp, 0x20+4 |
429 | add esp, 0x20+4 |
470 | mov [error_interrupt], 1 |
430 | mov [error_interrupt], 1 |
471 | call show_error_parameters |
431 | call show_error_parameters |
472 | mov edx, [TASK_BASE] |
432 | mov edx, [TASK_BASE] |
473 | mov byte [edx+TASKDATA.state], 4 |
433 | mov byte [edx+TASKDATA.state], 4 |
474 | jmp change_task |
434 | jmp change_task |
475 | .debug: |
435 | .debug: |
476 | ; we are debugged process, notify debugger and suspend ourself |
436 | ; we are debugged process, notify debugger and suspend ourself |
477 | ; eax=debugger PID |
437 | ; eax=debugger PID |
478 | pop edx |
438 | pop edx |
479 | mov ebx, dr7 |
439 | mov ebx, dr7 |
480 | mov cl, not 1 |
440 | mov cl, not 1 |
481 | .l1: |
441 | .l1: |
482 | test bl, 1 |
442 | test bl, 1 |
483 | jnz @f |
443 | jnz @f |
484 | and dl, cl |
444 | and dl, cl |
485 | @@: |
445 | @@: |
486 | shr ebx, 2 |
446 | shr ebx, 2 |
487 | add cl, cl |
447 | add cl, cl |
488 | inc ecx |
448 | inc ecx |
489 | cmp cl, not 10h |
449 | cmp cl, not 10h |
490 | jnz .l1 |
450 | jnz .l1 |
491 | push edx ; DR6 image |
451 | push edx ; DR6 image |
492 | mov ecx, [TASK_BASE] |
452 | mov ecx, [TASK_BASE] |
493 | push dword [ecx+TASKDATA.pid] ; PID |
453 | push dword [ecx+TASKDATA.pid] ; PID |
494 | push 12 |
454 | push 12 |
495 | pop ecx |
455 | pop ecx |
496 | push 3 ; 3 = debug exception |
456 | push 3 ; 3 = debug exception |
497 | call debugger_notify |
457 | call debugger_notify |
498 | pop ecx |
458 | pop ecx |
499 | pop ecx |
459 | pop ecx |
500 | pop ecx |
460 | pop ecx |
501 | mov edx, [TASK_BASE] |
461 | mov edx, [TASK_BASE] |
502 | mov byte [edx+TASKDATA.state], 1 ; suspended |
462 | mov byte [edx+TASKDATA.state], 1 ; suspended |
503 | call change_task |
463 | call change_task |
504 | restore_ring3_context |
464 | restore_ring3_context |
505 | iretd |
465 | iretd |