00001 #ifndef _STACK_C_
00002 #define _STACK_C_
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "sym.c"
00014
00015 static int (*_stp_kta)(unsigned long addr)=(void *)KTA;
00016
00017 #ifdef __x86_64__
00018 static void __stp_stack_print (unsigned long *stack, int verbose, int levels)
00019 {
00020 unsigned long addr;
00021
00022 if (verbose)
00023 _stp_print ("trace for %d (%s)\n", current->pid, current->comm);
00024
00025 while (((long) stack & (THREAD_SIZE-1)) != 0) {
00026 addr = *stack++;
00027 if (_stp_kta(addr)) {
00028 if (verbose)
00029 _stp_symbol_print (addr);
00030 else
00031 _stp_print ("0x%lx ", addr);
00032 }
00033 }
00034 _stp_print_str ("\n");
00035 }
00036
00037
00038 static char *__stp_stack_sprint (unsigned long *stack, int verbose, int levels)
00039 {
00040 unsigned long addr;
00041 char *ptr = _stp_scbuf_cur();
00042 while (((long) stack & (THREAD_SIZE-1)) != 0) {
00043 addr = *stack++;
00044 if (_stp_kta(addr)) {
00045 if (verbose)
00046 _stp_symbol_sprint (addr);
00047 else
00048 _stp_sprint ("0x%lx ", addr);
00049 }
00050 }
00051 return ptr;
00052 }
00053
00054 #else
00055
00056 static inline int valid_stack_ptr (struct thread_info *tinfo, void *p)
00057 {
00058 return p > (void *)tinfo &&
00059 p < (void *)tinfo + THREAD_SIZE - 3;
00060 }
00061
00062 static inline unsigned long _stp_print_context_stack (
00063 struct thread_info *tinfo,
00064 unsigned long *stack,
00065 unsigned long ebp )
00066 {
00067 unsigned long addr;
00068
00069 #ifdef CONFIG_FRAME_POINTER
00070 while (valid_stack_ptr(tinfo, (void *)ebp)) {
00071 addr = *(unsigned long *)(ebp + 4);
00072 _stp_symbol_print (addr);
00073 _stp_print_str("\n");
00074 ebp = *(unsigned long *)ebp;
00075 }
00076 #else
00077 while (valid_stack_ptr(tinfo, stack)) {
00078 addr = *stack++;
00079 if (_stp_kta (addr)) {
00080 _stp_symbol_print (addr);
00081 _stp_print_str ("\n");
00082 }
00083 }
00084 #endif
00085 return ebp;
00086 }
00087
00088 static inline unsigned long _stp_sprint_context_stack (
00089 struct thread_info *tinfo,
00090 unsigned long *stack,
00091 unsigned long ebp )
00092 {
00093 unsigned long addr;
00094
00095 #ifdef CONFIG_FRAME_POINTER
00096 while (valid_stack_ptr(tinfo, (void *)ebp)) {
00097 addr = *(unsigned long *)(ebp + 4);
00098 _stp_symbol_sprint (addr);
00099 _stp_sprint_str("\n");
00100 ebp = *(unsigned long *)ebp;
00101 }
00102 #else
00103 while (valid_stack_ptr(tinfo, stack)) {
00104 addr = *stack++;
00105 if (_stp_kta (addr)) {
00106 _stp_symbol_sprint (addr);
00107 _stp_sprint_str ("\n");
00108 }
00109 }
00110 #endif
00111 return ebp;
00112 }
00113
00114 static void __stp_stack_print (unsigned long *stack, int verbose, int levels)
00115 {
00116 unsigned long ebp;
00117
00118
00119 asm ("movl %%ebp, %0" : "=r" (ebp) : );
00120
00121 while (stack) {
00122 struct thread_info *context = (struct thread_info *)
00123 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00124 ebp = _stp_print_context_stack (context, stack, ebp);
00125 stack = (unsigned long*)context->previous_esp;
00126 }
00127 }
00128
00129 static void __stp_stack_sprint (unsigned long *stack, int verbose, int levels)
00130 {
00131 unsigned long ebp;
00132
00133
00134 asm ("movl %%ebp, %0" : "=r" (ebp) : );
00135
00136 while (stack) {
00137 struct thread_info *context = (struct thread_info *)
00138 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
00139 ebp = _stp_sprint_context_stack (context, stack, ebp);
00140 stack = (unsigned long*)context->previous_esp;
00141 }
00142 }
00143
00144 #endif
00145
00146 void _stp_stack_print (int verbose, int levels)
00147 {
00148 unsigned long stack;
00149 return __stp_stack_print (&stack, verbose, levels);
00150 }
00151
00152 char *_stp_stack_sprint (int verbose, int levels)
00153 {
00154 unsigned long stack;
00155 char *ptr = _stp_scbuf_cur();
00156 __stp_stack_sprint (&stack, verbose, levels);
00157 return ptr;
00158 }
00159
00160
00161 #endif