diff options
Diffstat (limited to 'macho64/atrace.s')
-rw-r--r-- | macho64/atrace.s | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/macho64/atrace.s b/macho64/atrace.s new file mode 100644 index 0000000..4f9bf6d --- /dev/null +++ b/macho64/atrace.s @@ -0,0 +1,474 @@ + + .text + + .globl init_profiler + .globl profile_r + .globl profile_l + .globl profile_l2 + .globl profile_n + .globl profile_n2 + .globl profile_s + .globl profile_s2 + .globl profile_t + .globl write_profile_stack + .globl stack_trace_depth + + .if ! LINUX + .globl allocate_memory + .endif + .globl __STRING__ + .globl _ab_stack_size + .globl _ew_print_string + .globl _ew_print_char + .globl _ew_print_text +/* .globl print_error */ +/* .globl profile_stack_pointer */ + +next = 0 +name_ = 8 +FunctionProfile = 16 + +profile_t: + sub qword ptr profile_stack_pointer[rip],8 + ret + +profile_r: + sub qword ptr profile_stack_pointer[rip],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[rip] + + mov qword ptr [rbp],rbx + add rbp,8 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_l: + call allocate_function_profile_record + att_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[rip] + + mov qword ptr [rbp],rbx + mov qword ptr 8[rbp],rbx + add rbp,16 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_l2: + att_call allocate_function_profile_record + att_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[rip] + + mov qword ptr [rbp],rbx + add rbp,8 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_n: + att_call allocate_function_profile_record + att_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[rip] + + mov qword ptr [rbp],rbx + mov qword ptr 8[rbp],rbx + add rbp,16 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_n2: + att_call allocate_function_profile_record + att_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[rip] + + mov qword ptr [rbp],rbx + mov qword ptr 8[rbp],rbx + add rbp,16 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_s2: + att_call allocate_function_profile_record + att_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[rip] + + mov qword ptr [rbp],rbx + add rbp,8 + mov qword ptr profile_stack_pointer[rip],rbp + + pop rbx + ret + +allocate_function_profile_record_s: + att_call allocate_function_profile_record + att_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[rip] + mov rbx,qword ptr global_last_allocated_block[rip] + + test rax,rax + jne no_alloc + + push rcx + push rdx + push rbp + + .if 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 + .if LINUX + mov rdi,8192 + /* 512*FunctionProfile */ + att_call _malloc + .else + mov rcx,512*FunctionProfile + call allocate_memory + .endif + mov rsp,rbp + + .if 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[rip],rbx + +no_alloc: + dec rax + mov qword ptr global_n_free_records_in_block[rip],rax + lea rax,FunctionProfile[rbx] + mov qword ptr global_last_allocated_block[rip],rax + + mov rax,qword ptr global_profile_records[rip] + mov qword ptr name_[rbx],rbp + + mov qword ptr next[rbx],rax + mov qword ptr global_profile_records[rip],rbx + + mov qword ptr [rbp],rbx + pop rax + ret + +no_memory: + lea rbp,not_enough_memory_for_profiler[rip] + pop rax + att_jmp print_error + +write_profile_stack: + .if LINUX + mov r13,rsi + mov r14,rdi + .endif + mov rax,qword ptr profile_stack_pointer[rip] + + test rax,rax + je stack_not_initialised + + push rax + + mov rbp,rsp + sub rsp,40 + and rsp,-16 + .if LINUX + lea rdi,stack_trace_string[rip] + .else + lea rcx,stack_trace_string + .endif + att_call _ew_print_string + mov rsp,rbp + + pop rax + +/* mov rbp,12 */ + mov rbp,qword ptr stack_trace_depth[rip] +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 + + .if LINUX + movsx rdx,dword ptr (-4)[rcx] + lea rdx,-4[rcx+rdx] + lea rdi,8[rcx] + mov r12,rdx + .else + mov edx,dword ptr (-4)[rcx] + add rcx,8 + + mov r12d,dword ptr [rdx] + lea r13,4[rdx] + .endif + + mov rbp,rsp + sub rsp,40 + and rsp,-16 + + att_call _ew_print_string + + .if LINUX + lea rdi,module_string[rip] + .else + lea rcx,module_string + .endif + att_call _ew_print_string + + .if LINUX + mov esi,dword ptr [r12] + lea rdi,4[r12] + .else + mov rdx,r12 + mov rcx,r13 + .endif + att_call _ew_print_text + + .if LINUX + mov rdi,'] + .else + mov rcx,'] + .endif + att_call _ew_print_char + + .if LINUX + mov rdi,10 + .else + mov rcx,10 + .endif + att_call _ew_print_char + + mov rsp,rbp + + pop rbp + pop rax + + sub rbp,1 + att_jne write_functions_on_stack + +end_profile_stack: +stack_not_initialised: + .if LINUX + mov rsi,r13 + mov rdi,r14 + .endif + ret + +init_profiler: + mov rbp,rsp + sub rsp,40 + and rsp,-16 + .if LINUX + mov r13,rsi + mov r14,rdi + mov rdi,qword ptr _ab_stack_size[rip] + att_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[rip] + att_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[rip],rdx + ret + +init_profiler_error: + mov qword ptr profile_stack_pointer[rip],0 + lea rbp,not_enough_memory_for_profile_stack[rip] + att_jmp print_error + + + + .data + + .align 8 + +global_n_free_records_in_block: + .quad 0 +/* 0 n free records in block */ +global_last_allocated_block: + .quad 0 +/* 8 latest allocated block */ +global_profile_records: + .quad 0 +/* 16 profile record list */ + +stack_trace_depth: + .quad 12 + .align 8 + +/* m_system also defined in istartup.s */ +/* +m_system: + .quad 6 + .ascii "System" + .byte 0 + .byte 0 +*/ + .long m_system-. +start_string: + .quad 0 + .ascii "start" + .byte 0 + .align 8 +not_enough_memory_for_profile_stack: + .ascii "not enough memory for profile stack" + .byte 10 + .byte 0 +not_enough_memory_for_profiler: + .ascii "not enough memory for profiler" + .byte 10 + .byte 0 +stack_trace_string: + .ascii "Stack trace:" + .byte 10 + .byte 0 +module_string: + .ascii " [module: " + .byte 0 + .align 8 + + + +/* end */ |