fetch-value.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /* Helper routines for libthread_db.
  2. Copyright (C) 2003, 2004 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "thread_dbP.h"
  16. #include <byteswap.h>
  17. #include <assert.h>
  18. td_err_e
  19. _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
  20. {
  21. if (*sizep == 0)
  22. {
  23. psaddr_t descptr;
  24. ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
  25. if (err == PS_NOSYM)
  26. return TD_NOCAPAB;
  27. if (err == PS_OK)
  28. err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
  29. if (err != PS_OK)
  30. return TD_ERR;
  31. if (*sizep & 0xff000000U)
  32. *sizep = bswap_32 (*sizep);
  33. }
  34. return TD_OK;
  35. }
  36. td_err_e
  37. _td_locate_field (td_thragent_t *ta,
  38. db_desc_t desc, int descriptor_name,
  39. psaddr_t idx, psaddr_t *address)
  40. {
  41. uint32_t elemsize;
  42. if (DB_DESC_SIZE (desc) == 0)
  43. {
  44. /* Read the information about this field from the inferior. */
  45. psaddr_t descptr;
  46. ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
  47. if (err == PS_NOSYM)
  48. return TD_NOCAPAB;
  49. if (err == PS_OK)
  50. err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
  51. if (err != PS_OK)
  52. return TD_ERR;
  53. if (DB_DESC_SIZE (desc) == 0)
  54. return TD_DBERR;
  55. if (DB_DESC_SIZE (desc) & 0xff000000U)
  56. {
  57. /* Byte-swap these words, though we leave the size word
  58. in native order as the handy way to distinguish. */
  59. DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
  60. DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
  61. }
  62. }
  63. if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
  64. /* This is an internal indicator to callers with nonzero IDX
  65. that the IDX value is too big. */
  66. return TD_NOAPLIC;
  67. elemsize = DB_DESC_SIZE (desc);
  68. if (elemsize & 0xff000000U)
  69. elemsize = bswap_32 (elemsize);
  70. *address += (int32_t) DB_DESC_OFFSET (desc);
  71. *address += (elemsize / 8 * (idx - (psaddr_t) 0));
  72. return TD_OK;
  73. }
  74. td_err_e
  75. _td_fetch_value (td_thragent_t *ta,
  76. db_desc_t desc, int descriptor_name,
  77. psaddr_t idx, psaddr_t address,
  78. psaddr_t *result)
  79. {
  80. ps_err_e err;
  81. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  82. if (terr != TD_OK)
  83. return terr;
  84. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  85. {
  86. uint8_t value;
  87. err = ps_pdread (ta->ph, address, &value, sizeof value);
  88. *result = (psaddr_t) 0 + value;
  89. }
  90. else if (DB_DESC_SIZE (desc) == 32)
  91. {
  92. uint32_t value;
  93. err = ps_pdread (ta->ph, address, &value, sizeof value);
  94. *result = (psaddr_t) 0 + value;
  95. }
  96. else if (DB_DESC_SIZE (desc) == 64)
  97. {
  98. uint64_t value;
  99. if (sizeof (psaddr_t) < 8)
  100. return TD_NOCAPAB;
  101. err = ps_pdread (ta->ph, address, &value, sizeof value);
  102. *result = (psaddr_t) 0 + value;
  103. }
  104. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  105. {
  106. uint32_t value;
  107. err = ps_pdread (ta->ph, address, &value, sizeof value);
  108. value = bswap_32 (value);
  109. *result = (psaddr_t) 0 + value;
  110. }
  111. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  112. {
  113. uint64_t value;
  114. if (sizeof (psaddr_t) < 8)
  115. return TD_NOCAPAB;
  116. err = ps_pdread (ta->ph, address, &value, sizeof value);
  117. value = bswap_64 (value);
  118. *result = (psaddr_t) 0 + value;
  119. }
  120. else
  121. return TD_DBERR;
  122. return err == PS_OK ? TD_OK : TD_ERR;
  123. }
  124. td_err_e
  125. _td_store_value (td_thragent_t *ta,
  126. uint32_t desc[2], int descriptor_name, psaddr_t idx,
  127. psaddr_t address, psaddr_t widened_value)
  128. {
  129. ps_err_e err;
  130. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  131. if (terr != TD_OK)
  132. return terr;
  133. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  134. {
  135. uint8_t value = widened_value - (psaddr_t) 0;
  136. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  137. }
  138. else if (DB_DESC_SIZE (desc) == 32)
  139. {
  140. uint32_t value = widened_value - (psaddr_t) 0;
  141. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  142. }
  143. else if (DB_DESC_SIZE (desc) == 64)
  144. {
  145. uint64_t value = widened_value - (psaddr_t) 0;
  146. if (sizeof (psaddr_t) < 8)
  147. return TD_NOCAPAB;
  148. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  149. }
  150. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  151. {
  152. uint32_t value = widened_value - (psaddr_t) 0;
  153. value = bswap_32 (value);
  154. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  155. }
  156. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  157. {
  158. uint64_t value = widened_value - (psaddr_t) 0;
  159. if (sizeof (psaddr_t) < 8)
  160. return TD_NOCAPAB;
  161. value = bswap_64 (value);
  162. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  163. }
  164. else
  165. return TD_DBERR;
  166. return err == PS_OK ? TD_OK : TD_ERR;
  167. }
  168. td_err_e
  169. _td_fetch_value_local (td_thragent_t *ta,
  170. db_desc_t desc, int descriptor_name, psaddr_t idx,
  171. void *address,
  172. psaddr_t *result)
  173. {
  174. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  175. if (terr != TD_OK)
  176. return terr;
  177. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  178. {
  179. uint8_t value;
  180. memcpy (&value, address, sizeof value);
  181. *result = (psaddr_t) 0 + value;
  182. }
  183. else if (DB_DESC_SIZE (desc) == 32)
  184. {
  185. uint32_t value;
  186. memcpy (&value, address, sizeof value);
  187. *result = (psaddr_t) 0 + value;
  188. }
  189. else if (DB_DESC_SIZE (desc) == 64)
  190. {
  191. uint64_t value;
  192. if (sizeof (psaddr_t) < 8)
  193. return TD_NOCAPAB;
  194. memcpy (&value, address, sizeof value);
  195. *result = (psaddr_t) 0 + value;
  196. }
  197. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  198. {
  199. uint32_t value;
  200. memcpy (&value, address, sizeof value);
  201. value = bswap_32 (value);
  202. *result = (psaddr_t) 0 + value;
  203. }
  204. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  205. {
  206. uint64_t value;
  207. if (sizeof (psaddr_t) < 8)
  208. return TD_NOCAPAB;
  209. memcpy (&value, address, sizeof value);
  210. value = bswap_64 (value);
  211. *result = (psaddr_t) 0 + value;
  212. }
  213. else
  214. return TD_DBERR;
  215. return TD_OK;
  216. }
  217. td_err_e
  218. _td_store_value_local (td_thragent_t *ta,
  219. uint32_t desc[2], int descriptor_name, psaddr_t idx,
  220. void *address, psaddr_t widened_value)
  221. {
  222. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  223. if (terr != TD_OK)
  224. return terr;
  225. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  226. {
  227. uint8_t value = widened_value - (psaddr_t) 0;
  228. memcpy (address, &value, sizeof value);
  229. }
  230. else if (DB_DESC_SIZE (desc) == 32)
  231. {
  232. uint32_t value = widened_value - (psaddr_t) 0;
  233. memcpy (address, &value, sizeof value);
  234. }
  235. else if (DB_DESC_SIZE (desc) == 64)
  236. {
  237. uint64_t value = widened_value - (psaddr_t) 0;
  238. if (sizeof (psaddr_t) < 8)
  239. return TD_NOCAPAB;
  240. memcpy (address, &value, sizeof value);
  241. }
  242. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  243. {
  244. uint32_t value = widened_value - (psaddr_t) 0;
  245. value = bswap_32 (value);
  246. memcpy (address, &value, sizeof value);
  247. }
  248. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  249. {
  250. uint64_t value = widened_value - (psaddr_t) 0;
  251. if (sizeof (psaddr_t) < 8)
  252. return TD_NOCAPAB;
  253. value = bswap_64 (value);
  254. memcpy (address, &value, sizeof value);
  255. }
  256. else
  257. return TD_DBERR;
  258. return TD_OK;
  259. }