2 * This file is part of ltrace.
3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
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.
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.
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
32 value_common_init(struct value *valp, struct Process *inferior,
33 struct value *parent, struct arg_type_info *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;
46 value_init(struct value *valp, struct Process *inferior, struct value *parent,
47 struct arg_type_info *type, int own_type)
49 assert(inferior != NULL);
50 value_common_init(valp, inferior, parent, type, own_type);
54 value_init_detached(struct value *valp, struct value *parent,
55 struct arg_type_info *type, int own_type)
57 value_common_init(valp, NULL, parent, type, own_type);
61 value_set_type(struct value *value, struct arg_type_info *type, int own_type)
63 if (value->own_type) {
64 type_destroy(value->type);
68 value->own_type = own_type;
72 value_take_type(struct value *value, struct arg_type_info **type,
76 *own_type = value->own_type;
81 value_release(struct value *val)
85 if (val->where == VAL_LOC_COPY) {
87 val->where = VAL_LOC_NODATA;
92 value_destroy(struct value *val)
97 value_set_type(val, NULL, 0);
101 value_reserve(struct value *valp, size_t size)
105 if (size <= sizeof(valp->u.value)) {
106 valp->where = VAL_LOC_WORD;
109 valp->where = VAL_LOC_COPY;
110 valp->u.address = calloc(size, 1);
111 if (valp->u.address == 0)
114 return value_get_raw_data(valp);
118 value_in_inferior(struct value *valp, arch_addr_t address)
121 valp->where = VAL_LOC_INFERIOR;
122 valp->u.address = address;
126 value_reify(struct value *val, struct value_dict *arguments)
128 if (val->where != VAL_LOC_INFERIOR)
130 assert(val->inferior != NULL);
132 size_t size = value_size(val, arguments);
133 if (size == (size_t)-1)
137 enum value_location_t nloc;
138 if (size <= sizeof(val->u.value)) {
139 data = &val->u.value;
148 if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) {
149 if (nloc == VAL_LOC_COPY)
155 if (nloc == VAL_LOC_COPY)
156 val->u.address = data;
162 value_get_data(struct value *val, struct value_dict *arguments)
164 if (value_reify(val, arguments) < 0)
166 return value_get_raw_data(val);
170 value_get_raw_data(struct value *val)
172 switch (val->where) {
173 case VAL_LOC_INFERIOR:
179 return val->u.address;
184 assert(!"Unexpected value of val->where");
189 value_clone(struct value *retp, const struct value *val)
192 if (val->where == VAL_LOC_COPY) {
193 assert(val->inferior != NULL);
194 size_t size = type_sizeof(val->inferior, val->type);
195 if (size == (size_t)-1)
198 retp->u.address = malloc(size);
199 if (retp->u.address == NULL)
202 memcpy(retp->u.address, val->u.address, size);
209 value_size(struct value *val, struct value_dict *arguments)
211 if (val->size != (size_t)-1)
214 if (val->type->type != ARGTYPE_ARRAY)
215 return val->size = type_sizeof(val->inferior, val->type);
218 if (expr_eval(val->type->u.array_info.length, val,
219 arguments, &length) < 0)
223 int o = value_extract_word(&length, (long *)&l, arguments);
224 value_destroy(&length);
229 size_t elt_size = type_sizeof(val->inferior,
230 val->type->u.array_info.elt_type);
231 if (elt_size == (size_t)-1)
234 return val->size = elt_size * l;
238 value_init_element(struct value *ret_val, struct value *val, size_t element)
240 size_t off = type_offsetof(val->inferior, val->type, element);
241 if (off == (size_t)-1)
244 struct arg_type_info *e_info = type_element(val->type, element);
248 value_common_init(ret_val, val->inferior, val, e_info, 0);
250 switch (val->where) {
253 ret_val->u.address = val->u.address + off;
254 ret_val->where = VAL_LOC_SHARED;
258 ret_val->u.address = value_get_raw_data(val) + off;
259 ret_val->where = VAL_LOC_SHARED;
262 case VAL_LOC_INFERIOR:
263 ret_val->u.inf_address = val->u.inf_address + off;
264 ret_val->where = VAL_LOC_INFERIOR;
268 assert(!"Can't offset NODATA.");
275 value_init_deref(struct value *ret_val, struct value *valp)
277 assert(valp->type->type == ARGTYPE_POINTER);
279 /* Note: extracting a pointer value should not need value_dict
280 * with function arguments. */
282 if (value_extract_word(valp, &l, NULL) < 0)
285 /* We need "long" to be long enough to hold platform
287 typedef char assert__long_enough_long[-(sizeof(l) < sizeof(void *))];
289 value_common_init(ret_val, valp->inferior, valp,
290 valp->type->u.ptr_info.info, 0);
291 ret_val->u.value = l; /* Set the address. */
292 ret_val->where = VAL_LOC_INFERIOR;
296 /* The functions value_extract_buf and value_extract_word assume that
297 * data in VALUE is stored at the start of the internal buffer. For
298 * value_extract_buf in particular there's no other reasonable
299 * default. If we need to copy out four bytes, they need to be the
300 * bytes pointed to by the buffer pointer.
302 * But actually the situation is similar for value_extract_word as
303 * well. This function is used e.g. to extract characters from
304 * strings. Those weren't stored by value_set_word, they might still
305 * be in client for all we know. So value_extract_word has to assume
306 * that the whole of data is data is stored at the buffer pointer.
308 * This is a problem on big endian machines, where 2-byte quantity
309 * carried in 4- or 8-byte long is stored at the end of that long.
310 * (Though that quantity itself is still big endian.) So we need to
311 * make a little dance to shift the value to the right part of the
320 unsigned char buf[0];
324 value_set_word(struct value *value, long word)
326 size_t sz = type_sizeof(value->inferior, value->type);
327 assert(sz != (size_t)-1);
328 assert(sz <= sizeof(value->u.value));
330 value->where = VAL_LOC_WORD;
332 union word_data u = {};
355 value->u.value = u.l;
359 value_extract_buf_sz(struct value *value, unsigned char *tgt, size_t sz,
360 struct value_dict *arguments)
362 unsigned char *data = value_get_data(value, arguments);
366 memcpy(tgt, data, sz);
371 value_extract_word(struct value *value, long *retp,
372 struct value_dict *arguments)
374 size_t sz = type_sizeof(value->inferior, value->type);
375 if (sz == (size_t)-1)
377 assert(sz <= sizeof(value->u.value));
384 union word_data u = {};
385 if (value_extract_buf_sz(value, u.buf, sz, arguments) < 0)
408 value_extract_buf(struct value *value, unsigned char *tgt,
409 struct value_dict *arguments)
411 size_t sz = type_sizeof(value->inferior, value->type);
412 if (sz == (size_t)-1)
415 return value_extract_buf_sz(value, tgt, sz, arguments);
419 value_get_parental_struct(struct value *val)
421 struct value *parent;
422 for (parent = val->parent; parent != NULL; parent = parent->parent)
423 if (parent->type->type == ARGTYPE_STRUCT)
429 value_is_zero(struct value *val, struct value_dict *arguments)
431 unsigned char *data = value_get_data(val, arguments);
434 size_t sz = type_sizeof(val->inferior, val->type);
435 if (sz == (size_t)-1)
440 for (j = 0; j < sz; ++j) {
450 value_equal(struct value *val1, struct value *val2,
451 struct value_dict *arguments)
453 size_t sz1 = type_sizeof(val1->inferior, val1->type);
454 size_t sz2 = type_sizeof(val2->inferior, val2->type);
455 if (sz1 == (size_t)-1 || sz2 == (size_t)-1)
460 unsigned char *data1 = value_get_data(val1, arguments);
461 unsigned char *data2 = value_get_data(val2, arguments);
462 if (data1 == NULL || data2 == NULL)
464 return memcmp(data1, data2, sz1) == 0 ? 1 : 0;
468 value_pass_by_reference(struct value *value)
470 assert(value != NULL);
471 assert(value->type->type == ARGTYPE_STRUCT);
473 struct arg_type_info *new_info = calloc(sizeof(*new_info), 1);
474 if (new_info == NULL)
478 struct arg_type_info *orig;
479 value_take_type(value, &orig, &own);
480 type_init_pointer(new_info, orig, own);
481 new_info->lens = orig->lens;
482 value_set_type(value, new_info, 1);