Subversion Repositories Kolibri OS

Rev

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