Subversion Repositories Kolibri OS

Rev

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

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