Subversion Repositories Kolibri OS

Rev

Rev 750 | Rev 1076 | 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: 1056 $
9
 
10
 
40 halyavin 11
; diamond, 2006
12
sys_debug_services:
1056 Galkov 13
        cmp     eax, 9
14
        ja      @f
15
        jmp     dword [sys_debug_services_table+eax*4]
16
@@:     ret
40 halyavin 17
sys_debug_services_table:
1056 Galkov 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
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
1056 Galkov 34
        ret
40 halyavin 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
1056 Galkov 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
1056 Galkov 50
        pop     ebx
51
        jnz     .ret_bad
52
;       clc     ; automatically
53
        ret
40 halyavin 54
.ret_bad:
1056 Galkov 55
        stc
56
        ret
40 halyavin 57
 
58
debug_detach:
59
; in: ebx=pid
60
; destroys eax,ebx
1056 Galkov 61
        call    get_debuggee_slot
62
        jc      .ret
380 serge 63
        and     dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
1056 Galkov 64
        call    do_resume
40 halyavin 65
.ret:
1056 Galkov 66
        sti
67
        ret
40 halyavin 68
 
69
debug_terminate:
70
; in: ebx=pid
1056 Galkov 71
        call    get_debuggee_slot
72
        jc      debug_detach.ret
73
        mov     ecx, eax
74
        shr     ecx, 5
75
        push    2
76
        pop     ebx
77
        jmp     sys_system
40 halyavin 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
1056 Galkov 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:
1056 Galkov 95
        sti
96
        ret
40 halyavin 97
.1:
1056 Galkov 98
        inc     ebx
99
        jmp     .2
40 halyavin 100
 
101
do_resume:
379 serge 102
        mov     bl, [CURRENT_TASK+eax+TASKDATA.state]
1056 Galkov 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
1056 Galkov 109
.ret:   ret
110
.1:     dec     ebx
111
        jmp     .2
40 halyavin 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
1056 Galkov 122
.ret:   sti
123
        ret
40 halyavin 124
 
125
debug_getcontext:
126
; in:
127
; ebx=pid
128
; ecx=sizeof(CONTEXT)
129
; edx->CONTEXT
130
; destroys eax,ecx,edx,esi,edi
1056 Galkov 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
1056 Galkov 150
        mov     [edi+24h], eax
465 serge 151
        lodsd                     ;esi
1056 Galkov 152
        mov     [edi+20h], eax
465 serge 153
        lodsd                     ; ebp
1056 Galkov 154
        mov     [edi+1Ch], eax
465 serge 155
        lodsd                     ;esp
156
        lodsd                     ;ebx
1056 Galkov 157
        mov     [edi+14h], eax
465 serge 158
        lodsd                     ;edx
1056 Galkov 159
        mov     [edi+10h], eax
465 serge 160
        lodsd                     ;ecx
1056 Galkov 161
        mov     [edi+0Ch], eax
465 serge 162
        lodsd                     ;eax
1056 Galkov 163
        mov     [edi+8], eax
465 serge 164
        lodsd                     ;eip
1056 Galkov 165
        mov     [edi], eax
465 serge 166
        lodsd                     ;cs
167
        lodsd                     ;eflags
1056 Galkov 168
        mov     [edi+4], eax
465 serge 169
        lodsd                     ;esp
1056 Galkov 170
        mov     [edi+18h], eax
40 halyavin 171
.ret:
1056 Galkov 172
        sti
173
        ret
40 halyavin 174
 
175
debug_setcontext:
176
; in:
177
; ebx=pid
178
; ecx=sizeof(CONTEXT)
179
; edx->CONTEXT
180
; destroys eax,ecx,edx,esi,edi
1056 Galkov 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
1056 Galkov 197
        stosd
465 serge 198
        mov     eax, [esi+20h]    ;esi
1056 Galkov 199
        stosd
465 serge 200
        mov     eax, [esi+1Ch]    ;ebp
1056 Galkov 201
        stosd
465 serge 202
        scasd
203
        mov     eax, [esi+14h]    ;ebx
1056 Galkov 204
        stosd
465 serge 205
        mov     eax, [esi+10h]    ;edx
1056 Galkov 206
        stosd
465 serge 207
        mov     eax, [esi+0Ch]    ;ecx
1056 Galkov 208
        stosd
465 serge 209
        mov     eax, [esi+8]      ;eax
1056 Galkov 210
        stosd
465 serge 211
        mov     eax, [esi]        ;eip
1056 Galkov 212
        stosd
213
        scasd
465 serge 214
        mov     eax, [esi+4]      ;eflags
