stacktrace.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. /*
  2. * Stack trace support for Microblaze.
  3. *
  4. * Copyright (C) 2009 Michal Simek <monstr@monstr.eu>
  5. * Copyright (C) 2009 PetaLogix
  6. *
  7. * This file is subject to the terms and conditions of the GNU General Public
  8. * License. See the file "COPYING" in the main directory of this archive
  9. * for more details.
  10. */
  11. #include <linux/sched.h>
  12. #include <linux/stacktrace.h>
  13. #include <linux/thread_info.h>
  14. #include <linux/ptrace.h>
  15. #include <linux/module.h>
  16. /* FIXME initial support */
  17. void save_stack_trace(struct stack_trace *trace)
  18. {
  19. unsigned long *sp;
  20. unsigned long addr;
  21. asm("addik %0, r1, 0" : "=r" (sp));
  22. while (!kstack_end(sp)) {
  23. addr = *sp++;
  24. if (__kernel_text_address(addr)) {
  25. if (trace->skip > 0)
  26. trace->skip--;
  27. else
  28. trace->entries[trace->nr_entries++] = addr;
  29. if (trace->nr_entries >= trace->max_entries)
  30. break;
  31. }
  32. }
  33. }
  34. EXPORT_SYMBOL_GPL(save_stack_trace);
  35. void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace)
  36. {
  37. unsigned int *sp;
  38. unsigned long addr;
  39. struct thread_info *ti = task_thread_info(tsk);
  40. if (tsk == current)
  41. asm("addik %0, r1, 0" : "=r" (sp));
  42. else
  43. sp = (unsigned int *)ti->cpu_context.r1;
  44. while (!kstack_end(sp)) {
  45. addr = *sp++;
  46. if (__kernel_text_address(addr)) {
  47. if (trace->skip > 0)
  48. trace->skip--;
  49. else
  50. trace->entries[trace->nr_entries++] = addr;
  51. if (trace->nr_entries >= trace->max_entries)
  52. break;
  53. }
  54. }
  55. }
  56. EXPORT_SYMBOL_GPL(save_stack_trace_tsk);