fetch-value.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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, write to the Free
  14. Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  15. 02111-1307 USA. */
  16. #include "thread_dbP.h"
  17. #include <byteswap.h>
  18. #include <assert.h>
  19. td_err_e
  20. _td_check_sizeof (td_thragent_t *ta, uint32_t *sizep, int sizep_name)
  21. {
  22. if (*sizep == 0)
  23. {
  24. psaddr_t descptr;
  25. ps_err_e err = td_lookup (ta->ph, sizep_name, &descptr);
  26. if (err == PS_NOSYM)
  27. return TD_NOCAPAB;
  28. if (err == PS_OK)
  29. err = ps_pdread (ta->ph, descptr, sizep, sizeof *sizep);
  30. if (err != PS_OK)
  31. return TD_ERR;
  32. if (*sizep & 0xff000000U)
  33. *sizep = bswap_32 (*sizep);
  34. }
  35. return TD_OK;
  36. }
  37. td_err_e
  38. _td_locate_field (td_thragent_t *ta,
  39. db_desc_t desc, int descriptor_name,
  40. psaddr_t idx, psaddr_t *address)
  41. {
  42. uint32_t elemsize;
  43. if (DB_DESC_SIZE (desc) == 0)
  44. {
  45. /* Read the information about this field from the inferior. */
  46. psaddr_t descptr;
  47. ps_err_e err = td_lookup (ta->ph, descriptor_name, &descptr);
  48. if (err == PS_NOSYM)
  49. return TD_NOCAPAB;
  50. if (err == PS_OK)
  51. err = ps_pdread (ta->ph, descptr, desc, DB_SIZEOF_DESC);
  52. if (err != PS_OK)
  53. return TD_ERR;
  54. if (DB_DESC_SIZE (desc) == 0)
  55. return TD_DBERR;
  56. if (DB_DESC_SIZE (desc) & 0xff000000U)
  57. {
  58. /* Byte-swap these words, though we leave the size word
  59. in native order as the handy way to distinguish. */
  60. DB_DESC_OFFSET (desc) = bswap_32 (DB_DESC_OFFSET (desc));
  61. DB_DESC_NELEM (desc) = bswap_32 (DB_DESC_NELEM (desc));
  62. }
  63. }
  64. if (idx != 0 && idx - (psaddr_t) 0 > DB_DESC_NELEM (desc))
  65. /* This is an internal indicator to callers with nonzero IDX
  66. that the IDX value is too big. */
  67. return TD_NOAPLIC;
  68. elemsize = DB_DESC_SIZE (desc);
  69. if (elemsize & 0xff000000U)
  70. elemsize = bswap_32 (elemsize);
  71. *address += (int32_t) DB_DESC_OFFSET (desc);
  72. *address += (elemsize / 8 * (idx - (psaddr_t) 0));
  73. return TD_OK;
  74. }
  75. td_err_e
  76. _td_fetch_value (td_thragent_t *ta,
  77. db_desc_t desc, int descriptor_name,
  78. psaddr_t idx, psaddr_t address,
  79. psaddr_t *result)
  80. {
  81. ps_err_e err;
  82. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  83. if (terr != TD_OK)
  84. return terr;
  85. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  86. {
  87. uint8_t value;
  88. err = ps_pdread (ta->ph, address, &value, sizeof value);
  89. *result = (psaddr_t) 0 + value;
  90. }
  91. else if (DB_DESC_SIZE (desc) == 32)
  92. {
  93. uint32_t value;
  94. err = ps_pdread (ta->ph, address, &value, sizeof value);
  95. *result = (psaddr_t) 0 + value;
  96. }
  97. else if (DB_DESC_SIZE (desc) == 64)
  98. {
  99. uint64_t value;
  100. if (sizeof (psaddr_t) < 8)
  101. return TD_NOCAPAB;
  102. err = ps_pdread (ta->ph, address, &value, sizeof value);
  103. *result = (psaddr_t) 0 + value;
  104. }
  105. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  106. {
  107. uint32_t value;
  108. err = ps_pdread (ta->ph, address, &value, sizeof value);
  109. value = bswap_32 (value);
  110. *result = (psaddr_t) 0 + value;
  111. }
  112. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  113. {
  114. uint64_t value;
  115. if (sizeof (psaddr_t) < 8)
  116. return TD_NOCAPAB;
  117. err = ps_pdread (ta->ph, address, &value, sizeof value);
  118. value = bswap_64 (value);
  119. *result = (psaddr_t) 0 + value;
  120. }
  121. else
  122. return TD_DBERR;
  123. return err == PS_OK ? TD_OK : TD_ERR;
  124. }
  125. td_err_e
  126. _td_store_value (td_thragent_t *ta,
  127. uint32_t desc[2], int descriptor_name, psaddr_t idx,
  128. psaddr_t address, psaddr_t widened_value)
  129. {
  130. ps_err_e err;
  131. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  132. if (terr != TD_OK)
  133. return terr;
  134. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  135. {
  136. uint8_t value = widened_value - (psaddr_t) 0;
  137. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  138. }
  139. else if (DB_DESC_SIZE (desc) == 32)
  140. {
  141. uint32_t value = widened_value - (psaddr_t) 0;
  142. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  143. }
  144. else if (DB_DESC_SIZE (desc) == 64)
  145. {
  146. uint64_t value = widened_value - (psaddr_t) 0;
  147. if (sizeof (psaddr_t) < 8)
  148. return TD_NOCAPAB;
  149. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  150. }
  151. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  152. {
  153. uint32_t value = widened_value - (psaddr_t) 0;
  154. value = bswap_32 (value);
  155. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  156. }
  157. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  158. {
  159. uint64_t value = widened_value - (psaddr_t) 0;
  160. if (sizeof (psaddr_t) < 8)
  161. return TD_NOCAPAB;
  162. value = bswap_64 (value);
  163. err = ps_pdwrite (ta->ph, address, &value, sizeof value);
  164. }
  165. else
  166. return TD_DBERR;
  167. return err == PS_OK ? TD_OK : TD_ERR;
  168. }
  169. td_err_e
  170. _td_fetch_value_local (td_thragent_t *ta,
  171. db_desc_t desc, int descriptor_name, psaddr_t idx,
  172. void *address,
  173. psaddr_t *result)
  174. {
  175. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  176. if (terr != TD_OK)
  177. return terr;
  178. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  179. {
  180. uint8_t value;
  181. memcpy (&value, address, sizeof value);
  182. *result = (psaddr_t) 0 + value;
  183. }
  184. else if (DB_DESC_SIZE (desc) == 32)
  185. {
  186. uint32_t value;
  187. memcpy (&value, address, sizeof value);
  188. *result = (psaddr_t) 0 + value;
  189. }
  190. else if (DB_DESC_SIZE (desc) == 64)
  191. {
  192. uint64_t value;
  193. if (sizeof (psaddr_t) < 8)
  194. return TD_NOCAPAB;
  195. memcpy (&value, address, sizeof value);
  196. *result = (psaddr_t) 0 + value;
  197. }
  198. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  199. {
  200. uint32_t value;
  201. memcpy (&value, address, sizeof value);
  202. value = bswap_32 (value);
  203. *result = (psaddr_t) 0 + value;
  204. }
  205. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  206. {
  207. uint64_t value;
  208. if (sizeof (psaddr_t) < 8)
  209. return TD_NOCAPAB;
  210. memcpy (&value, address, sizeof value);
  211. value = bswap_64 (value);
  212. *result = (psaddr_t) 0 + value;
  213. }
  214. else
  215. return TD_DBERR;
  216. return TD_OK;
  217. }
  218. td_err_e
  219. _td_store_value_local (td_thragent_t *ta,
  220. uint32_t desc[2], int descriptor_name, psaddr_t idx,
  221. void *address, psaddr_t widened_value)
  222. {
  223. td_err_e terr = _td_locate_field (ta, desc, descriptor_name, idx, &address);
  224. if (terr != TD_OK)
  225. return terr;
  226. if (DB_DESC_SIZE (desc) == 8 || DB_DESC_SIZE (desc) == bswap_32 (8))
  227. {
  228. uint8_t value = widened_value - (psaddr_t) 0;
  229. memcpy (address, &value, sizeof value);
  230. }
  231. else if (DB_DESC_SIZE (desc) == 32)
  232. {
  233. uint32_t value = widened_value - (psaddr_t) 0;
  234. memcpy (address, &value, sizeof value);
  235. }
  236. else if (DB_DESC_SIZE (desc) == 64)
  237. {
  238. uint64_t value = widened_value - (psaddr_t) 0;
  239. if (sizeof (psaddr_t) < 8)
  240. return TD_NOCAPAB;
  241. memcpy (address, &value, sizeof value);
  242. }
  243. else if (DB_DESC_SIZE (desc) == bswap_32 (32))
  244. {
  245. uint32_t value = widened_value - (psaddr_t) 0;
  246. value = bswap_32 (value);
  247. memcpy (address, &value, sizeof value);
  248. }
  249. else if (DB_DESC_SIZE (desc) == bswap_32 (64))
  250. {
  251. uint64_t value = widened_value - (psaddr_t) 0;
  252. if (sizeof (psaddr_t) < 8)
  253. return TD_NOCAPAB;
  254. value = bswap_64 (value);
  255. memcpy (address, &value, sizeof value);
  256. }
  257. else
  258. return TD_DBERR;
  259. return TD_OK;
  260. }