1056 Galkov 215
        stosd
465 serge 216
        mov     eax, [esi+18h]    ;esp
1056 Galkov 217
        stosd
40 halyavin 218
.stiret:
1056 Galkov 219
        sti
40 halyavin 220
.ret:
1056 Galkov 221
        ret
40 halyavin 222
 
66 diamond 223
debug_set_drx:
1056 Galkov 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
1056 Galkov 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
66 diamond 241
; clear breakpoint
1056 Galkov 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:
1056 Galkov 252
        and     dword [esp+36], 0
253
        sti
254
        ret
66 diamond 255
.errret:
1056 Galkov 256
        sti
257
        mov     dword [esp+36], 1
258
        ret
66 diamond 259
.errret2:
1056 Galkov 260
        sti
261
        mov     dword [esp+36], 2
262
        ret
66 diamond 263
.new:
264
; add new breakpoint
265
; cl=index; ch=flags; edx=address
1056 Galkov 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
1056 Galkov 294
        jmp     .okret
66 diamond 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
1056 Galkov 304
        push    ebx
305
        mov     ebx, esi
306
        call    check_region
307
        pop     ebx
308
        dec     eax
309
        jnz     .err
310
        call    get_debuggee_slot
311
        jc      .err
312
        shr     eax, 5
313
        mov     ebx, esi
314
        call    read_process_memory
315
        sti
316
        mov     dword [esp+36], eax
317
        ret
44 halyavin 318
.err:
1056 Galkov 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
1056 Galkov 330
        push    ebx
331
        mov     ebx, esi
332
        call    check_region
333
        pop     ebx
334
        dec     eax
335
        jnz     debug_read_process_memory.err
336
        call    get_debuggee_slot
337
        jc      debug_read_process_memory.err
338
        shr     eax, 5
339
        mov     ebx, esi
340
        call    write_process_memory
341
        sti
342
        mov     [esp+36], eax
343
        ret
40 halyavin 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
1056 Galkov 352
        xchg    ebp, eax
353
        mov     edi, [timer_ticks]
354
        add     edi, 500        ; 5 sec timeout
40 halyavin 355
.1:
1056 Galkov 356
        mov     eax, ebp
357
        shl     eax, 8
380 serge 358
        mov     edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
1056 Galkov 359
        test    edx, edx
360
        jz      .ret
40 halyavin 361
; read buffer header
1056 Galkov 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
40 halyavin 373
@@:
1056 Galkov 374
        cmp     dword [ebx], 0
375
        jg      @f
40 halyavin 376
.2:
1056 Galkov 377
        pop     ecx
378
        pop     ecx
379
        pop     ecx
379 serge 380
        cmp     dword [CURRENT_TASK], 1
1056 Galkov 381
        jnz     .notos
382
        cmp     [timer_ticks], edi
383
        jae     .ret
66 diamond 384
.notos:
1056 Galkov 385
        sti
386
        call    change_task
387
        cli
388
        jmp     .1
40 halyavin 389
@@:
1056 Galkov 390
        mov     ecx, [ebx+8]
391
        add     ecx, [ebx+4]
392
        cmp     ecx, [ebx]
393
        ja      .2
40 halyavin 394
; advance buffer position
1056 Galkov 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
40 halyavin 402
; write message
1056 Galkov 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
40 halyavin 411
; new debug event
1056 Galkov 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:
1056 Galkov 416
        ret
66 diamond 417
 
1056 Galkov 418
debug_ex:
66 diamond 419
; we are debugged process, notify debugger and suspend ourself
420
; eax=debugger PID
1056 Galkov 421
        mov     edx, dr6 ; debug_message data=DR6_image
422
        xor     ebx, ebx
423
        mov     dr6, ebx
424
        mov     ebx, dr7
425
        mov     cl, not 8
426
  .l1:  shl     bl,2
427
        jc      @f
428
        and     dl, cl
429
  @@:   sar     cl,1
430
        jc      .l1
431
        mov     ecx,3    ; debug_message code=debug_exception
432
.notify:
433
        push    edx      ; debug_message data
434
        mov     ebx, [TASK_BASE]
435
        push    [ebx+TASKDATA.pid] ; PID
436
        push    ecx      ; debug_message code
437
        mov     ecx,12   ; debug_message size
438
        call    debugger_notify ;; only ONE using, inline ???
439
        add     esp,12
379 serge 440
        mov     edx, [TASK_BASE]
1056 Galkov 441
        mov     byte [edx+TASKDATA.state], 1    ; suspended
442
        call    change_task
443
        restore_ring3_context
444
        iretd