diff options
Diffstat (limited to 'atrace.asm')
-rw-r--r-- | atrace.asm | 442 |
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 |