Subversion Repositories Kolibri OS

Rev

Rev 709 | Rev 1076 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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.  
  8. $Revision: 750 $
  9.  
  10.  
  11. ; diamond, 2006
  12. sys_debug_services:
  13.         cmp     eax, 9
  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
  27.         dd      debug_set_drx
  28.  
  29. debug_set_event_data:
  30. ; in: ebx = pointer
  31. ; destroys eax
  32.         mov     eax, [current_slot]
  33.         mov     [eax+APPDATA.dbg_event_mem], ebx
  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
  48.         mov     ebx, [CURRENT_TASK]
  49.         cmp     [SLOT_BASE+eax*8+APPDATA.debugger_slot], ebx
  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
  63.         and     dword [eax*8+SLOT_BASE+APPDATA.debugger_slot], 0
  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     ecx, eax
  74.         shr     ecx, 5
  75.         push    2
  76.         pop     ebx
  77.         jmp     sys_system
  78.  
  79. debug_suspend:
  80. ; in: ebx=pid
  81. ; destroys eax,ebx
  82.         cli
  83.         mov     eax, ebx
  84.         call    pid_to_slot
  85.         shl     eax, 5
  86.         jz      .ret
  87.         mov     bl, [CURRENT_TASK+eax+TASKDATA.state] ; process state
  88.         test    bl, bl
  89.         jz      .1
  90.         cmp     bl, 5
  91.         jnz     .ret
  92.         mov     bl, 2
  93. .2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
  94. .ret:
  95.         sti
  96.         ret
  97. .1:
  98.         inc     ebx
  99.         jmp     .2
  100.  
  101. do_resume:
  102.         mov     bl, [CURRENT_TASK+eax+TASKDATA.state]
  103.         cmp     bl, 1
  104.         jz      .1
  105.         cmp     bl, 2
  106.         jnz     .ret
  107.         mov     bl, 5
  108. .2:     mov     [CURRENT_TASK+eax+TASKDATA.state], bl
  109. .ret:   ret
  110. .1:     dec     ebx
  111.         jmp     .2
  112.  
  113. debug_resume:
  114. ; in: ebx=pid
  115. ; destroys eax,ebx
  116.         cli
  117.         mov     eax, ebx
  118.         call    pid_to_slot
  119.         shl     eax, 5
  120.         jz      .ret
  121.         call    do_resume
  122. .ret:   sti
  123.         ret
  124.  
  125. debug_getcontext:
  126. ; in:
  127. ; ebx=pid
  128. ; ecx=sizeof(CONTEXT)
  129. ; edx->CONTEXT
  130. ; destroys eax,ecx,edx,esi,edi
  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
  141.         mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
  142.         lea esi, [eax+RING0_STACK_SIZE]
  143.         mov     edi, edx
  144. .ring0:
  145. ; note that following code assumes that all interrupt/exception handlers
  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
  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.         lodsd                     ;eip
  165.         mov     [edi], eax
  166.         lodsd                     ;cs
  167.         lodsd                     ;eflags
  168.         mov     [edi+4], eax
  169.         lodsd                     ;esp
  170.         mov     [edi+18h], eax
  171. .ret:
  172.         sti
  173.         ret
  174.  
  175. debug_setcontext:
  176. ; in:
  177. ; ebx=pid
  178. ; ecx=sizeof(CONTEXT)
  179. ; edx->CONTEXT
  180. ; destroys eax,ecx,edx,esi,edi
  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
  191.         mov eax, [eax*8+SLOT_BASE+APPDATA.pl0_stack]
  192.         lea edi, [eax+RING0_STACK_SIZE]
  193.         mov     esi, edx
  194. .ring0:
  195.         sub     edi, 8+12+20h
  196.         mov     eax, [esi+24h]    ;edi
  197.         stosd
  198.         mov     eax, [esi+20h]    ;esi
  199.         stosd
  200.         mov     eax, [esi+1Ch]    ;ebp
  201.         stosd
  202.         scasd
  203.         mov     eax, [esi+14h]    ;ebx
  204.         stosd
  205.         mov     eax, [esi+10h]    ;edx
  206.         stosd
  207.         mov     eax, [esi+0Ch]    ;ecx
  208.         stosd
  209.         mov     eax, [esi+8]      ;eax
  210.         stosd
  211.         mov     eax, [esi]        ;eip
  212.         stosd
  213.         scasd
  214.         mov     eax, [esi+4]      ;eflags
  215.         stosd
  216.         mov     eax, [esi+18h]    ;esp
  217.         stosd
  218. .stiret:
  219.         sti
  220. .ret:
  221.         ret
  222.  
  223. debug_set_drx:
  224.         call    get_debuggee_slot
  225.         jc      .errret
  226.         mov     ebp, eax
  227.         lea     eax, [eax*8+SLOT_BASE+APPDATA.dbg_regs]
  228. ; [eax]=dr0, [eax+4]=dr1, [eax+8]=dr2, [eax+C]=dr3
  229. ; [eax+10]=dr7
  230.         cmp     edx, OS_BASE
  231.         jae      .errret
  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
  241. ; clear breakpoint
  242.         movzx   ecx, cl
  243.         add     ecx, ecx
  244.         and     dword [eax+ecx*2], 0    ; clear DR<i>
  245.         btr     dword [eax+10h], ecx    ; clear L<i> bit
  246.         test    byte [eax+10h], 55h
  247.         jnz     .okret
  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
  251. .okret:
  252.         and     dword [esp+36], 0
  253.         sti
  254.         ret
  255. .errret:
  256.         sti
  257.         mov     dword [esp+36], 1
  258.         ret
  259. .errret2:
  260.         sti
  261.         mov     dword [esp+36], 2
  262.         ret
  263. .new:
  264. ; add new breakpoint
  265. ; cl=index; ch=flags; edx=address
  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<i> flag
  283.         add     ecx, ecx
  284.         mov     [eax+ecx], edx          ; set DR<i>
  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
  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
  294.         jmp     .okret
  295.  
  296. debug_read_process_memory:
  297. ; in:
  298. ; ebx=pid
  299. ; ecx=length
  300. ; esi->buffer in debugger
  301. ; edx=address in debuggee
  302. ; out: [esp+36]=sizeof(read)
  303. ; destroys all
  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
  318. .err:
  319.         or      dword [esp+36], -1
  320.         ret
  321.  
  322. debug_write_process_memory:
  323. ; in:
  324. ; ebx=pid
  325. ; ecx=length
  326. ; esi->buffer in debugger
  327. ; edx=address in debuggee
  328. ; out: [esp+36]=sizeof(write)
  329. ; destroys all
  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
  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
  352.         xchg    ebp, eax
  353.         mov     edi, [timer_ticks]
  354.         add     edi, 500        ; 5 sec timeout
  355. .1:
  356.         mov     eax, ebp
  357.         shl     eax, 8
  358.         mov     edx, [SLOT_BASE+eax+APPDATA.dbg_event_mem]
  359.         test    edx, edx
  360.         jz      .ret
  361. ; read buffer header
  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
  373. @@:
  374.         cmp     dword [ebx], 0
  375.         jg      @f
  376. .2:
  377.         pop     ecx
  378.         pop     ecx
  379.         pop     ecx
  380.         cmp     dword [CURRENT_TASK], 1
  381.         jnz     .notos
  382.         cmp     [timer_ticks], edi
  383.         jae     .ret
  384. .notos:
  385.         sti
  386.         call    change_task
  387.         cli
  388.         jmp     .1
  389. @@:
  390.         mov     ecx, [ebx+8]
  391.         add     ecx, [ebx+4]
  392.         cmp     ecx, [ebx]
  393.         ja      .2
  394. ; advance buffer position
  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
  402. ; write message
  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
  411. ; new debug event
  412.         mov     eax, ebp
  413.         shl     eax, 8
  414.         or      byte [SLOT_BASE+eax+APPDATA.event_mask+1], 1      ; set flag 100h
  415. .ret:
  416.         ret
  417.  
  418. debug_exc:
  419.         test    byte [esp+8+2], 2
  420.         jnz     v86_debug_exc
  421. ; int 1 = #DB
  422.         save_ring3_context
  423.         cld
  424.         mov     ax, app_data ;os_data
  425.         mov     ds, ax
  426.         mov     es, ax
  427.         mov     eax, dr6
  428.         push    eax
  429.         xor     eax, eax
  430.         mov     dr6, eax
  431. ; test if debugging
  432.         cli
  433.         mov     eax, [current_slot]
  434.         mov     eax, [eax+APPDATA.debugger_slot]
  435.         test    eax, eax
  436.         jnz     .debug
  437.         sti
  438. ; not debuggee => say error and terminate
  439.         add     esp, 0x20+4
  440.         mov     [error_interrupt], 1
  441.         call    show_error_parameters
  442.         mov     edx, [TASK_BASE]
  443.         mov     byte [edx+TASKDATA.state], 4
  444.         jmp     change_task
  445. .debug:
  446. ; we are debugged process, notify debugger and suspend ourself
  447. ; eax=debugger PID
  448.         pop     edx
  449.         mov     ebx, dr7
  450.         mov     cl, not 1
  451. .l1:
  452.         test    bl, 1
  453.         jnz     @f
  454.         and     dl, cl
  455. @@:
  456.         shr     ebx, 2
  457.         add     cl, cl
  458.         inc     ecx
  459.         cmp     cl, not 10h
  460.         jnz     .l1
  461.         push    edx     ; DR6 image
  462.         mov     ecx, [TASK_BASE]
  463.         push    dword [ecx+TASKDATA.pid]        ; PID
  464.         push    12
  465.         pop     ecx
  466.         push    3       ; 3 = debug exception
  467.         call    debugger_notify
  468.         pop     ecx
  469.         pop     ecx
  470.         pop     ecx
  471.         mov     edx, [TASK_BASE]
  472.         mov     byte [edx+TASKDATA.state], 1    ; suspended
  473.         call    change_task
  474.         restore_ring3_context
  475.         iretd
  476.