Subversion Repositories Kolibri OS

Rev

Rev 113 | Rev 237 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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