1c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker/* 2c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker * Copyright (C) 1991, 1992 Linus Torvalds 3c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker * Copyright (C) 2000, 2001, 2002 Andi Kleen, SuSE Labs 4c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker */ 5c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 61965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#ifndef _ASM_X86_STACKTRACE_H 71965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#define _ASM_X86_STACKTRACE_H 8c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen 9c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#include <linux/uaccess.h> 109c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen#include <linux/ptrace.h> 11c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 120741f4d207a644482d7a040f05cd264c98cf7ee8Chuck Ebbertextern int kstack_depth_to_print; 130741f4d207a644482d7a040f05cd264c98cf7ee8Chuck Ebbert 1461c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbeckerstruct thread_info; 1561c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbeckerstruct stacktrace_ops; 1661c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker 1761c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbeckertypedef unsigned long (*walk_stack_t)(struct thread_info *tinfo, 1861c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker unsigned long *stack, 1961c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker unsigned long bp, 2061c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker const struct stacktrace_ops *ops, 2161c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker void *data, 2261c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker unsigned long *end, 2361c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker int *graph); 2461c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker 2561c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbeckerextern unsigned long 2661c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbeckerprint_context_stack(struct thread_info *tinfo, 2761c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker unsigned long *stack, unsigned long bp, 2861c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker const struct stacktrace_ops *ops, void *data, 2961c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker unsigned long *end, int *graph); 3061c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker 3106d65bda75341485d32f33da474b0664819ad497Frederic Weisbeckerextern unsigned long 3206d65bda75341485d32f33da474b0664819ad497Frederic Weisbeckerprint_context_stack_bp(struct thread_info *tinfo, 3306d65bda75341485d32f33da474b0664819ad497Frederic Weisbecker unsigned long *stack, unsigned long bp, 3406d65bda75341485d32f33da474b0664819ad497Frederic Weisbecker const struct stacktrace_ops *ops, void *data, 3506d65bda75341485d32f33da474b0664819ad497Frederic Weisbecker unsigned long *end, int *graph); 3606d65bda75341485d32f33da474b0664819ad497Frederic Weisbecker 37c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen/* Generic stack tracer with callbacks */ 38c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen 39c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleenstruct stacktrace_ops { 40bc850d6b374fffd08336996f4b4d3bbd6bf427f6Arjan van de Ven void (*address)(void *data, unsigned long address, int reliable); 41c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen /* On negative return stop dumping */ 42c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen int (*stack)(void *data, char *name); 4361c1917f47f73c968e92d04d15370b1dc3ec4592Frederic Weisbecker walk_stack_t walk_stack; 44c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen}; 45c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen 46bc850d6b374fffd08336996f4b4d3bbd6bf427f6Arjan van de Venvoid dump_trace(struct task_struct *tsk, struct pt_regs *regs, 47e8e999cf3cc733482e390b02ff25a64cecdc0b64Namhyung Kim unsigned long *stack, unsigned long bp, 489689ba8ad0dc27c0a2ce40eb4c0f8fb66551119cJan Beulich const struct stacktrace_ops *ops, void *data); 49c0b766f13d8e1189ce4d00e54700c9d96b543b9aAndi Kleen 50c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#ifdef CONFIG_X86_32 51c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#define STACKSLOTS_PER_LINE 8 52c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#define get_bp(bp) asm("movl %%ebp, %0" : "=r" (bp) :) 53c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#else 54c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#define STACKSLOTS_PER_LINE 4 55c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#define get_bp(bp) asm("movq %%rbp, %0" : "=r" (bp) :) 56c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#endif 57c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 589c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen#ifdef CONFIG_FRAME_POINTER 599c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersenstatic inline unsigned long 609c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersenstack_frame(struct task_struct *task, struct pt_regs *regs) 619c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen{ 629c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen unsigned long bp; 639c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen 649c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen if (regs) 659c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen return regs->bp; 669c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen 679c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen if (task == current) { 689c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen /* Grab bp right from our regs */ 699c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen get_bp(bp); 709c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen return bp; 719c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen } 729c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen 739c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen /* bp is the last reg pushed by switch_to */ 749c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen return *(unsigned long *)task->thread.sp; 759c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen} 769c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen#else 779c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersenstatic inline unsigned long 789c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersenstack_frame(struct task_struct *task, struct pt_regs *regs) 799c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen{ 809c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen return 0; 819c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen} 829c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen#endif 839c0729dc8062bed96189bd14ac6d4920f3958743Soeren Sandmann Pedersen 84c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckerextern void 85c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckershow_trace_log_lvl(struct task_struct *task, struct pt_regs *regs, 86e8e999cf3cc733482e390b02ff25a64cecdc0b64Namhyung Kim unsigned long *stack, unsigned long bp, char *log_lvl); 87c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 88c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckerextern void 89c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckershow_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, 90e8e999cf3cc733482e390b02ff25a64cecdc0b64Namhyung Kim unsigned long *sp, unsigned long bp, char *log_lvl); 91c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 92c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckerextern unsigned int code_bytes; 93c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 94c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker/* The form of the top of the frame on the stack */ 95c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckerstruct stack_frame { 96c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker struct stack_frame *next_frame; 97c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker unsigned long return_address; 98c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker}; 99c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 100c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbeckerstruct stack_frame_ia32 { 101c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker u32 next_frame; 102c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker u32 return_address; 103c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker}; 104c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 105b0f82b81fe6bbcf78d478071f33e44554726bc81Frederic Weisbeckerstatic inline unsigned long caller_frame_pointer(void) 106c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker{ 107c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker struct stack_frame *frame; 108c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 109c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker get_bp(frame); 110c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 111c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#ifdef CONFIG_FRAME_POINTER 112b0f82b81fe6bbcf78d478071f33e44554726bc81Frederic Weisbecker frame = frame->next_frame; 113c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker#endif 114c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 115c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker return (unsigned long)frame; 116c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker} 117c9cf4dbb4d9ca715d8fedf13301a53296429abc6Frederic Weisbecker 1181965aae3c98397aad957412413c07e97b1bd4e64H. Peter Anvin#endif /* _ASM_X86_STACKTRACE_H */ 119