stacktrace.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. /*
  2. * Stack trace management functions
  3. *
  4. * Copyright (C) 2007 Atmel Corporation
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. */
  10. #include <linux/sched.h>
  11. #include <linux/sched/task_stack.h>
  12. #include <linux/stacktrace.h>
  13. #include <linux/thread_info.h>
  14. #include <linux/module.h>
  15. register unsigned long current_frame_pointer asm("r7");
  16. struct stackframe {
  17. unsigned long lr;
  18. unsigned long fp;
  19. };
  20. /*
  21. * Save stack-backtrace addresses into a stack_trace buffer.
  22. */
  23. void save_stack_trace(struct stack_trace *trace)
  24. {
  25. unsigned long low, high;
  26. unsigned long fp;
  27. struct stackframe *frame;
  28. int skip = trace->skip;
  29. low = (unsigned long)task_stack_page(current);
  30. high = low + THREAD_SIZE;
  31. fp = current_frame_pointer;
  32. while (fp >= low && fp <= (high - 8)) {
  33. frame = (struct stackframe *)fp;
  34. if (skip) {
  35. skip--;
  36. } else {
  37. trace->entries[trace->nr_entries++] = frame->lr;
  38. if (trace->nr_entries >= trace->max_entries)
  39. break;
  40. }
  41. /*
  42. * The next frame must be at a higher address than the
  43. * current frame.
  44. */
  45. low = fp + 8;
  46. fp = frame->fp;
  47. }
  48. }
  49. EXPORT_SYMBOL_GPL(save_stack_trace);