lens_default.c revision ec4ab256e5c7fe1596dd90a3c8e8d4b052ca1207
1/* 2 * This file is part of ltrace. 3 * Copyright (C) 2011,2012 Petr Machata, Red Hat Inc. 4 * Copyright (C) 1998,2004,2007,2008,2009 Juan Cespedes 5 * Copyright (C) 2006 Ian Wienand 6 * Copyright (C) 2006 Steve Fink 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of the 11 * License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * 02110-1301 USA 22 */ 23 24#include <ctype.h> 25#include <stdlib.h> 26#include <assert.h> 27#include <inttypes.h> 28#include <stdarg.h> 29#include <stdio.h> 30#include <string.h> 31 32#include "proc.h" 33#include "lens_default.h" 34#include "value.h" 35#include "expr.h" 36#include "type.h" 37#include "common.h" 38#include "zero.h" 39 40#define READER(NAME, TYPE) \ 41 static int \ 42 NAME(struct value *value, TYPE *ret, struct value_dict *arguments) \ 43 { \ 44 union { \ 45 TYPE val; \ 46 unsigned char buf[0]; \ 47 } u; \ 48 if (value_extract_buf(value, u.buf, arguments) < 0) \ 49 return -1; \ 50 *ret = u.val; \ 51 return 0; \ 52 } 53 54READER(read_float, float) 55READER(read_double, double) 56 57#undef READER 58 59#define HANDLE_WIDTH(BITS) \ 60 do { \ 61 long l; \ 62 if (value_extract_word(value, &l, arguments) < 0) \ 63 return -1; \ 64 int##BITS##_t i = l; \ 65 uint64_t v = (uint64_t)(uint##BITS##_t)i; \ 66 switch (format) { \ 67 case INT_FMT_unknown: \ 68 if (l < -10000 || l > 10000) \ 69 case INT_FMT_x: \ 70 return fprintf(stream, "%#"PRIx64, v); \ 71 case INT_FMT_i: \ 72 case INT_FMT_default: \ 73 return fprintf(stream, "%"PRIi##BITS, i); \ 74 case INT_FMT_u: \ 75 return fprintf(stream, "%"PRIu64, v); \ 76 case INT_FMT_o: \ 77 return fprintf(stream, "0%"PRIo64, v); \ 78 } \ 79 } while (0) 80 81enum int_fmt_t 82{ 83 INT_FMT_i, 84 INT_FMT_u, 85 INT_FMT_o, 86 INT_FMT_x, 87 INT_FMT_unknown, 88 INT_FMT_default, 89}; 90 91static int 92format_integer(FILE *stream, struct value *value, enum int_fmt_t format, 93 struct value_dict *arguments) 94{ 95 switch (type_sizeof(value->inferior, value->type)) { 96 97 case 1: HANDLE_WIDTH(8); 98 case 2: HANDLE_WIDTH(16); 99 case 4: HANDLE_WIDTH(32); 100 case 8: HANDLE_WIDTH(64); 101 102 default: 103 assert(!"unsupported integer width"); 104 abort(); 105 106 case -1: 107 return -1; 108 } 109} 110 111#undef HANDLE_WIDTH 112 113static int 114acc_fprintf(int *countp, FILE *stream, const char *format, ...) 115{ 116 va_list pa; 117 va_start(pa, format); 118 int i = account_output(countp, vfprintf(stream, format, pa)); 119 va_end(pa); 120 121 return i; 122} 123 124static int 125format_char(FILE *stream, struct value *value, struct value_dict *arguments) 126{ 127 long lc; 128 if (value_extract_word(value, &lc, arguments) < 0) 129 return -1; 130 int c = (int)lc; 131 132 const char *fmt; 133 switch (c) { 134 case -1: 135 fmt = "EOF"; 136 break; 137 case 0: 138 fmt = "\\0"; 139 break; 140 case '\a': 141 fmt = "\\a"; 142 break; 143 case '\b': 144 fmt = "\\b"; 145 break; 146 case '\t': 147 fmt = "\\t"; 148 break; 149 case '\n': 150 fmt = "\\n"; 151 break; 152 case '\v': 153 fmt = "\\v"; 154 break; 155 case '\f': 156 fmt = "\\f"; 157 break; 158 case '\r': 159 fmt = "\\r"; 160 break; 161 case '\\': 162 fmt = "\\\\"; 163 break; 164 default: 165 if (isprint(c) || c == ' ') 166 fmt = "%c"; 167 else 168 fmt = "\\%03o"; 169 } 170 171 return fprintf(stream, fmt, c); 172} 173 174static int 175format_naked_char(FILE *stream, struct value *value, 176 struct value_dict *arguments) 177{ 178 int written = 0; 179 if (acc_fprintf(&written, stream, "'") < 0 180 || account_output(&written, 181 format_char(stream, value, arguments)) < 0 182 || acc_fprintf(&written, stream, "'") < 0) 183 return -1; 184 185 return written; 186} 187 188static int 189format_floating(FILE *stream, struct value *value, struct value_dict *arguments) 190{ 191 switch (value->type->type) { 192 float f; 193 double d; 194 case ARGTYPE_FLOAT: 195 if (read_float(value, &f, arguments) < 0) 196 return -1; 197 return fprintf(stream, "%f", (double)f); 198 case ARGTYPE_DOUBLE: 199 if (read_double(value, &d, arguments) < 0) 200 return -1; 201 return fprintf(stream, "%f", d); 202 default: 203 abort(); 204 } 205} 206 207struct format_argument_data 208{ 209 struct value *value; 210 struct value_dict *arguments; 211}; 212 213static int 214format_argument_cb(FILE *stream, void *ptr) 215{ 216 struct format_argument_data *data = ptr; 217 return format_argument(stream, data->value, data->arguments); 218} 219 220static int 221format_struct(FILE *stream, struct value *value, struct value_dict *arguments) 222{ 223 int written = 0; 224 if (acc_fprintf(&written, stream, "{ ") < 0) 225 return -1; 226 227 int need_delim = 0; 228 size_t i; 229 for (i = 0; i < type_struct_size(value->type); ++i) { 230 struct value element; 231 if (value_init_element(&element, value, i) < 0) 232 return -1; 233 234 struct format_argument_data data = { &element, arguments }; 235 int o = delim_output(stream, &need_delim, 236 format_argument_cb, &data); 237 value_destroy(&element); 238 if (o < 0) 239 return -1; 240 241 written += o; 242 } 243 if (acc_fprintf(&written, stream, " }") < 0) 244 return -1; 245 return written; 246} 247 248int 249format_pointer(FILE *stream, struct value *value, struct value_dict *arguments) 250{ 251 if (value_is_zero(value, arguments)) 252 return fprintf(stream, "nil"); 253 254 /* The following is for detecting recursion. We keep track of 255 * the values that were already displayed. Each time a 256 * pointer should be dereferenced, we compare its value to the 257 * value of each of the pointers dereferenced so far. If one 258 * of them matches, instead of recursing, we just printf which 259 * superstructure this pointer recurses to. */ 260 static struct vect pointers = {}; 261 if (pointers.elt_size == 0) 262 VECT_INIT(&pointers, struct value *); 263 264 /* Trim number of expanded structures of the same type. Even 265 * for non-recursive structure, we don't want to expand all of 266 * it if it's huge. */ 267 size_t i; 268 size_t len = vect_size(&pointers); 269 assert(value->type->type == ARGTYPE_POINTER); 270 struct arg_type_info *pointee = value->type->u.ptr_info.info; 271 if (pointee->type == ARGTYPE_STRUCT) { 272 size_t depth = 0; 273 for (i = 0; i < len; ++i) { 274 struct value *old 275 = *VECT_ELEMENT(&pointers, struct value *, i); 276 assert(old->type->type == ARGTYPE_POINTER); 277 struct arg_type_info *old_pointee 278 = old->type->u.ptr_info.info; 279 if (old_pointee == pointee) 280 depth++; 281 } 282 if (depth >= options.arraylen) 283 return fprintf(stream, "..."); 284 } 285 286 for (i = len; i-- > 0 ;) { 287 struct value **old = VECT_ELEMENT(&pointers, struct value *, i); 288 int rc = value_equal(value, *old, arguments); 289 if (rc < 0) 290 return -1; 291 if (rc > 0) { 292 size_t reclevel = len - i - 1; 293 char buf[reclevel + 1]; 294 memset(buf, '^', sizeof buf); 295 buf[reclevel] = 0; 296 return fprintf(stream, "recurse%s", buf); 297 } 298 } 299 300 /* OK, not a recursion. Remember this value for tracking. */ 301 if (VECT_PUSHBACK(&pointers, &value) < 0) 302 return -1; 303 304 struct value element; 305 int o; 306 if (value_init_deref(&element, value) < 0) { 307 o = -1; 308 goto done; 309 } 310 o = format_argument(stream, &element, arguments); 311 value_destroy(&element); 312 313done: 314 vect_popback(&pointers); 315 return o; 316} 317 318/* 319 * LENGTH is an expression whose evaluation will yield the actual 320 * length of the array. 321 * 322 * MAXLEN is the actual maximum length that we care about 323 * 324 * BEFORE if LENGTH>MAXLEN, we display ellipsis. We display it before 325 * the closing parenthesis if BEFORE, otherwise after it. 326 * 327 * OPEN, CLOSE, DELIM are opening and closing parenthesis and element 328 * delimiter. 329 */ 330int 331format_array(FILE *stream, struct value *value, struct value_dict *arguments, 332 struct expr_node *length, size_t maxlen, int before, 333 const char *open, const char *close, const char *delim) 334{ 335 /* We need "long" to be long enough to cover the whole address 336 * space. */ 337 typedef char assert__long_enough_long[-(sizeof(long) < sizeof(void *))]; 338 long l; 339 if (expr_eval_word(length, value, arguments, &l) < 0) 340 return -1; 341 size_t len = (size_t)l; 342 343 int written = 0; 344 if (acc_fprintf(&written, stream, "%s", open) < 0) 345 return -1; 346 347 size_t i; 348 for (i = 0; i < len && i <= maxlen; ++i) { 349 if (i == maxlen) { 350 if (before && acc_fprintf(&written, stream, "...") < 0) 351 return -1; 352 break; 353 } 354 355 if (i > 0 && acc_fprintf(&written, stream, "%s", delim) < 0) 356 return -1; 357 358 struct value element; 359 if (value_init_element(&element, value, i) < 0) 360 return -1; 361 int o = format_argument(stream, &element, arguments); 362 value_destroy(&element); 363 if (o < 0) 364 return -1; 365 written += o; 366 } 367 if (acc_fprintf(&written, stream, "%s", close) < 0) 368 return -1; 369 if (i == maxlen && !before && acc_fprintf(&written, stream, "...") < 0) 370 return -1; 371 372 return written; 373} 374 375static int 376toplevel_format_lens(struct lens *lens, FILE *stream, 377 struct value *value, struct value_dict *arguments, 378 enum int_fmt_t int_fmt) 379{ 380 switch (value->type->type) { 381 case ARGTYPE_VOID: 382 return fprintf(stream, "<void>"); 383 384 case ARGTYPE_SHORT: 385 case ARGTYPE_INT: 386 case ARGTYPE_LONG: 387 return format_integer(stream, value, int_fmt, arguments); 388 389 case ARGTYPE_USHORT: 390 case ARGTYPE_UINT: 391 case ARGTYPE_ULONG: 392 if (int_fmt == INT_FMT_i || int_fmt == INT_FMT_default) 393 int_fmt = INT_FMT_u; 394 return format_integer(stream, value, int_fmt, arguments); 395 396 case ARGTYPE_CHAR: 397 if (int_fmt == INT_FMT_default) 398 return format_naked_char(stream, value, arguments); 399 return format_integer(stream, value, int_fmt, arguments); 400 401 case ARGTYPE_FLOAT: 402 case ARGTYPE_DOUBLE: 403 return format_floating(stream, value, arguments); 404 405 case ARGTYPE_STRUCT: 406 return format_struct(stream, value, arguments); 407 408 case ARGTYPE_POINTER: 409 if (value->type->u.array_info.elt_type->type != ARGTYPE_VOID) 410 return format_pointer(stream, value, arguments); 411 return format_integer(stream, value, INT_FMT_x, arguments); 412 413 case ARGTYPE_ARRAY: 414 return format_array(stream, value, arguments, 415 value->type->u.array_info.length, 416 options.arraylen, 1, "[ ", " ]", ", "); 417 } 418 abort(); 419} 420 421static int 422default_lens_format_cb(struct lens *lens, FILE *stream, 423 struct value *value, struct value_dict *arguments) 424{ 425 return toplevel_format_lens(lens, stream, value, arguments, 426 INT_FMT_default); 427} 428 429struct lens default_lens = { 430 .format_cb = default_lens_format_cb, 431}; 432 433 434static int 435blind_lens_format_cb(struct lens *lens, FILE *stream, 436 struct value *value, struct value_dict *arguments) 437{ 438 return 0; 439} 440 441struct lens blind_lens = { 442 .format_cb = blind_lens_format_cb, 443}; 444 445 446static int 447octal_lens_format_cb(struct lens *lens, FILE *stream, 448 struct value *value, struct value_dict *arguments) 449{ 450 return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_o); 451} 452 453struct lens octal_lens = { 454 .format_cb = octal_lens_format_cb, 455}; 456 457 458static int 459hex_lens_format_cb(struct lens *lens, FILE *stream, 460 struct value *value, struct value_dict *arguments) 461{ 462 return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_x); 463} 464 465struct lens hex_lens = { 466 .format_cb = hex_lens_format_cb, 467}; 468 469 470static int 471dec_lens_format_cb(struct lens *lens, FILE *stream, 472 struct value *value, struct value_dict *arguments) 473{ 474 return toplevel_format_lens(lens, stream, value, arguments, INT_FMT_u); 475} 476 477struct lens dec_lens = { 478 .format_cb = dec_lens_format_cb, 479}; 480 481 482static int 483guess_lens_format_cb(struct lens *lens, FILE *stream, 484 struct value *value, struct value_dict *arguments) 485{ 486 return toplevel_format_lens(lens, stream, value, arguments, 487 INT_FMT_unknown); 488} 489 490struct lens guess_lens = { 491 .format_cb = guess_lens_format_cb, 492}; 493 494 495static int 496bool_lens_format_cb(struct lens *lens, FILE *stream, 497 struct value *value, struct value_dict *arguments) 498{ 499 switch (value->type->type) { 500 case ARGTYPE_VOID: 501 case ARGTYPE_FLOAT: 502 case ARGTYPE_DOUBLE: 503 case ARGTYPE_STRUCT: 504 case ARGTYPE_POINTER: 505 case ARGTYPE_ARRAY: 506 return toplevel_format_lens(lens, stream, value, 507 arguments, INT_FMT_default); 508 509 int zero; 510 case ARGTYPE_SHORT: 511 case ARGTYPE_INT: 512 case ARGTYPE_LONG: 513 case ARGTYPE_USHORT: 514 case ARGTYPE_UINT: 515 case ARGTYPE_ULONG: 516 case ARGTYPE_CHAR: 517 if ((zero = value_is_zero(value, arguments)) < 0) 518 return -1; 519 if (zero) 520 return fprintf(stream, "false"); 521 else 522 return fprintf(stream, "true"); 523 } 524 abort(); 525} 526 527struct lens bool_lens = { 528 .format_cb = bool_lens_format_cb, 529}; 530 531 532static int 533string_lens_format_cb(struct lens *lens, FILE *stream, 534 struct value *value, struct value_dict *arguments) 535{ 536 switch (value->type->type) { 537 case ARGTYPE_POINTER: 538 /* This should really be written as either "string", 539 * or, if lens, then string(array(char, zero)*). But 540 * I suspect people are so used to the char * C idiom, 541 * that string(char *) might actually turn up. So 542 * let's just support it. */ 543 if (value->type->u.ptr_info.info->type == ARGTYPE_CHAR) { 544 struct arg_type_info info[2]; 545 type_init_array(&info[1], 546 value->type->u.ptr_info.info, 0, 547 expr_node_zero(), 0); 548 type_init_pointer(&info[0], &info[1], 0); 549 info->lens = lens; 550 info->own_lens = 0; 551 struct value tmp; 552 if (value_clone(&tmp, value) < 0) 553 return -1; 554 value_set_type(&tmp, info, 0); 555 int ret = string_lens_format_cb(lens, stream, &tmp, 556 arguments); 557 type_destroy(&info[0]); 558 type_destroy(&info[1]); 559 value_destroy(&tmp); 560 return ret; 561 } 562 563 /* fall-through */ 564 case ARGTYPE_VOID: 565 case ARGTYPE_FLOAT: 566 case ARGTYPE_DOUBLE: 567 case ARGTYPE_STRUCT: 568 case ARGTYPE_SHORT: 569 case ARGTYPE_INT: 570 case ARGTYPE_LONG: 571 case ARGTYPE_USHORT: 572 case ARGTYPE_UINT: 573 case ARGTYPE_ULONG: 574 return toplevel_format_lens(lens, stream, value, 575 arguments, INT_FMT_default); 576 577 case ARGTYPE_CHAR: 578 return format_char(stream, value, arguments); 579 580 case ARGTYPE_ARRAY: 581 return format_array(stream, value, arguments, 582 value->type->u.array_info.length, 583 options.strlen, 0, "\"", "\"", ""); 584 } 585 abort(); 586} 587 588struct lens string_lens = { 589 .format_cb = string_lens_format_cb, 590}; 591 592static int 593out_bits(FILE *stream, size_t low, size_t high) 594{ 595 if (low == high) 596 return fprintf(stream, "%zd", low); 597 else 598 return fprintf(stream, "%zd-%zd", low, high); 599} 600 601static unsigned 602bitcount(unsigned u) 603{ 604 int c = 0; 605 for (; u > 0; u &= u - 1) 606 c++; 607 return c; 608} 609 610static int 611bitvect_lens_format_cb(struct lens *lens, FILE *stream, 612 struct value *value, struct value_dict *arguments) 613{ 614 unsigned char *data = value_get_data(value, arguments); 615 if (data == NULL) 616 return -1; 617 size_t sz = type_sizeof(value->inferior, value->type); 618 if (sz == (size_t)-1) 619 return -1; 620 621 size_t i; 622 unsigned char buf[sz]; 623 switch ((int)value->type->type) { 624 union bitvect_integral_64 625 { 626 uint8_t u8; 627 uint16_t u16; 628 uint32_t u32; 629 uint64_t u64; 630 unsigned char buf[0]; 631 } bv; 632 633 case ARGTYPE_POINTER: 634 return format_pointer(stream, value, arguments); 635 636 case ARGTYPE_STRUCT: 637 case ARGTYPE_ARRAY: 638 break; 639 640 default: 641 assert(sz <= sizeof(bv)); 642 memmove(bv.buf, data, sz); 643 644 if (sz == 1) 645 bv.u64 = bv.u8; 646 else if (sz == 2) 647 bv.u64 = bv.u16; 648 else if (sz == 4) 649 bv.u64 = bv.u32; 650 651 for (i = 0; i < sz; ++i) { 652 buf[i] = bv.u64 & 0xff; 653 bv.u64 >>= 8; 654 } 655 data = buf; 656 } 657 658 size_t bits = 0; 659 for (i = 0; i < sz; ++i) 660 bits += bitcount(data[i]); 661 662 /* If there's more 1's than 0's, show inverse. */ 663 unsigned neg = bits > sz * 4 ? 0xff : 0x00; 664 665 int o = 0; 666 if (acc_fprintf(&o, stream, "%s<", "~" + (neg == 0x00)) < 0) 667 return -1; 668 669 size_t bitno = 0; 670 ssize_t low = -1; 671 for (i = 0; i < sz; ++i) { 672 unsigned char m; 673 unsigned char d = data[i] ^ neg; 674 for (m = 0x01; m != 0; m <<= 1) { 675 int bit = !!(m & d); 676 if (low < 0) { 677 if (bit) { 678 if (low == -2 679 && acc_fprintf(&o, stream, ",") < 0) 680 return -1; 681 low = bitno; 682 } 683 } else if (!bit) { 684 if (account_output(&o, out_bits(stream, low, 685 bitno-1)) < 0) 686 return -1; 687 low = -2; 688 } 689 bitno++; 690 } 691 } 692 if (low >= 0 && account_output(&o, out_bits(stream, low, bitno-1)) < 0) 693 return -1; 694 695 if (fputc('>', stream) < 0) 696 return -1; 697 o += 1; 698 699 return o; 700} 701 702struct lens bitvect_lens = { 703 .format_cb = bitvect_lens_format_cb, 704}; 705