|
|
1.1 ! root 1: /* Print values for GNU debugger gdb. ! 2: Copyright (C) 1986, 1988 Free Software Foundation, Inc. ! 3: ! 4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY ! 5: WARRANTY. No author or distributor accepts responsibility to anyone ! 6: for the consequences of using it or for whether it serves any ! 7: particular purpose or works at all, unless he says so in writing. ! 8: Refer to the GDB General Public License for full details. ! 9: ! 10: Everyone is granted permission to copy, modify and redistribute GDB, ! 11: but only under the conditions described in the GDB General Public ! 12: License. A copy of this license is supposed to have been given to you ! 13: along with GDB so you can know your rights and responsibilities. It ! 14: should be in a file named COPYING. Among other things, the copyright ! 15: notice and this notice must be preserved on all copies. ! 16: ! 17: In other words, go ahead and share GDB, but don't try to stop ! 18: anyone else from sharing it farther. Help stamp out software hoarding! ! 19: */ ! 20: ! 21: #include <stdio.h> ! 22: #include "defs.h" ! 23: #include "initialize.h" ! 24: #include "param.h" ! 25: #include "symtab.h" ! 26: #include "value.h" ! 27: ! 28: /* Maximum number of chars to print for a string pointer value ! 29: or vector contents. */ ! 30: ! 31: static int print_max; ! 32: ! 33: static void type_print_varspec_suffix (); ! 34: static void type_print_varspec_prefix (); ! 35: static void type_print_base (); ! 36: ! 37: START_FILE ! 38: ! 39: char **unsigned_type_table; ! 40: char **signed_type_table; ! 41: char **float_type_table; ! 42: ! 43: /* Print the value VAL in C-ish syntax on stream STREAM. ! 44: FORMAT is a format-letter, or 0 for print in natural format of data type. ! 45: If the object printed is a string pointer, returns ! 46: the number of string bytes printed. */ ! 47: ! 48: value_print (val, stream, format) ! 49: value val; ! 50: FILE *stream; ! 51: char format; ! 52: { ! 53: register int i, n, typelen; ! 54: ! 55: /* A "repeated" value really contains several values in a row. ! 56: They are made by the @ operator. ! 57: Print such values as if they were arrays. */ ! 58: ! 59: if (VALUE_REPEATED (val)) ! 60: { ! 61: n = VALUE_REPETITIONS (val); ! 62: typelen = TYPE_LENGTH (VALUE_TYPE (val)); ! 63: fputc ('{', stream); ! 64: /* Print arrays of characters using string syntax. */ ! 65: if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT ! 66: && format == 0) ! 67: { ! 68: fputc ('"', stream); ! 69: for (i = 0; i < n && i < print_max; i++) ! 70: { ! 71: QUIT; ! 72: printchar (VALUE_CONTENTS (val)[i], stream, '"'); ! 73: } ! 74: if (i < n) ! 75: fprintf (stream, "..."); ! 76: fputc ('"', stream); ! 77: } ! 78: else ! 79: { ! 80: for (i = 0; i < n && i < print_max; i++) ! 81: { ! 82: if (i) ! 83: fprintf (stream, ", "); ! 84: val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i, ! 85: VALUE_ADDRESS (val) + typelen * i, stream, format); ! 86: } ! 87: if (i < n) ! 88: fprintf (stream, "..."); ! 89: } ! 90: fputc ('}', stream); ! 91: } ! 92: else ! 93: { ! 94: /* A simple (nonrepeated) value */ ! 95: /* If it is a pointer, indicate what it points to. */ ! 96: if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR) ! 97: { ! 98: fprintf (stream, "("); ! 99: type_print (VALUE_TYPE (val), "", stream, -1); ! 100: fprintf (stream, ") "); ! 101: } ! 102: return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), ! 103: VALUE_ADDRESS (val), stream, format); ! 104: } ! 105: } ! 106: ! 107: /* Print data of type TYPE located at VALADDR (within GDB), ! 108: which came from the inferior at address ADDRESS, ! 109: onto stdio stream STREAM according to FORMAT ! 110: (a letter or 0 for natural format). ! 111: ! 112: If the data are a string pointer, returns the number of ! 113: sting characters printed. */ ! 114: ! 115: int ! 116: val_print (type, valaddr, address, stream, format) ! 117: struct type *type; ! 118: char *valaddr; ! 119: CORE_ADDR address; ! 120: FILE *stream; ! 121: char format; ! 122: { ! 123: register int i; ! 124: int len; ! 125: struct type *elttype; ! 126: int eltlen; ! 127: int val; ! 128: unsigned char c; ! 129: ! 130: QUIT; ! 131: ! 132: switch (TYPE_CODE (type)) ! 133: { ! 134: case TYPE_CODE_ARRAY: ! 135: if (TYPE_LENGTH (type) >= 0) ! 136: { ! 137: elttype = TYPE_TARGET_TYPE (type); ! 138: eltlen = TYPE_LENGTH (elttype); ! 139: len = TYPE_LENGTH (type) / eltlen; ! 140: fprintf (stream, "{"); ! 141: /* For an array of chars, print with string syntax. */ ! 142: if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT ! 143: && format == 0) ! 144: { ! 145: fputc ('"', stream); ! 146: for (i = 0; i < len && i < print_max; i++) ! 147: { ! 148: QUIT; ! 149: printchar (valaddr[i], stream, '"'); ! 150: } ! 151: if (i < len) ! 152: fprintf (stream, "..."); ! 153: fputc ('"', stream); ! 154: } ! 155: else ! 156: { ! 157: for (i = 0; i < len && i < print_max; i++) ! 158: { ! 159: if (i) fprintf (stream, ", "); ! 160: val_print (elttype, valaddr + i * eltlen, ! 161: 0, stream, format); ! 162: } ! 163: if (i < len) ! 164: fprintf (stream, "..."); ! 165: } ! 166: fprintf (stream, "}"); ! 167: break; ! 168: } ! 169: /* Array of unspecified length: treat like pointer. */ ! 170: ! 171: case TYPE_CODE_PTR: ! 172: if (format) ! 173: { ! 174: print_scalar_formatted (valaddr, type, format, 0, stream); ! 175: break; ! 176: } ! 177: fprintf (stream, "0x%x", * (int *) valaddr); ! 178: /* For a pointer to char or unsigned char, ! 179: also print the string pointed to, unless pointer is null. */ ! 180: ! 181: /* For an array of chars, print with string syntax. */ ! 182: elttype = TYPE_TARGET_TYPE (type); ! 183: if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT ! 184: && format == 0 ! 185: && unpack_long (type, valaddr) != 0) ! 186: { ! 187: fputc (' ', stream); ! 188: fputc ('"', stream); ! 189: for (i = 0; i < print_max; i++) ! 190: { ! 191: QUIT; ! 192: read_memory (unpack_long (type, valaddr) + i, &c, 1); ! 193: if (c == 0) ! 194: break; ! 195: printchar (c, stream, '"'); ! 196: } ! 197: fputc ('"', stream); ! 198: if (i == print_max) ! 199: fprintf (stream, "..."); ! 200: fflush (stream); ! 201: /* Return number of characters printed, plus one for the ! 202: terminating null if we have "reached the end". */ ! 203: return i + (i != print_max); ! 204: } ! 205: break; ! 206: ! 207: case TYPE_CODE_STRUCT: ! 208: case TYPE_CODE_UNION: ! 209: fprintf (stream, "{"); ! 210: len = TYPE_NFIELDS (type); ! 211: for (i = 0; i < len; i++) ! 212: { ! 213: if (i) fprintf (stream, ", "); ! 214: fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i)); ! 215: if (TYPE_FIELD_PACKED (type, i)) ! 216: { ! 217: val = unpack_field_as_long (type, valaddr, i); ! 218: val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream, format); ! 219: } ! 220: else ! 221: val_print (TYPE_FIELD_TYPE (type, i), ! 222: valaddr + TYPE_FIELD_BITPOS (type, i) / 8, ! 223: 0, stream, format); ! 224: } ! 225: fprintf (stream, "}"); ! 226: break; ! 227: ! 228: case TYPE_CODE_ENUM: ! 229: if (format) ! 230: { ! 231: print_scalar_formatted (valaddr, type, format, 0, stream); ! 232: break; ! 233: } ! 234: len = TYPE_NFIELDS (type); ! 235: val = unpack_long (builtin_type_int, valaddr); ! 236: for (i = 0; i < len; i++) ! 237: { ! 238: QUIT; ! 239: if (val == TYPE_FIELD_VALUE (type, i)) ! 240: break; ! 241: } ! 242: if (i < len) ! 243: fprintf (stream, "%s", TYPE_FIELD_NAME (type, i)); ! 244: else ! 245: fprintf (stream, "%d", val); ! 246: break; ! 247: ! 248: case TYPE_CODE_FUNC: ! 249: if (format) ! 250: { ! 251: print_scalar_formatted (valaddr, type, format, 0, stream); ! 252: break; ! 253: } ! 254: fprintf (stream, "{"); ! 255: type_print (type, "", stream, -1); ! 256: fprintf (stream, "} "); ! 257: fprintf (stream, "0x%x", address); ! 258: break; ! 259: ! 260: case TYPE_CODE_INT: ! 261: if (format) ! 262: { ! 263: print_scalar_formatted (valaddr, type, format, 0, stream); ! 264: break; ! 265: } ! 266: fprintf (stream, ! 267: TYPE_UNSIGNED (type) ? "%u" : "%d", ! 268: unpack_long (type, valaddr)); ! 269: if (TYPE_LENGTH (type) == 1) ! 270: { ! 271: fprintf (stream, " '"); ! 272: printchar (unpack_long (type, valaddr), stream, '\''); ! 273: fputc ('\'', stream); ! 274: } ! 275: break; ! 276: ! 277: case TYPE_CODE_FLT: ! 278: if (format) ! 279: { ! 280: print_scalar_formatted (valaddr, type, format, 0, stream); ! 281: break; ! 282: } ! 283: #ifdef IEEE_FLOAT ! 284: if (is_nan (unpack_double (type, valaddr))) ! 285: { ! 286: fprintf (stream, "Nan"); ! 287: break; ! 288: } ! 289: #endif ! 290: fprintf (stream, "%g", unpack_double (type, valaddr)); ! 291: break; ! 292: ! 293: case TYPE_CODE_VOID: ! 294: fprintf (stream, "void"); ! 295: break; ! 296: ! 297: default: ! 298: error ("Invalid type code in symbol table."); ! 299: } ! 300: fflush (stream); ! 301: } ! 302: ! 303: #ifdef IEEE_FLOAT ! 304: ! 305: union ieee { ! 306: int i[2]; ! 307: double d; ! 308: }; ! 309: ! 310: /* Nonzero if ARG (a double) is a NAN. */ ! 311: ! 312: int ! 313: is_nan (arg) ! 314: union ieee arg; ! 315: { ! 316: int lowhalf, highhalf; ! 317: union { int i; char c; } test; ! 318: ! 319: /* Separate the high and low words of the double. ! 320: Distinguish big and little-endian machines. */ ! 321: test.i = 1; ! 322: if (test.c != 1) ! 323: /* Big-endian machine */ ! 324: lowhalf = arg.i[1], highhalf = arg.i[0]; ! 325: else ! 326: lowhalf = arg.i[0], highhalf = arg.i[1]; ! 327: ! 328: /* Nan: exponent is the maximum possible, and fraction is nonzero. */ ! 329: return (((highhalf>>20) & 0x7ff) == 0x7ff ! 330: && ! 331: ! ((highhalf & 0xfffff == 0) && (lowhalf == 0))); ! 332: } ! 333: #endif ! 334: ! 335: /* Print a description of a type TYPE ! 336: in the form of a declaration of a variable named VARSTRING. ! 337: Output goes to STREAM (via stdio). ! 338: If SHOW is positive, we show the contents of the outermost level ! 339: of structure even if there is a type name that could be used instead. ! 340: If SHOW is negative, we never show the details of elements' types. */ ! 341: ! 342: type_print (type, varstring, stream, show) ! 343: struct type *type; ! 344: char *varstring; ! 345: FILE *stream; ! 346: int show; ! 347: { ! 348: type_print_1 (type, varstring, stream, show, 0); ! 349: } ! 350: ! 351: /* LEVEL is the depth to indent lines by. */ ! 352: ! 353: type_print_1 (type, varstring, stream, show, level) ! 354: struct type *type; ! 355: char *varstring; ! 356: FILE *stream; ! 357: int show; ! 358: int level; ! 359: { ! 360: register enum type_code code; ! 361: type_print_base (type, stream, show, level); ! 362: code = TYPE_CODE (type); ! 363: if ((varstring && *varstring) ! 364: || ! 365: /* Need a space if going to print stars or brackets; ! 366: but not if we will print just a type name. */ ! 367: ((show > 0 || TYPE_NAME (type) == 0) ! 368: && ! 369: (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC ! 370: || code == TYPE_CODE_ARRAY))) ! 371: fprintf (stream, " "); ! 372: type_print_varspec_prefix (type, stream, show, 0); ! 373: fprintf (stream, "%s", varstring); ! 374: type_print_varspec_suffix (type, stream, show, 0); ! 375: } ! 376: ! 377: /* Print any asterisks or open-parentheses needed before the ! 378: variable name (to describe its type). ! 379: ! 380: On outermost call, pass 0 for PASSED_A_PTR. ! 381: On outermost call, SHOW > 0 means should ignore ! 382: any typename for TYPE and show its details. ! 383: SHOW is always zero on recursive calls. */ ! 384: ! 385: static void ! 386: type_print_varspec_prefix (type, stream, show, passed_a_ptr) ! 387: struct type *type; ! 388: FILE *stream; ! 389: int show; ! 390: int passed_a_ptr; ! 391: { ! 392: if (type == 0) ! 393: return; ! 394: ! 395: if (TYPE_NAME (type) && show <= 0) ! 396: return; ! 397: ! 398: QUIT; ! 399: ! 400: switch (TYPE_CODE (type)) ! 401: { ! 402: case TYPE_CODE_PTR: ! 403: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); ! 404: fputc ('*', stream); ! 405: break; ! 406: ! 407: case TYPE_CODE_FUNC: ! 408: case TYPE_CODE_ARRAY: ! 409: type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); ! 410: if (passed_a_ptr) ! 411: fputc ('(', stream); ! 412: break; ! 413: } ! 414: } ! 415: ! 416: /* Print any array sizes, function arguments or close parentheses ! 417: needed after the variable name (to describe its type). ! 418: Args work like type_print_varspec_prefix. */ ! 419: ! 420: static void ! 421: type_print_varspec_suffix (type, stream, show, passed_a_ptr) ! 422: struct type *type; ! 423: FILE *stream; ! 424: int show; ! 425: int passed_a_ptr; ! 426: { ! 427: if (type == 0) ! 428: return; ! 429: ! 430: if (TYPE_NAME (type) && show <= 0) ! 431: return; ! 432: ! 433: QUIT; ! 434: ! 435: switch (TYPE_CODE (type)) ! 436: { ! 437: case TYPE_CODE_ARRAY: ! 438: type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); ! 439: if (passed_a_ptr) ! 440: fprintf (stream, ")"); ! 441: fprintf (stream, "["); ! 442: if (TYPE_LENGTH (type) >= 0) ! 443: fprintf (stream, "%d", ! 444: TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type))); ! 445: fprintf (stream, "]"); ! 446: break; ! 447: ! 448: case TYPE_CODE_PTR: ! 449: type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1); ! 450: break; ! 451: ! 452: case TYPE_CODE_FUNC: ! 453: type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); ! 454: if (passed_a_ptr) ! 455: fprintf (stream, ")"); ! 456: fprintf (stream, "()"); ! 457: break; ! 458: } ! 459: } ! 460: ! 461: /* Print the name of the type (or the ultimate pointer target, ! 462: function value or array element), or the description of a ! 463: structure or union. ! 464: ! 465: SHOW nonzero means don't print this type as just its name; ! 466: show its real definition even if it has a name. ! 467: SHOW zero means print just typename or struct tag if there is one ! 468: SHOW negative means abbreviate structure elements. ! 469: SHOW is decremented for printing of structure elements. ! 470: ! 471: LEVEL is the depth to indent by. ! 472: We increase it for some recursive calls. */ ! 473: ! 474: static void ! 475: type_print_base (type, stream, show, level) ! 476: struct type *type; ! 477: FILE *stream; ! 478: int show; ! 479: int level; ! 480: { ! 481: char *name; ! 482: register int i; ! 483: register int len; ! 484: register int lastval; ! 485: ! 486: QUIT; ! 487: ! 488: if (type == 0) ! 489: { ! 490: fprintf (stream, "type unknown"); ! 491: return; ! 492: } ! 493: ! 494: if (TYPE_NAME (type) && show <= 0) ! 495: { ! 496: fprintf (stream, TYPE_NAME (type)); ! 497: return; ! 498: } ! 499: ! 500: switch (TYPE_CODE (type)) ! 501: { ! 502: case TYPE_CODE_ARRAY: ! 503: case TYPE_CODE_PTR: ! 504: case TYPE_CODE_FUNC: ! 505: type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); ! 506: break; ! 507: ! 508: case TYPE_CODE_STRUCT: ! 509: fprintf (stream, "struct "); ! 510: goto struct_union; ! 511: ! 512: case TYPE_CODE_UNION: ! 513: fprintf (stream, "union "); ! 514: struct_union: ! 515: if (TYPE_NAME (type) && (name = TYPE_NAME (type))) ! 516: { ! 517: while (*name != ' ') name++; ! 518: fprintf (stream, "%s ", name + 1); ! 519: } ! 520: if (show < 0) ! 521: fprintf (stream, "{...}"); ! 522: else ! 523: { ! 524: fprintf (stream, "{"); ! 525: len = TYPE_NFIELDS (type); ! 526: fprintf (stream, "\n"); ! 527: for (i = 0; i < len; i++) ! 528: { ! 529: QUIT; ! 530: print_spaces (level + 4, stream); ! 531: ! 532: /* If this is a bit-field and there is a gap before it, ! 533: print a nameless field to account for the gap. */ ! 534: ! 535: if (TYPE_FIELD_PACKED (type, i)) ! 536: { ! 537: int gap = (TYPE_FIELD_BITPOS (type, i) ! 538: - (i > 0 ! 539: ? (TYPE_FIELD_BITPOS (type, i - 1) ! 540: + (TYPE_FIELD_PACKED (type, i - 1) ! 541: ? TYPE_FIELD_BITSIZE (type, i - 1) ! 542: : TYPE_LENGTH (TYPE_FIELD_TYPE (type, i - 1)) * 8)) ! 543: : 0)); ! 544: if (gap != 0) ! 545: { ! 546: fprintf (stream, "int : %d;\n", gap); ! 547: print_spaces (level + 4, stream); ! 548: } ! 549: } ! 550: ! 551: /* Print the declaration of this field. */ ! 552: ! 553: type_print_1 (TYPE_FIELD_TYPE (type, i), ! 554: TYPE_FIELD_NAME (type, i), ! 555: stream, show - 1, level + 4); ! 556: ! 557: /* Print the field width. */ ! 558: ! 559: if (TYPE_FIELD_PACKED (type, i)) ! 560: fprintf (stream, " : %d", TYPE_FIELD_BITSIZE (type, i)); ! 561: ! 562: fprintf (stream, ";\n"); ! 563: } ! 564: print_spaces (level, stream); ! 565: fputc ('}', stream); ! 566: } ! 567: break; ! 568: ! 569: case TYPE_CODE_ENUM: ! 570: fprintf (stream, "enum "); ! 571: if (TYPE_NAME (type)) ! 572: { ! 573: name = TYPE_NAME (type); ! 574: while (*name != ' ') name++; ! 575: fprintf (stream, "%s ", name + 1); ! 576: } ! 577: if (show < 0) ! 578: fprintf (stream, "{...}"); ! 579: else ! 580: { ! 581: fprintf (stream, "{"); ! 582: len = TYPE_NFIELDS (type); ! 583: lastval = 0; ! 584: for (i = 0; i < len; i++) ! 585: { ! 586: QUIT; ! 587: if (i) fprintf (stream, ", "); ! 588: fprintf (stream, "%s", TYPE_FIELD_NAME (type, i)); ! 589: if (lastval != TYPE_FIELD_VALUE (type, i)) ! 590: { ! 591: fprintf (stream, " : %d", TYPE_FIELD_VALUE (type, i)); ! 592: lastval = TYPE_FIELD_VALUE (type, i); ! 593: } ! 594: lastval++; ! 595: } ! 596: fprintf (stream, "}"); ! 597: } ! 598: break; ! 599: ! 600: case TYPE_CODE_INT: ! 601: if (TYPE_UNSIGNED (type)) ! 602: name = unsigned_type_table[TYPE_LENGTH (type)]; ! 603: else ! 604: name = signed_type_table[TYPE_LENGTH (type)]; ! 605: fprintf (stream, "%s", name); ! 606: break; ! 607: ! 608: case TYPE_CODE_FLT: ! 609: name = float_type_table[TYPE_LENGTH (type)]; ! 610: fprintf (stream, "%s", name); ! 611: break; ! 612: ! 613: case TYPE_CODE_VOID: ! 614: fprintf (stream, "void"); ! 615: break; ! 616: ! 617: case 0: ! 618: fprintf (stream, "struct unknown"); ! 619: break; ! 620: ! 621: default: ! 622: error ("Invalid type code in symbol table."); ! 623: } ! 624: } ! 625: ! 626: static void ! 627: set_maximum_command (arg) ! 628: char *arg; ! 629: { ! 630: if (!arg) error_no_arg ("value for maximum elements to print"); ! 631: print_max = atoi (arg); ! 632: } ! 633: ! 634: static ! 635: initialize () ! 636: { ! 637: add_com ("set-maximum", class_vars, set_maximum_command, ! 638: "Set NUMBER as limit on string chars or array elements to print."); ! 639: ! 640: print_max = 200; ! 641: ! 642: unsigned_type_table ! 643: = (char **) xmalloc ((1 + sizeof (unsigned long)) * sizeof (char *)); ! 644: bzero (unsigned_type_table, (1 + sizeof (unsigned long))); ! 645: unsigned_type_table[sizeof (unsigned char)] = "unsigned char"; ! 646: unsigned_type_table[sizeof (unsigned short)] = "unsigned short"; ! 647: unsigned_type_table[sizeof (unsigned long)] = "unsigned long"; ! 648: unsigned_type_table[sizeof (unsigned int)] = "unsigned int"; ! 649: ! 650: signed_type_table ! 651: = (char **) xmalloc ((1 + sizeof (long)) * sizeof (char *)); ! 652: bzero (signed_type_table, (1 + sizeof (long))); ! 653: signed_type_table[sizeof (char)] = "char"; ! 654: signed_type_table[sizeof (short)] = "short"; ! 655: signed_type_table[sizeof (long)] = "long"; ! 656: signed_type_table[sizeof (int)] = "int"; ! 657: ! 658: float_type_table ! 659: = (char **) xmalloc ((1 + sizeof (double)) * sizeof (char *)); ! 660: bzero (float_type_table, (1 + sizeof (double))); ! 661: float_type_table[sizeof (float)] = "float"; ! 662: float_type_table[sizeof (double)] = "double"; ! 663: } ! 664: ! 665: END_FILE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.