blob: 2125ba9435284df8d6d621c0257659bf0c379939 [file] [log] [blame]
Petr Machata000e3112012-01-03 17:03:39 +01001/*
2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 */
20
21#include <string.h>
22#include <assert.h>
23#include <stdlib.h>
24
25#include "value.h"
26#include "type.h"
27#include "common.h"
Petr Machata94078ec2012-01-05 18:07:02 +010028#include "expr.h"
Petr Machata64262602012-01-07 03:41:36 +010029#include "backend.h"
Petr Machata000e3112012-01-03 17:03:39 +010030
31static void
Petr Machata929bd572012-12-17 03:20:34 +010032value_common_init(struct value *valp, struct process *inferior,
Petr Machata000e3112012-01-03 17:03:39 +010033 struct value *parent, struct arg_type_info *type,
34 int own_type)
35{
36 valp->type = type;
37 valp->own_type = own_type;
38 valp->inferior = inferior;
39 memset(&valp->u, 0, sizeof(valp->u));
40 valp->where = VAL_LOC_NODATA;
41 valp->parent = parent;
42 valp->size = (size_t)-1;
43}
44
45void
Petr Machata929bd572012-12-17 03:20:34 +010046value_init(struct value *valp, struct process *inferior, struct value *parent,
Petr Machata000e3112012-01-03 17:03:39 +010047 struct arg_type_info *type, int own_type)
48{
49 assert(inferior != NULL);
50 value_common_init(valp, inferior, parent, type, own_type);
51}
52
53void
54value_init_detached(struct value *valp, struct value *parent,
55 struct arg_type_info *type, int own_type)
56{
57 value_common_init(valp, NULL, parent, type, own_type);
58}
59
60void
61value_set_type(struct value *value, struct arg_type_info *type, int own_type)
62{
Petr Machata635786d2012-10-30 00:26:21 +010063 if (value->own_type) {
Petr Machata000e3112012-01-03 17:03:39 +010064 type_destroy(value->type);
Petr Machata635786d2012-10-30 00:26:21 +010065 free(value->type);
66 }
Petr Machata000e3112012-01-03 17:03:39 +010067 value->type = type;
68 value->own_type = own_type;
69}
70
71void
72value_take_type(struct value *value, struct arg_type_info **type,
73 int *own_type)
74{
75 *type = value->type;
76 *own_type = value->own_type;
77 value->own_type = 0;
78}
79
80void
81value_release(struct value *val)
82{
83 if (val == NULL)
84 return;
85 if (val->where == VAL_LOC_COPY) {
86 free(val->u.address);
87 val->where = VAL_LOC_NODATA;
88 }
89}
90
91void
92value_destroy(struct value *val)
93{
94 if (val == NULL)
95 return;
96 value_release(val);
97 value_set_type(val, NULL, 0);
98}
99
Petr Machata000e3112012-01-03 17:03:39 +0100100unsigned char *
101value_reserve(struct value *valp, size_t size)
102{
Petr Machata0d40d112012-10-30 16:41:44 +0100103 value_release(valp);
104
Petr Machata000e3112012-01-03 17:03:39 +0100105 if (size <= sizeof(valp->u.value)) {
Petr Machata5062d312012-05-04 13:09:35 +0200106 valp->where = VAL_LOC_WORD;
107 valp->u.value = 0;
Petr Machata000e3112012-01-03 17:03:39 +0100108 } else {
109 valp->where = VAL_LOC_COPY;
110 valp->u.address = calloc(size, 1);
111 if (valp->u.address == 0)
112 return NULL;
113 }
114 return value_get_raw_data(valp);
115}
116
Petr Machata429b1842012-10-30 16:44:52 +0100117void
118value_in_inferior(struct value *valp, arch_addr_t address)
119{
120 value_release(valp);
121 valp->where = VAL_LOC_INFERIOR;
122 valp->u.address = address;
123}
124
Petr Machata000e3112012-01-03 17:03:39 +0100125int
126value_reify(struct value *val, struct value_dict *arguments)
127{
128 if (val->where != VAL_LOC_INFERIOR)
129 return 0;
130 assert(val->inferior != NULL);
131
132 size_t size = value_size(val, arguments);
133 if (size == (size_t)-1)
134 return -1;
135
136 void *data;
137 enum value_location_t nloc;
138 if (size <= sizeof(val->u.value)) {
139 data = &val->u.value;
140 nloc = VAL_LOC_WORD;
141 } else {
142 data = malloc(size);
143 if (data == NULL)
144 return -1;
145 nloc = VAL_LOC_COPY;
146 }
147
Petr Machata2b955a52012-10-29 18:50:17 +0100148 if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) {
Petr Machata000e3112012-01-03 17:03:39 +0100149 if (nloc == VAL_LOC_COPY)
150 free(data);
151 return -1;
152 }
153
154 val->where = nloc;
155 if (nloc == VAL_LOC_COPY)
156 val->u.address = data;
157
158 return 0;
159}
160
161unsigned char *
162value_get_data(struct value *val, struct value_dict *arguments)
163{
164 if (value_reify(val, arguments) < 0)
165 return NULL;
166 return value_get_raw_data(val);
167}
168
169unsigned char *
170value_get_raw_data(struct value *val)
171{
172 switch (val->where) {
173 case VAL_LOC_INFERIOR:
174 abort();
175 case VAL_LOC_NODATA:
176 return NULL;
177 case VAL_LOC_COPY:
178 case VAL_LOC_SHARED:
179 return val->u.address;
180 case VAL_LOC_WORD:
181 return val->u.buf;
182 }
183
184 assert(!"Unexpected value of val->where");
185 abort();
186}
187
188int
Petr Machataedce6cf2012-11-26 15:51:12 +0100189value_clone(struct value *retp, const struct value *val)
Petr Machata000e3112012-01-03 17:03:39 +0100190{
191 *retp = *val;
Petr Machatacd6ff362013-10-10 14:50:28 +0200192
193 if (val->own_type) {
194 retp->type = malloc(sizeof(struct arg_type_info));
195 if (type_clone (retp->type, val->type) < 0) {
196 free(retp->type);
197 return -1;
198 }
199 }
200
Petr Machata000e3112012-01-03 17:03:39 +0100201 if (val->where == VAL_LOC_COPY) {
202 assert(val->inferior != NULL);
203 size_t size = type_sizeof(val->inferior, val->type);
Petr Machatacd6ff362013-10-10 14:50:28 +0200204 if (size == (size_t)-1) {
205 fail:
206 if (retp->own_type) {
207 type_destroy(retp->type);
208 free(retp->type);
209 }
Petr Machata000e3112012-01-03 17:03:39 +0100210 return -1;
Petr Machatacd6ff362013-10-10 14:50:28 +0200211 }
Petr Machata000e3112012-01-03 17:03:39 +0100212
213 retp->u.address = malloc(size);
214 if (retp->u.address == NULL)
Petr Machatacd6ff362013-10-10 14:50:28 +0200215 goto fail;
Petr Machata000e3112012-01-03 17:03:39 +0100216
217 memcpy(retp->u.address, val->u.address, size);
218 }
219
220 return 0;
221}
222
Petr Machata000e3112012-01-03 17:03:39 +0100223size_t
224value_size(struct value *val, struct value_dict *arguments)
225{
226 if (val->size != (size_t)-1)
227 return val->size;
228
229 if (val->type->type != ARGTYPE_ARRAY)
230 return val->size = type_sizeof(val->inferior, val->type);
231
232 struct value length;
Petr Machata94078ec2012-01-05 18:07:02 +0100233 if (expr_eval(val->type->u.array_info.length, val,
Petr Machata000e3112012-01-03 17:03:39 +0100234 arguments, &length) < 0)
235 return (size_t)-1;
236
237 size_t l;
238 int o = value_extract_word(&length, (long *)&l, arguments);
239 value_destroy(&length);
240
241 if (o < 0)
242 return (size_t)-1;
243
Petr Machata47671872012-01-07 01:04:40 +0100244 size_t elt_size = type_sizeof(val->inferior,
245 val->type->u.array_info.elt_type);
Petr Machata000e3112012-01-03 17:03:39 +0100246 if (elt_size == (size_t)-1)
247 return (size_t)-1;
248
249 return val->size = elt_size * l;
250}
251
252int
253value_init_element(struct value *ret_val, struct value *val, size_t element)
254{
255 size_t off = type_offsetof(val->inferior, val->type, element);
256 if (off == (size_t)-1)
257 return -1;
258
259 struct arg_type_info *e_info = type_element(val->type, element);
260 if (e_info == NULL)
261 return -1;
262
263 value_common_init(ret_val, val->inferior, val, e_info, 0);
264
265 switch (val->where) {
266 case VAL_LOC_COPY:
267 case VAL_LOC_SHARED:
268 ret_val->u.address = val->u.address + off;
269 ret_val->where = VAL_LOC_SHARED;
270 return 0;
271
272 case VAL_LOC_WORD:
273 ret_val->u.address = value_get_raw_data(val) + off;
274 ret_val->where = VAL_LOC_SHARED;
275 return 0;
276
277 case VAL_LOC_INFERIOR:
Petr Machata2b955a52012-10-29 18:50:17 +0100278 ret_val->u.inf_address = val->u.inf_address + off;
Petr Machata000e3112012-01-03 17:03:39 +0100279 ret_val->where = VAL_LOC_INFERIOR;
280 return 0;
281
282 case VAL_LOC_NODATA:
283 assert(!"Can't offset NODATA.");
284 abort();
285 }
286 abort();
287}
288
289int
290value_init_deref(struct value *ret_val, struct value *valp)
291{
292 assert(valp->type->type == ARGTYPE_POINTER);
293
294 /* Note: extracting a pointer value should not need value_dict
295 * with function arguments. */
296 long l;
297 if (value_extract_word(valp, &l, NULL) < 0)
298 return -1;
299
300 /* We need "long" to be long enough to hold platform
301 * pointers. */
Peter Wua77b2672013-09-26 00:55:55 +0200302 (void)sizeof(char[1 - 2*(sizeof(l) < sizeof(void *))]);
Petr Machata000e3112012-01-03 17:03:39 +0100303
304 value_common_init(ret_val, valp->inferior, valp,
305 valp->type->u.ptr_info.info, 0);
306 ret_val->u.value = l; /* Set the address. */
307 ret_val->where = VAL_LOC_INFERIOR;
308 return 0;
309}
310
Petr Machata4c2109a2012-05-04 03:56:12 +0200311/* The functions value_extract_buf and value_extract_word assume that
312 * data in VALUE is stored at the start of the internal buffer. For
313 * value_extract_buf in particular there's no other reasonable
314 * default. If we need to copy out four bytes, they need to be the
315 * bytes pointed to by the buffer pointer.
316 *
317 * But actually the situation is similar for value_extract_word as
318 * well. This function is used e.g. to extract characters from
319 * strings. Those weren't stored by value_set_word, they might still
320 * be in client for all we know. So value_extract_word has to assume
321 * that the whole of data is data is stored at the buffer pointer.
322 *
323 * This is a problem on big endian machines, where 2-byte quantity
324 * carried in 4- or 8-byte long is stored at the end of that long.
325 * (Though that quantity itself is still big endian.) So we need to
326 * make a little dance to shift the value to the right part of the
327 * buffer. */
328
329union word_data {
330 uint8_t u8;
331 uint16_t u16;
332 uint32_t u32;
333 uint64_t u64;
334 long l;
335 unsigned char buf[0];
336} u;
337
338void
339value_set_word(struct value *value, long word)
340{
341 size_t sz = type_sizeof(value->inferior, value->type);
342 assert(sz != (size_t)-1);
Petr Machataac147e92012-05-04 13:10:04 +0200343 assert(sz <= sizeof(value->u.value));
Petr Machata4c2109a2012-05-04 03:56:12 +0200344
345 value->where = VAL_LOC_WORD;
346
347 union word_data u = {};
348
349 switch (sz) {
350 case 0:
351 u.l = 0;
352 break;
353 case 1:
354 u.u8 = word;
355 break;
356 case 2:
357 u.u16 = word;
358 break;
359 case 4:
360 u.u32 = word;
361 break;
362 case 8:
363 u.u64 = word;
364 break;
365 default:
366 assert(sz != sz);
367 abort();
368 }
369
370 value->u.value = u.l;
371}
372
Petr Machataad168452012-05-04 03:22:59 +0200373static int
374value_extract_buf_sz(struct value *value, unsigned char *tgt, size_t sz,
375 struct value_dict *arguments)
Petr Machata000e3112012-01-03 17:03:39 +0100376{
Petr Machataad168452012-05-04 03:22:59 +0200377 unsigned char *data = value_get_data(value, arguments);
378 if (data == NULL)
Petr Machata000e3112012-01-03 17:03:39 +0100379 return -1;
Petr Machataad168452012-05-04 03:22:59 +0200380
381 memcpy(tgt, data, sz);
Petr Machata000e3112012-01-03 17:03:39 +0100382 return 0;
383}
384
385int
Petr Machataad168452012-05-04 03:22:59 +0200386value_extract_word(struct value *value, long *retp,
387 struct value_dict *arguments)
388{
389 size_t sz = type_sizeof(value->inferior, value->type);
390 if (sz == (size_t)-1)
391 return -1;
Petr Machataac147e92012-05-04 13:10:04 +0200392 assert(sz <= sizeof(value->u.value));
Petr Machataad168452012-05-04 03:22:59 +0200393
394 if (sz == 0) {
395 *retp = 0;
396 return 0;
397 }
398
Petr Machata4c2109a2012-05-04 03:56:12 +0200399 union word_data u = {};
Petr Machataad168452012-05-04 03:22:59 +0200400 if (value_extract_buf_sz(value, u.buf, sz, arguments) < 0)
401 return -1;
402
403 switch (sz) {
404 case 1:
405 *retp = (long)u.u8;
406 return 0;
407 case 2:
408 *retp = (long)u.u16;
409 return 0;
410 case 4:
411 *retp = (long)u.u32;
412 return 0;
413 case 8:
414 *retp = (long)u.u64;
415 return 0;
416 default:
417 assert(sz != sz);
418 abort();
419 }
420}
421
422int
Petr Machata000e3112012-01-03 17:03:39 +0100423value_extract_buf(struct value *value, unsigned char *tgt,
424 struct value_dict *arguments)
425{
Petr Machata000e3112012-01-03 17:03:39 +0100426 size_t sz = type_sizeof(value->inferior, value->type);
427 if (sz == (size_t)-1)
428 return -1;
429
Petr Machataad168452012-05-04 03:22:59 +0200430 return value_extract_buf_sz(value, tgt, sz, arguments);
Petr Machata000e3112012-01-03 17:03:39 +0100431}
432
433struct value *
434value_get_parental_struct(struct value *val)
435{
436 struct value *parent;
437 for (parent = val->parent; parent != NULL; parent = parent->parent)
438 if (parent->type->type == ARGTYPE_STRUCT)
439 return parent;
440 return NULL;
441}
442
443int
444value_is_zero(struct value *val, struct value_dict *arguments)
445{
446 unsigned char *data = value_get_data(val, arguments);
447 if (data == NULL)
448 return -1;
449 size_t sz = type_sizeof(val->inferior, val->type);
450 if (sz == (size_t)-1)
451 return -1;
452
453 int zero = 1;
454 size_t j;
455 for (j = 0; j < sz; ++j) {
456 if (data[j] != 0) {
457 zero = 0;
458 break;
459 }
460 }
461 return zero;
462}
Petr Machata2fb192b2012-05-04 14:18:35 +0200463
464int
Petr Machata40bab822012-11-19 00:11:22 +0100465value_equal(struct value *val1, struct value *val2,
466 struct value_dict *arguments)
467{
468 size_t sz1 = type_sizeof(val1->inferior, val1->type);
469 size_t sz2 = type_sizeof(val2->inferior, val2->type);
470 if (sz1 == (size_t)-1 || sz2 == (size_t)-1)
471 return -1;
472 if (sz1 != sz2)
473 return 0;
474
475 unsigned char *data1 = value_get_data(val1, arguments);
476 unsigned char *data2 = value_get_data(val2, arguments);
477 if (data1 == NULL || data2 == NULL)
478 return -1;
479 return memcmp(data1, data2, sz1) == 0 ? 1 : 0;
480}
481
482int
Petr Machata2fb192b2012-05-04 14:18:35 +0200483value_pass_by_reference(struct value *value)
484{
485 assert(value != NULL);
486 assert(value->type->type == ARGTYPE_STRUCT);
487
488 struct arg_type_info *new_info = calloc(sizeof(*new_info), 1);
489 if (new_info == NULL)
490 return -1;
491
492 int own;
493 struct arg_type_info *orig;
494 value_take_type(value, &orig, &own);
495 type_init_pointer(new_info, orig, own);
496 new_info->lens = orig->lens;
497 value_set_type(value, new_info, 1);
498
499 return 0;
500}