|
|
1.1 ! root 1: /* Output sdb-format symbol table information from GNU compiler. ! 2: Copyright (C) 1988, 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: /* [email protected] says: ! 21: I modified the struct.c example and have a nm of a .o resulting from the ! 22: AT&T C compiler. From the example below I would conclude the following: ! 23: ! 24: 1. All .defs from structures are emitted as scanned. The example below ! 25: clearly shows the symbol table entries for BoxRec2 are after the first ! 26: function. ! 27: ! 28: 2. All functions and their locals (including statics) are emitted as scanned. ! 29: ! 30: 3. All nested unnamed union and structure .defs must be emitted before ! 31: the structure in which they are nested. The AT&T assembler is a ! 32: one pass beast as far as symbolics are concerned. ! 33: ! 34: 4. All structure .defs are emitted before the typedefs that refer to them. ! 35: ! 36: 5. All top level static and external variable definitions are moved to the ! 37: end of file with all top level statics occuring first before externs. ! 38: ! 39: 6. All undefined references are at the end of the file. ! 40: */ ! 41: ! 42: #include "config.h" ! 43: ! 44: #ifdef SDB_DEBUGGING_INFO ! 45: ! 46: #include "tree.h" ! 47: #include "rtl.h" ! 48: #include <stdio.h> ! 49: #include "regs.h" ! 50: #include "flags.h" ! 51: #include "insn-config.h" ! 52: #include "reload.h" ! 53: ! 54: /* Mips systems use the SDB functions to dump out symbols, but ! 55: do not supply usable syms.h include files. */ ! 56: #if defined(USG) && !defined(MIPS) ! 57: #include <syms.h> ! 58: /* Use T_INT if we don't have T_VOID. */ ! 59: #ifndef T_VOID ! 60: #define T_VOID T_INT ! 61: #endif ! 62: #else /* not USG, or MIPS */ ! 63: #include "gsyms.h" ! 64: #endif /* not USG, or MIPS */ ! 65: ! 66: /* #include <storclass.h> used to be this instead of syms.h. */ ! 67: ! 68: /* 1 if PARM is passed to this function in memory. */ ! 69: ! 70: #define PARM_PASSED_IN_MEMORY(PARM) \ ! 71: (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM) ! 72: ! 73: /* A C expression for the integer offset value of an automatic variable ! 74: (C_AUTO) having address X (an RTX). */ ! 75: #ifndef DEBUGGER_AUTO_OFFSET ! 76: #define DEBUGGER_AUTO_OFFSET(X) \ ! 77: (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) ! 78: #endif ! 79: ! 80: /* A C expression for the integer offset value of an argument (C_ARG) ! 81: having address X (an RTX). The nominal offset is OFFSET. */ ! 82: #ifndef DEBUGGER_ARG_OFFSET ! 83: #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) ! 84: #endif ! 85: ! 86: /* Line number of beginning of current function, minus one. ! 87: Negative means not in a function or not using sdb. */ ! 88: ! 89: int sdb_begin_function_line = -1; ! 90: ! 91: /* Counter to generate unique "names" for nameless struct members. */ ! 92: ! 93: static int unnamed_struct_number = 0; ! 94: ! 95: extern FILE *asm_out_file; ! 96: ! 97: extern tree current_function_decl; ! 98: ! 99: void sdbout_init (); ! 100: void sdbout_symbol (); ! 101: void sdbout_types(); ! 102: ! 103: static void sdbout_typedefs (); ! 104: static void sdbout_syms (); ! 105: static void sdbout_one_type (); ! 106: static void sdbout_queue_anonymous_type (); ! 107: static void sdbout_dequeue_anonymous_type (); ! 108: static int plain_type_1 (); ! 109: ! 110: /* Define the default sizes for various types. */ ! 111: ! 112: #ifndef CHAR_TYPE_SIZE ! 113: #define CHAR_TYPE_SIZE BITS_PER_UNIT ! 114: #endif ! 115: ! 116: #ifndef SHORT_TYPE_SIZE ! 117: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) ! 118: #endif ! 119: ! 120: #ifndef INT_TYPE_SIZE ! 121: #define INT_TYPE_SIZE BITS_PER_WORD ! 122: #endif ! 123: ! 124: #ifndef LONG_TYPE_SIZE ! 125: #define LONG_TYPE_SIZE BITS_PER_WORD ! 126: #endif ! 127: ! 128: #ifndef LONG_LONG_TYPE_SIZE ! 129: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) ! 130: #endif ! 131: ! 132: #ifndef FLOAT_TYPE_SIZE ! 133: #define FLOAT_TYPE_SIZE BITS_PER_WORD ! 134: #endif ! 135: ! 136: #ifndef DOUBLE_TYPE_SIZE ! 137: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) ! 138: #endif ! 139: ! 140: #ifndef LONG_DOUBLE_TYPE_SIZE ! 141: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) ! 142: #endif ! 143: ! 144: /* Random macros describing parts of SDB data. */ ! 145: ! 146: /* Put something here if lines get too long */ ! 147: #define CONTIN ! 148: ! 149: /* Default value of delimiter is ";". */ ! 150: #ifndef SDB_DELIM ! 151: #define SDB_DELIM ";" ! 152: #endif ! 153: ! 154: /* Maximum number of dimensions the assembler will allow. */ ! 155: #ifndef SDB_MAX_DIM ! 156: #define SDB_MAX_DIM 4 ! 157: #endif ! 158: ! 159: #ifndef PUT_SDB_SCL ! 160: #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM) ! 161: #endif ! 162: ! 163: #ifndef PUT_SDB_INT_VAL ! 164: #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\t.val\t%d%s", (a), SDB_DELIM) ! 165: #endif ! 166: ! 167: #ifndef PUT_SDB_VAL ! 168: #define PUT_SDB_VAL(a) \ ! 169: ( fputs ("\t.val\t", asm_out_file), \ ! 170: output_addr_const (asm_out_file, (a)), \ ! 171: fprintf (asm_out_file, SDB_DELIM)) ! 172: #endif ! 173: ! 174: #ifndef PUT_SDB_DEF ! 175: #define PUT_SDB_DEF(a) \ ! 176: do { fprintf (asm_out_file, "\t.def\t"); \ ! 177: ASM_OUTPUT_LABELREF (asm_out_file, a); \ ! 178: fprintf (asm_out_file, SDB_DELIM); } while (0) ! 179: #endif ! 180: ! 181: #ifndef PUT_SDB_PLAIN_DEF ! 182: #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM) ! 183: #endif ! 184: ! 185: #ifndef PUT_SDB_ENDEF ! 186: #define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file) ! 187: #endif ! 188: ! 189: #ifndef PUT_SDB_TYPE ! 190: #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM) ! 191: #endif ! 192: ! 193: #ifndef PUT_SDB_SIZE ! 194: #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\t.size\t%d%s", a, SDB_DELIM) ! 195: #endif ! 196: ! 197: #ifndef PUT_SDB_START_DIM ! 198: #define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t") ! 199: #endif ! 200: ! 201: #ifndef PUT_SDB_NEXT_DIM ! 202: #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a) ! 203: #endif ! 204: ! 205: #ifndef PUT_SDB_LAST_DIM ! 206: #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM) ! 207: #endif ! 208: ! 209: #ifndef PUT_SDB_TAG ! 210: #define PUT_SDB_TAG(a) \ ! 211: do { fprintf (asm_out_file, "\t.tag\t"); \ ! 212: ASM_OUTPUT_LABELREF (asm_out_file, a); \ ! 213: fprintf (asm_out_file, SDB_DELIM); } while (0) ! 214: #endif ! 215: ! 216: #ifndef PUT_SDB_BLOCK_START ! 217: #define PUT_SDB_BLOCK_START(LINE) \ ! 218: fprintf (asm_out_file, \ ! 219: "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! 220: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 221: #endif ! 222: ! 223: #ifndef PUT_SDB_BLOCK_END ! 224: #define PUT_SDB_BLOCK_END(LINE) \ ! 225: fprintf (asm_out_file, \ ! 226: "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \ ! 227: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 228: #endif ! 229: ! 230: #ifndef PUT_SDB_FUNCTION_START ! 231: #define PUT_SDB_FUNCTION_START(LINE) \ ! 232: fprintf (asm_out_file, \ ! 233: "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! 234: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 235: #endif ! 236: ! 237: #ifndef PUT_SDB_FUNCTION_END ! 238: #define PUT_SDB_FUNCTION_END(LINE) \ ! 239: fprintf (asm_out_file, \ ! 240: "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \ ! 241: SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM) ! 242: #endif ! 243: ! 244: #ifndef PUT_SDB_EPILOGUE_END ! 245: #define PUT_SDB_EPILOGUE_END(NAME) \ ! 246: do { fprintf (asm_out_file, "\t.def\t"); \ ! 247: ASM_OUTPUT_LABELREF (asm_out_file, NAME); \ ! 248: fprintf (asm_out_file, \ ! 249: "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n", \ ! 250: SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0) ! 251: #endif ! 252: ! 253: #ifndef SDB_GENERATE_FAKE ! 254: #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \ ! 255: sprintf ((BUFFER), ".%dfake", (NUMBER)); ! 256: #endif ! 257: ! 258: /* Return the sdb tag identifier string for TYPE ! 259: if TYPE has already been defined; otherwise return a null pointer. */ ! 260: ! 261: #define KNOWN_TYPE_TAG(type) (char *)(TYPE_SYMTAB_ADDRESS (type)) ! 262: ! 263: /* Set the sdb tag identifier string for TYPE to NAME. */ ! 264: ! 265: #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \ ! 266: (TYPE_SYMTAB_ADDRESS (TYPE) = (int)(NAME)) ! 267: ! 268: /* Return the name (a string) of the struct, union or enum tag ! 269: described by the TREE_LIST node LINK. This is 0 for an anonymous one. */ ! 270: ! 271: #define TAG_NAME(link) \ ! 272: (((link) && TREE_PURPOSE ((link)) \ ! 273: && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \ ! 274: ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0) ! 275: ! 276: /* Ensure we don't output a negative line number. */ ! 277: #define MAKE_LINE_SAFE(line) \ ! 278: if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1 ! 279: ! 280: /* Set up for SDB output at the start of compilation. */ ! 281: ! 282: void ! 283: sdbout_init (asm_file, input_file_name, syms) ! 284: FILE *asm_file; ! 285: char *input_file_name; ! 286: tree syms; ! 287: { ! 288: #if 0 /* Nothing need be output for the predefined types. */ ! 289: /* Get all permanent types that have typedef names, ! 290: and output them all, except for those already output. */ ! 291: ! 292: sdbout_typedefs (syms); ! 293: #endif ! 294: } ! 295: ! 296: #if 0 ! 297: ! 298: /* return the tag identifier for type ! 299: */ ! 300: ! 301: char * ! 302: tag_of_ru_type (type,link) ! 303: tree type,link; ! 304: { ! 305: if (TYPE_SYMTAB_ADDRESS (type)) ! 306: return (char *)TYPE_SYMTAB_ADDRESS (type); ! 307: if (link && TREE_PURPOSE (link) ! 308: && IDENTIFIER_POINTER (TREE_PURPOSE (link))) ! 309: TYPE_SYMTAB_ADDRESS (type) ! 310: = (int)IDENTIFIER_POINTER (TREE_PURPOSE (link)); ! 311: else ! 312: return (char *) TYPE_SYMTAB_ADDRESS (type); ! 313: } ! 314: #endif ! 315: ! 316: /* Return a unique string to name an anonymous type. */ ! 317: ! 318: static char * ! 319: gen_fake_label () ! 320: { ! 321: char label[10]; ! 322: char *labelstr; ! 323: SDB_GENERATE_FAKE (label, unnamed_struct_number); ! 324: unnamed_struct_number++; ! 325: labelstr = (char *) permalloc (strlen (label) + 1); ! 326: strcpy (labelstr, label); ! 327: return labelstr; ! 328: } ! 329: ! 330: /* Return the number which describes TYPE for SDB. ! 331: For pointers, etc., this function is recursive. ! 332: Each record, union or enumeral type must already have had a ! 333: tag number output. */ ! 334: ! 335: /* The number is given by d6d5d4d3d2d1bbbb ! 336: where bbbb is 4 bit basic type, and di indicate one of notype,ptr,fn,array. ! 337: Thus, char *foo () has bbbb=T_CHAR ! 338: d1=D_FCN ! 339: d2=D_PTR ! 340: N_BTMASK= 017 1111 basic type field. ! 341: N_TSHIFT= 2 derived type shift ! 342: N_BTSHFT= 4 Basic type shift */ ! 343: ! 344: /* Produce the number that describes a pointer, function or array type. ! 345: PREV is the number describing the target, value or element type. ! 346: DT_type describes how to transform that type. */ ! 347: #define PUSH_DERIVED_LEVEL(DT_type,PREV) \ ! 348: ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK)) ! 349: ! 350: /* Number of elements used in sdb_dims. */ ! 351: static int sdb_n_dims = 0; ! 352: ! 353: /* Table of array dimensions of current type. */ ! 354: static int sdb_dims[SDB_MAX_DIM]; ! 355: ! 356: /* Size of outermost array currently being processed. */ ! 357: static int sdb_type_size = -1; ! 358: ! 359: static int ! 360: plain_type (type) ! 361: tree type; ! 362: { ! 363: int val = plain_type_1 (type); ! 364: ! 365: /* If we have already saved up some array dimensions, print them now. */ ! 366: if (sdb_n_dims > 0) ! 367: { ! 368: int i; ! 369: PUT_SDB_START_DIM; ! 370: for (i = sdb_n_dims - 1; i > 0; i--) ! 371: PUT_SDB_NEXT_DIM (sdb_dims[i]); ! 372: PUT_SDB_LAST_DIM (sdb_dims[0]); ! 373: sdb_n_dims = 0; ! 374: ! 375: sdb_type_size = int_size_in_bytes (type); ! 376: /* Don't kill sdb if type is not laid out or has variable size. */ ! 377: if (sdb_type_size < 0) ! 378: sdb_type_size = 0; ! 379: } ! 380: /* If we have computed the size of an array containing this type, ! 381: print it now. */ ! 382: if (sdb_type_size >= 0) ! 383: { ! 384: PUT_SDB_SIZE (sdb_type_size); ! 385: sdb_type_size = -1; ! 386: } ! 387: return val; ! 388: } ! 389: ! 390: static void ! 391: sdbout_record_type_name (type) ! 392: tree type; ! 393: { ! 394: char *name = 0; ! 395: int no_name; ! 396: ! 397: if (KNOWN_TYPE_TAG (type)) ! 398: return; ! 399: ! 400: if (TYPE_NAME (type) != 0) ! 401: { ! 402: tree t = 0; ! 403: /* Find the IDENTIFIER_NODE for the type name. */ ! 404: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! 405: { ! 406: t = TYPE_NAME (type); ! 407: } ! 408: #if 1 /* As a temprary hack, use typedef names for C++ only. */ ! 409: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 410: && TYPE_LANG_SPECIFIC (type)) ! 411: { ! 412: t = DECL_NAME (TYPE_NAME (type)); ! 413: } ! 414: #endif ! 415: ! 416: /* Now get the name as a string, or invent one. */ ! 417: if (t != 0) ! 418: name = IDENTIFIER_POINTER (t); ! 419: } ! 420: ! 421: no_name = (name == 0 || *name == 0); ! 422: if (no_name) ! 423: name = gen_fake_label (); ! 424: ! 425: SET_KNOWN_TYPE_TAG (type, name); ! 426: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 427: if (no_name) ! 428: sdbout_queue_anonymous_type (type); ! 429: #endif ! 430: } ! 431: ! 432: static int ! 433: plain_type_1 (type) ! 434: tree type; ! 435: { ! 436: if (type == 0) ! 437: type = void_type_node; ! 438: if (type == error_mark_node) ! 439: type = integer_type_node; ! 440: type = TYPE_MAIN_VARIANT (type); ! 441: ! 442: switch (TREE_CODE (type)) ! 443: { ! 444: case VOID_TYPE: ! 445: return T_VOID; ! 446: case INTEGER_TYPE: ! 447: { ! 448: int size = int_size_in_bytes (type) * BITS_PER_UNIT; ! 449: if (size == CHAR_TYPE_SIZE) ! 450: return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR); ! 451: if (size == SHORT_TYPE_SIZE) ! 452: return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT); ! 453: if (size == INT_TYPE_SIZE) ! 454: return (TREE_UNSIGNED (type) ? T_UINT : T_INT); ! 455: return 0; ! 456: } ! 457: ! 458: case REAL_TYPE: ! 459: { ! 460: int size = int_size_in_bytes (type) * BITS_PER_UNIT; ! 461: if (size == FLOAT_TYPE_SIZE) ! 462: return T_FLOAT; ! 463: if (size == DOUBLE_TYPE_SIZE) ! 464: return T_DOUBLE; ! 465: return 0; ! 466: } ! 467: ! 468: case ARRAY_TYPE: ! 469: { ! 470: int m; ! 471: m = plain_type_1 (TREE_TYPE (type)); ! 472: if (sdb_n_dims < SDB_MAX_DIM) ! 473: sdb_dims[sdb_n_dims++] ! 474: = (TYPE_DOMAIN (type) ! 475: ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1 ! 476: : 0); ! 477: return PUSH_DERIVED_LEVEL (DT_ARY, m); ! 478: } ! 479: ! 480: case RECORD_TYPE: ! 481: case UNION_TYPE: ! 482: case ENUMERAL_TYPE: ! 483: { ! 484: char *tag; ! 485: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 486: sdbout_record_type_name (type); ! 487: #endif ! 488: #ifndef SDB_ALLOW_UNKNOWN_REFERENCES ! 489: if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0) ! 490: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 491: || TYPE_MODE (type) != VOIDmode ! 492: #endif ! 493: ) ! 494: #endif ! 495: { ! 496: /* Output the referenced structure tag name ! 497: only if the .def has already been finished. ! 498: At least on 386, the Unix assembler ! 499: cannot handle forward references to tags. */ ! 500: /* But the 88100, it requires them, sigh... */ ! 501: /* And the MIPS requires unknown refs as well... */ ! 502: tag = KNOWN_TYPE_TAG (type); ! 503: PUT_SDB_TAG (tag); ! 504: /* These 3 lines used to follow the close brace. ! 505: However, a size of 0 without a tag implies a tag of 0, ! 506: so if we don't know a tag, we can't mention the size. */ ! 507: sdb_type_size = int_size_in_bytes (type); ! 508: if (sdb_type_size < 0) ! 509: sdb_type_size = 0; ! 510: } ! 511: return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT ! 512: : (TREE_CODE (type) == UNION_TYPE) ? T_UNION ! 513: : T_ENUM); ! 514: } ! 515: case POINTER_TYPE: ! 516: case REFERENCE_TYPE: ! 517: { ! 518: int m = plain_type_1 (TREE_TYPE (type)); ! 519: return PUSH_DERIVED_LEVEL (DT_PTR, m); ! 520: } ! 521: case FUNCTION_TYPE: ! 522: case METHOD_TYPE: ! 523: { ! 524: int m = plain_type_1 (TREE_TYPE (type)); ! 525: return PUSH_DERIVED_LEVEL (DT_FCN, m); ! 526: } ! 527: default: ! 528: return 0; ! 529: } ! 530: } ! 531: ! 532: /* Output the symbols defined in block number DO_BLOCK. ! 533: Set NEXT_BLOCK_NUMBER to 0 before calling. ! 534: ! 535: This function works by walking the tree structure of blocks, ! 536: counting blocks until it finds the desired block. */ ! 537: ! 538: static int do_block = 0; ! 539: ! 540: static int next_block_number; ! 541: ! 542: static void ! 543: sdbout_block (block) ! 544: register tree block; ! 545: { ! 546: while (block) ! 547: { ! 548: /* Ignore blocks never expanded or otherwise marked as real. */ ! 549: if (TREE_USED (block)) ! 550: { ! 551: /* When we reach the specified block, output its symbols. */ ! 552: if (next_block_number == do_block) ! 553: { ! 554: sdbout_syms (BLOCK_VARS (block)); ! 555: } ! 556: ! 557: /* If we are past the specified block, stop the scan. */ ! 558: if (next_block_number > do_block) ! 559: return; ! 560: ! 561: next_block_number++; ! 562: ! 563: /* Scan the blocks within this block. */ ! 564: sdbout_block (BLOCK_SUBBLOCKS (block)); ! 565: } ! 566: ! 567: block = BLOCK_CHAIN (block); ! 568: } ! 569: } ! 570: ! 571: /* Call sdbout_symbol on each decl in the chain SYMS. */ ! 572: ! 573: static void ! 574: sdbout_syms (syms) ! 575: tree syms; ! 576: { ! 577: while (syms) ! 578: { ! 579: if (TREE_CODE (syms) != LABEL_DECL) ! 580: sdbout_symbol (syms, 1); ! 581: syms = TREE_CHAIN (syms); ! 582: } ! 583: } ! 584: ! 585: /* Output SDB information for a symbol described by DECL. ! 586: LOCAL is nonzero if the symbol is not file-scope. */ ! 587: ! 588: void ! 589: sdbout_symbol (decl, local) ! 590: tree decl; ! 591: int local; ! 592: { ! 593: int letter = 0; ! 594: tree type = TREE_TYPE (decl); ! 595: tree context = NULL_TREE; ! 596: rtx value; ! 597: int regno = -1; ! 598: char *name; ! 599: ! 600: sdbout_one_type (type); ! 601: ! 602: switch (TREE_CODE (decl)) ! 603: { ! 604: case CONST_DECL: ! 605: /* Enum values are defined by defining the enum type. */ ! 606: return; ! 607: ! 608: case FUNCTION_DECL: ! 609: /* Don't mention a nested function under its parent. */ ! 610: context = decl_function_context (decl); ! 611: if (context == current_function_decl) ! 612: return; ! 613: if (TREE_EXTERNAL (decl)) ! 614: return; ! 615: if (GET_CODE (DECL_RTL (decl)) != MEM ! 616: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) ! 617: return; ! 618: PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); ! 619: PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); ! 620: PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT); ! 621: break; ! 622: ! 623: case TYPE_DECL: ! 624: /* Done with tagged types. */ ! 625: if (DECL_NAME (decl) == 0) ! 626: return; ! 627: ! 628: /* Output typedef name. */ ! 629: PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 630: PUT_SDB_SCL (C_TPDEF); ! 631: break; ! 632: ! 633: case PARM_DECL: ! 634: /* Parm decls go in their own separate chains ! 635: and are output by sdbout_reg_parms and sdbout_parms. */ ! 636: abort (); ! 637: ! 638: case VAR_DECL: ! 639: /* Don't mention a variable that is external. ! 640: Let the file that defines it describe it. */ ! 641: if (TREE_EXTERNAL (decl)) ! 642: return; ! 643: ! 644: /* If there was an error in the declaration, don't dump core ! 645: if there is no RTL associated with the variable doesn't ! 646: exist. */ ! 647: if (DECL_RTL (decl) == 0) ! 648: return; ! 649: ! 650: value = eliminate_regs (DECL_RTL (decl), 0, 0); ! 651: ! 652: /* Don't mention a variable at all ! 653: if it was completely optimized into nothingness. ! 654: ! 655: If DECL was from an inline function, then its rtl ! 656: is not identically the rtl that was used in this ! 657: particular compilation. */ ! 658: if (GET_CODE (value) == REG) ! 659: { ! 660: regno = REGNO (DECL_RTL (decl)); ! 661: if (regno >= FIRST_PSEUDO_REGISTER) ! 662: regno = reg_renumber[REGNO (DECL_RTL (decl))]; ! 663: if (regno < 0) ! 664: return; ! 665: } ! 666: else if (GET_CODE (DECL_RTL (decl)) == SUBREG) ! 667: { ! 668: int offset = 0; ! 669: while (GET_CODE (value) == SUBREG) ! 670: { ! 671: offset += SUBREG_WORD (value); ! 672: value = SUBREG_REG (value); ! 673: } ! 674: if (GET_CODE (value) == REG) ! 675: { ! 676: regno = REGNO (value); ! 677: if (regno >= FIRST_PSEUDO_REGISTER) ! 678: regno = reg_renumber[REGNO (value)]; ! 679: if (regno >= 0) ! 680: regno += offset; ! 681: } ! 682: } ! 683: ! 684: /* Emit any structure, union, or enum type that has not been output. ! 685: This occurs for tag-less structs (et al) used to declare variables ! 686: within functions. */ ! 687: if (TREE_CODE (type) == ENUMERAL_TYPE ! 688: || TREE_CODE (type) == RECORD_TYPE ! 689: || TREE_CODE (type) == UNION_TYPE) ! 690: { ! 691: if (TYPE_SIZE (type) != 0 /* not a forward reference */ ! 692: && KNOWN_TYPE_TAG (type) == 0) /* not yet declared */ ! 693: sdbout_one_type (type); ! 694: } ! 695: ! 696: /* Defer SDB information for top-level initialized variables! */ ! 697: if (! local ! 698: && GET_CODE (value) == MEM ! 699: && DECL_INITIAL (decl)) ! 700: return; ! 701: ! 702: /* Record the name for, starting a symtab entry. */ ! 703: name = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 704: ! 705: if (GET_CODE (value) == MEM ! 706: && GET_CODE (XEXP (value, 0)) == SYMBOL_REF) ! 707: { ! 708: PUT_SDB_DEF (name); ! 709: if (TREE_PUBLIC (decl)) ! 710: { ! 711: PUT_SDB_VAL (XEXP (value, 0)); ! 712: PUT_SDB_SCL (C_EXT); ! 713: } ! 714: else ! 715: { ! 716: PUT_SDB_VAL (XEXP (value, 0)); ! 717: PUT_SDB_SCL (C_STAT); ! 718: } ! 719: } ! 720: else if (regno >= 0) ! 721: { ! 722: PUT_SDB_DEF (name); ! 723: PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno)); ! 724: PUT_SDB_SCL (C_REG); ! 725: } ! 726: else if (GET_CODE (value) == MEM ! 727: && (GET_CODE (XEXP (value, 0)) == MEM ! 728: || (GET_CODE (XEXP (value, 0)) == REG ! 729: && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM ! 730: && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM))) ! 731: /* If the value is indirect by memory or by a register ! 732: that isn't the frame pointer ! 733: then it means the object is variable-sized and address through ! 734: that register or stack slot. COFF has no way to represent this ! 735: so all we can do is output the variable as a pointer. */ ! 736: { ! 737: PUT_SDB_DEF (name); ! 738: if (GET_CODE (XEXP (value, 0)) == REG) ! 739: { ! 740: PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0)))); ! 741: PUT_SDB_SCL (C_REG); ! 742: } ! 743: else ! 744: { ! 745: /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) ! 746: (CONST_INT...)))). ! 747: We want the value of that CONST_INT. */ ! 748: /* Encore compiler hates a newline in a macro arg, it seems. */ ! 749: PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET ! 750: (XEXP (XEXP (value, 0), 0))); ! 751: PUT_SDB_SCL (C_AUTO); ! 752: } ! 753: ! 754: type = build_pointer_type (TREE_TYPE (decl)); ! 755: } ! 756: else if (GET_CODE (value) == MEM ! 757: && GET_CODE (XEXP (value, 0)) == PLUS ! 758: && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG ! 759: && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT) ! 760: { ! 761: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))). ! 762: We want the value of that CONST_INT. */ ! 763: PUT_SDB_DEF (name); ! 764: PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0))); ! 765: PUT_SDB_SCL (C_AUTO); ! 766: } ! 767: else ! 768: { ! 769: /* It is something we don't know how to represent for SDB. */ ! 770: return; ! 771: } ! 772: break; ! 773: } ! 774: PUT_SDB_TYPE (plain_type (type)); ! 775: PUT_SDB_ENDEF; ! 776: } ! 777: ! 778: /* Output SDB information for a top-level initialized variable ! 779: that has been delayed. */ ! 780: ! 781: void ! 782: sdbout_toplevel_data (decl) ! 783: tree decl; ! 784: { ! 785: tree type = TREE_TYPE (decl); ! 786: ! 787: if (! (TREE_CODE (decl) == VAR_DECL ! 788: && GET_CODE (DECL_RTL (decl)) == MEM ! 789: && DECL_INITIAL (decl))) ! 790: abort (); ! 791: ! 792: PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); ! 793: PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0)); ! 794: if (TREE_PUBLIC (decl)) ! 795: { ! 796: PUT_SDB_SCL (C_EXT); ! 797: } ! 798: else ! 799: { ! 800: PUT_SDB_SCL (C_STAT); ! 801: } ! 802: PUT_SDB_TYPE (plain_type (type)); ! 803: PUT_SDB_ENDEF; ! 804: } ! 805: ! 806: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 807: ! 808: /* Machinery to record and output anonymous types. */ ! 809: ! 810: static tree anonymous_types; ! 811: ! 812: static void ! 813: sdbout_queue_anonymous_type (type) ! 814: tree type; ! 815: { ! 816: anonymous_types = saveable_tree_cons (NULL_TREE, type, anonymous_types); ! 817: } ! 818: ! 819: static void ! 820: sdbout_dequeue_anonymous_types () ! 821: { ! 822: register tree types, link; ! 823: ! 824: while (anonymous_types) ! 825: { ! 826: types = nreverse (anonymous_types); ! 827: anonymous_types = NULL_TREE; ! 828: ! 829: for (link = types; link; link = TREE_CHAIN (link)) ! 830: { ! 831: register tree type = TREE_VALUE (link); ! 832: ! 833: if (! TREE_ASM_WRITTEN (type)) ! 834: sdbout_one_type (type); ! 835: } ! 836: } ! 837: } ! 838: ! 839: #endif ! 840: ! 841: /* Given a chain of ..._TYPE nodes, all of which have names, ! 842: output definitions of those names, as typedefs. */ ! 843: ! 844: void ! 845: sdbout_types (types) ! 846: register tree types; ! 847: { ! 848: register tree link; ! 849: ! 850: for (link = types; link; link = TREE_CHAIN (link)) ! 851: sdbout_one_type (link); ! 852: ! 853: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 854: sdbout_dequeue_anonymous_types (); ! 855: #endif ! 856: } ! 857: ! 858: static void ! 859: sdbout_type (type) ! 860: tree type; ! 861: { ! 862: register tree tem; ! 863: if (type == error_mark_node) ! 864: type = integer_type_node; ! 865: PUT_SDB_TYPE (plain_type (type)); ! 866: } ! 867: ! 868: /* Output types of the fields of type TYPE, if they are structs. ! 869: ! 870: Formerly did not chase through pointer types, since that could be circular. ! 871: They must come before TYPE, since forward refs are not allowed. ! 872: Now [email protected] says to try them. */ ! 873: ! 874: static void ! 875: sdbout_field_types (type) ! 876: tree type; ! 877: { ! 878: tree tail; ! 879: for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail)) ! 880: if (TREE_CODE (TREE_TYPE (tail)) == POINTER_TYPE) ! 881: sdbout_one_type (TREE_TYPE (TREE_TYPE (tail))); ! 882: else ! 883: sdbout_one_type (TREE_TYPE (tail)); ! 884: } ! 885: ! 886: /* Use this to put out the top level defined record and union types ! 887: for later reference. If this is a struct with a name, then put that ! 888: name out. Other unnamed structs will have .xxfake labels generated so ! 889: that they may be referred to later. ! 890: The label will be stored in the KNOWN_TYPE_TAG slot of a type. ! 891: It may NOT be called recursively. */ ! 892: ! 893: static void ! 894: sdbout_one_type (type) ! 895: tree type; ! 896: { ! 897: text_section (); ! 898: ! 899: switch (TREE_CODE (type)) ! 900: { ! 901: case RECORD_TYPE: ! 902: case UNION_TYPE: ! 903: case ENUMERAL_TYPE: ! 904: type = TYPE_MAIN_VARIANT (type); ! 905: /* Don't output a type twice. */ ! 906: if (TREE_ASM_WRITTEN (type)) ! 907: /* James said test TREE_ASM_BEING_WRITTEN here. */ ! 908: return; ! 909: ! 910: /* Output nothing if type is not yet defined. */ ! 911: if (TYPE_SIZE (type) == 0) ! 912: return; ! 913: ! 914: TREE_ASM_WRITTEN (type) = 1; ! 915: #if 1 ! 916: /* This is reputed to cause trouble with the following case, ! 917: but perhaps checking TYPE_SIZE above will fix it. ! 918: ! 919: /* Here is a test case: ! 920: ! 921: struct foo { ! 922: struct badstr *bbb; ! 923: } forwardref; ! 924: ! 925: typedef struct intermediate { ! 926: int aaaa; ! 927: } intermediate_ref; ! 928: ! 929: typedef struct badstr { ! 930: int ccccc; ! 931: } badtype; */ ! 932: ! 933: #if 0 ! 934: TREE_ASM_BEING_WRITTEN (type) = 1; ! 935: #endif ! 936: /* This change, which ought to make better output, ! 937: used to make the COFF assembler unhappy. ! 938: Changes involving KNOWN_TYPE_TAG may fix the problem. */ ! 939: /* Before really doing anything, output types we want to refer to. */ ! 940: /* Note that in version 1 the following two lines ! 941: are not used if forward references are in use. */ ! 942: if (TREE_CODE (type) != ENUMERAL_TYPE) ! 943: sdbout_field_types (type); ! 944: #if 0 ! 945: TREE_ASM_WRITTEN (type) = 1; ! 946: #endif ! 947: #endif ! 948: ! 949: /* Output a structure type. */ ! 950: { ! 951: int size = int_size_in_bytes (type); ! 952: int member_scl; ! 953: tree tem; ! 954: int i, n_baseclasses = 0; ! 955: ! 956: /* Record the type tag, but not in its permanent place just yet. */ ! 957: sdbout_record_type_name (type); ! 958: ! 959: PUT_SDB_DEF (KNOWN_TYPE_TAG (type)); ! 960: ! 961: switch (TREE_CODE (type)) ! 962: { ! 963: case UNION_TYPE: ! 964: PUT_SDB_SCL (C_UNTAG); ! 965: PUT_SDB_TYPE (T_UNION); ! 966: member_scl = C_MOU; ! 967: break; ! 968: ! 969: case RECORD_TYPE: ! 970: PUT_SDB_SCL (C_STRTAG); ! 971: PUT_SDB_TYPE (T_STRUCT); ! 972: member_scl = C_MOS; ! 973: break; ! 974: ! 975: case ENUMERAL_TYPE: ! 976: PUT_SDB_SCL (C_ENTAG); ! 977: PUT_SDB_TYPE (T_ENUM); ! 978: member_scl = C_MOE; ! 979: break; ! 980: } ! 981: ! 982: PUT_SDB_SIZE (size); ! 983: PUT_SDB_ENDEF; ! 984: ! 985: /* Print out the base class information with fields ! 986: named after the types they hold. */ ! 987: if (TYPE_BINFO (type) ! 988: && TYPE_BINFO_BASETYPES (type)) ! 989: n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); ! 990: for (i = 0; i < n_baseclasses; i++) ! 991: { ! 992: tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i); ! 993: tree child_type = BINFO_TYPE (child); ! 994: tree child_type_name; ! 995: if (TYPE_NAME (child_type) == 0) ! 996: continue; ! 997: if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE) ! 998: child_type_name = TYPE_NAME (child_type); ! 999: else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL) ! 1000: child_type_name = DECL_NAME (TYPE_NAME (child_type)); ! 1001: else ! 1002: continue; ! 1003: ! 1004: CONTIN; ! 1005: PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name)); ! 1006: PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child))); ! 1007: PUT_SDB_SCL (member_scl); ! 1008: sdbout_type (BINFO_TYPE (child)); ! 1009: PUT_SDB_ENDEF; ! 1010: } ! 1011: ! 1012: /* output the individual fields */ ! 1013: ! 1014: if (TREE_CODE (type) == ENUMERAL_TYPE) ! 1015: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) ! 1016: { ! 1017: PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem))); ! 1018: PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem))); ! 1019: PUT_SDB_SCL (C_MOE); ! 1020: PUT_SDB_TYPE (T_MOE); ! 1021: PUT_SDB_ENDEF; ! 1022: } ! 1023: ! 1024: else /* record or union type */ ! 1025: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) ! 1026: /* Output the name, type, position (in bits), size (in bits) ! 1027: of each field. */ ! 1028: ! 1029: /* Omit here the nameless fields that are used to skip bits. ! 1030: Also omit fields with variable size or position. ! 1031: Also omit non FIELD_DECL nodes that GNU C++ may put here. */ ! 1032: if (TREE_CODE (tem) == FIELD_DECL ! 1033: && DECL_NAME (tem) != 0 ! 1034: && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST ! 1035: && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) ! 1036: { ! 1037: CONTIN; ! 1038: PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (tem))); ! 1039: if (DECL_BIT_FIELD_TYPE (tem)) ! 1040: { ! 1041: PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); ! 1042: PUT_SDB_SCL (C_FIELD); ! 1043: sdbout_type (DECL_BIT_FIELD_TYPE (tem)); ! 1044: PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem))); ! 1045: } ! 1046: else ! 1047: { ! 1048: PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)) ! 1049: / BITS_PER_UNIT); ! 1050: PUT_SDB_SCL (member_scl); ! 1051: sdbout_type (TREE_TYPE (tem)); ! 1052: } ! 1053: PUT_SDB_ENDEF; ! 1054: } ! 1055: /* output end of a structure,union, or enumeral definition */ ! 1056: ! 1057: PUT_SDB_PLAIN_DEF ("eos"); ! 1058: PUT_SDB_INT_VAL (size); ! 1059: PUT_SDB_SCL (C_EOS); ! 1060: PUT_SDB_TAG (KNOWN_TYPE_TAG (type)); ! 1061: PUT_SDB_SIZE (size); ! 1062: PUT_SDB_ENDEF; ! 1063: break; ! 1064: } ! 1065: } ! 1066: } ! 1067: ! 1068: /* The following two functions output definitions of function parameters. ! 1069: Each parameter gets a definition locating it in the parameter list. ! 1070: Each parameter that is a register variable gets a second definition ! 1071: locating it in the register. ! 1072: ! 1073: Printing or argument lists in gdb uses the definitions that ! 1074: locate in the parameter list. But reference to the variable in ! 1075: expressions uses preferentially the definition as a register. */ ! 1076: ! 1077: /* Output definitions, referring to storage in the parmlist, ! 1078: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ ! 1079: ! 1080: static void ! 1081: sdbout_parms (parms) ! 1082: tree parms; ! 1083: { ! 1084: for (; parms; parms = TREE_CHAIN (parms)) ! 1085: if (DECL_NAME (parms)) ! 1086: { ! 1087: int current_sym_value = 0; ! 1088: char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); ! 1089: ! 1090: if (name == 0 || *name == 0) ! 1091: name = gen_fake_label (); ! 1092: ! 1093: /* Perform any necessary register eliminations on the parameter's rtl, ! 1094: so that the debugging output will be accurate. */ ! 1095: DECL_INCOMING_RTL (parms) = ! 1096: eliminate_regs (DECL_INCOMING_RTL (parms), 0, 0); ! 1097: DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, 0); ! 1098: ! 1099: if (PARM_PASSED_IN_MEMORY (parms)) ! 1100: { ! 1101: rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); ! 1102: tree type; ! 1103: ! 1104: /* ??? Here we assume that the parm address is indexed ! 1105: off the frame pointer or arg pointer. ! 1106: If that is not true, we produce meaningless results, ! 1107: but do not crash. */ ! 1108: if (GET_CODE (addr) == PLUS ! 1109: && GET_CODE (XEXP (addr, 1)) == CONST_INT) ! 1110: current_sym_value = INTVAL (XEXP (addr, 1)); ! 1111: else ! 1112: current_sym_value = 0; ! 1113: ! 1114: if (GET_CODE (DECL_RTL (parms)) == REG ! 1115: && REGNO (DECL_RTL (parms)) >= 0 ! 1116: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) ! 1117: type = DECL_ARG_TYPE (parms); ! 1118: else ! 1119: { ! 1120: int original_sym_value = current_sym_value; ! 1121: ! 1122: /* This is the case where the parm is passed as an int or ! 1123: double and it is converted to a char, short or float ! 1124: and stored back in the parmlist. In this case, describe ! 1125: the parm with the variable's declared type, and adjust ! 1126: the address if the least significant bytes (which we are ! 1127: using) are not the first ones. */ ! 1128: #if BYTES_BIG_ENDIAN ! 1129: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) ! 1130: current_sym_value += ! 1131: (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) ! 1132: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); ! 1133: #endif ! 1134: if (GET_CODE (DECL_RTL (parms)) == MEM ! 1135: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS ! 1136: && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) ! 1137: == CONST_INT) ! 1138: && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) ! 1139: == current_sym_value)) ! 1140: type = TREE_TYPE (parms); ! 1141: else ! 1142: { ! 1143: current_sym_value = original_sym_value; ! 1144: type = DECL_ARG_TYPE (parms); ! 1145: } ! 1146: } ! 1147: ! 1148: PUT_SDB_DEF (name); ! 1149: PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr)); ! 1150: PUT_SDB_SCL (C_ARG); ! 1151: PUT_SDB_TYPE (plain_type (type)); ! 1152: PUT_SDB_ENDEF; ! 1153: } ! 1154: else if (GET_CODE (DECL_RTL (parms)) == REG) ! 1155: { ! 1156: rtx best_rtl; ! 1157: /* Parm passed in registers and lives in registers or nowhere. */ ! 1158: ! 1159: /* If parm lives in a register, use that register; ! 1160: pretend the parm was passed there. It would be more consistent ! 1161: to describe the register where the parm was passed, ! 1162: but in practice that register usually holds something else. */ ! 1163: if (REGNO (DECL_RTL (parms)) >= 0 ! 1164: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) ! 1165: best_rtl = DECL_RTL (parms); ! 1166: /* If the parm lives nowhere, ! 1167: use the register where it was passed. */ ! 1168: else ! 1169: best_rtl = DECL_INCOMING_RTL (parms); ! 1170: ! 1171: PUT_SDB_DEF (name); ! 1172: PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl))); ! 1173: PUT_SDB_SCL (C_REGPARM); ! 1174: PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0)); ! 1175: PUT_SDB_ENDEF; ! 1176: } ! 1177: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 1178: && XEXP (DECL_RTL (parms), 0) != const0_rtx) ! 1179: { ! 1180: /* Parm was passed in registers but lives on the stack. */ ! 1181: ! 1182: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), ! 1183: in which case we want the value of that CONST_INT, ! 1184: or (MEM (REG ...)) or (MEM (MEM ...)), ! 1185: in which case we use a value of zero. */ ! 1186: if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG ! 1187: || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) ! 1188: current_sym_value = 0; ! 1189: else ! 1190: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); ! 1191: ! 1192: /* Again, this assumes the offset is based on the arg pointer. */ ! 1193: PUT_SDB_DEF (name); ! 1194: PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, ! 1195: XEXP (DECL_RTL (parms), 0))); ! 1196: PUT_SDB_SCL (C_ARG); ! 1197: PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0)); ! 1198: PUT_SDB_ENDEF; ! 1199: } ! 1200: } ! 1201: } ! 1202: ! 1203: /* Output definitions for the places where parms live during the function, ! 1204: when different from where they were passed, when the parms were passed ! 1205: in memory. ! 1206: ! 1207: It is not useful to do this for parms passed in registers ! 1208: that live during the function in different registers, because it is ! 1209: impossible to look in the passed register for the passed value, ! 1210: so we use the within-the-function register to begin with. ! 1211: ! 1212: PARMS is a chain of PARM_DECL nodes. */ ! 1213: ! 1214: static void ! 1215: sdbout_reg_parms (parms) ! 1216: tree parms; ! 1217: { ! 1218: for (; parms; parms = TREE_CHAIN (parms)) ! 1219: if (DECL_NAME (parms)) ! 1220: { ! 1221: char *name = IDENTIFIER_POINTER (DECL_NAME (parms)); ! 1222: ! 1223: /* Report parms that live in registers during the function ! 1224: but were passed in memory. */ ! 1225: if (GET_CODE (DECL_RTL (parms)) == REG ! 1226: && REGNO (DECL_RTL (parms)) >= 0 ! 1227: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER ! 1228: && PARM_PASSED_IN_MEMORY (parms)) ! 1229: { ! 1230: if (name == 0 || *name == 0) ! 1231: name = gen_fake_label (); ! 1232: PUT_SDB_DEF (name); ! 1233: PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)))); ! 1234: PUT_SDB_SCL (C_REG); ! 1235: PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0)); ! 1236: PUT_SDB_ENDEF; ! 1237: } ! 1238: /* Report parms that live in memory but not where they were passed. */ ! 1239: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 1240: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS ! 1241: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT ! 1242: && PARM_PASSED_IN_MEMORY (parms) ! 1243: && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) ! 1244: { ! 1245: #if 0 /* ??? It is not clear yet what should replace this. */ ! 1246: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT; ! 1247: /* A parm declared char is really passed as an int, ! 1248: so it occupies the least significant bytes. ! 1249: On a big-endian machine those are not the low-numbered ones. */ ! 1250: #if BYTES_BIG_ENDIAN ! 1251: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) ! 1252: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) ! 1253: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); ! 1254: #endif ! 1255: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...} ! 1256: #endif ! 1257: { ! 1258: if (name == 0 || *name == 0) ! 1259: name = gen_fake_label (); ! 1260: PUT_SDB_DEF (name); ! 1261: PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET ! 1262: (XEXP (DECL_RTL (parms), 0))); ! 1263: PUT_SDB_SCL (C_AUTO); ! 1264: PUT_SDB_TYPE (plain_type (TREE_TYPE (parms))); ! 1265: PUT_SDB_ENDEF; ! 1266: } ! 1267: } ! 1268: } ! 1269: } ! 1270: ! 1271: /* Describe the beginning of an internal block within a function. ! 1272: Also output descriptions of variables defined in this block. ! 1273: ! 1274: N is the number of the block, by order of beginning, counting from 1, ! 1275: and not counting the outermost (function top-level) block. ! 1276: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), ! 1277: if the count starts at 0 for the outermost one. */ ! 1278: ! 1279: void ! 1280: sdbout_begin_block (file, line, n) ! 1281: FILE *file; ! 1282: int line; ! 1283: int n; ! 1284: { ! 1285: tree decl = current_function_decl; ! 1286: MAKE_LINE_SAFE (line); ! 1287: PUT_SDB_BLOCK_START (line - sdb_begin_function_line); ! 1288: if (n == 1) ! 1289: { ! 1290: /* Include the outermost BLOCK's variables in block 1. */ ! 1291: next_block_number = 0; ! 1292: do_block = 0; ! 1293: sdbout_block (DECL_INITIAL (decl)); ! 1294: } ! 1295: /* If -g1, suppress all the internal symbols of functions ! 1296: except for arguments. */ ! 1297: if (debug_info_level != DINFO_LEVEL_TERSE) ! 1298: { ! 1299: next_block_number = 0; ! 1300: do_block = n; ! 1301: sdbout_block (DECL_INITIAL (decl)); ! 1302: } ! 1303: ! 1304: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 1305: sdbout_dequeue_anonymous_types (); ! 1306: #endif ! 1307: } ! 1308: ! 1309: /* Describe the end line-number of an internal block within a function. */ ! 1310: ! 1311: void ! 1312: sdbout_end_block (file, line) ! 1313: FILE *file; ! 1314: int line; ! 1315: { ! 1316: MAKE_LINE_SAFE (line); ! 1317: PUT_SDB_BLOCK_END (line - sdb_begin_function_line); ! 1318: } ! 1319: ! 1320: /* Output sdb info for the current function name. ! 1321: Called from assemble_start_function. */ ! 1322: ! 1323: void ! 1324: sdbout_mark_begin_function () ! 1325: { ! 1326: sdbout_symbol (current_function_decl, 0); ! 1327: } ! 1328: ! 1329: /* Called at beginning of function body (after prologue). ! 1330: Record the function's starting line number, so we can output ! 1331: relative line numbers for the other lines. ! 1332: Describe beginning of outermost block. ! 1333: Also describe the parameter list. */ ! 1334: ! 1335: void ! 1336: sdbout_begin_function (line) ! 1337: int line; ! 1338: { ! 1339: sdb_begin_function_line = line - 1; ! 1340: PUT_SDB_FUNCTION_START (line); ! 1341: sdbout_parms (DECL_ARGUMENTS (current_function_decl)); ! 1342: sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl)); ! 1343: } ! 1344: ! 1345: /* Called at end of function (before epilogue). ! 1346: Describe end of outermost block. */ ! 1347: ! 1348: void ! 1349: sdbout_end_function (line) ! 1350: int line; ! 1351: { ! 1352: #ifdef SDB_ALLOW_FORWARD_REFERENCES ! 1353: sdbout_dequeue_anonymous_types (); ! 1354: #endif ! 1355: ! 1356: MAKE_LINE_SAFE (line); ! 1357: PUT_SDB_FUNCTION_END (line - sdb_begin_function_line); ! 1358: ! 1359: /* Indicate we are between functions, for line-number output. */ ! 1360: sdb_begin_function_line = -1; ! 1361: } ! 1362: ! 1363: /* Output sdb info for the absolute end of a function. ! 1364: Called after the epilogue is output. */ ! 1365: ! 1366: void ! 1367: sdbout_end_epilogue () ! 1368: { ! 1369: char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)); ! 1370: PUT_SDB_EPILOGUE_END (name); ! 1371: } ! 1372: ! 1373: /* Output sdb info for the given label. Called only if LABEL_NAME (insn) ! 1374: is present. */ ! 1375: ! 1376: void ! 1377: sdbout_label (insn) ! 1378: register rtx insn; ! 1379: { ! 1380: PUT_SDB_DEF (LABEL_NAME (insn)); ! 1381: PUT_SDB_VAL (insn); ! 1382: PUT_SDB_SCL (C_LABEL); ! 1383: PUT_SDB_TYPE (T_NULL); ! 1384: PUT_SDB_ENDEF; ! 1385: } ! 1386: ! 1387: #endif /* SDB_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.