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.

addr2line.c 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. #include <stddef.h>
  2. #include <rtthread.h>
  3. #include "addr2line.h"
  4. #define PROJECT_NAME "project.out"
  5. #define addr2line_print rt_kprintf
  6. // 错误类型打印
  7. #define DUMP_CPU_ARM_CORTEX_M0 0
  8. #define DUMP_CPU_ARM_CORTEX_M3 1
  9. #define DUMP_CPU_ARM_CORTEX_M4 2
  10. #define DUMP_CPU_ARM_CORTEX_M7 3
  11. #define DUMP_CPU_PLATFORM_TYPE DUMP_CPU_ARM_CORTEX_M4
  12. /* system handler control and state register */
  13. #ifndef DUMP_SYSHND_CTRL
  14. #define DUMP_SYSHND_CTRL (*(volatile unsigned int*) (0xE000ED24u))
  15. #endif
  16. /* memory management fault status register */
  17. #ifndef DUMP_NVIC_MFSR
  18. #define DUMP_NVIC_MFSR (*(volatile unsigned char*) (0xE000ED28u))
  19. #endif
  20. /* bus fault status register */
  21. #ifndef DUMP_NVIC_BFSR
  22. #define DUMP_NVIC_BFSR (*(volatile unsigned char*) (0xE000ED29u))
  23. #endif
  24. /* usage fault status register */
  25. #ifndef DUMP_NVIC_UFSR
  26. #define DUMP_NVIC_UFSR (*(volatile unsigned short*)(0xE000ED2Au))
  27. #endif
  28. /* hard fault status register */
  29. #ifndef DUMP_NVIC_HFSR
  30. #define DUMP_NVIC_HFSR (*(volatile unsigned int*) (0xE000ED2Cu))
  31. #endif
  32. /* debug fault status register */
  33. #ifndef DUMP_NVIC_DFSR
  34. #define DUMP_NVIC_DFSR (*(volatile unsigned short*)(0xE000ED30u))
  35. #endif
  36. /* memory management fault address register */
  37. #ifndef DUMP_NVIC_MMAR
  38. #define DUMP_NVIC_MMAR (*(volatile unsigned int*) (0xE000ED34u))
  39. #endif
  40. /* bus fault manage address register */
  41. #ifndef DUMP_NVIC_BFAR
  42. #define DUMP_NVIC_BFAR (*(volatile unsigned int*) (0xE000ED38u))
  43. #endif
  44. /* auxiliary fault status register */
  45. #ifndef DUMP_NVIC_AFSR
  46. #define DUMP_NVIC_AFSR (*(volatile unsigned short*)(0xE000ED3Cu))
  47. #endif
  48. /**
  49. * Cortex-M fault registers
  50. */
  51. struct dump_hard_fault_regs
  52. {
  53. struct
  54. {
  55. unsigned int r0; // Register R0
  56. unsigned int r1; // Register R1
  57. unsigned int r2; // Register R2
  58. unsigned int r3; // Register R3
  59. unsigned int r12; // Register R12
  60. unsigned int lr; // Link register
  61. unsigned int pc; // Program counter
  62. union
  63. {
  64. unsigned int value;
  65. struct
  66. {
  67. unsigned int IPSR : 8; // Interrupt Program Status register (IPSR)
  68. unsigned int EPSR : 19; // Execution Program Status register (EPSR)
  69. unsigned int APSR : 5; // Application Program Status register (APSR)
  70. } bits;
  71. } psr; // Program status register.
  72. } saved;
  73. union
  74. {
  75. unsigned int value;
  76. struct
  77. {
  78. unsigned int MEMFAULTACT : 1; // Read as 1 if memory management fault is active
  79. unsigned int BUSFAULTACT : 1; // Read as 1 if bus fault exception is active
  80. unsigned int UnusedBits1 : 1;
  81. unsigned int USGFAULTACT : 1; // Read as 1 if usage fault exception is active
  82. unsigned int UnusedBits2 : 3;
  83. unsigned int SVCALLACT : 1; // Read as 1 if SVC exception is active
  84. unsigned int MONITORACT : 1; // Read as 1 if debug monitor exception is active
  85. unsigned int UnusedBits3 : 1;
  86. unsigned int PENDSVACT : 1; // Read as 1 if PendSV exception is active
  87. unsigned int SYSTICKACT : 1; // Read as 1 if SYSTICK exception is active
  88. unsigned int USGFAULTPENDED : 1; // Usage fault pended; usage fault started but was replaced by a higher-priority exception
  89. unsigned int MEMFAULTPENDED : 1; // Memory management fault pended; memory management fault started but was replaced by a higher-priority exception
  90. unsigned int BUSFAULTPENDED : 1; // Bus fault pended; bus fault handler was started but was replaced by a higher-priority exception
  91. unsigned int SVCALLPENDED : 1; // SVC pended; SVC was started but was replaced by a higher-priority exception
  92. unsigned int MEMFAULTENA : 1; // Memory management fault handler enable
  93. unsigned int BUSFAULTENA : 1; // Bus fault handler enable
  94. unsigned int USGFAULTENA : 1; // Usage fault handler enable
  95. } bits;
  96. } syshndctrl; // System Handler Control and State Register (0xE000ED24)
  97. union
  98. {
  99. unsigned char value;
  100. struct
  101. {
  102. unsigned char IACCVIOL : 1; // Instruction access violation
  103. unsigned char DACCVIOL : 1; // Data access violation
  104. unsigned char UnusedBits : 1;
  105. unsigned char MUNSTKERR : 1; // Unstacking error
  106. unsigned char MSTKERR : 1; // Stacking error
  107. unsigned char MLSPERR : 1; // Floating-point lazy state preservation (M4/M7)
  108. unsigned char UnusedBits2 : 1;
  109. unsigned char MMARVALID : 1; // Indicates the MMAR is valid
  110. } bits;
  111. } mfsr; // Memory Management Fault Status Register (0xE000ED28)
  112. unsigned int mmar; // Memory Management Fault Address Register (0xE000ED34)
  113. union
  114. {
  115. unsigned char value;
  116. struct
  117. {
  118. unsigned char IBUSERR : 1; // Instruction access violation
  119. unsigned char PRECISERR : 1; // Precise data access violation
  120. unsigned char IMPREISERR : 1; // Imprecise data access violation
  121. unsigned char UNSTKERR : 1; // Unstacking error
  122. unsigned char STKERR : 1; // Stacking error
  123. unsigned char LSPERR : 1; // Floating-point lazy state preservation (M4/M7)
  124. unsigned char UnusedBits : 1;
  125. unsigned char BFARVALID : 1; // Indicates BFAR is valid
  126. } bits;
  127. } bfsr; // Bus Fault Status Register (0xE000ED29)
  128. unsigned int bfar; // Bus Fault Manage Address Register (0xE000ED38)
  129. union
  130. {
  131. unsigned short value;
  132. struct
  133. {
  134. unsigned short UNDEFINSTR : 1; // Attempts to execute an undefined instruction
  135. unsigned short INVSTATE : 1; // Attempts to switch to an invalid state (e.g., ARM)
  136. unsigned short INVPC : 1; // Attempts to do an exception with a bad value in the EXC_RETURN number
  137. unsigned short NOCP : 1; // Attempts to execute a coprocessor instruction
  138. unsigned short UnusedBits : 4;
  139. unsigned short UNALIGNED : 1; // Indicates that an unaligned access fault has taken place
  140. unsigned short DIVBYZERO0 : 1; // Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)
  141. } bits;
  142. } ufsr; // Usage Fault Status Register (0xE000ED2A)
  143. union
  144. {
  145. unsigned int value;
  146. struct
  147. {
  148. unsigned int UnusedBits : 1;
  149. unsigned int VECTBL : 1; // Indicates hard fault is caused by failed vector fetch
  150. unsigned int UnusedBits2 : 28;
  151. unsigned int FORCED : 1; // Indicates hard fault is taken because of bus fault/memory management fault/usage fault
  152. unsigned int DEBUGEVT : 1; // Indicates hard fault is triggered by debug event
  153. } bits;
  154. } hfsr; // Hard Fault Status Register (0xE000ED2C)
  155. union
  156. {
  157. unsigned int value;
  158. struct
  159. {
  160. unsigned int HALTED : 1; // Halt requested in NVIC
  161. unsigned int BKPT : 1; // BKPT instruction executed
  162. unsigned int DWTTRAP : 1; // DWT match occurred
  163. unsigned int VCATCH : 1; // Vector fetch occurred
  164. unsigned int EXTERNAL : 1; // EDBGRQ signal asserted
  165. } bits;
  166. } dfsr; // Debug Fault Status Register (0xE000ED30)
  167. unsigned int afsr; // Auxiliary Fault Status Register (0xE000ED3C), Vendor controlled (optional)
  168. };
  169. enum
  170. {
  171. PRINT_MAIN_STACK_CFG_ERROR,
  172. PRINT_FIRMWARE_INFO,
  173. PRINT_ASSERT_ON_THREAD,
  174. PRINT_ASSERT_ON_HANDLER,
  175. PRINT_THREAD_STACK_INFO,
  176. PRINT_MAIN_STACK_INFO,
  177. PRINT_THREAD_STACK_OVERFLOW,
  178. PRINT_MAIN_STACK_OVERFLOW,
  179. PRINT_CALL_STACK_INFO,
  180. PRINT_CALL_STACK_ERR,
  181. PRINT_FAULT_ON_THREAD,
  182. PRINT_FAULT_ON_HANDLER,
  183. PRINT_REGS_TITLE,
  184. PRINT_HFSR_VECTBL,
  185. PRINT_MFSR_IACCVIOL,
  186. PRINT_MFSR_DACCVIOL,
  187. PRINT_MFSR_MUNSTKERR,
  188. PRINT_MFSR_MSTKERR,
  189. PRINT_MFSR_MLSPERR,
  190. PRINT_BFSR_IBUSERR,
  191. PRINT_BFSR_PRECISERR,
  192. PRINT_BFSR_IMPREISERR,
  193. PRINT_BFSR_UNSTKERR,
  194. PRINT_BFSR_STKERR,
  195. PRINT_BFSR_LSPERR,
  196. PRINT_UFSR_UNDEFINSTR,
  197. PRINT_UFSR_INVSTATE,
  198. PRINT_UFSR_INVPC,
  199. PRINT_UFSR_NOCP,
  200. PRINT_UFSR_UNALIGNED,
  201. PRINT_UFSR_DIVBYZERO0,
  202. PRINT_DFSR_HALTED,
  203. PRINT_DFSR_BKPT,
  204. PRINT_DFSR_DWTTRAP,
  205. PRINT_DFSR_VCATCH,
  206. PRINT_DFSR_EXTERNAL,
  207. PRINT_MMAR,
  208. PRINT_BFAR,
  209. };
  210. static const char *const print_info[] = {
  211. [PRINT_MAIN_STACK_CFG_ERROR] = "ERROR: Unable to get the main stack information, please check the configuration of the main stack\n",
  212. [PRINT_FIRMWARE_INFO] = "Firmware name: %s, hardware version: %s, software version: %s\n",
  213. [PRINT_ASSERT_ON_THREAD] = "Assert on thread %s\n",
  214. [PRINT_ASSERT_ON_HANDLER] = "Assert on interrupt or bare metal(no OS) environment\n",
  215. [PRINT_THREAD_STACK_INFO] = "===== Thread stack information =====\n",
  216. [PRINT_MAIN_STACK_INFO] = "====== Main stack information ======\n",
  217. [PRINT_THREAD_STACK_OVERFLOW] = "Error: Thread stack(%08x) was overflow\n",
  218. [PRINT_MAIN_STACK_OVERFLOW] = "Error: Main stack(%08x) was overflow\n",
  219. [PRINT_CALL_STACK_INFO] = "Show more call stack info by run: addr2line -e %s%s -a -f %.*s\n",
  220. [PRINT_CALL_STACK_ERR] = "Dump call stack has an error\n",
  221. [PRINT_FAULT_ON_THREAD] = "Fault on thread %s\n",
  222. [PRINT_FAULT_ON_HANDLER] = "Fault on interrupt or bare metal(no OS) environment\n",
  223. [PRINT_REGS_TITLE] = "=================== Registers information ====================\n",
  224. [PRINT_HFSR_VECTBL] = "Hard fault is caused by failed vector fetch\n",
  225. [PRINT_MFSR_IACCVIOL] = "Memory management fault is caused by instruction access violation\n",
  226. [PRINT_MFSR_DACCVIOL] = "Memory management fault is caused by data access violation\n",
  227. [PRINT_MFSR_MUNSTKERR] = "Memory management fault is caused by unstacking error\n",
  228. [PRINT_MFSR_MSTKERR] = "Memory management fault is caused by stacking error\n",
  229. [PRINT_MFSR_MLSPERR] = "Memory management fault is caused by floating-point lazy state preservation\n",
  230. [PRINT_BFSR_IBUSERR] = "Bus fault is caused by instruction access violation\n",
  231. [PRINT_BFSR_PRECISERR] = "Bus fault is caused by precise data access violation\n",
  232. [PRINT_BFSR_IMPREISERR] = "Bus fault is caused by imprecise data access violation\n",
  233. [PRINT_BFSR_UNSTKERR] = "Bus fault is caused by unstacking error\n",
  234. [PRINT_BFSR_STKERR] = "Bus fault is caused by stacking error\n",
  235. [PRINT_BFSR_LSPERR] = "Bus fault is caused by floating-point lazy state preservation\n",
  236. [PRINT_UFSR_UNDEFINSTR] = "Usage fault is caused by attempts to execute an undefined instruction\n",
  237. [PRINT_UFSR_INVSTATE] = "Usage fault is caused by attempts to switch to an invalid state (e.g., ARM)\n",
  238. [PRINT_UFSR_INVPC] = "Usage fault is caused by attempts to do an exception with a bad value in the EXC_RETURN number\n",
  239. [PRINT_UFSR_NOCP] = "Usage fault is caused by attempts to execute a coprocessor instruction\n",
  240. [PRINT_UFSR_UNALIGNED] = "Usage fault is caused by indicates that an unaligned access fault has taken place\n",
  241. [PRINT_UFSR_DIVBYZERO0] = "Usage fault is caused by Indicates a divide by zero has taken place (can be set only if DIV_0_TRP is set)\n",
  242. [PRINT_DFSR_HALTED] = "Debug fault is caused by halt requested in NVIC\n",
  243. [PRINT_DFSR_BKPT] = "Debug fault is caused by BKPT instruction executed\n",
  244. [PRINT_DFSR_DWTTRAP] = "Debug fault is caused by DWT match occurred\n",
  245. [PRINT_DFSR_VCATCH] = "Debug fault is caused by Vector fetch occurred\n",
  246. [PRINT_DFSR_EXTERNAL] = "Debug fault is caused by EDBGRQ signal asserted\n",
  247. [PRINT_MMAR] = "The memory management fault occurred address is %08x\n",
  248. [PRINT_BFAR] = "The bus fault occurred address is %08x\n",
  249. };
  250. static struct dump_hard_fault_regs regs;
  251. #if (DUMP_CPU_PLATFORM_TYPE != DUMP_CPU_ARM_CORTEX_M0)
  252. /**
  253. * fault diagnosis then print cause of fault
  254. */
  255. static void fault_diagnosis(void)
  256. {
  257. if (regs.hfsr.bits.VECTBL)
  258. {
  259. addr2line_print(print_info[PRINT_HFSR_VECTBL]);
  260. }
  261. if (regs.hfsr.bits.FORCED)
  262. {
  263. /* Memory Management Fault */
  264. if (regs.mfsr.value)
  265. {
  266. if (regs.mfsr.bits.IACCVIOL)
  267. {
  268. addr2line_print(print_info[PRINT_MFSR_IACCVIOL]);
  269. }
  270. if (regs.mfsr.bits.DACCVIOL)
  271. {
  272. addr2line_print(print_info[PRINT_MFSR_DACCVIOL]);
  273. }
  274. if (regs.mfsr.bits.MUNSTKERR)
  275. {
  276. addr2line_print(print_info[PRINT_MFSR_MUNSTKERR]);
  277. }
  278. if (regs.mfsr.bits.MSTKERR)
  279. {
  280. addr2line_print(print_info[PRINT_MFSR_MSTKERR]);
  281. }
  282. #if (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M4) || (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M7)
  283. if (regs.mfsr.bits.MLSPERR)
  284. {
  285. addr2line_print(print_info[PRINT_MFSR_MLSPERR]);
  286. }
  287. #endif
  288. if (regs.mfsr.bits.MMARVALID)
  289. {
  290. if (regs.mfsr.bits.IACCVIOL || regs.mfsr.bits.DACCVIOL)
  291. {
  292. addr2line_print(print_info[PRINT_MMAR], regs.mmar);
  293. }
  294. }
  295. }
  296. /* Bus Fault */
  297. if (regs.bfsr.value)
  298. {
  299. if (regs.bfsr.bits.IBUSERR)
  300. {
  301. addr2line_print(print_info[PRINT_BFSR_IBUSERR]);
  302. }
  303. if (regs.bfsr.bits.PRECISERR)
  304. {
  305. addr2line_print(print_info[PRINT_BFSR_PRECISERR]);
  306. }
  307. if (regs.bfsr.bits.IMPREISERR)
  308. {
  309. addr2line_print(print_info[PRINT_BFSR_IMPREISERR]);
  310. }
  311. if (regs.bfsr.bits.UNSTKERR)
  312. {
  313. addr2line_print(print_info[PRINT_BFSR_UNSTKERR]);
  314. }
  315. if (regs.bfsr.bits.STKERR)
  316. {
  317. addr2line_print(print_info[PRINT_BFSR_STKERR]);
  318. }
  319. #if (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M4) || (DUMP_CPU_PLATFORM_TYPE == DUMP_CPU_ARM_CORTEX_M7)
  320. if (regs.bfsr.bits.LSPERR)
  321. {
  322. addr2line_print(print_info[PRINT_BFSR_LSPERR]);
  323. }
  324. #endif
  325. if (regs.bfsr.bits.BFARVALID)
  326. {
  327. if (regs.bfsr.bits.PRECISERR)
  328. {
  329. addr2line_print(print_info[PRINT_BFAR], regs.bfar);
  330. }
  331. }
  332. }
  333. /* Usage Fault */
  334. if (regs.ufsr.value)
  335. {
  336. if (regs.ufsr.bits.UNDEFINSTR)
  337. {
  338. addr2line_print(print_info[PRINT_UFSR_UNDEFINSTR]);
  339. }
  340. if (regs.ufsr.bits.INVSTATE)
  341. {
  342. addr2line_print(print_info[PRINT_UFSR_INVSTATE]);
  343. }
  344. if (regs.ufsr.bits.INVPC)
  345. {
  346. addr2line_print(print_info[PRINT_UFSR_INVPC]);
  347. }
  348. if (regs.ufsr.bits.NOCP)
  349. {
  350. addr2line_print(print_info[PRINT_UFSR_NOCP]);
  351. }
  352. if (regs.ufsr.bits.UNALIGNED)
  353. {
  354. addr2line_print(print_info[PRINT_UFSR_UNALIGNED]);
  355. }
  356. if (regs.ufsr.bits.DIVBYZERO0)
  357. {
  358. addr2line_print(print_info[PRINT_UFSR_DIVBYZERO0]);
  359. }
  360. }
  361. }
  362. /* Debug Fault */
  363. if (regs.hfsr.bits.DEBUGEVT)
  364. {
  365. if (regs.dfsr.value)
  366. {
  367. if (regs.dfsr.bits.HALTED)
  368. {
  369. addr2line_print(print_info[PRINT_DFSR_HALTED]);
  370. }
  371. if (regs.dfsr.bits.BKPT)
  372. {
  373. addr2line_print(print_info[PRINT_DFSR_BKPT]);
  374. }
  375. if (regs.dfsr.bits.DWTTRAP)
  376. {
  377. addr2line_print(print_info[PRINT_DFSR_DWTTRAP]);
  378. }
  379. if (regs.dfsr.bits.VCATCH)
  380. {
  381. addr2line_print(print_info[PRINT_DFSR_VCATCH]);
  382. }
  383. if (regs.dfsr.bits.EXTERNAL)
  384. {
  385. addr2line_print(print_info[PRINT_DFSR_EXTERNAL]);
  386. }
  387. }
  388. }
  389. }
  390. #endif
  391. int coredump_fault_diagnosis(void)
  392. {
  393. /* the Cortex-M0 is not support fault diagnosis */
  394. #if (DUMP_CPU_PLATFORM_TYPE != DUMP_CPU_ARM_CORTEX_M0)
  395. regs.syshndctrl.value = DUMP_SYSHND_CTRL; // System Handler Control and State Register
  396. regs.mfsr.value = DUMP_NVIC_MFSR; // Memory Fault Status Register
  397. regs.mmar = DUMP_NVIC_MMAR; // Memory Management Fault Address Register
  398. regs.bfsr.value = DUMP_NVIC_BFSR; // Bus Fault Status Register
  399. regs.bfar = DUMP_NVIC_BFAR; // Bus Fault Manage Address Register
  400. regs.ufsr.value = DUMP_NVIC_UFSR; // Usage Fault Status Register
  401. regs.hfsr.value = DUMP_NVIC_HFSR; // Hard Fault Status Register
  402. regs.dfsr.value = DUMP_NVIC_DFSR; // Debug Fault Status Register
  403. regs.afsr = DUMP_NVIC_AFSR; // Auxiliary Fault Status Register
  404. fault_diagnosis();
  405. return 0;
  406. #endif
  407. return -1;
  408. }
  409. int addr2line_print_stack_before(uint32_t exc_return)
  410. {
  411. int on_thread_before_fault = exc_return & (1UL << 2);
  412. /* check which stack was used before (MSP or PSP) */
  413. if (on_thread_before_fault)
  414. addr2line_print(print_info[PRINT_FAULT_ON_THREAD], rt_thread_self()->name != NULL ? rt_thread_self()->name : "NO_NAME");
  415. else
  416. addr2line_print(print_info[PRINT_FAULT_ON_HANDLER]);
  417. coredump_fault_diagnosis();
  418. return 0;
  419. }
  420. void addr2line_trigger_exception(void)
  421. {
  422. volatile int *SCB_CCR = (volatile int *)0xE000ED14; // SCB->CCR
  423. int x, y, z;
  424. *SCB_CCR |= (1 << 4); /* bit4: DIV_0_TRP. */
  425. x = 10;
  426. y = strlen("");
  427. z = x / y;
  428. addr2line_print("z:%d\n", z);
  429. }
  430. // addr to line
  431. #include <stdbool.h>
  432. #pragma section = ".text"
  433. static bool is_in_text(uint32_t addr)
  434. {
  435. #if 0
  436. uint32_t code_start_addr = (uint32_t)&CODE_SECTION_START(CMB_CODE_SECTION_NAME);
  437. uint32_t code_size = (uint32_t)&CODE_SECTION_END(CMB_CODE_SECTION_NAME) - code_start_addr;
  438. #else
  439. uint32_t code_start_addr = (uint32_t)__section_begin(".text");
  440. uint32_t code_size = (uint32_t)__section_end(".text") - code_start_addr;
  441. #endif
  442. if (code_start_addr < addr && addr <= code_start_addr + code_size)
  443. {
  444. return true;
  445. }
  446. return false;
  447. }
  448. static bool disassembly_ins_is_bl_blx(uint32_t addr)
  449. {
  450. #define BL_INS_MASK 0xF800
  451. #define BL_INS_HIGH 0xF800
  452. #define BL_INS_LOW 0xF000
  453. #define BLX_INX_MASK 0xFF00
  454. #define BLX_INX 0x4700
  455. uint16_t ins1 = *((uint16_t *)addr);
  456. uint16_t ins2 = *((uint16_t *)(addr + 2));
  457. if ((ins2 & BL_INS_MASK) == BL_INS_HIGH && (ins1 & BL_INS_MASK) == BL_INS_LOW)
  458. {
  459. return true;
  460. }
  461. else if ((ins2 & BLX_INX_MASK) == BLX_INX)
  462. {
  463. return true;
  464. }
  465. else
  466. {
  467. return false;
  468. }
  469. }
  470. // 只会找符合要求的lr,不能找pc值。所以要指定pc
  471. void addr2line_cmd_with_pc_print(uint32_t *thread_pc, uint32_t *addr, int size)
  472. {
  473. addr2line_print("addr2line -e " PROJECT_NAME " -a -f ");
  474. size /= sizeof(uint32_t);
  475. if (thread_pc)
  476. addr2line_print("%08x ", thread_pc);
  477. for (int i = 1; i < size; i++)
  478. {
  479. const uint32_t lr = addr[i];
  480. if (false == is_in_text(lr))
  481. continue;
  482. uint32_t pc = lr - sizeof(size_t); // 假设当前是lr寄存器的值,向下增长4就是pc寄存器的值
  483. if (pc % 2 == 0) // thumb 指令pc寄存器值一定是偶数
  484. continue;
  485. pc = lr - 1; // lr寄存器值保存的是pc+1
  486. if ((uint32_t)thread_pc == pc) // 忽略:已经指定打印过了
  487. continue;
  488. if (true == disassembly_ins_is_bl_blx(pc - sizeof(size_t))) // pc 的上一条指令是跳转指
  489. {
  490. // if (i + 1 < size && pc != addr[i + 1] && true == is_in_text(addr[i + 1])) // 最后一次调用的情况:LR、PC还在CPU寄存器里面挨着的
  491. // {
  492. // addr2line_print("%08x ", addr[i + 1]);
  493. // i++;
  494. // }
  495. addr2line_print("%08x ", pc);
  496. }
  497. }
  498. addr2line_print("\n");
  499. }
  500. void addr2line_cmd_print(uint32_t *addr, int size)
  501. {
  502. addr2line_cmd_with_pc_print(NULL, addr, size);
  503. }
  504. #if 0
  505. static void test_addr2line(void)
  506. {
  507. uint32_t sg_test_stack[] =
  508. {
  509. 0x00000001, 0x000514d5, 0x000000f0, 0x00000001,
  510. 0x000c3fcc, 0x00000000, 0x000538b4, 0x00549822,
  511. 0xdeadbeef, 0x00000000, 0x00000000, 0x00000000,
  512. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  513. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  514. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  515. 0x00000000, 0x0000000a, 0x00000210, 0x00000000,
  516. 0x00000000, 0x00000006, 0x000514eb, 0x000516f8,
  517. 0x49000000, 0x00000004, 0x0000007d, 0x00000000,
  518. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  519. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  520. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  521. 0x00000000, 0x00000010, 0x00000000, 0x00000200,
  522. 0x00000000, 0x000008f4, 0x000537bb, 0x000000f0,
  523. 0x00000000, 0x00000001, 0x00000002, 0x20033378,
  524. 0x000468e3, 0x00000000, 0x20036c3c, 0x20036c78,
  525. 0x000b8789, 0x00000000, 0x20016dd8, 0x20008198,
  526. 0x000b819f, 0x00000000, 0x2003727c, 0x20016dd8,
  527. 0x0006047f, 0x00000050, 0x00000000, 0x20016dd8,
  528. 0x00000001, 0x00000001, 0x000604dd, 0x00000000,
  529. 0x2003092c, 0x20030b1c, 0x200334f4, 0x200334b4,
  530. 0x00060215, 0x2003764c, 0x20036e98, 0x00000008,
  531. 0x200081f4, 0x200334b4, 0x00000000, 0x0068007a,
  532. 0x00000000, 0x20030b1c, 0x00063dd3, 0x007a0068,
  533. 0x00000000, 0x00000000, 0x00000000, 0x00000000,
  534. 0xffffffff, 0x20033520, 0x2003060c, 0x2002cc84,
  535. 0x2002cbf4, 0x20033378, 0x0005ce35, 0x20030e20,
  536. 0x000d17c8, 0x20030214, 0x00000014, 0xdeadbeef,
  537. 0xdeadbeef, 0xdeadbeef, 0x00057c99, 0x00000000,
  538. 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef,
  539. 0x000302e7
  540. };
  541. uint32_t *addr = sg_test_stack;
  542. int size = sizeof(sg_test_stack);
  543. _addr2line_print(addr, size);
  544. }
  545. #endif