summaryrefslogtreecommitdiff
path: root/macho64/atrace.s
diff options
context:
space:
mode:
Diffstat (limited to 'macho64/atrace.s')
-rw-r--r--macho64/atrace.s474
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 */