Subversion Repositories Kolibri OS

Rev

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

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