dwarf_i.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. #ifndef DWARF_I_H
  2. #define DWARF_I_H
  3. /* This file contains definitions that cannot be used in code outside
  4. of libunwind. In particular, most inline functions are here
  5. because otherwise they'd generate unresolved references when the
  6. files are compiled with inlining disabled. */
  7. #include "dwarf.h"
  8. #include "libunwind_i.h"
  9. /* Unless we are told otherwise, assume that a "machine address" is
  10. the size of an unw_word_t. */
  11. #ifndef dwarf_addr_size
  12. # define dwarf_addr_size(as) (sizeof (unw_word_t))
  13. #endif
  14. #define dwarf_to_unw_regnum_map UNW_OBJ (dwarf_to_unw_regnum_map)
  15. extern uint8_t dwarf_to_unw_regnum_map[DWARF_REGNUM_MAP_LENGTH];
  16. /* REG is evaluated multiple times; it better be side-effects free! */
  17. #define dwarf_to_unw_regnum(reg) \
  18. (((reg) <= DWARF_REGNUM_MAP_LENGTH) ? dwarf_to_unw_regnum_map[reg] : 0)
  19. #ifdef UNW_LOCAL_ONLY
  20. /* In the local-only case, we can let the compiler directly access
  21. memory and don't need to worry about differing byte-order. */
  22. union __attribute__ ((packed)) _dwarf_misaligned_value_t
  23. {
  24. int8_t s8;
  25. int16_t s16;
  26. int32_t s32;
  27. int64_t s64;
  28. uint8_t u8;
  29. uint16_t u16;
  30. uint32_t u32;
  31. uint64_t u64;
  32. void *ptr;
  33. };
  34. typedef union _dwarf_misaligned_value_t dwarf_misaligned_value_t;
  35. static inline int
  36. dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  37. int8_t *val, void *arg)
  38. {
  39. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  40. *val = mvp->s8;
  41. *addr += sizeof (mvp->s8);
  42. return 0;
  43. }
  44. static inline int
  45. dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  46. int16_t *val, void *arg)
  47. {
  48. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  49. *val = mvp->s16;
  50. *addr += sizeof (mvp->s16);
  51. return 0;
  52. }
  53. static inline int
  54. dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  55. int32_t *val, void *arg)
  56. {
  57. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  58. *val = mvp->s32;
  59. *addr += sizeof (mvp->s32);
  60. return 0;
  61. }
  62. static inline int
  63. dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  64. int64_t *val, void *arg)
  65. {
  66. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  67. *val = mvp->s64;
  68. *addr += sizeof (mvp->s64);
  69. return 0;
  70. }
  71. static inline int
  72. dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  73. uint8_t *val, void *arg)
  74. {
  75. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  76. *val = mvp->u8;
  77. *addr += sizeof (mvp->u8);
  78. return 0;
  79. }
  80. static inline int
  81. dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  82. uint16_t *val, void *arg)
  83. {
  84. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  85. *val = mvp->u16;
  86. *addr += sizeof (mvp->u16);
  87. return 0;
  88. }
  89. static inline int
  90. dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  91. uint32_t *val, void *arg)
  92. {
  93. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  94. *val = mvp->u32;
  95. *addr += sizeof (mvp->u32);
  96. return 0;
  97. }
  98. static inline int
  99. dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  100. uint64_t *val, void *arg)
  101. {
  102. dwarf_misaligned_value_t *mvp = (void *) (uintptr_t) *addr;
  103. *val = mvp->u64;
  104. *addr += sizeof (mvp->u64);
  105. return 0;
  106. }
  107. #else /* !UNW_LOCAL_ONLY */
  108. static inline int
  109. dwarf_readu8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  110. uint8_t *valp, void *arg)
  111. {
  112. unw_word_t val, aligned_addr = *addr & -sizeof (unw_word_t);
  113. unw_word_t off = *addr - aligned_addr;
  114. int ret;
  115. *addr += 1;
  116. ret = (*a->access_mem) (as, aligned_addr, &val, 0, arg);
  117. #if __BYTE_ORDER == __LITTLE_ENDIAN
  118. val >>= 8*off;
  119. #else
  120. val >>= 8*(sizeof (unw_word_t) - 1 - off);
  121. #endif
  122. *valp = (uint8_t) val;
  123. return ret;
  124. }
  125. static inline int
  126. dwarf_readu16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  127. uint16_t *val, void *arg)
  128. {
  129. uint8_t v0, v1;
  130. int ret;
  131. if ((ret = dwarf_readu8 (as, a, addr, &v0, arg)) < 0
  132. || (ret = dwarf_readu8 (as, a, addr, &v1, arg)) < 0)
  133. return ret;
  134. if (tdep_big_endian (as))
  135. *val = (uint16_t) v0 << 8 | v1;
  136. else
  137. *val = (uint16_t) v1 << 8 | v0;
  138. return 0;
  139. }
  140. static inline int
  141. dwarf_readu32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  142. uint32_t *val, void *arg)
  143. {
  144. uint16_t v0, v1;
  145. int ret;
  146. if ((ret = dwarf_readu16 (as, a, addr, &v0, arg)) < 0
  147. || (ret = dwarf_readu16 (as, a, addr, &v1, arg)) < 0)
  148. return ret;
  149. if (tdep_big_endian (as))
  150. *val = (uint32_t) v0 << 16 | v1;
  151. else
  152. *val = (uint32_t) v1 << 16 | v0;
  153. return 0;
  154. }
  155. static inline int
  156. dwarf_readu64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  157. uint64_t *val, void *arg)
  158. {
  159. uint32_t v0, v1;
  160. int ret;
  161. if ((ret = dwarf_readu32 (as, a, addr, &v0, arg)) < 0
  162. || (ret = dwarf_readu32 (as, a, addr, &v1, arg)) < 0)
  163. return ret;
  164. if (tdep_big_endian (as))
  165. *val = (uint64_t) v0 << 32 | v1;
  166. else
  167. *val = (uint64_t) v1 << 32 | v0;
  168. return 0;
  169. }
  170. static inline int
  171. dwarf_reads8 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  172. int8_t *val, void *arg)
  173. {
  174. uint8_t uval;
  175. int ret;
  176. if ((ret = dwarf_readu8 (as, a, addr, &uval, arg)) < 0)
  177. return ret;
  178. *val = (int8_t) uval;
  179. return 0;
  180. }
  181. static inline int
  182. dwarf_reads16 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  183. int16_t *val, void *arg)
  184. {
  185. uint16_t uval;
  186. int ret;
  187. if ((ret = dwarf_readu16 (as, a, addr, &uval, arg)) < 0)
  188. return ret;
  189. *val = (int16_t) uval;
  190. return 0;
  191. }
  192. static inline int
  193. dwarf_reads32 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  194. int32_t *val, void *arg)
  195. {
  196. uint32_t uval;
  197. int ret;
  198. if ((ret = dwarf_readu32 (as, a, addr, &uval, arg)) < 0)
  199. return ret;
  200. *val = (int32_t) uval;
  201. return 0;
  202. }
  203. static inline int
  204. dwarf_reads64 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  205. int64_t *val, void *arg)
  206. {
  207. uint64_t uval;
  208. int ret;
  209. if ((ret = dwarf_readu64 (as, a, addr, &uval, arg)) < 0)
  210. return ret;
  211. *val = (int64_t) uval;
  212. return 0;
  213. }
  214. #endif /* !UNW_LOCAL_ONLY */
  215. static inline int
  216. dwarf_readw (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  217. unw_word_t *val, void *arg)
  218. {
  219. uint32_t u32;
  220. uint64_t u64;
  221. int ret;
  222. switch (dwarf_addr_size (as))
  223. {
  224. case 4:
  225. ret = dwarf_readu32 (as, a, addr, &u32, arg);
  226. if (ret < 0)
  227. return ret;
  228. *val = u32;
  229. return ret;
  230. case 8:
  231. ret = dwarf_readu64 (as, a, addr, &u64, arg);
  232. if (ret < 0)
  233. return ret;
  234. *val = u64;
  235. return ret;
  236. default:
  237. abort ();
  238. }
  239. }
  240. /* Read an unsigned "little-endian base 128" value. See Chapter 7.6
  241. of DWARF spec v3. */
  242. static inline int
  243. dwarf_read_uleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  244. unw_word_t *valp, void *arg)
  245. {
  246. unw_word_t val = 0, shift = 0;
  247. unsigned char byte;
  248. int ret;
  249. do
  250. {
  251. if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
  252. return ret;
  253. val |= ((unw_word_t) byte & 0x7f) << shift;
  254. shift += 7;
  255. }
  256. while (byte & 0x80);
  257. *valp = val;
  258. return 0;
  259. }
  260. /* Read a signed "little-endian base 128" value. See Chapter 7.6 of
  261. DWARF spec v3. */
  262. static inline int
  263. dwarf_read_sleb128 (unw_addr_space_t as, unw_accessors_t *a, unw_word_t *addr,
  264. unw_word_t *valp, void *arg)
  265. {
  266. unw_word_t val = 0, shift = 0;
  267. unsigned char byte;
  268. int ret;
  269. do
  270. {
  271. if ((ret = dwarf_readu8 (as, a, addr, &byte, arg)) < 0)
  272. return ret;
  273. val |= ((unw_word_t) byte & 0x7f) << shift;
  274. shift += 7;
  275. }
  276. while (byte & 0x80);
  277. if (shift < 8 * sizeof (unw_word_t) && (byte & 0x40) != 0)
  278. /* sign-extend negative value */
  279. val |= ((unw_word_t) -1) << shift;
  280. *valp = val;
  281. return 0;
  282. }
  283. static ALWAYS_INLINE int
  284. dwarf_read_encoded_pointer_inlined (unw_addr_space_t as, unw_accessors_t *a,
  285. unw_word_t *addr, unsigned char encoding,
  286. const unw_proc_info_t *pi,
  287. unw_word_t *valp, void *arg)
  288. {
  289. unw_word_t val, initial_addr = *addr;
  290. uint16_t uval16;
  291. uint32_t uval32;
  292. uint64_t uval64;
  293. int16_t sval16;
  294. int32_t sval32;
  295. int64_t sval64;
  296. int ret;
  297. /* DW_EH_PE_omit and DW_EH_PE_aligned don't follow the normal
  298. format/application encoding. Handle them first. */
  299. if (encoding == DW_EH_PE_omit)
  300. {
  301. *valp = 0;
  302. return 0;
  303. }
  304. else if (encoding == DW_EH_PE_aligned)
  305. {
  306. int size = dwarf_addr_size (as);
  307. *addr = (initial_addr + size - 1) & -size;
  308. return dwarf_readw (as, a, addr, valp, arg);
  309. }
  310. switch (encoding & DW_EH_PE_FORMAT_MASK)
  311. {
  312. case DW_EH_PE_ptr:
  313. if ((ret = dwarf_readw (as, a, addr, &val, arg)) < 0)
  314. return ret;
  315. break;
  316. case DW_EH_PE_uleb128:
  317. if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
  318. return ret;
  319. break;
  320. case DW_EH_PE_udata2:
  321. if ((ret = dwarf_readu16 (as, a, addr, &uval16, arg)) < 0)
  322. return ret;
  323. val = uval16;
  324. break;
  325. case DW_EH_PE_udata4:
  326. if ((ret = dwarf_readu32 (as, a, addr, &uval32, arg)) < 0)
  327. return ret;
  328. val = uval32;
  329. break;
  330. case DW_EH_PE_udata8:
  331. if ((ret = dwarf_readu64 (as, a, addr, &uval64, arg)) < 0)
  332. return ret;
  333. val = uval64;
  334. break;
  335. case DW_EH_PE_sleb128:
  336. if ((ret = dwarf_read_uleb128 (as, a, addr, &val, arg)) < 0)
  337. return ret;
  338. break;
  339. case DW_EH_PE_sdata2:
  340. if ((ret = dwarf_reads16 (as, a, addr, &sval16, arg)) < 0)
  341. return ret;
  342. val = sval16;
  343. break;
  344. case DW_EH_PE_sdata4:
  345. if ((ret = dwarf_reads32 (as, a, addr, &sval32, arg)) < 0)
  346. return ret;
  347. val = sval32;
  348. break;
  349. case DW_EH_PE_sdata8:
  350. if ((ret = dwarf_reads64 (as, a, addr, &sval64, arg)) < 0)
  351. return ret;
  352. val = sval64;
  353. break;
  354. default:
  355. Debug (1, "unexpected encoding format 0x%x\n",
  356. encoding & DW_EH_PE_FORMAT_MASK);
  357. return -UNW_EINVAL;
  358. }
  359. if (val == 0)
  360. {
  361. /* 0 is a special value and always absolute. */
  362. *valp = 0;
  363. return 0;
  364. }
  365. switch (encoding & DW_EH_PE_APPL_MASK)
  366. {
  367. case DW_EH_PE_absptr:
  368. break;
  369. case DW_EH_PE_pcrel:
  370. val += initial_addr;
  371. break;
  372. case DW_EH_PE_datarel:
  373. /* XXX For now, assume that data-relative addresses are relative
  374. to the global pointer. */
  375. val += pi->gp;
  376. break;
  377. case DW_EH_PE_funcrel:
  378. val += pi->start_ip;
  379. break;
  380. case DW_EH_PE_textrel:
  381. /* XXX For now we don't support text-rel values. If there is a
  382. platform which needs this, we probably would have to add a
  383. "segbase" member to unw_proc_info_t. */
  384. default:
  385. Debug (1, "unexpected application type 0x%x\n",
  386. encoding & DW_EH_PE_APPL_MASK);
  387. return -UNW_EINVAL;
  388. }
  389. /* Trim off any extra bits. Assume that sign extension isn't
  390. required; the only place it is needed is MIPS kernel space
  391. addresses. */
  392. if (sizeof (val) > dwarf_addr_size (as))
  393. {
  394. assert (dwarf_addr_size (as) == 4);
  395. val = (uint32_t) val;
  396. }
  397. if (encoding & DW_EH_PE_indirect)
  398. {
  399. unw_word_t indirect_addr = val;
  400. if ((ret = dwarf_readw (as, a, &indirect_addr, &val, arg)) < 0)
  401. return ret;
  402. }
  403. *valp = val;
  404. return 0;
  405. }
  406. #endif /* DWARF_I_H */