kolibrios-gitea/kernel/trunk/core/debug.inc

348 lines
5.8 KiB
PHP
Raw Normal View History

; this code uses following additions to system structures:
; in additional app info at 80000..8FFFF:
; AC (dword) 0 or debugger slot
; BC (dword) address of debug event memory
; new process slot state:
; 1 = suspended
; 2 = suspended waiting for event
; new event: 8 (and new possible bitflag for A8 in additional app info)
; diamond, 2006
sys_debug_services:
cmp eax, 8
ja @f
jmp dword [sys_debug_services_table+eax*4]
@@: ret
sys_debug_services_table:
dd debug_set_event_data
dd debug_getcontext
dd debug_setcontext
dd debug_detach
dd debug_suspend
dd debug_resume
dd debug_read_process_memory
dd debug_write_process_memory
dd debug_terminate
debug_set_event_data:
; in: ebx = pointer
; destroys eax
mov eax, [0x3000]
shl eax, 8
mov [eax+0x80000+0xBC], ebx
ret
get_debuggee_slot:
; in: ebx=PID
; out: CF=1 if error
; CF=0 and eax=slot*0x20 if ok
; out: interrupts disabled
cli
mov eax, ebx
call pid_to_slot
test eax, eax
jz .ret_bad
shl eax, 5
push ebx
mov ebx, [0x3000]
cmp [0x80000+eax*8+0xAC], ebx
pop ebx
jnz .ret_bad
; clc ; automatically
ret
.ret_bad:
stc
ret
debug_detach:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
and dword [eax*8+0x80000+0xAC], 0
call do_resume
.ret:
sti
ret
debug_terminate:
; in: ebx=pid
call get_debuggee_slot
jc debug_detach.ret
mov ebx, eax
shr ebx, 5
push 2
pop eax
jmp sys_system
debug_suspend:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
mov bl, [0x3000+eax+0xA] ; process state
test bl, bl
jz .1
cmp bl, 5
jnz .ret
mov bl, 2
.2: mov [0x3000+eax+0xA], bl
.ret:
sti
ret
.1:
inc ebx
jmp .2
do_resume:
mov bl, [0x3000+eax+0xA]
cmp bl, 1
jz .1
cmp bl, 2
jnz .ret
mov bl, 5
.2: mov [0x3000+eax+0xA], bl
.ret: ret
.1: dec ebx
jmp .2
debug_resume:
; in: ebx=pid
; destroys eax,ebx
call get_debuggee_slot
jc .ret
call do_resume
.ret: sti
ret
debug_getcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .ret
imul eax, tss_step/32
add eax, tss_data
mov edi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea esi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .ret
.ring0:
; note that following code assumes that all interrupt/exception handlers
; saves ring-3 context by push ds es, pushad in this order
mov esi, [l.esp0 - tss_sceleton + eax]
; top of ring0 stack: ring3 stack ptr (ss+esp), iret data (cs+eip+eflags), ds, es, pushad
sub esi, 8+12+8+20h
lodsd
mov [edi+24h], eax
lodsd
mov [edi+20h], eax
lodsd
mov [edi+1Ch], eax
lodsd
lodsd
mov [edi+14h], eax
lodsd
mov [edi+10h], eax
lodsd
mov [edi+0Ch], eax
lodsd
mov [edi+8], eax
add esi, 8
lodsd
mov [edi], eax
lodsd
lodsd
mov [edi+4], eax
lodsd
mov [edi+18h], eax
.ret:
sti
ret
debug_setcontext:
; in:
; ebx=pid
; ecx=sizeof(CONTEXT)
; edx->CONTEXT
; destroys eax,ecx,edx,esi,edi
cmp ecx, 28h
jnz .ret
add edx, std_application_base_address
push ebx
mov ebx, edx
call check_region
pop ebx
dec eax
jnz .ret
call get_debuggee_slot
jc .stiret
imul eax, tss_step/32
add eax, tss_data
mov esi, edx
cmp [l.cs - tss_sceleton + eax], app_code
jnz .ring0
lea edi, [l.eip - tss_sceleton + eax]
shr ecx, 2
rep movsd
jmp .stiret
.ring0:
mov edi, [l.esp0 - tss_sceleton + eax]
sub edi, 8+12+8+20h
mov eax, [esi+24h]
stosd
mov eax, [esi+20h]
stosd
mov eax, [esi+1Ch]
stosd
scasd
mov eax, [esi+14h]
stosd
mov eax, [esi+10h]
stosd
mov eax, [esi+0Ch]
stosd
mov eax, [esi+8]
stosd
add edi, 8
mov eax, [esi]
stosd
scasd
mov eax, [esi+4]
stosd
mov eax, [esi+18h]
stosd
.stiret:
sti
.ret:
ret
debug_read_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(read)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz .err
call get_debuggee_slot
jc .err
shr eax, 5
mov ebx, esi
call read_process_memory
sti
mov dword [esp+36], eax
ret
.err:
or dword [esp+36], -1
ret
debug_write_process_memory:
; in:
; ebx=pid
; ecx=length
; esi->buffer in debugger
; edx=address in debuggee
; out: [esp+36]=sizeof(write)
; destroys all
add esi, std_application_base_address
push ebx
mov ebx, esi
call check_region
pop ebx
dec eax
jnz debug_read_process_memory.err
call get_debuggee_slot
jc debug_read_process_memory.err
shr eax, 5
mov ebx, esi
call write_process_memory
sti
mov [esp+36], eax
ret
debugger_notify:
; in: eax=debugger slot
; ecx=size of debug message
; [esp+4]..[esp+4+ecx]=message
; interrupts must be disabled!
; destroys all general registers
; interrupts remain disabled
mov ebp, eax
shl eax, 8
.1:
mov edx, [0x80000+eax+0xBC]
test edx, edx
jz .ret
; read buffer header
push ecx
push eax
push eax
mov eax, ebp
mov ebx, esp
mov ecx, 8
call read_process_memory
cmp eax, ecx
jz @f
add esp, 12
jmp .ret
@@:
cmp dword [ebx], 0
jg @f
.2:
pop ecx
pop ecx
pop ecx
sti
call change_task
cli
jmp .1
@@:
mov ecx, [ebx+8]
add ecx, [ebx+4]
cmp ecx, [ebx]
ja .2
; advance buffer position
push ecx
mov ecx, 4
sub ebx, ecx
mov eax, ebp
add edx, ecx
call write_process_memory
pop eax
; write message
mov eax, ebp
add edx, ecx
add edx, [ebx+8]
add ebx, 20
pop ecx
pop ecx
pop ecx
call write_process_memory
; new debug event
mov eax, ebp
shl eax, 8
or byte [0x80000+eax+0xA8+1], 1 ; set flag 100h
.ret:
ret