Subversion Repositories Kolibri OS

Rev

Rev 427 | Blame | Last modification | View Log | Download | RSS feed

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