Subversion Repositories Kolibri OS

Rev

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

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