|
Packit |
0021fb |
/*
|
|
Packit |
0021fb |
* This file is part of ltrace.
|
|
Packit |
0021fb |
* Copyright (C) 2011,2012 Petr Machata, Red Hat Inc.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This program is free software; you can redistribute it and/or
|
|
Packit |
0021fb |
* modify it under the terms of the GNU General Public License as
|
|
Packit |
0021fb |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
0021fb |
* License, or (at your option) any later version.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This program is distributed in the hope that it will be useful, but
|
|
Packit |
0021fb |
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
0021fb |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
0021fb |
* General Public License for more details.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* You should have received a copy of the GNU General Public License
|
|
Packit |
0021fb |
* along with this program; if not, write to the Free Software
|
|
Packit |
0021fb |
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
Packit |
0021fb |
* 02110-1301 USA
|
|
Packit |
0021fb |
*/
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#include <string.h>
|
|
Packit |
0021fb |
#include <assert.h>
|
|
Packit |
0021fb |
#include <stdlib.h>
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
#include "value.h"
|
|
Packit |
0021fb |
#include "type.h"
|
|
Packit |
0021fb |
#include "common.h"
|
|
Packit |
0021fb |
#include "expr.h"
|
|
Packit |
0021fb |
#include "backend.h"
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
static void
|
|
Packit |
0021fb |
value_common_init(struct value *valp, struct process *inferior,
|
|
Packit |
0021fb |
struct value *parent, struct arg_type_info *type,
|
|
Packit |
0021fb |
int own_type)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
valp->type = type;
|
|
Packit |
0021fb |
valp->own_type = own_type;
|
|
Packit |
0021fb |
valp->inferior = inferior;
|
|
Packit |
0021fb |
memset(&valp->u, 0, sizeof(valp->u));
|
|
Packit |
0021fb |
valp->where = VAL_LOC_NODATA;
|
|
Packit |
0021fb |
valp->parent = parent;
|
|
Packit |
0021fb |
valp->size = (size_t)-1;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_init(struct value *valp, struct process *inferior, struct value *parent,
|
|
Packit |
0021fb |
struct arg_type_info *type, int own_type)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
assert(inferior != NULL);
|
|
Packit |
0021fb |
value_common_init(valp, inferior, parent, type, own_type);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_init_detached(struct value *valp, struct value *parent,
|
|
Packit |
0021fb |
struct arg_type_info *type, int own_type)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
value_common_init(valp, NULL, parent, type, own_type);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_set_type(struct value *value, struct arg_type_info *type, int own_type)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (value->own_type) {
|
|
Packit |
0021fb |
type_destroy(value->type);
|
|
Packit |
0021fb |
free(value->type);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
value->type = type;
|
|
Packit |
0021fb |
value->own_type = own_type;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_take_type(struct value *value, struct arg_type_info **type,
|
|
Packit |
0021fb |
int *own_type)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
*type = value->type;
|
|
Packit |
0021fb |
*own_type = value->own_type;
|
|
Packit |
0021fb |
value->own_type = 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_release(struct value *val)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (val == NULL)
|
|
Packit |
0021fb |
return;
|
|
Packit |
0021fb |
if (val->where == VAL_LOC_COPY) {
|
|
Packit |
0021fb |
free(val->u.address);
|
|
Packit |
0021fb |
val->where = VAL_LOC_NODATA;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_destroy(struct value *val)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (val == NULL)
|
|
Packit |
0021fb |
return;
|
|
Packit |
0021fb |
value_release(val);
|
|
Packit |
0021fb |
value_set_type(val, NULL, 0);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
unsigned char *
|
|
Packit |
0021fb |
value_reserve(struct value *valp, size_t size)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
value_release(valp);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (size <= sizeof(valp->u.value)) {
|
|
Packit |
0021fb |
valp->where = VAL_LOC_WORD;
|
|
Packit |
0021fb |
valp->u.value = 0;
|
|
Packit |
0021fb |
} else {
|
|
Packit |
0021fb |
valp->where = VAL_LOC_COPY;
|
|
Packit |
0021fb |
valp->u.address = calloc(size, 1);
|
|
Packit |
0021fb |
if (valp->u.address == 0)
|
|
Packit |
0021fb |
return NULL;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
return value_get_raw_data(valp);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_in_inferior(struct value *valp, arch_addr_t address)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
value_release(valp);
|
|
Packit |
0021fb |
valp->where = VAL_LOC_INFERIOR;
|
|
Packit |
0021fb |
valp->u.address = address;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_reify(struct value *val, struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (val->where != VAL_LOC_INFERIOR)
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
assert(val->inferior != NULL);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
size_t size = value_size(val, arguments);
|
|
Packit |
0021fb |
if (size == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void *data;
|
|
Packit |
0021fb |
enum value_location_t nloc;
|
|
Packit |
0021fb |
if (size <= sizeof(val->u.value)) {
|
|
Packit |
0021fb |
data = &val->u.value;
|
|
Packit |
0021fb |
nloc = VAL_LOC_WORD;
|
|
Packit |
0021fb |
} else {
|
|
Packit |
0021fb |
data = malloc(size);
|
|
Packit |
0021fb |
if (data == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
nloc = VAL_LOC_COPY;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) {
|
|
Packit |
0021fb |
if (nloc == VAL_LOC_COPY)
|
|
Packit |
0021fb |
free(data);
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
val->where = nloc;
|
|
Packit |
0021fb |
if (nloc == VAL_LOC_COPY)
|
|
Packit |
0021fb |
val->u.address = data;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
unsigned char *
|
|
Packit |
0021fb |
value_get_data(struct value *val, struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (value_reify(val, arguments) < 0)
|
|
Packit |
0021fb |
return NULL;
|
|
Packit |
0021fb |
return value_get_raw_data(val);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
unsigned char *
|
|
Packit |
0021fb |
value_get_raw_data(struct value *val)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
switch (val->where) {
|
|
Packit |
0021fb |
case VAL_LOC_INFERIOR:
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
case VAL_LOC_NODATA:
|
|
Packit |
0021fb |
return NULL;
|
|
Packit |
0021fb |
case VAL_LOC_COPY:
|
|
Packit |
0021fb |
case VAL_LOC_SHARED:
|
|
Packit |
0021fb |
return val->u.address;
|
|
Packit |
0021fb |
case VAL_LOC_WORD:
|
|
Packit |
0021fb |
return val->u.buf;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
assert(!"Unexpected value of val->where");
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_clone(struct value *retp, const struct value *val)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
*retp = *val;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (val->own_type) {
|
|
Packit |
0021fb |
retp->type = malloc(sizeof(struct arg_type_info));
|
|
Packit |
0021fb |
if (type_clone (retp->type, val->type) < 0) {
|
|
Packit |
0021fb |
free(retp->type);
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (val->where == VAL_LOC_COPY) {
|
|
Packit |
0021fb |
assert(val->inferior != NULL);
|
|
Packit |
0021fb |
size_t size = type_sizeof(val->inferior, val->type);
|
|
Packit |
0021fb |
if (size == (size_t)-1) {
|
|
Packit |
0021fb |
fail:
|
|
Packit |
0021fb |
if (retp->own_type) {
|
|
Packit |
0021fb |
type_destroy(retp->type);
|
|
Packit |
0021fb |
free(retp->type);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
retp->u.address = malloc(size);
|
|
Packit |
0021fb |
if (retp->u.address == NULL)
|
|
Packit |
0021fb |
goto fail;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
memcpy(retp->u.address, val->u.address, size);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
size_t
|
|
Packit |
0021fb |
value_size(struct value *val, struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
if (val->size != (size_t)-1)
|
|
Packit |
0021fb |
return val->size;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (val->type->type != ARGTYPE_ARRAY)
|
|
Packit |
0021fb |
return val->size = type_sizeof(val->inferior, val->type);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
struct value length;
|
|
Packit |
0021fb |
if (expr_eval(val->type->u.array_info.length, val,
|
|
Packit |
0021fb |
arguments, &length) < 0)
|
|
Packit |
0021fb |
return (size_t)-1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
size_t l;
|
|
Packit |
0021fb |
int o = value_extract_word(&length, (long *)&l, arguments);
|
|
Packit |
0021fb |
value_destroy(&length);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (o < 0)
|
|
Packit |
0021fb |
return (size_t)-1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
size_t elt_size = type_sizeof(val->inferior,
|
|
Packit |
0021fb |
val->type->u.array_info.elt_type);
|
|
Packit |
0021fb |
if (elt_size == (size_t)-1)
|
|
Packit |
0021fb |
return (size_t)-1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
return val->size = elt_size * l;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_init_element(struct value *ret_val, struct value *val, size_t element)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
size_t off = type_offsetof(val->inferior, val->type, element);
|
|
Packit |
0021fb |
if (off == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
struct arg_type_info *e_info = type_element(val->type, element);
|
|
Packit |
0021fb |
if (e_info == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
value_common_init(ret_val, val->inferior, val, e_info, 0);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
switch (val->where) {
|
|
Packit |
0021fb |
case VAL_LOC_COPY:
|
|
Packit |
0021fb |
case VAL_LOC_SHARED:
|
|
Packit |
0021fb |
ret_val->u.address = val->u.address + off;
|
|
Packit |
0021fb |
ret_val->where = VAL_LOC_SHARED;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
case VAL_LOC_WORD:
|
|
Packit |
0021fb |
ret_val->u.address = value_get_raw_data(val) + off;
|
|
Packit |
0021fb |
ret_val->where = VAL_LOC_SHARED;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
case VAL_LOC_INFERIOR:
|
|
Packit |
0021fb |
ret_val->u.inf_address = val->u.inf_address + off;
|
|
Packit |
0021fb |
ret_val->where = VAL_LOC_INFERIOR;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
case VAL_LOC_NODATA:
|
|
Packit |
0021fb |
assert(!"Can't offset NODATA.");
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_init_deref(struct value *ret_val, struct value *valp)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
assert(valp->type->type == ARGTYPE_POINTER);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* Note: extracting a pointer value should not need value_dict
|
|
Packit |
0021fb |
* with function arguments. */
|
|
Packit |
0021fb |
long l;
|
|
Packit |
0021fb |
if (value_extract_word(valp, &l, NULL) < 0)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* We need "long" to be long enough to hold platform
|
|
Packit |
0021fb |
* pointers. */
|
|
Packit |
0021fb |
(void)sizeof(char[1 - 2*(sizeof(l) < sizeof(void *))]);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
value_common_init(ret_val, valp->inferior, valp,
|
|
Packit |
0021fb |
valp->type->u.ptr_info.info, 0);
|
|
Packit |
0021fb |
ret_val->u.value = l; /* Set the address. */
|
|
Packit |
0021fb |
ret_val->where = VAL_LOC_INFERIOR;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
/* The functions value_extract_buf and value_extract_word assume that
|
|
Packit |
0021fb |
* data in VALUE is stored at the start of the internal buffer. For
|
|
Packit |
0021fb |
* value_extract_buf in particular there's no other reasonable
|
|
Packit |
0021fb |
* default. If we need to copy out four bytes, they need to be the
|
|
Packit |
0021fb |
* bytes pointed to by the buffer pointer.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* But actually the situation is similar for value_extract_word as
|
|
Packit |
0021fb |
* well. This function is used e.g. to extract characters from
|
|
Packit |
0021fb |
* strings. Those weren't stored by value_set_word, they might still
|
|
Packit |
0021fb |
* be in client for all we know. So value_extract_word has to assume
|
|
Packit |
0021fb |
* that the whole of data is data is stored at the buffer pointer.
|
|
Packit |
0021fb |
*
|
|
Packit |
0021fb |
* This is a problem on big endian machines, where 2-byte quantity
|
|
Packit |
0021fb |
* carried in 4- or 8-byte long is stored at the end of that long.
|
|
Packit |
0021fb |
* (Though that quantity itself is still big endian.) So we need to
|
|
Packit |
0021fb |
* make a little dance to shift the value to the right part of the
|
|
Packit |
0021fb |
* buffer. */
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
union word_data {
|
|
Packit |
0021fb |
uint8_t u8;
|
|
Packit |
0021fb |
uint16_t u16;
|
|
Packit |
0021fb |
uint32_t u32;
|
|
Packit |
0021fb |
uint64_t u64;
|
|
Packit |
0021fb |
long l;
|
|
Packit |
0021fb |
unsigned char buf[0];
|
|
Packit |
0021fb |
} u;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
void
|
|
Packit |
0021fb |
value_set_word(struct value *value, long word)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
size_t sz = type_sizeof(value->inferior, value->type);
|
|
Packit |
0021fb |
assert(sz != (size_t)-1);
|
|
Packit |
0021fb |
assert(sz <= sizeof(value->u.value));
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
value->where = VAL_LOC_WORD;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
union word_data u = {};
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
switch (sz) {
|
|
Packit |
0021fb |
case 0:
|
|
Packit |
0021fb |
u.l = 0;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
case 1:
|
|
Packit |
0021fb |
u.u8 = word;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
case 2:
|
|
Packit |
0021fb |
u.u16 = word;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
case 4:
|
|
Packit |
0021fb |
u.u32 = word;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
case 8:
|
|
Packit |
0021fb |
u.u64 = word;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
default:
|
|
Packit |
0021fb |
assert(sz != sz);
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
value->u.value = u.l;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
static int
|
|
Packit |
0021fb |
value_extract_buf_sz(struct value *value, unsigned char *tgt, size_t sz,
|
|
Packit |
0021fb |
struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
unsigned char *data = value_get_data(value, arguments);
|
|
Packit |
0021fb |
if (data == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
memcpy(tgt, data, sz);
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_extract_word(struct value *value, long *retp,
|
|
Packit |
0021fb |
struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
size_t sz = type_sizeof(value->inferior, value->type);
|
|
Packit |
0021fb |
if (sz == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
assert(sz <= sizeof(value->u.value));
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
if (sz == 0) {
|
|
Packit |
0021fb |
*retp = 0;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
union word_data u = {};
|
|
Packit |
0021fb |
if (value_extract_buf_sz(value, u.buf, sz, arguments) < 0)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
switch (sz) {
|
|
Packit |
0021fb |
case 1:
|
|
Packit |
0021fb |
*retp = (long)u.u8;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
case 2:
|
|
Packit |
0021fb |
*retp = (long)u.u16;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
case 4:
|
|
Packit |
0021fb |
*retp = (long)u.u32;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
case 8:
|
|
Packit |
0021fb |
*retp = (long)u.u64;
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
default:
|
|
Packit |
0021fb |
assert(sz != sz);
|
|
Packit |
0021fb |
abort();
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_extract_buf(struct value *value, unsigned char *tgt,
|
|
Packit |
0021fb |
struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
size_t sz = type_sizeof(value->inferior, value->type);
|
|
Packit |
0021fb |
if (sz == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
return value_extract_buf_sz(value, tgt, sz, arguments);
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
struct value *
|
|
Packit |
0021fb |
value_get_parental_struct(struct value *val)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
struct value *parent;
|
|
Packit |
0021fb |
for (parent = val->parent; parent != NULL; parent = parent->parent)
|
|
Packit |
0021fb |
if (parent->type->type == ARGTYPE_STRUCT)
|
|
Packit |
0021fb |
return parent;
|
|
Packit |
0021fb |
return NULL;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_is_zero(struct value *val, struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
unsigned char *data = value_get_data(val, arguments);
|
|
Packit |
0021fb |
if (data == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
size_t sz = type_sizeof(val->inferior, val->type);
|
|
Packit |
0021fb |
if (sz == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int zero = 1;
|
|
Packit |
0021fb |
size_t j;
|
|
Packit |
0021fb |
for (j = 0; j < sz; ++j) {
|
|
Packit |
0021fb |
if (data[j] != 0) {
|
|
Packit |
0021fb |
zero = 0;
|
|
Packit |
0021fb |
break;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
return zero;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_equal(struct value *val1, struct value *val2,
|
|
Packit |
0021fb |
struct value_dict *arguments)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
size_t sz1 = type_sizeof(val1->inferior, val1->type);
|
|
Packit |
0021fb |
size_t sz2 = type_sizeof(val2->inferior, val2->type);
|
|
Packit |
0021fb |
if (sz1 == (size_t)-1 || sz2 == (size_t)-1)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
if (sz1 != sz2)
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
unsigned char *data1 = value_get_data(val1, arguments);
|
|
Packit |
0021fb |
unsigned char *data2 = value_get_data(val2, arguments);
|
|
Packit |
0021fb |
if (data1 == NULL || data2 == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
return memcmp(data1, data2, sz1) == 0 ? 1 : 0;
|
|
Packit |
0021fb |
}
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int
|
|
Packit |
0021fb |
value_pass_by_reference(struct value *value)
|
|
Packit |
0021fb |
{
|
|
Packit |
0021fb |
assert(value != NULL);
|
|
Packit |
0021fb |
assert(value->type->type == ARGTYPE_STRUCT);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
struct arg_type_info *new_info = calloc(sizeof(*new_info), 1);
|
|
Packit |
0021fb |
if (new_info == NULL)
|
|
Packit |
0021fb |
return -1;
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
int own;
|
|
Packit |
0021fb |
struct arg_type_info *orig;
|
|
Packit |
0021fb |
value_take_type(value, &orig, &own);
|
|
Packit |
0021fb |
type_init_pointer(new_info, orig, own);
|
|
Packit |
0021fb |
new_info->lens = orig->lens;
|
|
Packit |
0021fb |
value_set_type(value, new_info, 1);
|
|
Packit |
0021fb |
|
|
Packit |
0021fb |
return 0;
|
|
Packit |
0021fb |
}
|