summaryrefslogtreecommitdiff
path: root/atrace.asm
diff options
context:
space:
mode:
Diffstat (limited to 'atrace.asm')
-rw-r--r--atrace.asm442
1 files changed, 442 insertions, 0 deletions
diff --git a/atrace.asm b/atrace.asm
new file mode 100644
index 0000000..b56ffe0
--- /dev/null
+++ b/atrace.asm
@@ -0,0 +1,442 @@
+
+_TEXT segment para 'CODE'
+_TEXT ends
+_DATA segment para 'DATA'
+_DATA ends
+
+ _TEXT segment
+
+ public init_profiler
+ public profile_r
+ public profile_l
+ public profile_l2
+ public profile_n
+ public profile_n2
+ public profile_s
+ public profile_s2
+ public profile_t
+ public write_profile_stack
+ public stack_trace_depth
+
+ ifndef LINUX
+ extrn allocate_memory:near
+ endif
+ extrn __STRING__:near
+ extrn ab_stack_size:near
+ extrn ew_print_string:near
+ extrn ew_print_char:near
+ extrn ew_print_text:near
+; extrn print_error:near
+; extrn profile_stack_pointer:near
+
+next = 0
+name_ = 8
+FunctionProfile = 16
+
+profile_t:
+ sub qword ptr profile_stack_pointer,8
+ ret
+
+profile_r:
+ sub qword ptr profile_stack_pointer,8
+ ret
+
+profile_l:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_l
+allocate_function_profile_record_lr:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ add rbp,8
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_l:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_lr
+
+profile_l2:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_l2
+allocate_function_profile_record_l2r:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ mov qword ptr 8[rbp],rbx
+ add rbp,16
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_l2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_l2r
+
+profile_n:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_n
+allocate_function_profile_record_nr:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ add rbp,8
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_n:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_nr
+
+profile_n2:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_n2
+allocate_function_profile_record_n2r:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ mov qword ptr 8[rbp],rbx
+ add rbp,16
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_n2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_n2r
+
+profile_s2:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_s2
+allocate_function_profile_record_s2r:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ mov qword ptr 8[rbp],rbx
+ add rbp,16
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_s2:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_s2r
+
+profile_s:
+ push rbx
+ mov rbx,qword ptr [rbp]
+
+ test rbx,rbx
+ je allocate_function_profile_record_s
+allocate_function_profile_record_sr:
+ mov rbp,qword ptr profile_stack_pointer
+
+ mov qword ptr [rbp],rbx
+ add rbp,8
+ mov qword ptr profile_stack_pointer,rbp
+
+ pop rbx
+ ret
+
+allocate_function_profile_record_s:
+ call allocate_function_profile_record
+ jmp allocate_function_profile_record_sr
+
+; argument: rbp: function name adress-4
+; result: rbx: function profile record adress
+
+allocate_function_profile_record:
+ push rax
+ mov rax,qword ptr global_n_free_records_in_block
+ mov rbx,qword ptr global_last_allocated_block
+
+ test rax,rax
+ jne no_alloc
+
+ push rcx
+ push rdx
+ push rbp
+
+ ifdef LINUX
+ sub rsp,104
+ mov qword ptr [rsp],rsi
+ mov qword ptr 8[rsp],rdi
+ mov qword ptr 16[rsp],r8
+ mov qword ptr 24[rsp],r10
+ mov qword ptr 32[rsp],r11
+ movsd qword ptr 40[rsp],xmm0
+ movsd qword ptr 48[rsp],xmm1
+ movsd qword ptr 56[rsp],xmm2
+ movsd qword ptr 64[rsp],xmm3
+ movsd qword ptr 72[rsp],xmm4
+ movsd qword ptr 80[rsp],xmm5
+ movsd qword ptr 88[rsp],xmm6
+ movsd qword ptr 96[rsp],xmm7
+ else
+ sub rsp,72
+ mov qword ptr [rsp],r8
+ mov qword ptr 8[rsp],r10
+ mov qword ptr 16[rsp],r11
+ movsd qword ptr 24[rsp],xmm0
+ movsd qword ptr 32[rsp],xmm1
+ movsd qword ptr 40[rsp],xmm2
+ movsd qword ptr 48[rsp],xmm3
+ movsd qword ptr 56[rsp],xmm4
+ movsd qword ptr 64[rsp],xmm5
+ endif
+
+ mov rbp,rsp
+ sub rsp,40
+ and rsp,-16
+ ifdef LINUX
+ mov rdi,8192
+ ; 512*FunctionProfile
+ call malloc
+ else
+ mov rcx,512*FunctionProfile
+ call allocate_memory
+ endif
+ mov rsp,rbp
+
+ ifdef LINUX
+ mov rsi,qword ptr [rsp]
+ mov rdi,qword ptr 8[rsp]
+ mov r8,qword ptr 16[rsp]
+ mov r10,qword ptr 24[rsp]
+ mov r11,qword ptr 32[rsp]
+ movlpd xmm0,qword ptr 40[rsp]
+ movlpd xmm1,qword ptr 48[rsp]
+ movlpd xmm2,qword ptr 56[rsp]
+ movlpd xmm3,qword ptr 64[rsp]
+ movlpd xmm4,qword ptr 72[rsp]
+ movlpd xmm5,qword ptr 80[rsp]
+ movlpd xmm6,qword ptr 88[rsp]
+ movlpd xmm7,qword ptr 96[rsp]
+ add rsp,104
+ else
+ mov r8,qword ptr [rsp]
+ mov r10,qword ptr 8[rsp]
+ mov r11,qword ptr 16[rsp]
+ movlpd xmm0,qword ptr 24[rsp]
+ movlpd xmm1,qword ptr 32[rsp]
+ movlpd xmm2,qword ptr 40[rsp]
+ movlpd xmm3,qword ptr 48[rsp]
+ movlpd xmm4,qword ptr 56[rsp]
+ movlpd xmm5,qword ptr 64[rsp]
+ add rsp,72
+ endif
+
+ test rax,rax
+
+ pop rbp
+ pop rdx
+ pop rcx
+
+ je no_memory
+
+ mov rbx,rax
+ mov rax,512
+ mov qword ptr global_last_allocated_block,rbx
+
+no_alloc:
+ dec rax
+ mov qword ptr global_n_free_records_in_block,rax
+ lea rax,FunctionProfile[rbx]
+ mov qword ptr global_last_allocated_block,rax
+
+ mov rax,qword ptr global_profile_records
+ mov qword ptr name_[rbx],rbp
+
+ mov qword ptr next[rbx],rax
+ mov qword ptr global_profile_records,rbx
+
+ mov qword ptr [rbp],rbx
+ pop rax
+ ret
+
+no_memory:
+ lea rbp,not_enough_memory_for_profiler
+ pop rax
+ jmp print_error
+
+write_profile_stack:
+ mov rax,qword ptr profile_stack_pointer
+
+ test rax,rax
+ je stack_not_initialised
+
+ push rax
+
+ mov rbp,rsp
+ sub rsp,40
+ and rsp,-16
+ lea rcx,stack_trace_string
+ call ew_print_string
+ mov rsp,rbp
+
+ pop rax
+
+; mov rbp,12
+ mov rbp,qword ptr stack_trace_depth
+write_functions_on_stack:
+ mov rbx,qword ptr (-8)[rax]
+ sub rax,8
+
+ test rbx,rbx
+ je end_profile_stack
+
+ push rax
+ mov rcx,qword ptr name_[rbx]
+
+ push rbp
+
+ mov edx,dword ptr (-4)[rcx]
+ add rcx,8
+
+ mov r12d,dword ptr [rdx]
+ lea r13,4[rdx]
+
+ mov rbp,rsp
+ sub rsp,40
+ and rsp,-16
+
+ call ew_print_string
+
+ lea rcx,module_string
+ call ew_print_string
+
+ mov rdx,r12
+ mov rcx,r13
+ call ew_print_text
+
+ mov rcx,']'
+ call ew_print_char
+
+ mov rcx,10
+ call ew_print_char
+
+ mov rsp,rbp
+
+ pop rbp
+ pop rax
+
+ sub rbp,1
+ jne write_functions_on_stack
+
+end_profile_stack:
+stack_not_initialised:
+ ret
+
+init_profiler:
+ mov rbp,rsp
+ sub rsp,40
+ and rsp,-16
+ ifdef LINUX
+ mov r13,rsi
+ mov r14,rdi
+ mov rdi,qword ptr ab_stack_size
+ call malloc
+ mov rsi,r13
+ mov rdi,r14
+ else
+ mov rcx,qword ptr ab_stack_size
+ call allocate_memory
+ endif
+ mov rsp,rbp
+
+ test rax,rax
+ je init_profiler_error
+
+ push rax
+
+ lea rbp,start_string
+ call allocate_function_profile_record
+
+ pop rdx
+
+ mov qword ptr 8[rdx],rbx
+ mov qword ptr [rdx],0
+ add rdx,16
+ mov qword ptr profile_stack_pointer,rdx
+ ret
+
+init_profiler_error:
+ mov qword ptr profile_stack_pointer,0
+ lea rbp,not_enough_memory_for_profile_stack
+ jmp print_error
+
+_TEXT ends
+
+ _DATA segment
+
+ align (1 shl 3)
+
+global_n_free_records_in_block:
+ dq 0
+; 0 n free records in block
+global_last_allocated_block:
+ dq 0
+; 8 latest allocated block
+global_profile_records:
+ dq 0
+; 16 profile record list
+
+stack_trace_depth:
+ dq 12
+ align (1 shl 3)
+
+; m_system also defined in istartup.s
+; m_system:
+; dq 6
+; db "System"
+; db 0
+; db 0
+
+ dd m_system
+start_string:
+ dq 0
+ db "start"
+ db 0
+ align (1 shl 3)
+not_enough_memory_for_profile_stack:
+ db "not enough memory for profile stack"
+ db 10
+ db 0
+not_enough_memory_for_profiler:
+ db "not enough memory for profiler"
+ db 10
+ db 0
+stack_trace_string:
+ db "Stack trace:"
+ db 10
+ db 0
+module_string:
+ db " [module: "
+ db 0
+ align (1 shl 3)
+
+_DATA ends
+
+; end