Subversion Repositories Kolibri OS

Rev

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

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