1 /* 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" 28 #include "expr.h" 29 #include "backend.h" 30 31 static void 32 value_common_init(struct value *valp, struct process *inferior, 33 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 45 void 46 value_init(struct value *valp, struct process *inferior, struct value *parent, 47 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 53 void 54 value_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 60 void 61 value_set_type(struct value *value, struct arg_type_info *type, int own_type) 62 { 63 if (value->own_type) { 64 type_destroy(value->type); 65 free(value->type); 66 } 67 value->type = type; 68 value->own_type = own_type; 69 } 70 71 void 72 value_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 80 void 81 value_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 91 void 92 value_destroy(struct value *val) 93 { 94 if (val == NULL) 95 return; 96 value_release(val); 97 value_set_type(val, NULL, 0); 98 } 99 100 unsigned char * 101 value_reserve(struct value *valp, size_t size) 102 { 103 value_release(valp); 104 105 if (size <= sizeof(valp->u.value)) { 106 valp->where = VAL_LOC_WORD; 107 valp->u.value = 0; 108 } 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 117 void 118 value_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 125 int 126 value_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 148 if (umovebytes(val->inferior, val->u.inf_address, data, size) < size) { 149 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 161 unsigned char * 162 value_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 169 unsigned char * 170 value_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 188 int 189 value_clone(struct value *retp, const struct value *val) 190 { 191 *retp = *val; 192 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 201 if (val->where == VAL_LOC_COPY) { 202 assert(val->inferior != NULL); 203 size_t size = type_sizeof(val->inferior, val->type); 204 if (size == (size_t)-1) { 205 fail: 206 if (retp->own_type) { 207 type_destroy(retp->type); 208 free(retp->type); 209 } 210 return -1; 211 } 212 213 retp->u.address = malloc(size); 214 if (retp->u.address == NULL) 215 goto fail; 216 217 memcpy(retp->u.address, val->u.address, size); 218 } 219 220 return 0; 221 } 222 223 size_t 224 value_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; 233 if (expr_eval(val->type->u.array_info.length, val, 234 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 244 size_t elt_size = type_sizeof(val->inferior, 245 val->type->u.array_info.elt_type); 246 if (elt_size == (size_t)-1) 247 return (size_t)-1; 248 249 return val->size = elt_size * l; 250 } 251 252 int 253 value_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: 278 ret_val->u.inf_address = val->u.inf_address + off; 279 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 289 int 290 value_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. */ 302 (void)sizeof(char[1 - 2*(sizeof(l) < sizeof(void *))]); 303 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 311 /* 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 329 union 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 338 void 339 value_set_word(struct value *value, long word) 340 { 341 size_t sz = type_sizeof(value->inferior, value->type); 342 assert(sz != (size_t)-1); 343 assert(sz <= sizeof(value->u.value)); 344 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 373 static int 374 value_extract_buf_sz(struct value *value, unsigned char *tgt, size_t sz, 375 struct value_dict *arguments) 376 { 377 unsigned char *data = value_get_data(value, arguments); 378 if (data == NULL) 379 return -1; 380 381 memcpy(tgt, data, sz); 382 return 0; 383 } 384 385 int 386 value_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; 392 assert(sz <= sizeof(value->u.value)); 393 394 if (sz == 0) { 395 *retp = 0; 396 return 0; 397 } 398 399 union word_data u = {}; 400 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 422 int 423 value_extract_buf(struct value *value, unsigned char *tgt, 424 struct value_dict *arguments) 425 { 426 size_t sz = type_sizeof(value->inferior, value->type); 427 if (sz == (size_t)-1) 428 return -1; 429 430 return value_extract_buf_sz(value, tgt, sz, arguments); 431 } 432 433 struct value * 434 value_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 443 int 444 value_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 } 463 464 int 465 value_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 482 int 483 value_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 } 501