|
|
1.1 ! root 1: /* Output dbx-format symbol table information from GNU compiler. ! 2: Copyright (C) 1987 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is distributed in the hope that it will be useful, ! 7: but WITHOUT ANY WARRANTY. No author or distributor ! 8: accepts responsibility to anyone for the consequences of using it ! 9: or for whether it serves any particular purpose or works at all, ! 10: unless he says so in writing. Refer to the GNU CC General Public ! 11: License for full details. ! 12: ! 13: Everyone is granted permission to copy, modify and redistribute ! 14: GNU CC, but only under the conditions described in the ! 15: GNU CC General Public License. A copy of this license is ! 16: supposed to have been given to you along with GNU CC so you ! 17: can know your rights and responsibilities. It should be in a ! 18: file named COPYING. Among other things, the copyright notice ! 19: and this notice must be preserved on all copies. */ ! 20: ! 21: ! 22: /* Output dbx-format symbol table data. ! 23: This consists of many symbol table entries, each of them ! 24: a .stabs assembler pseudo-op with four operands: ! 25: a "name" which is really a description of one symbol and its type, ! 26: a "code", which is a symbol defined in stab.h whose name starts with N_, ! 27: an unused operand always 0, ! 28: and a "value" which is an address or an offset. ! 29: The name is enclosed in doublequote characters. ! 30: ! 31: Each function, variable, typedef, and structure tag ! 32: has a symbol table entry to define it. ! 33: The beginning and end of each level of name scoping within ! 34: a function are also marked by special symbol table entries. ! 35: ! 36: The "name" consists of the symbol name, a colon, a kind-of-symbol letter, ! 37: and a data type number. The data type number may be followed by ! 38: "=" and a type definition; normally this will happen the first time ! 39: the type number is mentioned. The type definition may refer to ! 40: other types by number, and those type numbers may be followed ! 41: by "=" and nested definitions. ! 42: ! 43: This can make the "name" quite long. ! 44: When a name is more than 80 characters, we split the .stabs pseudo-op ! 45: into two .stabs pseudo-ops, both sharing the same "code" and "value". ! 46: The first one is marked as continued with a double-backslash at the ! 47: end of its "name". ! 48: ! 49: The kind-of-symbol letter distinguished function names from global ! 50: variables from file-scope variables from parameters from auto ! 51: variables in memory from typedef names from register variables. ! 52: See `dbxout_symbol'. ! 53: ! 54: The "code" is mostly redundant with the kind-of-symbol letter ! 55: that goes in the "name", but not entirely: for symbols located ! 56: in static storage, the "code" says which segment the address is in, ! 57: which controls how it is relocated. ! 58: ! 59: The "value" for a symbol in static storage ! 60: is the core address of the symbol (actually, the assembler ! 61: label for the symbol). For a symbol located in a stack slot ! 62: it is the stack offset; for one in a register, the register number. ! 63: For a typedef symbol, it is zero. ! 64: ! 65: For more on data type definitions, see `dbxout_type'. */ ! 66: ! 67: #include "config.h" ! 68: #include "tree.h" ! 69: #include "rtl.h" ! 70: #include "c-tree.h" ! 71: #include <stdio.h> ! 72: #include <stab.h> ! 73: ! 74: /* Stream for writing to assembler file. */ ! 75: ! 76: static FILE *asmfile; ! 77: ! 78: enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED}; ! 79: ! 80: /* Vector recording the status of describing C data types. ! 81: When we first notice a data type (a tree node), ! 82: we assign it a number using next_type_number. ! 83: That is its index in this vector. ! 84: The vector element says whether we have yet output ! 85: the definition of the type. TYPE_XREF says we have ! 86: output it as a cross-reference only. */ ! 87: ! 88: enum typestatus *typevec; ! 89: ! 90: /* Number of elements of space allocated in `typevec'. */ ! 91: ! 92: static int typevec_len; ! 93: ! 94: /* In dbx output, each type gets a unique number. ! 95: This is the number for the next type output. ! 96: The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */ ! 97: ! 98: static int next_type_number; ! 99: ! 100: /* In dbx output, we must assign symbol-blocks id numbers ! 101: in the order in which their beginnings are encountered. ! 102: We output debugging info that refers to the beginning and ! 103: end of the ranges of code in each block ! 104: with assembler labels LBBn and LBEn, where n is the block number. ! 105: The labels are generated in final, which assigns numbers to the ! 106: blocks in the same way. */ ! 107: ! 108: static int next_block_number; ! 109: ! 110: /* These variables are for dbxout_symbol to communicate to ! 111: dbxout_finish_symbol. ! 112: current_sym_code is the symbol-type-code, a symbol N_... define in stab.h. ! 113: current_sym_value and current_sym_addr are two ways to address the ! 114: value to store in the symtab entry. ! 115: current_sym_addr if nonzero represents the value as an rtx. ! 116: If that is zero, current_sym_value is used. This is used ! 117: when the value is an offset (such as for auto variables, ! 118: register variables and parms). */ ! 119: ! 120: static int current_sym_code; ! 121: static int current_sym_value; ! 122: static rtx current_sym_addr; ! 123: ! 124: /* Number of chars of symbol-description generated so far for the ! 125: current symbol. Used by CHARS and CONTIN. */ ! 126: ! 127: static int current_sym_nchars; ! 128: ! 129: /* Report having output N chars of the current symbol-description. */ ! 130: ! 131: #define CHARS(N) (current_sym_nchars += (N)) ! 132: ! 133: /* Break the current symbol-description, generating a continuation, ! 134: if it has become long. */ ! 135: ! 136: #define CONTIN \ ! 137: do {if (current_sym_nchars > 80) dbxout_continue ();} while (0) ! 138: ! 139: void dbxout_types (); ! 140: void dbxout_tags (); ! 141: static void dbxout_type_name (); ! 142: static void dbxout_type (); ! 143: static void dbxout_type_def (); ! 144: static void dbxout_finish_symbol (); ! 145: static void dbxout_continue (); ! 146: ! 147: /* At the beginning of compilation, start writing the symbol table. ! 148: Initialize `typevec' and output the standard data types of C. */ ! 149: ! 150: void ! 151: dbxout_init (asm_file, input_file_name) ! 152: FILE *asm_file; ! 153: char *input_file_name; ! 154: { ! 155: asmfile = asm_file; ! 156: ! 157: typevec_len = 100; ! 158: typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]); ! 159: bzero (typevec, typevec_len * sizeof typevec[0]); ! 160: ! 161: fprintf (asmfile, ! 162: "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n", ! 163: input_filename, N_SO); ! 164: ! 165: next_type_number = 1; ! 166: next_block_number = 2; ! 167: ! 168: /* Make sure that types `int' and `char' have numbers 1 and 2. ! 169: Definitions of other integer types will refer to those numbers. */ ! 170: ! 171: dbxout_type_def (integer_type_node); ! 172: dbxout_type_def (char_type_node); ! 173: ! 174: /* Get all permanent types not yet gotten ! 175: and output them. */ ! 176: ! 177: dbxout_types (get_permanent_types ()); ! 178: } ! 179: ! 180: /* Continue a symbol-description that gets too big. ! 181: End one symbol table entry with a double-backslash ! 182: and start a new one, eventually producing something like ! 183: .stabs "start......\\",code,0,value ! 184: .stabs "...rest",code,0,value */ ! 185: ! 186: static void ! 187: dbxout_continue () ! 188: { ! 189: fprintf (asmfile, "\\\\"); ! 190: dbxout_finish_symbol (); ! 191: fprintf (asmfile, ".stabs \""); ! 192: current_sym_nchars = 0; ! 193: } ! 194: ! 195: /* Output a reference to a type. If the type has not yet been ! 196: described in the dbx output, output its definition now. ! 197: For a type already defined, just refer to its definition ! 198: using the type number. ! 199: ! 200: If FULL is nonzero, and the type has been described only with ! 201: a forward-reference, output the definition now. ! 202: If FULL is zero in this case, just refer to the forward-reference ! 203: using the number previously allocated. */ ! 204: ! 205: static void ! 206: dbxout_type (type, full) ! 207: tree type; ! 208: int full; ! 209: { ! 210: register tree tem; ! 211: ! 212: if (TYPE_SYMTAB_ADDRESS (type) == 0) ! 213: { ! 214: /* Type has no dbx number assigned. Assign next available number. */ ! 215: TYPE_SYMTAB_ADDRESS (type) = next_type_number++; ! 216: ! 217: /* Make sure type vector is long enough to record about this type. */ ! 218: ! 219: if (next_type_number == typevec_len) ! 220: { ! 221: typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]); ! 222: bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]); ! 223: typevec_len *= 2; ! 224: } ! 225: } ! 226: ! 227: /* Output the number of this type, to refer to it. */ ! 228: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type)); ! 229: CHARS (3); ! 230: ! 231: /* If this type's definition has been output or is now being output, ! 232: that is all. */ ! 233: ! 234: switch (typevec[TYPE_SYMTAB_ADDRESS (type)]) ! 235: { ! 236: case TYPE_UNSEEN: ! 237: break; ! 238: case TYPE_XREF: ! 239: if (! full) ! 240: return; ! 241: break; ! 242: case TYPE_DEFINED: ! 243: return; ! 244: } ! 245: ! 246: /* Output a definition now. */ ! 247: ! 248: fprintf (asmfile, "="); ! 249: CHARS (1); ! 250: ! 251: /* Mark it as defined, so that if it is self-referent ! 252: we will not get into an infinite recursion of definitions. */ ! 253: ! 254: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED; ! 255: ! 256: switch (TREE_CODE (type)) ! 257: { ! 258: case VOID_TYPE: ! 259: /* For a void type, just define it as itself; ie, "5=5". ! 260: This makes us consider it defined ! 261: without saying what it is. The debugger will make it ! 262: a void type when the reference is seen, and nothing will ! 263: ever override that default. */ ! 264: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type)); ! 265: CHARS (3); ! 266: break; ! 267: ! 268: case INTEGER_TYPE: ! 269: if (type == char_type_node) ! 270: /* Output the type `char' as a subrange of itself! ! 271: I don't understand this definition, just copied it ! 272: from the output of pcc. */ ! 273: fprintf (asmfile, "r2;0;127;"); ! 274: else ! 275: /* Output other integer types as subranges of `int'. */ ! 276: fprintf (asmfile, "r1;%d;%d;", ! 277: TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)), ! 278: TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))); ! 279: CHARS (25); ! 280: break; ! 281: ! 282: case REAL_TYPE: ! 283: /* This must be magic. */ ! 284: fprintf (asmfile, "r1;%d;0;", ! 285: TREE_INT_CST_LOW (size_in_bytes (type))); ! 286: CHARS (16); ! 287: break; ! 288: ! 289: case ARRAY_TYPE: ! 290: /* Output "a" followed by a range type definition ! 291: for the index type of the array ! 292: followed by a reference to the target-type. ! 293: ar1;0;N;M for an array of type M and size N. */ ! 294: fprintf (asmfile, "ar1;0;%d;", ! 295: TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))); ! 296: CHARS (17); ! 297: dbxout_type (TREE_TYPE (type), 0); ! 298: break; ! 299: ! 300: case RECORD_TYPE: ! 301: case UNION_TYPE: ! 302: /* Output a structure type. */ ! 303: if ((TYPE_NAME (type) != 0 && !full) ! 304: || TYPE_SIZE (type) == 0) ! 305: { ! 306: /* If the type is just a cross reference, output one ! 307: and mark the type as partially described. ! 308: If it later becomes defined, we will output ! 309: its real definition. */ ! 310: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu"); ! 311: CHARS (3); ! 312: dbxout_type_name (type); ! 313: fprintf (asmfile, ":"); ! 314: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF; ! 315: break; ! 316: } ! 317: tem = size_in_bytes (type); ! 318: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d", ! 319: TREE_INT_CST_LOW (tem)); ! 320: CHARS (11); ! 321: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) ! 322: /* Output the name, type, position (in bits), size (in bits) ! 323: of each field. */ ! 324: /* Omit here the nameless fields that are used to skip bits. */ ! 325: if (DECL_NAME (tem) != 0) ! 326: { ! 327: CONTIN; ! 328: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); ! 329: CHARS (1 + strlen (IDENTIFIER_POINTER (DECL_NAME (tem)))); ! 330: dbxout_type (TREE_TYPE (tem), 0); ! 331: fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem), ! 332: TREE_INT_CST_LOW (DECL_SIZE (tem)) * DECL_SIZE_UNIT (tem)); ! 333: CHARS (23); ! 334: } ! 335: putc (';', asmfile); ! 336: CHARS (1); ! 337: break; ! 338: ! 339: case ENUMERAL_TYPE: ! 340: if ((TYPE_NAME (type) != 0 && !full) ! 341: || TYPE_SIZE (type) == 0) ! 342: { ! 343: fprintf (asmfile, "xe"); ! 344: CHARS (3); ! 345: dbxout_type_name (type); ! 346: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF; ! 347: fprintf (asmfile, ":"); ! 348: return; ! 349: } ! 350: putc ('e', asmfile); ! 351: CHARS (1); ! 352: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) ! 353: { ! 354: fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)), ! 355: TREE_INT_CST_LOW (TREE_VALUE (tem))); ! 356: CHARS (11 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (tem)))); ! 357: if (TREE_CHAIN (tem) != 0) ! 358: CONTIN; ! 359: } ! 360: putc (';', asmfile); ! 361: CHARS (1); ! 362: break; ! 363: ! 364: case POINTER_TYPE: ! 365: putc ('*', asmfile); ! 366: CHARS (1); ! 367: dbxout_type (TREE_TYPE (type), 0); ! 368: break; ! 369: ! 370: case FUNCTION_TYPE: ! 371: putc ('f', asmfile); ! 372: CHARS (1); ! 373: dbxout_type (TREE_TYPE (type), 0); ! 374: break; ! 375: } ! 376: } ! 377: ! 378: /* Output the name of type TYPE, with no punctuation. ! 379: Such names can be set up either by typedef declarations ! 380: or by struct, enum and union tags. */ ! 381: ! 382: static void ! 383: dbxout_type_name (type) ! 384: register tree type; ! 385: { ! 386: register char *name; ! 387: if (TYPE_NAME (type) == 0) ! 388: abort (); ! 389: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! 390: name = IDENTIFIER_POINTER (TYPE_NAME (type)); ! 391: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) ! 392: name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); ! 393: else ! 394: abort (); ! 395: ! 396: fprintf (asmfile, "%s", name); ! 397: CHARS (strlen (name)); ! 398: } ! 399: ! 400: /* Output a .stabs for the symbol defined by DECL, ! 401: which must be a ..._DECL node in the normal namespace. ! 402: It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL. ! 403: LOCAL is nonzero if the scope is less than the entire file. */ ! 404: ! 405: void ! 406: dbxout_symbol (decl, local) ! 407: tree decl; ! 408: int local; ! 409: { ! 410: int symcode; ! 411: int letter; ! 412: ! 413: /* If global, first output all types and all ! 414: struct, enum and union tags that have been created ! 415: and not yet output. */ ! 416: ! 417: if (local == 0) ! 418: { ! 419: dbxout_tags (gettags ()); ! 420: dbxout_types (get_permanent_types ()); ! 421: } ! 422: ! 423: current_sym_code = 0; ! 424: current_sym_value = 0; ! 425: current_sym_addr = 0; ! 426: ! 427: /* The output will always start with the symbol name, ! 428: so count that always in the length-output-so-far. */ ! 429: ! 430: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 431: ! 432: switch (TREE_CODE (decl)) ! 433: { ! 434: case CONST_DECL: ! 435: /* Enum values are defined by defining the enum type. */ ! 436: break; ! 437: ! 438: case FUNCTION_DECL: ! 439: if (TREE_EXTERNAL (decl)) ! 440: break; ! 441: if (GET_CODE (DECL_RTL (decl)) != MEM ! 442: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) ! 443: break; ! 444: fprintf (asmfile, ".stabs \"%s:%c", ! 445: IDENTIFIER_POINTER (DECL_NAME (decl)), ! 446: TREE_PUBLIC (decl) ? 'F' : 'f'); ! 447: ! 448: current_sym_code = N_FUN; ! 449: current_sym_addr = XEXP (DECL_RTL (decl), 0); ! 450: ! 451: if (TREE_TYPE (TREE_TYPE (decl))) ! 452: dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0); ! 453: else ! 454: dbxout_type (void_type_node, 0); ! 455: dbxout_finish_symbol (); ! 456: break; ! 457: ! 458: case TYPE_DECL: ! 459: /* Output typedef name. */ ! 460: fprintf (asmfile, ".stabs \"%s:t", ! 461: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 462: ! 463: current_sym_code = N_LSYM; ! 464: ! 465: dbxout_type (TREE_TYPE (decl), 0); ! 466: dbxout_finish_symbol (); ! 467: break; ! 468: ! 469: case PARM_DECL: ! 470: /* Parm decls go in their own separate chains ! 471: and are output by dbxout_reg_parms and dbxout_parms. */ ! 472: abort (); ! 473: ! 474: case VAR_DECL: ! 475: /* Don't mention a variable that is external. ! 476: Let the file that defines it describe it. */ ! 477: if (TREE_EXTERNAL (decl)) ! 478: break; ! 479: ! 480: /* Don't mention a variable at all ! 481: if it was completely optimized into nothingness. */ ! 482: if (GET_CODE (DECL_RTL (decl)) == REG ! 483: && REGNO (DECL_RTL (decl)) == -1) ! 484: break; ! 485: ! 486: /* Ok, start a symtab entry and output the variable name. */ ! 487: fprintf (asmfile, ".stabs \"%s:", ! 488: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 489: ! 490: /* The kind-of-variable letter depends on where ! 491: the variable is and on the scope of its name: ! 492: G and N_GSYM for static storage and global scope, ! 493: S for static storage and file scope, ! 494: v for static storage and local scope, ! 495: for those two, use N_LCSYM if data is in bss segment, ! 496: N_STSYM if it is in data segment, or N_FUN if in text segment. ! 497: no letter at all, and N_LSYM, for auto variable, ! 498: r and N_RSYM for register variable. */ ! 499: ! 500: if (GET_CODE (DECL_RTL (decl)) == MEM ! 501: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF) ! 502: { ! 503: if (TREE_PUBLIC (decl)) ! 504: { ! 505: letter = 'G'; ! 506: current_sym_code = N_GSYM; ! 507: } ! 508: else ! 509: { ! 510: current_sym_addr = XEXP (DECL_RTL (decl), 0); ! 511: ! 512: letter = TREE_PERMANENT (decl) ? 'S' : 'v'; ! 513: ! 514: if (!DECL_INITIAL (decl)) ! 515: current_sym_code = N_LCSYM; ! 516: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl)) ! 517: /* This is not quite right, but it's the closest ! 518: of all the codes that Unix defines. */ ! 519: current_sym_code = N_FUN; ! 520: else ! 521: current_sym_code = N_STSYM; ! 522: } ! 523: putc (letter, asmfile); ! 524: dbxout_type (TREE_TYPE (decl), 0); ! 525: dbxout_finish_symbol (); ! 526: } ! 527: else ! 528: { ! 529: if (GET_CODE (DECL_RTL (decl)) == REG) ! 530: { ! 531: letter = 'r'; ! 532: current_sym_code = N_RSYM; ! 533: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl))); ! 534: } ! 535: else ! 536: { ! 537: letter = 0; ! 538: current_sym_code = N_LSYM; ! 539: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))). ! 540: We want the value of that CONST_INT. */ ! 541: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1)); ! 542: } ! 543: if (letter) putc (letter, asmfile); ! 544: dbxout_type (TREE_TYPE (decl), 0); ! 545: dbxout_finish_symbol (); ! 546: } ! 547: break; ! 548: } ! 549: } ! 550: ! 551: static void ! 552: dbxout_finish_symbol () ! 553: { ! 554: fprintf (asmfile, "\",%d,0,0,", current_sym_code); ! 555: if (current_sym_addr) ! 556: output_addr_const (asmfile, current_sym_addr); ! 557: else ! 558: fprintf (asmfile, "%d", current_sym_value); ! 559: putc ('\n', asmfile); ! 560: } ! 561: ! 562: /* Output definitions of all the decls in a chain. */ ! 563: ! 564: static void ! 565: dbxout_syms (syms) ! 566: tree syms; ! 567: { ! 568: while (syms) ! 569: { ! 570: dbxout_symbol (syms, 1); ! 571: syms = TREE_CHAIN (syms); ! 572: } ! 573: } ! 574: ! 575: /* The following two functions output definitions of function parameters. ! 576: Each parameter gets a definition locating it in the parameter list. ! 577: Each parameter that is a register variable gets a second definition ! 578: locating it in the register. ! 579: ! 580: Printing or argument lists in gdb uses the definitions that ! 581: locate in the parameter list. But reference to the variable in ! 582: expressions uses preferentially the definition as a register. */ ! 583: ! 584: /* Output definitions, referring to storage in the parmlist, ! 585: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ ! 586: ! 587: static void ! 588: dbxout_parms (parms) ! 589: tree parms; ! 590: { ! 591: for (; parms; parms = TREE_CHAIN (parms)) ! 592: { ! 593: current_sym_code = N_PSYM; ! 594: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT; ! 595: /* A parm declared char is really passed as an int, ! 596: so it occupies the least significant bytes. ! 597: On a big-endian machine those are not the low-numbered ones. */ ! 598: #ifdef BYTES_BIG_ENDIAN ! 599: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) ! 600: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); ! 601: #endif ! 602: current_sym_addr = 0; ! 603: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); ! 604: ! 605: fprintf (asmfile, ".stabs \"%s:p", ! 606: IDENTIFIER_POINTER (DECL_NAME (parms))); ! 607: dbxout_type (TREE_TYPE (parms), 0); ! 608: dbxout_finish_symbol (); ! 609: } ! 610: } ! 611: ! 612: /* Output definitions, referring to registers, ! 613: of all the parms in PARMS which are stored in registers during the function. ! 614: PARMS is a chain of PARM_DECL nodes. */ ! 615: ! 616: static void ! 617: dbxout_reg_parms (parms) ! 618: tree parms; ! 619: { ! 620: while (parms) ! 621: { ! 622: if (GET_CODE (DECL_RTL (parms)) == REG ! 623: && REGNO (DECL_RTL (parms)) >= 0) ! 624: { ! 625: current_sym_code = N_RSYM; ! 626: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))); ! 627: current_sym_addr = 0; ! 628: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); ! 629: fprintf (asmfile, ".stabs \"%s:r", ! 630: IDENTIFIER_POINTER (DECL_NAME (parms))); ! 631: dbxout_type (TREE_TYPE (parms), 0); ! 632: dbxout_finish_symbol (); ! 633: } ! 634: parms = TREE_CHAIN (parms); ! 635: } ! 636: } ! 637: ! 638: /* Given a chain of ..._TYPE nodes, all of which have names, ! 639: output definitions of those names, as typedefs. */ ! 640: ! 641: void ! 642: dbxout_types (types) ! 643: register tree types; ! 644: { ! 645: while (types) ! 646: { ! 647: if (TYPE_NAME (types) ! 648: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL) ! 649: dbxout_type_def (types); ! 650: types = TREE_CHAIN (types); ! 651: } ! 652: } ! 653: ! 654: /* Output a definition of a typedef name. ! 655: It works much like any other kind of symbol definition. */ ! 656: ! 657: static void ! 658: dbxout_type_def (type) ! 659: tree type; ! 660: { ! 661: current_sym_code = N_LSYM; ! 662: current_sym_value = 0; ! 663: current_sym_addr = 0; ! 664: current_sym_nchars = 0; ! 665: current_sym_nchars ! 666: = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); ! 667: ! 668: fprintf (asmfile, ".stabs \"%s:t", ! 669: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)))); ! 670: dbxout_type (type, 1); ! 671: dbxout_finish_symbol (); ! 672: } ! 673: ! 674: /* Output the tags (struct, union and enum definitions with names) for a block, ! 675: given a list of them (a chain of TREE_LIST nodes) in TAGS. ! 676: We must check to include those that have been mentioned already with ! 677: only a cross-reference. */ ! 678: ! 679: void ! 680: dbxout_tags (tags) ! 681: tree tags; ! 682: { ! 683: register tree link; ! 684: for (link = tags; link; link = TREE_CHAIN (link)) ! 685: { ! 686: register tree type = TREE_VALUE (link); ! 687: if (TREE_PURPOSE (link) != 0 ! 688: && (TYPE_SYMTAB_ADDRESS (type) == 0 ! 689: || (typevec[TYPE_SYMTAB_ADDRESS (type)] != TYPE_DEFINED)) ! 690: && TYPE_SIZE (type) != 0) ! 691: { ! 692: current_sym_code = N_LSYM; ! 693: current_sym_value = 0; ! 694: current_sym_addr = 0; ! 695: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (link))); ! 696: ! 697: fprintf (asmfile, ".stabs \"%s:T", ! 698: IDENTIFIER_POINTER (TREE_PURPOSE (link))); ! 699: dbxout_type (type, 1); ! 700: dbxout_finish_symbol (); ! 701: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED; ! 702: } ! 703: } ! 704: } ! 705: ! 706: /* Output everything about a symbol block (that is to say, a LET_STMT node ! 707: that represents a scope level), ! 708: including recursive output of contained blocks. ! 709: ! 710: STMT is the LET_STMT node. ! 711: DEPTH is its depth within containing symbol blocks. ! 712: ARGS is usually zero; but for the outermost block of the ! 713: body of a function, it is a chain of PARM_DECLs for the function parameters. ! 714: We output definitions of all the register parms ! 715: as if they were local variables of that block. ! 716: ! 717: Actually, STMT may be several statements chained together. ! 718: We handle them all in sequence. */ ! 719: ! 720: static void ! 721: dbxout_block (stmt, depth, args) ! 722: register tree stmt; ! 723: int depth; ! 724: { ! 725: int blocknum; ! 726: ! 727: while (stmt) ! 728: { ! 729: switch (TREE_CODE (stmt)) ! 730: { ! 731: case COMPOUND_STMT: ! 732: case LOOP_STMT: ! 733: dbxout_block (STMT_BODY (stmt), depth, 0); ! 734: break; ! 735: ! 736: case IF_STMT: ! 737: dbxout_block (STMT_THEN (stmt), depth, 0); ! 738: dbxout_block (STMT_ELSE (stmt), depth, 0); ! 739: break; ! 740: ! 741: case LET_STMT: ! 742: /* In dbx format, the syms of a block come before the N_LBRAC. */ ! 743: dbxout_tags (STMT_TYPE_TAGS (stmt)); ! 744: dbxout_syms (STMT_VARS (stmt), 1); ! 745: if (args) ! 746: dbxout_reg_parms (args); ! 747: ! 748: /* Now output an N_LBRAC symbol to represent the beginning of ! 749: the block. Use the block's tree-walk order to generate ! 750: the assembler symbols LBBn and LBEn ! 751: that final will define around the code in this block. */ ! 752: if (depth > 0) ! 753: { ! 754: blocknum = next_block_number++; ! 755: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum); ! 756: } ! 757: ! 758: /* Output the interior of the block. */ ! 759: dbxout_block (STMT_BODY (stmt), depth + 1, 0); ! 760: ! 761: /* Refer to the marker for the end of the block. */ ! 762: if (depth > 0) ! 763: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum); ! 764: } ! 765: stmt = TREE_CHAIN (stmt); ! 766: } ! 767: } ! 768: ! 769: /* Output dbx data for a function definition. ! 770: This includes a definition of the function name itself (a symbol), ! 771: definitions of the parameters (locating them in the parameter list) ! 772: and then output the block that makes up the function's body ! 773: (including all the auto variables of the function). */ ! 774: ! 775: void ! 776: dbxout_function (decl) ! 777: tree decl; ! 778: { ! 779: dbxout_symbol (decl, 0); ! 780: dbxout_parms (DECL_ARGUMENTS (decl)); ! 781: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); ! 782: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.