OSDN Git Service

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