My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

unwinder.h 5.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. /***************************************************************************
  2. * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
  3. * Updated, adapted and several bug fixes on 2018 by Eduardo José Tagle
  4. *
  5. * This program is PUBLIC DOMAIN.
  6. * This means that there is no copyright and anyone is able to take a copy
  7. * for free and use it as they wish, with or without modifications, and in
  8. * any context, commerically or otherwise. The only limitation is that I
  9. * don't guarantee that the software is fit for any purpose or accept any
  10. * liability for its use or misuse - this software is without warranty.
  11. **************************************************************************/
  12. /** \file
  13. * Interface to the ARM stack unwinding module.
  14. **************************************************************************/
  15. #pragma once
  16. #include <stdint.h>
  17. /** \def UNW_DEBUG
  18. * If this define is set, additional information will be produced while
  19. * unwinding the stack to allow debug of the unwind module itself.
  20. */
  21. /* #define UNW_DEBUG 1 */
  22. /***************************************************************************
  23. * Type Definitions
  24. **************************************************************************/
  25. /** Possible results for UnwindStart to return.
  26. */
  27. typedef enum {
  28. /** Unwinding was successful and complete. */
  29. UNWIND_SUCCESS = 0,
  30. /** Not an error: More frames are available. */
  31. UNWIND_MORE_AVAILABLE = 1,
  32. /** Unsupported DWARF unwind personality. */
  33. UNWIND_UNSUPPORTED_DWARF_PERSONALITY = -1,
  34. /** Refused to perform unwind. */
  35. UNWIND_REFUSED = -2,
  36. /** Reached an invalid SP. */
  37. UNWIND_INVALID_SP = -3,
  38. /** Reached an invalid PC */
  39. UNWIND_INVALID_PC = -4,
  40. /** Unsupported DWARF instruction */
  41. UNWIND_UNSUPPORTED_DWARF_INSTR = -5,
  42. /** More than UNW_MAX_INSTR_COUNT instructions were interpreted. */
  43. UNWIND_EXHAUSTED = -6,
  44. /** Unwinding stopped because the reporting func returned false. */
  45. UNWIND_TRUNCATED = -7,
  46. /** Read data was found to be inconsistent. */
  47. UNWIND_INCONSISTENT = -8,
  48. /** Unsupported instruction or data found. */
  49. UNWIND_UNSUPPORTED = -9,
  50. /** General failure. */
  51. UNWIND_FAILURE = -10,
  52. /** Illegal instruction. */
  53. UNWIND_ILLEGAL_INSTR = -11,
  54. /** Unwinding hit the reset vector. */
  55. UNWIND_RESET = -12,
  56. /** Failed read for an instruction word. */
  57. UNWIND_IREAD_W_FAIL = -13,
  58. /** Failed read for an instruction half-word. */
  59. UNWIND_IREAD_H_FAIL = -14,
  60. /** Failed read for an instruction byte. */
  61. UNWIND_IREAD_B_FAIL = -15,
  62. /** Failed read for a data word. */
  63. UNWIND_DREAD_W_FAIL = -16,
  64. /** Failed read for a data half-word. */
  65. UNWIND_DREAD_H_FAIL = -17,
  66. /** Failed read for a data byte. */
  67. UNWIND_DREAD_B_FAIL = -18,
  68. /** Failed write for a data word. */
  69. UNWIND_DWRITE_W_FAIL = -19
  70. } UnwResult;
  71. /** A backtrace report */
  72. typedef struct {
  73. uint32_t function; /** Starts address of function */
  74. const char *name; /** Function name, or null if not available */
  75. uint32_t address; /** PC on that function */
  76. } UnwReport;
  77. /** Type for function pointer for result callback.
  78. * The function is passed two parameters, the first is a void * pointer,
  79. * and the second is the return address of the function. The bottom bit
  80. * of the passed address indicates the execution mode; if it is set,
  81. * the execution mode at the return address is Thumb, otherwise it is
  82. * ARM.
  83. *
  84. * The return value of this function determines whether unwinding should
  85. * continue or not. If true is returned, unwinding will continue and the
  86. * report function maybe called again in future. If false is returned,
  87. * unwinding will stop with UnwindStart() returning UNWIND_TRUNCATED.
  88. */
  89. typedef bool (*UnwindReportFunc)(void* data, const UnwReport* bte);
  90. /** Structure that holds memory callback function pointers.
  91. */
  92. typedef struct {
  93. /** Report an unwind result. */
  94. UnwindReportFunc report;
  95. /** Read a 32 bit word from memory.
  96. * The memory address to be read is passed as \a address, and
  97. * \a *val is expected to be populated with the read value.
  98. * If the address cannot or should not be read, false can be
  99. * returned to indicate that unwinding should stop. If true
  100. * is returned, \a *val is assumed to be valid and unwinding
  101. * will continue.
  102. */
  103. bool (*readW)(const uint32_t address, uint32_t *val);
  104. /** Read a 16 bit half-word from memory.
  105. * This function has the same usage as for readW, but is expected
  106. * to read only a 16 bit value.
  107. */
  108. bool (*readH)(const uint32_t address, uint16_t *val);
  109. /** Read a byte from memory.
  110. * This function has the same usage as for readW, but is expected
  111. * to read only an 8 bit value.
  112. */
  113. bool (*readB)(const uint32_t address, uint8_t *val);
  114. #ifdef UNW_DEBUG
  115. /** Print a formatted line for debug. */
  116. void (*printf)(const char *format, ...);
  117. #endif
  118. } UnwindCallbacks;
  119. /* A frame */
  120. typedef struct {
  121. uint32_t fp;
  122. uint32_t sp;
  123. uint32_t lr;
  124. uint32_t pc;
  125. } UnwindFrame;
  126. /** Start unwinding the current stack.
  127. * This will unwind the stack starting at the PC value supplied to in the
  128. * link register (i.e. not a normal register) and the stack pointer value
  129. * supplied.
  130. *
  131. * -If the program was compiled with -funwind-tables it will use them to
  132. * perform the traceback. Otherwise, brute force will be employed
  133. * -If the program was compiled with -mpoke-function-name, then you will
  134. * get function names in the traceback. Otherwise, you will not.
  135. */
  136. UnwResult UnwindStart(UnwindFrame* frame, const UnwindCallbacks *cb, void *data);