Subversion Repositories Kolibri OS

Rev

Rev 444 | Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. $Revision: 431 $
  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.  
  9. ; diamond, 2006
  10. sys_debug_services:
  11.         cmp     eax, 9
  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
  25.         dd      debug_set_drx
  26.  
  27. debug_set_event_data:
  28. ; in: ebx = pointer
  29. ; destroys eax
  30.         mov     eax, [current_slot]
  31.         mov     [eax+APPDATA.dbg_event_mem], ebx
  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
  46.         mov     ebx, [CURRENT_TASK]
  47.         cmp     [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
  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
  61.         and     dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
  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
  82.         mov     bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
  83.         test    bl, bl
  84.         jz      .1
  85.         cmp     bl, 5
  86.         jnz     .ret
  87.         mov     bl, 2
  88. .2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
  89. .ret:
  90.         sti
  91.         ret
  92. .1:
  93.         inc     ebx
  94.         jmp     .2
  95.  
  96. do_resume:
  97.         mov     bl, [CURRENT_TASK+eax+TASKDATA.state]
  98.         cmp     bl, 1
  99.         jz      .1
  100.         cmp     bl, 2
  101.         jnz     .ret
  102.         mov     bl, 5
  103. .2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
  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
  133.         mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
  134.         lea esi, [eax+RING0_STACK_SIZE]
  135.         mov     edi, edx
  136. .ring0:
  137. ; note that following code assumes that all interrupt/exception handlers
  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
  142.         mov     [edi+24h], eax
  143.         lodsd                     ;esi
  144.         mov     [edi+20h], eax
  145.         lodsd                     ; ebp
  146.         mov     [edi+1Ch], eax
  147.         lodsd                     ;esp
  148.         lodsd                     ;ebx
  149.         mov     [edi+14h], eax
  150.         lodsd                     ;edx
  151.         mov     [edi+10h], eax
  152.         lodsd                     ;ecx
  153.         mov     [edi+0Ch], eax
  154.         lodsd                     ;eax
  155.         mov     [edi+8], eax
  156.         lodsd                     ;eip
  157.         mov     [edi], eax
  158.         lodsd                     ;cs
  159.         lodsd                     ;eflags
  160.         mov     [edi+4], eax
  161.         lodsd                     ;esp
  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
  183.         mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
  184.         lea edi, [eax+RING0_STACK_SIZE]
  185.         mov     esi, edx
  186. .ring0:
  187.         sub     edi, 8+12+20h
  188.         mov     eax, [esi+24h]    ;edi
  189.         stosd
  190.         mov     eax, [esi+20h]    ;esi
  191.         stosd
  192.         mov     eax, [esi+1Ch]    ;ebp
  193.         stosd
  194.         scasd
  195.         mov     eax, [esi+14h]    ;ebx
  196.         stosd
  197.         mov     eax, [esi+10h]    ;edx
  198.         stosd
  199.         mov     eax, [esi+0Ch]    ;ecx
  200.         stosd
  201.         mov     eax, [esi+8]      ;eax
  202.         stosd
  203.         mov     eax, [esi]        ;eip
  204.         stosd
  205.         scasd
  206.         mov     eax, [esi+4]      ;eflags
  207.         stosd
  208.         mov     eax, [esi+18h]    ;esp
  209.         stosd
  210. .stiret:
  211.         sti
  212. .ret:
  213.         ret
  214.  
  215. debug_set_drx:
  216.         call    get_debuggee_slot
  217.         jc      .errret
  218.         mov     ebp, eax
  219.         lea     eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
  220. ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
  221. ; [eax+10]=dr7
  222.         cmp     edx, OS_BASE
  223.         jae      .errret
  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<i>
  237.         btr     dword [eax+10h], ecx    ; clear L<i> bit
  238.         test    byte [eax+10h], 55h
  239.         jnz     .okret
  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
  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<i> flag
  275.         add     ecx, ecx
  276.         mov     [eax+ecx], edx          ; set DR<i>
  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
  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
  286.         jmp     .okret
  287.  
  288. debug_read_process_memory:
  289. ; in:
  290. ; ebx=pid
  291. ; ecx=length
  292. ; esi->buffer in debugger
  293. ; edx=address in debuggee
  294. ; out: [esp+36]=sizeof(read)
  295. ; destroys all
  296.         push    ebx
  297.         mov     ebx, esi
  298.         call    check_region
  299.         pop     ebx
  300.         dec     eax
  301.         jnz     .err
  302.         call    get_debuggee_slot
  303.         jc      .err
  304.         shr     eax, 5
  305.         mov     ebx, esi
  306.         call    read_process_memory
  307.         sti
  308.         mov     dword [esp+36], eax
  309.         ret
  310. .err:
  311.         or      dword [esp+36], -1
  312.         ret
  313.  
  314. debug_write_process_memory:
  315. ; in:
  316. ; ebx=pid
  317. ; ecx=length
  318. ; esi->buffer in debugger
  319. ; edx=address in debuggee
  320. ; out: [esp+36]=sizeof(write)
  321. ; destroys all
  322.         push    ebx
  323.         mov     ebx, esi
  324.         call    check_region
  325.         pop     ebx
  326.         dec     eax
  327.         jnz     debug_read_process_memory.err
  328.         call    get_debuggee_slot
  329.         jc      debug_read_process_memory.err
  330.         shr     eax, 5
  331.         mov     ebx, esi
  332.         call    write_process_memory
  333.         sti
  334.         mov     [esp+36], eax
  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
  344.         xchg    ebp, eax
  345.         mov     edi, [timer_ticks]
  346.         add     edi, 500        ; 5 sec timeout
  347. .1:
  348.         mov     eax, ebp
  349.         shl     eax, 8
  350.         mov     edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
  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
  372.         cmp     dword [CURRENT_TASK], 1
  373.         jnz     .notos
  374.         cmp     [timer_ticks], edi
  375.         jae     .ret
  376. .notos:
  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
  406.         or      byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1      ; set flag 100h
  407. .ret:
  408.         ret
  409.  
  410. debug_exc:
  411. ; int 1 = #DB
  412.         save_ring3_context
  413.         cld
  414.         mov     ax, app_data ;os_data
  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
  423.         mov     eax, [current_slot]
  424.         mov     eax, [eax+APPDATA.debugger_slot]
  425.         test    eax, eax
  426.         jnz     .debug
  427.         sti
  428. ; not debuggee => say error and terminate
  429.         add     esp, 0x20+4
  430.         mov     [error_interrupt], 1
  431.         call    show_error_parameters
  432.         mov     edx, [TASK_BASE]
  433.         mov     byte [edx+TASKDATA.state], 4
  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
  452.         mov     ecx, [TASK_BASE]
  453.         push    dword [ecx+TASKDATA.pid]        ; PID
  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
  461.         mov     edx, [TASK_BASE]
  462.         mov     byte [edx+TASKDATA.state], 1    ; suspended
  463.         call    change_task
  464.         restore_ring3_context
  465.         iretd
  466.