Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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