Subversion Repositories Kolibri OS

Rev

Rev 438 | 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.     ;    add     edx, std_application_base_address
  126.         push    ebx
  127.         mov     ebx, edx
  128.         call    check_region
  129.         pop     ebx
  130.         dec     eax
  131.         jnz     .ret
  132.         call    get_debuggee_slot
  133.         jc      .ret
  134. ;        imul    eax, tss_step/32
  135. ;        add     eax, tss_data
  136.         mov     edi, edx
  137. ;        cmp     [eax+TSS._cs], app_code
  138. ;        jnz     .ring0
  139. ;        lea     esi, [eax+TSS._eip]
  140. ;        shr     ecx, 2
  141. ;        rep     movsd
  142. ;        jmp     .ret
  143. .ring0:
  144. ; note that following code assumes that all interrupt/exception handlers
  145. ; saves ring-3 context by pushad in this order
  146.         mov     esi, [tss._esp0]
  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
  150.         mov     [edi+24h], eax
  151.         lodsd                     ;esi
  152.         mov     [edi+20h], eax
  153.         lodsd                     ; ebp
  154.         mov     [edi+1Ch], eax
  155.         lodsd                     ;esp
  156.         lodsd                     ;ebx
  157.         mov     [edi+14h], eax
  158.         lodsd                     ;edx
  159.         mov     [edi+10h], eax
  160.         lodsd                     ;ecx
  161.         mov     [edi+0Ch], eax
  162.         lodsd                     ;eax
  163.         mov     [edi+8], eax
  164. ;;;        add     esi, 8         ;ds es
  165.         lodsd                     ;eip
  166.         mov     [edi], eax
  167.         lodsd                     ;cs
  168.         lodsd                     ;eflags
  169.         mov     [edi+4], eax
  170.         lodsd                     ;esp
  171.         mov     [edi+18h], eax
  172. .ret:
  173.         sti
  174.         ret
  175.  
  176. debug_setcontext:
  177. ; in:
  178. ; ebx=pid
  179. ; ecx=sizeof(CONTEXT)
  180. ; edx->CONTEXT
  181. ; destroys eax,ecx,edx,esi,edi
  182.         cmp     ecx, 28h
  183.         jnz     .ret
  184.     ;    add     edx, std_application_base_address
  185.         push    ebx
  186.         mov     ebx, edx
  187.         call    check_region
  188.         pop     ebx
  189.         dec     eax
  190.         jnz     .ret
  191.         call    get_debuggee_slot
  192.         jc      .stiret
  193. ;        imul    eax, tss_step/32
  194. ;        add     eax, tss_data
  195.         mov     esi, edx
  196. ;        cmp     [eax+TSS._cs], app_code
  197. ;        jnz     .ring0
  198. ;        lea     edi, [eax+TSS._eip]
  199. ;        shr     ecx, 2
  200. ;        rep     movsd
  201. ;        jmp     .stiret
  202. .ring0:
  203.         mov     edi, [tss._esp0]
  204.         sub     edi, 8+12+20h
  205.         mov     eax, [esi+24h]    ;edi
  206.         stosd
  207.         mov     eax, [esi+20h]    ;esi
  208.         stosd
  209.         mov     eax, [esi+1Ch]    ;ebp
  210.         stosd
  211.         scasd
  212.         mov     eax, [esi+14h]    ;ebx
  213.         stosd
  214.         mov     eax, [esi+10h]    ;edx
  215.         stosd
  216.         mov     eax, [esi+0Ch]    ;ecx
  217.         stosd
  218.         mov     eax, [esi+8]      ;eax
  219.         stosd
  220. ;;;        add     edi, 8         ;ds es
  221.         mov     eax, [esi]        ;eip
  222.         stosd
  223.         scasd
  224.         mov     eax, [esi+4]      ;eflags
  225.         stosd
  226.         mov     eax, [esi+18h]    ;esp
  227.         stosd
  228. .stiret:
  229.         sti
  230. .ret:
  231.         ret
  232.  
  233. debug_set_drx:
  234.         call    get_debuggee_slot
  235.         jc      .errret
  236.         mov     ebp, eax
  237.         lea     eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
  238. ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
  239. ; [eax+10]=dr7
  240.     ;    add     edx, std_application_base_address
  241.         jc      .errret
  242.         cmp     cl, 3
  243.         ja      .errret
  244.         mov     ebx, dr7
  245.         shr     ebx, cl
  246.         shr     ebx, cl
  247.         test    ebx, 2          ; bit 1+2*index = G0..G3, global break enable
  248.         jnz     .errret2
  249.         test    ch, ch
  250.         jns     .new
  251. ; clear breakpoint
  252.         movzx   ecx, cl
  253.         add     ecx, ecx
  254.         and     dword [eax+ecx*2], 0    ; clear DR<i>
  255.         btr     dword [eax+10h], ecx    ; clear L<i> bit
  256.         test    byte [eax+10h], 55h
  257.         jnz     .okret
  258. ;        imul    eax, ebp, tss_step/32
  259. ;        and     byte [eax + tss_data + TSS._trap], not 1
  260. .okret:
  261.         and     dword [esp+36], 0
  262.         sti
  263.         ret
  264. .errret:
  265.         sti
  266.         mov     dword [esp+36], 1
  267.         ret
  268. .errret2:
  269.         sti
  270.         mov     dword [esp+36], 2
  271.         ret
  272. .new:
  273. ; add new breakpoint
  274. ; cl=index; ch=flags; edx=address
  275.         test    ch, 0xF0
  276.         jnz     .errret
  277.         mov     bl, ch
  278.         and     bl, 3
  279.         cmp     bl, 2
  280.         jz      .errret
  281.         mov     bl, ch
  282.         shr     bl, 2
  283.         cmp     bl, 2
  284.         jz      .errret
  285.         test    dl, bl
  286.         jnz     .errret
  287.         or      byte [eax+10h+1], 3     ; set GE and LE flags
  288.         movzx   ebx, ch
  289.         movzx   ecx, cl
  290.         add     ecx, ecx
  291.         bts     dword [eax+10h], ecx    ; set L<i> flag
  292.         add     ecx, ecx
  293.         mov     [eax+ecx], edx          ; set DR<i>
  294.         shl     ebx, cl
  295.         mov     edx, 0xF
  296.         shl     edx, cl
  297.         not     edx
  298.         and     [eax+10h+2], dx
  299.         or      [eax+10h+2], bx         ; set R/W and LEN fields
  300. ;        imul    eax, ebp, tss_step/32
  301. ;        or      byte [eax + tss_data + TSS._trap], 1
  302.         jmp     .okret
  303.  
  304. debug_read_process_memory:
  305. ; in:
  306. ; ebx=pid
  307. ; ecx=length
  308. ; esi->buffer in debugger
  309. ; edx=address in debuggee
  310. ; out: [esp+36]=sizeof(read)
  311. ; destroys all
  312.     ;    add     esi, std_application_base_address
  313.         push    ebx
  314.         mov     ebx, esi
  315.         call    check_region
  316.         pop     ebx
  317.         dec     eax
  318.         jnz     .err
  319.         call    get_debuggee_slot
  320.         jc      .err
  321.         shr     eax, 5
  322.         mov     ebx, esi
  323.         call    read_process_memory
  324.         sti
  325.         mov     dword [esp+36], eax
  326.         ret
  327. .err:
  328.         or      dword [esp+36], -1
  329.         ret
  330.  
  331. debug_write_process_memory:
  332. ; in:
  333. ; ebx=pid
  334. ; ecx=length
  335. ; esi->buffer in debugger
  336. ; edx=address in debuggee
  337. ; out: [esp+36]=sizeof(write)
  338. ; destroys all
  339.     ;    add     esi, std_application_base_address
  340.         push    ebx
  341.         mov     ebx, esi
  342.         call    check_region
  343.         pop     ebx
  344.         dec     eax
  345.         jnz     debug_read_process_memory.err
  346.         call    get_debuggee_slot
  347.         jc      debug_read_process_memory.err
  348.         shr     eax, 5
  349.         mov     ebx, esi
  350.         call    write_process_memory
  351.         sti
  352.         mov     [esp+36], eax
  353.         ret
  354.  
  355. debugger_notify:
  356. ; in: eax=debugger slot
  357. ;     ecx=size of debug message
  358. ;     [esp+4]..[esp+4+ecx]=message
  359. ; interrupts must be disabled!
  360. ; destroys all general registers
  361. ; interrupts remain disabled
  362.         xchg    ebp, eax
  363.         mov     edi, [timer_ticks]
  364.         add     edi, 500        ; 5 sec timeout
  365. .1:
  366.         mov     eax, ebp
  367.         shl     eax, 8
  368.         mov     edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
  369.         test    edx, edx
  370.         jz      .ret
  371. ; read buffer header
  372.         push    ecx
  373.         push    eax
  374.         push    eax
  375.         mov     eax, ebp
  376.         mov     ebx, esp
  377.         mov     ecx, 8
  378.         call    read_process_memory
  379.         cmp     eax, ecx
  380.         jz      @f
  381.         add     esp, 12
  382.         jmp     .ret
  383. @@:
  384.         cmp     dword [ebx], 0
  385.         jg      @f
  386. .2:
  387.         pop     ecx
  388.         pop     ecx
  389.         pop     ecx
  390.         cmp     dword [CURRENT_TASK], 1
  391.         jnz     .notos
  392.         cmp     [timer_ticks], edi
  393.         jae     .ret
  394. .notos:
  395.         sti
  396.         call    change_task
  397.         cli
  398.         jmp     .1
  399. @@:
  400.         mov     ecx, [ebx+8]
  401.         add     ecx, [ebx+4]
  402.         cmp     ecx, [ebx]
  403.         ja      .2
  404. ; advance buffer position
  405.         push    ecx
  406.         mov     ecx, 4
  407.         sub     ebx, ecx
  408.         mov     eax, ebp
  409.         add     edx, ecx
  410.         call    write_process_memory
  411.         pop     eax
  412. ; write message
  413.         mov     eax, ebp
  414.         add     edx, ecx
  415.         add     edx, [ebx+8]
  416.         add     ebx, 20
  417.         pop     ecx
  418.         pop     ecx
  419.         pop     ecx
  420.         call    write_process_memory
  421. ; new debug event
  422.         mov     eax, ebp
  423.         shl     eax, 8
  424.         or      byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1      ; set flag 100h
  425. .ret:
  426.         ret
  427.  
  428. debug_exc:
  429. ; int 1 = #DB
  430.         save_ring3_context
  431.         cld
  432.         mov     ax, app_data ;os_data
  433.         mov     ds, ax
  434.         mov     es, ax
  435.         mov     eax, dr6
  436.         test    ax, ax
  437.         jns     @f
  438. ; this is exception from task switch
  439. ; set DRx registers for task and continue
  440.         mov     eax, [CURRENT_TASK]
  441.         shl     eax, 8
  442.         add     eax, SLOT_BASE+APPDATA.dbg_regs
  443.         mov     ecx, [eax+0]
  444.         mov     dr0, ecx
  445.         mov     ecx, [eax+4]
  446.         mov     dr1, ecx
  447.         mov     ecx, [eax+8]
  448.         mov     dr2, ecx
  449.         mov     ecx, [eax+0Ch]
  450.         mov     dr3, ecx
  451.         xor     ecx, ecx
  452.         mov     dr6, ecx
  453.         mov     ecx, [eax+10h]
  454.         mov     dr7, ecx
  455.         restore_ring3_context
  456.         iretd
  457. @@:
  458.         push    eax
  459.         xor     eax, eax
  460.         mov     dr6, eax
  461. ; test if debugging
  462.         cli
  463.         mov     eax, [current_slot]
  464.         mov     eax, [eax+APPDATA.debugger_slot]
  465.         test    eax, eax
  466.         jnz     .debug
  467.         sti
  468. ; not debuggee => say error and terminate
  469.         add     esp, 0x20+4
  470.         mov     [error_interrupt], 1
  471.         call    show_error_parameters
  472.         mov     edx, [TASK_BASE]
  473.         mov     byte [edx+TASKDATA.state], 4
  474.         jmp     change_task
  475. .debug:
  476. ; we are debugged process, notify debugger and suspend ourself
  477. ; eax=debugger PID
  478.         pop     edx
  479.         mov     ebx, dr7
  480.         mov     cl, not 1
  481. .l1:
  482.         test    bl, 1
  483.         jnz     @f
  484.         and     dl, cl
  485. @@:
  486.         shr     ebx, 2
  487.         add     cl, cl
  488.         inc     ecx
  489.         cmp     cl, not 10h
  490.         jnz     .l1
  491.         push    edx     ; DR6 image
  492.         mov     ecx, [TASK_BASE]
  493.         push    dword [ecx+TASKDATA.pid]        ; PID
  494.         push    12
  495.         pop     ecx
  496.         push    3       ; 3 = debug exception
  497.         call    debugger_notify
  498.         pop     ecx
  499.         pop     ecx
  500.         pop     ecx
  501.         mov     edx, [TASK_BASE]
  502.         mov     byte [edx+TASKDATA.state], 1    ; suspended
  503.         call    change_task
  504.         restore_ring3_context
  505.         iretd
  506.