Subversion Repositories Kolibri OS

Rev

Rev 684 | Rev 750 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
431 serge 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
 
593 mikedld 8
$Revision: 709 $
9
 
10
 
40 halyavin 11
; diamond, 2006
12
sys_debug_services:
66 diamond 13
	cmp	eax, 9
40 halyavin 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
66 diamond 27
	dd	debug_set_drx
40 halyavin 28
 
29
debug_set_event_data:
30
; in: ebx = pointer
31
; destroys eax
465 serge 32
        mov     eax, [current_slot]
33
        mov     [eax+APPDATA.dbg_event_mem], ebx
40 halyavin 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
379 serge 48
        mov     ebx, [CURRENT_TASK]
380 serge 49
        cmp     [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
40 halyavin 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
380 serge 63
        and     dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
40 halyavin 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
684 diamond 73
	mov	ecx, eax
74
	shr	ecx, 5
40 halyavin 75
	push	2
684 diamond 76
	pop	ebx
40 halyavin 77
	jmp	sys_system
78
 
79
debug_suspend:
80
; in: ebx=pid
81
; destroys eax,ebx
667 diamond 82
        cli
83
        mov     eax, ebx
84
        call    pid_to_slot
680 diamond 85
        shl     eax, 5
667 diamond 86
        jz      .ret
379 serge 87
        mov     bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
40 halyavin 88
	test	bl, bl
89
	jz	.1
90
	cmp	bl, 5
91
	jnz	.ret
92
	mov	bl, 2
379 serge 93
.2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
40 halyavin 94
.ret:
95
	sti
96
	ret
97
.1:
98
	inc	ebx
99
	jmp	.2
100
 
101
do_resume:
379 serge 102
        mov     bl, [CURRENT_TASK+eax+TASKDATA.state]
40 halyavin 103
	cmp	bl, 1
104
	jz	.1
105
	cmp	bl, 2
106
	jnz	.ret
107
	mov	bl, 5
379 serge 108
.2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
40 halyavin 109
.ret:	ret
110
.1:	dec	ebx
111
	jmp	.2
112
 
113
debug_resume:
114
; in: ebx=pid
115
; destroys eax,ebx
667 diamond 116
        cli
117
        mov     eax, ebx
118
        call    pid_to_slot
680 diamond 119
        shl     eax, 5
667 diamond 120
        jz      .ret
121
        call    do_resume
40 halyavin 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
465 serge 141
        mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
142
        lea esi, [eax+RING0_STACK_SIZE]
143
        mov     edi, edx
40 halyavin 144
.ring0:
145
; note that following code assumes that all interrupt/exception handlers
465 serge 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
40 halyavin 150
	mov	[edi+24h], eax
465 serge 151
        lodsd                     ;esi
40 halyavin 152
	mov	[edi+20h], eax
465 serge 153
        lodsd                     ; ebp
40 halyavin 154
	mov	[edi+1Ch], eax
465 serge 155
        lodsd                     ;esp
156
        lodsd                     ;ebx
40 halyavin 157
	mov	[edi+14h], eax
465 serge 158
        lodsd                     ;edx
40 halyavin 159
	mov	[edi+10h], eax
465 serge 160
        lodsd                     ;ecx
40 halyavin 161
	mov	[edi+0Ch], eax
465 serge 162
        lodsd                     ;eax
40 halyavin 163
	mov	[edi+8], eax
465 serge 164
        lodsd                     ;eip
40 halyavin 165
	mov	[edi], eax
465 serge 166
        lodsd                     ;cs
167
        lodsd                     ;eflags
40 halyavin 168
	mov	[edi+4], eax
465 serge 169
        lodsd                     ;esp
40 halyavin 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
465 serge 191
        mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
192
        lea edi, [eax+RING0_STACK_SIZE]
193
        mov     esi, edx
40 halyavin 194
.ring0:
465 serge 195
        sub     edi, 8+12+20h
196
        mov     eax, [esi+24h]    ;edi
40 halyavin 197
	stosd
465 serge 198
        mov     eax, [esi+20h]    ;esi
40 halyavin 199
	stosd
465 serge 200
        mov     eax, [esi+1Ch]    ;ebp
40 halyavin 201
	stosd
465 serge 202
        scasd
203
        mov     eax, [esi+14h]    ;ebx
40 halyavin 204
	stosd
465 serge 205
        mov     eax, [esi+10h]    ;edx
40 halyavin 206
	stosd
465 serge 207
        mov     eax, [esi+0Ch]    ;ecx
40 halyavin 208
	stosd
465 serge 209
        mov     eax, [esi+8]      ;eax
40 halyavin 210
	stosd
465 serge 211
        mov     eax, [esi]        ;eip
40 halyavin 212
	stosd
213
	scasd
465 serge 214
        mov     eax, [esi+4]      ;eflags
40 halyavin 215
	stosd
465 serge 216
        mov     eax, [esi+18h]    ;esp
40 halyavin 217
	stosd
218
.stiret:
219
	sti
220
.ret:
221
	ret
222
 
66 diamond 223
debug_set_drx:
224
	call	get_debuggee_slot
225
	jc	.errret
226
	mov	ebp, eax
380 serge 227
        lea     eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
66 diamond 228
; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
229
; [eax+10]=dr7
465 serge 230
        cmp     edx, OS_BASE
231
        jae      .errret
66 diamond 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
465 serge 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
66 diamond 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
465 serge 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
66 diamond 294
	jmp	.okret
295
 
40 halyavin 296
debug_read_process_memory:
297
; in:
298
; ebx=pid
299
; ecx=length
300
; esi->buffer in debugger
301
; edx=address in debuggee
44 halyavin 302
; out: [esp+36]=sizeof(read)
40 halyavin 303
; destroys all
304
	push	ebx
305
	mov	ebx, esi
306
	call	check_region
307
	pop	ebx
308
	dec	eax
44 halyavin 309
	jnz	.err
40 halyavin 310
	call	get_debuggee_slot
44 halyavin 311
	jc	.err
312
	shr	eax, 5
40 halyavin 313
	mov	ebx, esi
314
	call	read_process_memory
315
	sti
44 halyavin 316
	mov	dword [esp+36], eax
40 halyavin 317
	ret
44 halyavin 318
.err:
319
	or	dword [esp+36], -1
320
	ret
40 halyavin 321
 
322
debug_write_process_memory:
323
; in:
324
; ebx=pid
325
; ecx=length
326
; esi->buffer in debugger
327
; edx=address in debuggee
44 halyavin 328
; out: [esp+36]=sizeof(write)
40 halyavin 329
; destroys all
330
	push	ebx
331
	mov	ebx, esi
332
	call	check_region
333
	pop	ebx
334
	dec	eax
44 halyavin 335
	jnz	debug_read_process_memory.err
40 halyavin 336
	call	get_debuggee_slot
44 halyavin 337
	jc	debug_read_process_memory.err
338
	shr	eax, 5
40 halyavin 339
	mov	ebx, esi
340
	call	write_process_memory
341
	sti
44 halyavin 342
	mov	[esp+36], eax
40 halyavin 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
66 diamond 352
	xchg	ebp, eax
63 halyavin 353
	mov	edi, [timer_ticks]
354
	add	edi, 500	; 5 sec timeout
40 halyavin 355
.1:
66 diamond 356
	mov	eax, ebp
357
	shl	eax, 8
380 serge 358
        mov     edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
40 halyavin 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
379 serge 380
        cmp     dword [CURRENT_TASK], 1
66 diamond 381
	jnz	.notos
63 halyavin 382
	cmp	[timer_ticks], edi
383
	jae	.ret
66 diamond 384
.notos:
40 halyavin 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
380 serge 414
        or      byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1      ; set flag 100h
40 halyavin 415
.ret:
416
	ret
66 diamond 417
 
418
debug_exc:
709 diamond 419
        test    byte [esp+8+2], 2
420
        jnz     v86_debug_exc
66 diamond 421
; int 1 = #DB
709 diamond 422
        save_ring3_context
423
        cld
465 serge 424
        mov     ax, app_data ;os_data
66 diamond 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
465 serge 433
        mov     eax, [current_slot]
434
        mov     eax, [eax+APPDATA.debugger_slot]
66 diamond 435
	test	eax, eax
436
	jnz	.debug
437
	sti
438
; not debuggee => say error and terminate
465 serge 439
        add     esp, 0x20+4
66 diamond 440
	mov	[error_interrupt], 1
441
	call	show_error_parameters
379 serge 442
        mov     edx, [TASK_BASE]
115 poddubny 443
	mov	byte [edx+TASKDATA.state], 4
66 diamond 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
379 serge 462
        mov     ecx, [TASK_BASE]
115 poddubny 463
	push	dword [ecx+TASKDATA.pid]	; PID
66 diamond 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
379 serge 471
        mov     edx, [TASK_BASE]
115 poddubny 472
	mov	byte [edx+TASKDATA.state], 1	; suspended
66 diamond 473
	call	change_task
474
	restore_ring3_context
475
	iretd