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.

unwarm.h 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /***************************************************************************
  2. * ARM Stack Unwinder, Michael.McTernan.2001@cs.bris.ac.uk
  3. *
  4. * This program is PUBLIC DOMAIN.
  5. * This means that there is no copyright and anyone is able to take a copy
  6. * for free and use it as they wish, with or without modifications, and in
  7. * any context, commerically or otherwise. The only limitation is that I
  8. * don't guarantee that the software is fit for any purpose or accept any
  9. * liability for its use or misuse - this software is without warranty.
  10. ***************************************************************************
  11. * File Description: Internal interface between the ARM unwinding sub-modules.
  12. **************************************************************************/
  13. #pragma once
  14. #include "unwinder.h"
  15. /** The maximum number of instructions to interpet in a function.
  16. * Unwinding will be unconditionally stopped and UNWIND_EXHAUSTED returned
  17. * if more than this number of instructions are interpreted in a single
  18. * function without unwinding a stack frame. This prevents infinite loops
  19. * or corrupted program memory from preventing unwinding from progressing.
  20. */
  21. #define UNW_MAX_INSTR_COUNT 500
  22. /** The size of the hash used to track reads and writes to memory.
  23. * This should be a prime value for efficiency.
  24. */
  25. #define MEM_HASH_SIZE 31
  26. /***************************************************************************
  27. * Type Definitions
  28. **************************************************************************/
  29. typedef enum {
  30. /** Invalid value. */
  31. REG_VAL_INVALID = 0x00,
  32. REG_VAL_FROM_STACK = 0x01,
  33. REG_VAL_FROM_MEMORY = 0x02,
  34. REG_VAL_FROM_CONST = 0x04,
  35. REG_VAL_ARITHMETIC = 0x80
  36. } RegValOrigin;
  37. /** Type for tracking information about a register.
  38. * This stores the register value, as well as other data that helps unwinding.
  39. */
  40. typedef struct {
  41. /** The value held in the register. */
  42. uint32_t v;
  43. /** The origin of the register value.
  44. * This is used to track how the value in the register was loaded.
  45. */
  46. int o; /* (RegValOrigin) */
  47. } RegData;
  48. /** Structure used to track reads and writes to memory.
  49. * This structure is used as a hash to store a small number of writes
  50. * to memory.
  51. */
  52. typedef struct {
  53. /** Memory contents. */
  54. uint32_t v[MEM_HASH_SIZE];
  55. /** Address at which v[n] represents. */
  56. uint32_t a[MEM_HASH_SIZE];
  57. /** Indicates whether the data in v[n] and a[n] is occupied.
  58. * Each bit represents one hash value.
  59. */
  60. uint8_t used[(MEM_HASH_SIZE + 7) / 8];
  61. /** Indicates whether the data in v[n] is valid.
  62. * This allows a[n] to be set, but for v[n] to be marked as invalid.
  63. * Specifically this is needed for when an untracked register value
  64. * is written to memory.
  65. */
  66. uint8_t tracked[(MEM_HASH_SIZE + 7) / 8];
  67. } MemData;
  68. /** Structure that is used to keep track of unwinding meta-data.
  69. * This data is passed between all the unwinding functions.
  70. */
  71. typedef struct {
  72. /** The register values and meta-data. */
  73. RegData regData[16];
  74. /** Memory tracking data. */
  75. MemData memData;
  76. /** Pointer to the callback functions */
  77. const UnwindCallbacks *cb;
  78. /** Pointer to pass to the report function. */
  79. const void *reportData;
  80. } UnwState;
  81. /***************************************************************************
  82. * Macros
  83. **************************************************************************/
  84. #define M_IsOriginValid(v) !!((v) & 0x7F)
  85. #define M_Origin2Str(v) ((v) ? "VALID" : "INVALID")
  86. #ifdef UNW_DEBUG
  87. #define UnwPrintd1(a) state->cb->printf(a)
  88. #define UnwPrintd2(a,b) state->cb->printf(a,b)
  89. #define UnwPrintd3(a,b,c) state->cb->printf(a,b,c)
  90. #define UnwPrintd4(a,b,c,d) state->cb->printf(a,b,c,d)
  91. #define UnwPrintd5(a,b,c,d,e) state->cb->printf(a,b,c,d,e)
  92. #define UnwPrintd6(a,b,c,d,e,f) state->cb->printf(a,b,c,d,e,f)
  93. #define UnwPrintd7(a,b,c,d,e,f,g) state->cb->printf(a,b,c,d,e,f,g)
  94. #define UnwPrintd8(a,b,c,d,e,f,g,h) state->cb->printf(a,b,c,d,e,f,g,h)
  95. #else
  96. #define UnwPrintd1(a)
  97. #define UnwPrintd2(a,b)
  98. #define UnwPrintd3(a,b,c)
  99. #define UnwPrintd4(a,b,c,d)
  100. #define UnwPrintd5(a,b,c,d,e)
  101. #define UnwPrintd6(a,b,c,d,e,f)
  102. #define UnwPrintd7(a,b,c,d,e,f,g)
  103. #define UnwPrintd8(a,b,c,d,e,f,g,h)
  104. #endif
  105. /***************************************************************************
  106. * Function Prototypes
  107. **************************************************************************/
  108. UnwResult UnwStartArm(UnwState * const state);
  109. UnwResult UnwStartThumb(UnwState * const state);
  110. void UnwInvalidateRegisterFile(RegData *regFile);
  111. void UnwInitState(UnwState * const state, const UnwindCallbacks *cb, void *rptData, uint32_t pcValue, uint32_t spValue);
  112. bool UnwReportRetAddr(UnwState * const state, uint32_t addr);
  113. bool UnwMemWriteRegister(UnwState * const state, const uint32_t addr, const RegData * const reg);
  114. bool UnwMemReadRegister(UnwState * const state, const uint32_t addr, RegData * const reg);
  115. void UnwMemHashGC(UnwState * const state);