stacktrace.c 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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/stacktrace.h>
  12. #include <linux/thread_info.h>
  13. register unsigned long current_frame_pointer asm("r7");
  14. struct stackframe {
  15. unsigned long lr;
  16. unsigned long fp;
  17. };
  18. /*
  19. * Save stack-backtrace addresses into a stack_trace buffer.
  20. */
  21. void save_stack_trace(struct stack_trace *trace)
  22. {
  23. unsigned long low, high;
  24. unsigned long fp;
  25. struct stackframe *frame;
  26. int skip = trace->skip;
  27. low = (unsigned long)task_stack_page(current);
  28. high = low + THREAD_SIZE;
  29. fp = current_frame_pointer;
  30. while (fp >= low && fp <= (high - 8)) {
  31. frame = (struct stackframe *)fp;
  32. if (skip) {
  33. skip--;
  34. } else {
  35. trace->entries[trace->nr_entries++] = frame->lr;
  36. if (trace->nr_entries >= trace->max_entries)
  37. break;
  38. }
  39. /*
  40. * The next frame must be at a higher address than the
  41. * current frame.
  42. */
  43. low = fp + 8;
  44. fp = frame->fp;
  45. }
  46. }