Subversion Repositories Kolibri OS

Rev

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