您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

addr2line.c 22KB

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