|
|
1.1 ! root 1: /* This file contains code written by Ron Guilmette ([email protected]) for ! 2: Network Computing Devices, August, September, October, November 1990. ! 3: ! 4: Output Dwarf format symbol table information from the GNU C compiler. ! 5: Copyright (C) 1992 Free Software Foundation, Inc. ! 6: ! 7: This file is part of GNU CC. ! 8: ! 9: GNU CC is free software; you can redistribute it and/or modify ! 10: it under the terms of the GNU General Public License as published by ! 11: the Free Software Foundation; either version 2, or (at your option) ! 12: any later version. ! 13: ! 14: GNU CC is distributed in the hope that it will be useful, ! 15: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 17: GNU General Public License for more details. ! 18: ! 19: You should have received a copy of the GNU General Public License ! 20: along with GNU CC; see the file COPYING. If not, write to ! 21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 22: ! 23: #include "config.h" ! 24: ! 25: #ifdef DWARF_DEBUGGING_INFO ! 26: #include <stdio.h> ! 27: #include "dwarf.h" ! 28: #include "tree.h" ! 29: #include "flags.h" ! 30: #include "rtl.h" ! 31: #include "insn-config.h" ! 32: #include "reload.h" ! 33: #include "output.h" ! 34: ! 35: /* #define NDEBUG 1 */ ! 36: #include <assert.h> ! 37: ! 38: #if defined(DWARF_TIMESTAMPS) ! 39: #if defined(POSIX) ! 40: #include <time.h> ! 41: #else /* !defined(POSIX) */ ! 42: #include <sys/types.h> ! 43: #if defined(__STDC__) ! 44: extern time_t time (time_t *); ! 45: #else /* !defined(__STDC__) */ ! 46: extern time_t time (); ! 47: #endif /* !defined(__STDC__) */ ! 48: #endif /* !defined(POSIX) */ ! 49: #endif /* defined(DWARF_TIMESTAMPS) */ ! 50: ! 51: #if defined(USG) || defined(POSIX) ! 52: #include <string.h> ! 53: #else ! 54: #include <strings.h> ! 55: #define strrchr rindex ! 56: #define getcwd(s,len) getwd(s) ! 57: #endif ! 58: ! 59: /* IMPORTANT NOTE: Please see the file README.DWARF for important details ! 60: regarding the GNU implementation of Dwarf. */ ! 61: ! 62: /* NOTE: In the comments in this file, many references are made to ! 63: so called "Debugging Information Entries". For the sake of brevity, ! 64: this term is abbreviated to `DIE' throughout the remainder of this ! 65: file. */ ! 66: ! 67: /* Note that the implementation of C++ support herein is (as yet) unfinished. ! 68: If you want to try to complete it, more power to you. */ ! 69: ! 70: #if defined(__GNUC__) && (NDEBUG == 1) ! 71: #define inline static inline ! 72: #else ! 73: #define inline static ! 74: #endif ! 75: ! 76: /* How to start an assembler comment. */ ! 77: #ifndef ASM_COMMENT_START ! 78: #define ASM_COMMENT_START ";#" ! 79: #endif ! 80: ! 81: /* Define a macro which, when given a pointer to some BLOCK node, returns ! 82: a pointer to the FUNCTION_DECL node from which the given BLOCK node ! 83: was instantiated (as an inline expansion). This macro needs to be ! 84: defined properly in tree.h, however for the moment, we just fake it. */ ! 85: ! 86: #define BLOCK_INLINE_FUNCTION(block) 0 ! 87: ! 88: /* Define a macro which returns non-zero for any tagged type which is ! 89: used (directly or indirectly) in the specification of either some ! 90: function's return type or some formal parameter of some function. ! 91: We use this macro when we are operating in "terse" mode to help us ! 92: know what tagged types have to be represented in Dwarf (even in ! 93: terse mode) and which ones don't. ! 94: ! 95: A flag bit with this meaning really should be a part of the normal ! 96: GCC ..._TYPE nodes, but at the moment, there is no such bit defined ! 97: for these nodes. For now, we have to just fake it. It it safe for ! 98: us to simply return zero for all complete tagged types (which will ! 99: get forced out anyway if they were used in the specification of some ! 100: formal or return type) and non-zero for all incomplete tagged types. ! 101: */ ! 102: ! 103: #define TYPE_USED_FOR_FUNCTION(tagged_type) (TYPE_SIZE (tagged_type) == 0) ! 104: ! 105: #define BITFIELD_OFFSET_BITS(DECL) \ ! 106: ((unsigned) TREE_INT_CST_LOW (DECL_FIELD_BITPOS (DECL))) ! 107: #define BITFIELD_OFFSET_UNITS(DECL) \ ! 108: (BITFIELD_OFFSET_BITS(DECL) / (unsigned) BITS_PER_UNIT) ! 109: #define BITFIELD_OFFSET_WORDS_IN_UNITS(DECL) \ ! 110: ((BITFIELD_OFFSET_BITS(DECL) / (unsigned) BITS_PER_WORD) * UNITS_PER_WORD) ! 111: ! 112: extern int flag_traditional; ! 113: extern char *version_string; ! 114: extern char *language_string; ! 115: ! 116: /* Maximum size (in bytes) of an artificially generated label. */ ! 117: ! 118: #define MAX_ARTIFICIAL_LABEL_BYTES 30 ! 119: ! 120: /* Make sure we know the sizes of the various types dwarf can describe. ! 121: These are only defaults. If the sizes are different for your target, ! 122: you should override these values by defining the appropriate symbols ! 123: in your tm.h file. */ ! 124: ! 125: #ifndef CHAR_TYPE_SIZE ! 126: #define CHAR_TYPE_SIZE BITS_PER_UNIT ! 127: #endif ! 128: ! 129: #ifndef SHORT_TYPE_SIZE ! 130: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2) ! 131: #endif ! 132: ! 133: #ifndef INT_TYPE_SIZE ! 134: #define INT_TYPE_SIZE BITS_PER_WORD ! 135: #endif ! 136: ! 137: #ifndef LONG_TYPE_SIZE ! 138: #define LONG_TYPE_SIZE BITS_PER_WORD ! 139: #endif ! 140: ! 141: #ifndef LONG_LONG_TYPE_SIZE ! 142: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) ! 143: #endif ! 144: ! 145: #ifndef WCHAR_TYPE_SIZE ! 146: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE ! 147: #endif ! 148: ! 149: #ifndef WCHAR_UNSIGNED ! 150: #define WCHAR_UNSIGNED 0 ! 151: #endif ! 152: ! 153: #ifndef FLOAT_TYPE_SIZE ! 154: #define FLOAT_TYPE_SIZE BITS_PER_WORD ! 155: #endif ! 156: ! 157: #ifndef DOUBLE_TYPE_SIZE ! 158: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) ! 159: #endif ! 160: ! 161: #ifndef LONG_DOUBLE_TYPE_SIZE ! 162: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) ! 163: #endif ! 164: ! 165: /* Structure to keep track of source filenames. */ ! 166: ! 167: struct filename_entry { ! 168: unsigned number; ! 169: char * name; ! 170: }; ! 171: ! 172: typedef struct filename_entry filename_entry; ! 173: ! 174: /* Pointer to an array of elements, each one having the structure above. */ ! 175: ! 176: static filename_entry *filename_table; ! 177: ! 178: /* Total number of entries in the table (i.e. array) pointed to by ! 179: `filename_table'. This is the *total* and includes both used and ! 180: unused slots. */ ! 181: ! 182: static unsigned ft_entries_allocated; ! 183: ! 184: /* Number of entries in the filename_table which are actually in use. */ ! 185: ! 186: static unsigned ft_entries; ! 187: ! 188: /* Size (in elements) of increments by which we may expand the filename ! 189: table. Actually, a single hunk of space of this size should be enough ! 190: for most typical programs. */ ! 191: ! 192: #define FT_ENTRIES_INCREMENT 64 ! 193: ! 194: /* Local pointer to the name of the main input file. Initialized in ! 195: dwarfout_init. */ ! 196: ! 197: static char *primary_filename; ! 198: ! 199: /* Pointer to the most recent filename for which we produced some line info. */ ! 200: ! 201: static char *last_filename; ! 202: ! 203: /* For Dwarf output, we must assign lexical-blocks id numbers ! 204: in the order in which their beginnings are encountered. ! 205: We output Dwarf debugging info that refers to the beginnings ! 206: and ends of the ranges of code for each lexical block with ! 207: assembler labels ..Bn and ..Bn.e, where n is the block number. ! 208: The labels themselves are generated in final.c, which assigns ! 209: numbers to the blocks in the same way. */ ! 210: ! 211: static unsigned next_block_number = 2; ! 212: ! 213: /* Counter to generate unique names for DIEs. */ ! 214: ! 215: static unsigned next_unused_dienum = 1; ! 216: ! 217: /* Number of the DIE which is currently being generated. */ ! 218: ! 219: static unsigned current_dienum; ! 220: ! 221: /* Number to use for the special "pubname" label on the next DIE which ! 222: represents a function or data object defined in this compilation ! 223: unit which has "extern" linkage. */ ! 224: ! 225: static next_pubname_number = 0; ! 226: ! 227: #define NEXT_DIE_NUM pending_sibling_stack[pending_siblings-1] ! 228: ! 229: /* Pointer to a dynamically allocated list of pre-reserved and still ! 230: pending sibling DIE numbers. Note that this list will grow as needed. */ ! 231: ! 232: static unsigned *pending_sibling_stack; ! 233: ! 234: /* Counter to keep track of the number of pre-reserved and still pending ! 235: sibling DIE numbers. */ ! 236: ! 237: static unsigned pending_siblings; ! 238: ! 239: /* The currently allocated size of the above list (expressed in number of ! 240: list elements). */ ! 241: ! 242: static unsigned pending_siblings_allocated; ! 243: ! 244: /* Size (in elements) of increments by which we may expand the pending ! 245: sibling stack. Actually, a single hunk of space of this size should ! 246: be enough for most typical programs. */ ! 247: ! 248: #define PENDING_SIBLINGS_INCREMENT 64 ! 249: ! 250: /* Non-zero if we are performing our file-scope finalization pass and if ! 251: we should force out Dwarf decsriptions of any and all file-scope ! 252: tagged types which are still incomplete types. */ ! 253: ! 254: static int finalizing = 0; ! 255: ! 256: /* A pointer to the base of a list of pending types which we haven't ! 257: generated DIEs for yet, but which we will have to come back to ! 258: later on. */ ! 259: ! 260: static tree *pending_types_list; ! 261: ! 262: /* Number of elements currently allocated for the pending_types_list. */ ! 263: ! 264: static unsigned pending_types_allocated; ! 265: ! 266: /* Number of elements of pending_types_list currently in use. */ ! 267: ! 268: static unsigned pending_types; ! 269: ! 270: /* Size (in elements) of increments by which we may expand the pending ! 271: types list. Actually, a single hunk of space of this size should ! 272: be enough for most typical programs. */ ! 273: ! 274: #define PENDING_TYPES_INCREMENT 64 ! 275: ! 276: /* Pointer to an artifical RECORD_TYPE which we create in dwarfout_init. ! 277: This is used in a hack to help us get the DIEs describing types of ! 278: formal parameters to come *after* all of the DIEs describing the formal ! 279: parameters themselves. That's necessary in order to be compatible ! 280: with what the brain-dammaged svr4 SDB debugger requires. */ ! 281: ! 282: static tree fake_containing_scope; ! 283: ! 284: /* The number of the current function definition that we are generating ! 285: debugging information for. These numbers range from 1 up to the maximum ! 286: number of function definitions contained within the current compilation ! 287: unit. These numbers are used to create unique labels for various things ! 288: contained within various function definitions. */ ! 289: ! 290: static unsigned current_funcdef_number = 1; ! 291: ! 292: /* Forward declarations for functions defined in this file. */ ! 293: ! 294: static void output_type (); ! 295: static void type_attribute (); ! 296: static void output_decls_for_scope (); ! 297: static void output_decl (); ! 298: static unsigned lookup_filename (); ! 299: ! 300: /* Definitions of defaults for assembler-dependent names of various ! 301: pseudo-ops and section names. ! 302: ! 303: Theses may be overridden in your tm.h file (if necessary) for your ! 304: particular assembler. The default values provided here correspond to ! 305: what is expected by "standard" AT&T System V.4 assemblers. */ ! 306: ! 307: #ifndef FILE_ASM_OP ! 308: #define FILE_ASM_OP "\t.file" ! 309: #endif ! 310: #ifndef VERSION_ASM_OP ! 311: #define VERSION_ASM_OP "\t.version" ! 312: #endif ! 313: #ifndef SECTION_ASM_OP ! 314: #define SECTION_ASM_OP "\t.section" ! 315: #endif ! 316: #ifndef UNALIGNED_SHORT_ASM_OP ! 317: #define UNALIGNED_SHORT_ASM_OP "\t.2byte" ! 318: #endif ! 319: #ifndef UNALIGNED_INT_ASM_OP ! 320: #define UNALIGNED_INT_ASM_OP "\t.4byte" ! 321: #endif ! 322: #ifndef DEF_ASM_OP ! 323: #define DEF_ASM_OP "\t.set" ! 324: #endif ! 325: ! 326: /* This macro is already used elsewhere and has a published default. */ ! 327: #ifndef ASM_BYTE_OP ! 328: #define ASM_BYTE_OP "\t.byte" ! 329: #endif ! 330: ! 331: /* Definitions of defaults for formats and names of various special ! 332: (artificial) labels which may be generated within this file (when ! 333: the -g options is used and DWARF_DEBUGGING_INFO is in effect. ! 334: ! 335: If necessary, these may be overridden from within your tm.h file, ! 336: but typically, you should never need to override these. */ ! 337: ! 338: #ifndef TEXT_BEGIN_LABEL ! 339: #define TEXT_BEGIN_LABEL "._text_b" ! 340: #endif ! 341: #ifndef TEXT_END_LABEL ! 342: #define TEXT_END_LABEL "._text_e" ! 343: #endif ! 344: ! 345: #ifndef DATA_BEGIN_LABEL ! 346: #define DATA_BEGIN_LABEL "._data_b" ! 347: #endif ! 348: #ifndef DATA_END_LABEL ! 349: #define DATA_END_LABEL "._data_e" ! 350: #endif ! 351: ! 352: #ifndef DATA1_BEGIN_LABEL ! 353: #define DATA1_BEGIN_LABEL "._data1_b" ! 354: #endif ! 355: #ifndef DATA1_END_LABEL ! 356: #define DATA1_END_LABEL "._data1_e" ! 357: #endif ! 358: ! 359: #ifndef RODATA_BEGIN_LABEL ! 360: #define RODATA_BEGIN_LABEL "._rodata_b" ! 361: #endif ! 362: #ifndef RODATA_END_LABEL ! 363: #define RODATA_END_LABEL "._rodata_e" ! 364: #endif ! 365: ! 366: #ifndef RODATA1_BEGIN_LABEL ! 367: #define RODATA1_BEGIN_LABEL "._rodata1_b" ! 368: #endif ! 369: #ifndef RODATA1_END_LABEL ! 370: #define RODATA1_END_LABEL "._rodata1_e" ! 371: #endif ! 372: ! 373: #ifndef BSS_BEGIN_LABEL ! 374: #define BSS_BEGIN_LABEL "._bss_b" ! 375: #endif ! 376: #ifndef BSS_END_LABEL ! 377: #define BSS_END_LABEL "._bss_e" ! 378: #endif ! 379: ! 380: #ifndef LINE_BEGIN_LABEL ! 381: #define LINE_BEGIN_LABEL "._line_b" ! 382: #endif ! 383: #ifndef LINE_LAST_ENTRY_LABEL ! 384: #define LINE_LAST_ENTRY_LABEL "._line_last" ! 385: #endif ! 386: #ifndef LINE_END_LABEL ! 387: #define LINE_END_LABEL "._line_e" ! 388: #endif ! 389: ! 390: #ifndef DEBUG_BEGIN_LABEL ! 391: #define DEBUG_BEGIN_LABEL "._debug_b" ! 392: #endif ! 393: #ifndef SFNAMES_BEGIN_LABEL ! 394: #define SFNAMES_BEGIN_LABEL "._sfnames_b" ! 395: #endif ! 396: #ifndef SRCINFO_BEGIN_LABEL ! 397: #define SRCINFO_BEGIN_LABEL "._srcinfo_b" ! 398: #endif ! 399: #ifndef MACINFO_BEGIN_LABEL ! 400: #define MACINFO_BEGIN_LABEL "._macinfo_b" ! 401: #endif ! 402: ! 403: #ifndef DIE_BEGIN_LABEL_FMT ! 404: #define DIE_BEGIN_LABEL_FMT "._D%u" ! 405: #endif ! 406: #ifndef DIE_END_LABEL_FMT ! 407: #define DIE_END_LABEL_FMT "._D%u_e" ! 408: #endif ! 409: #ifndef PUB_DIE_LABEL_FMT ! 410: #define PUB_DIE_LABEL_FMT "._P%u" ! 411: #endif ! 412: #ifndef INSN_LABEL_FMT ! 413: #define INSN_LABEL_FMT "._I%u_%u" ! 414: #endif ! 415: #ifndef BLOCK_BEGIN_LABEL_FMT ! 416: #define BLOCK_BEGIN_LABEL_FMT "._B%u" ! 417: #endif ! 418: #ifndef BLOCK_END_LABEL_FMT ! 419: #define BLOCK_END_LABEL_FMT "._B%u_e" ! 420: #endif ! 421: #ifndef SS_BEGIN_LABEL_FMT ! 422: #define SS_BEGIN_LABEL_FMT "._s%u" ! 423: #endif ! 424: #ifndef SS_END_LABEL_FMT ! 425: #define SS_END_LABEL_FMT "._s%u_e" ! 426: #endif ! 427: #ifndef EE_BEGIN_LABEL_FMT ! 428: #define EE_BEGIN_LABEL_FMT "._e%u" ! 429: #endif ! 430: #ifndef EE_END_LABEL_FMT ! 431: #define EE_END_LABEL_FMT "._e%u_e" ! 432: #endif ! 433: #ifndef MT_BEGIN_LABEL_FMT ! 434: #define MT_BEGIN_LABEL_FMT "._t%u" ! 435: #endif ! 436: #ifndef MT_END_LABEL_FMT ! 437: #define MT_END_LABEL_FMT "._t%u_e" ! 438: #endif ! 439: #ifndef LOC_BEGIN_LABEL_FMT ! 440: #define LOC_BEGIN_LABEL_FMT "._l%u" ! 441: #endif ! 442: #ifndef LOC_END_LABEL_FMT ! 443: #define LOC_END_LABEL_FMT "._l%u_e" ! 444: #endif ! 445: #ifndef BOUND_BEGIN_LABEL_FMT ! 446: #define BOUND_BEGIN_LABEL_FMT "._b%u_%u_%c" ! 447: #endif ! 448: #ifndef BOUND_END_LABEL_FMT ! 449: #define BOUND_END_LABEL_FMT "._b%u_%u_%c_e" ! 450: #endif ! 451: #ifndef DERIV_BEGIN_LABEL_FMT ! 452: #define DERIV_BEGIN_LABEL_FMT "._d%u" ! 453: #endif ! 454: #ifndef DERIV_END_LABEL_FMT ! 455: #define DERIV_END_LABEL_FMT "._d%u_e" ! 456: #endif ! 457: #ifndef SL_BEGIN_LABEL_FMT ! 458: #define SL_BEGIN_LABEL_FMT "._sl%u" ! 459: #endif ! 460: #ifndef SL_END_LABEL_FMT ! 461: #define SL_END_LABEL_FMT "._sl%u_e" ! 462: #endif ! 463: #ifndef FUNC_END_LABEL_FMT ! 464: #define FUNC_END_LABEL_FMT "._f%u_e" ! 465: #endif ! 466: #ifndef TYPE_NAME_FMT ! 467: #define TYPE_NAME_FMT "._T%u" ! 468: #endif ! 469: #ifndef LINE_CODE_LABEL_FMT ! 470: #define LINE_CODE_LABEL_FMT "._LC%u" ! 471: #endif ! 472: #ifndef SFNAMES_ENTRY_LABEL_FMT ! 473: #define SFNAMES_ENTRY_LABEL_FMT "._F%u" ! 474: #endif ! 475: #ifndef LINE_ENTRY_LABEL_FMT ! 476: #define LINE_ENTRY_LABEL_FMT "._LE%u" ! 477: #endif ! 478: ! 479: /* Definitions of defaults for various types of primitive assembly language ! 480: output operations. ! 481: ! 482: If necessary, these may be overridden from within your tm.h file, ! 483: but typically, you should never need to override these. */ ! 484: ! 485: #ifndef ASM_OUTPUT_SOURCE_FILENAME ! 486: #define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME) \ ! 487: fprintf ((FILE), "%s\t\"%s\"\n", FILE_ASM_OP, NAME) ! 488: #endif ! 489: ! 490: #ifndef ASM_OUTPUT_DEF ! 491: #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \ ! 492: do { fprintf ((FILE), "%s\t", DEF_ASM_OP); \ ! 493: assemble_name (FILE, LABEL1); \ ! 494: fprintf (FILE, ","); \ ! 495: assemble_name (FILE, LABEL2); \ ! 496: fprintf (FILE, "\n"); \ ! 497: } while (0) ! 498: #endif ! 499: ! 500: #ifndef ASM_DWARF_DEBUG_SECTION ! 501: #define ASM_DWARF_DEBUG_SECTION(FILE) \ ! 502: fprintf ((FILE), "%s\t.debug\n", SECTION_ASM_OP) ! 503: #endif ! 504: ! 505: #ifndef ASM_DWARF_LINE_SECTION ! 506: #define ASM_DWARF_LINE_SECTION(FILE) \ ! 507: fprintf ((FILE), "%s\t.line\n", SECTION_ASM_OP) ! 508: #endif ! 509: ! 510: #ifndef ASM_DWARF_SFNAMES_SECTION ! 511: #define ASM_DWARF_SFNAMES_SECTION(FILE) \ ! 512: fprintf ((FILE), "%s\t.debug_sfnames\n", SECTION_ASM_OP) ! 513: #endif ! 514: ! 515: #ifndef ASM_DWARF_SRCINFO_SECTION ! 516: #define ASM_DWARF_SRCINFO_SECTION(FILE) \ ! 517: fprintf ((FILE), "%s\t.debug_srcinfo\n", SECTION_ASM_OP) ! 518: #endif ! 519: ! 520: #ifndef ASM_DWARF_MACINFO_SECTION ! 521: #define ASM_DWARF_MACINFO_SECTION(FILE) \ ! 522: fprintf ((FILE), "%s\t.debug_macinfo\n", SECTION_ASM_OP) ! 523: #endif ! 524: ! 525: #ifndef ASM_DWARF_PUBNAMES_SECTION ! 526: #define ASM_DWARF_PUBNAMES_SECTION(FILE) \ ! 527: fprintf ((FILE), "%s\t.debug_pubnames\n", SECTION_ASM_OP) ! 528: #endif ! 529: ! 530: #ifndef ASM_DWARF_ARANGES_SECTION ! 531: #define ASM_DWARF_ARANGES_SECTION(FILE) \ ! 532: fprintf ((FILE), "%s\t.debug_aranges\n", SECTION_ASM_OP) ! 533: #endif ! 534: ! 535: #ifndef ASM_DWARF_TEXT_SECTION ! 536: #define ASM_DWARF_TEXT_SECTION(FILE) \ ! 537: fprintf ((FILE), "%s\t.text\n", SECTION_ASM_OP) ! 538: #endif ! 539: ! 540: #ifndef ASM_DWARF_DATA_SECTION ! 541: #define ASM_DWARF_DATA_SECTION(FILE) \ ! 542: fprintf ((FILE), "%s\t.data\n", SECTION_ASM_OP) ! 543: #endif ! 544: ! 545: #ifndef ASM_DWARF_DATA1_SECTION ! 546: #define ASM_DWARF_DATA1_SECTION(FILE) \ ! 547: fprintf ((FILE), "%s\t.data1\n", SECTION_ASM_OP) ! 548: #endif ! 549: ! 550: #ifndef ASM_DWARF_RODATA_SECTION ! 551: #define ASM_DWARF_RODATA_SECTION(FILE) \ ! 552: fprintf ((FILE), "%s\t.rodata\n", SECTION_ASM_OP) ! 553: #endif ! 554: ! 555: #ifndef ASM_DWARF_RODATA1_SECTION ! 556: #define ASM_DWARF_RODATA1_SECTION(FILE) \ ! 557: fprintf ((FILE), "%s\t.rodata1\n", SECTION_ASM_OP) ! 558: #endif ! 559: ! 560: #ifndef ASM_DWARF_BSS_SECTION ! 561: #define ASM_DWARF_BSS_SECTION(FILE) \ ! 562: fprintf ((FILE), "%s\t.bss\n", SECTION_ASM_OP) ! 563: #endif ! 564: ! 565: #ifndef ASM_DWARF_POP_SECTION ! 566: #define ASM_DWARF_POP_SECTION(FILE) \ ! 567: fprintf ((FILE), "\t.previous\n") ! 568: #endif ! 569: ! 570: #ifndef ASM_OUTPUT_DWARF_DELTA2 ! 571: #define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2) \ ! 572: do { fprintf ((FILE), "%s\t", UNALIGNED_SHORT_ASM_OP); \ ! 573: assemble_name (FILE, LABEL1); \ ! 574: fprintf (FILE, "-"); \ ! 575: assemble_name (FILE, LABEL2); \ ! 576: fprintf (FILE, "\n"); \ ! 577: } while (0) ! 578: #endif ! 579: ! 580: #ifndef ASM_OUTPUT_DWARF_DELTA4 ! 581: #define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2) \ ! 582: do { fprintf ((FILE), "%s\t", UNALIGNED_INT_ASM_OP); \ ! 583: assemble_name (FILE, LABEL1); \ ! 584: fprintf (FILE, "-"); \ ! 585: assemble_name (FILE, LABEL2); \ ! 586: fprintf (FILE, "\n"); \ ! 587: } while (0) ! 588: #endif ! 589: ! 590: #ifndef ASM_OUTPUT_DWARF_TAG ! 591: #define ASM_OUTPUT_DWARF_TAG(FILE,TAG) \ ! 592: fprintf ((FILE), "%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \ ! 593: (unsigned) TAG, ASM_COMMENT_START, tag_name (TAG)) ! 594: #endif ! 595: ! 596: #ifndef ASM_OUTPUT_DWARF_ATTRIBUTE ! 597: #define ASM_OUTPUT_DWARF_ATTRIBUTE(FILE,ATTRIBUTE) \ ! 598: fprintf ((FILE), "%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \ ! 599: (unsigned) ATTRIBUTE, ASM_COMMENT_START, attribute_name (ATTRIBUTE)) ! 600: #endif ! 601: ! 602: #ifndef ASM_OUTPUT_DWARF_STACK_OP ! 603: #define ASM_OUTPUT_DWARF_STACK_OP(FILE,OP) \ ! 604: fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \ ! 605: (unsigned) OP, ASM_COMMENT_START, stack_op_name (OP)) ! 606: #endif ! 607: ! 608: #ifndef ASM_OUTPUT_DWARF_FUND_TYPE ! 609: #define ASM_OUTPUT_DWARF_FUND_TYPE(FILE,FT) \ ! 610: fprintf ((FILE), "%s\t0x%x\t%s %s\n", UNALIGNED_SHORT_ASM_OP, \ ! 611: (unsigned) FT, ASM_COMMENT_START, fundamental_type_name (FT)) ! 612: #endif ! 613: ! 614: #ifndef ASM_OUTPUT_DWARF_FMT_BYTE ! 615: #define ASM_OUTPUT_DWARF_FMT_BYTE(FILE,FMT) \ ! 616: fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \ ! 617: (unsigned) FMT, ASM_COMMENT_START, format_byte_name (FMT)) ! 618: #endif ! 619: ! 620: #ifndef ASM_OUTPUT_DWARF_TYPE_MODIFIER ! 621: #define ASM_OUTPUT_DWARF_TYPE_MODIFIER(FILE,MOD) \ ! 622: fprintf ((FILE), "%s\t0x%x\t%s %s\n", ASM_BYTE_OP, \ ! 623: (unsigned) MOD, ASM_COMMENT_START, modifier_name (MOD)) ! 624: #endif ! 625: ! 626: #ifndef ASM_OUTPUT_DWARF_ADDR ! 627: #define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL) \ ! 628: do { fprintf ((FILE), "%s\t", UNALIGNED_INT_ASM_OP); \ ! 629: assemble_name (FILE, LABEL); \ ! 630: fprintf (FILE, "\n"); \ ! 631: } while (0) ! 632: #endif ! 633: ! 634: #ifndef ASM_OUTPUT_DWARF_ADDR_CONST ! 635: #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX) \ ! 636: fprintf ((FILE), "%s\t", UNALIGNED_INT_ASM_OP); \ ! 637: output_addr_const ((FILE), (RTX)); \ ! 638: fputc ('\n', (FILE)) ! 639: #endif ! 640: ! 641: #ifndef ASM_OUTPUT_DWARF_REF ! 642: #define ASM_OUTPUT_DWARF_REF(FILE,LABEL) \ ! 643: do { fprintf ((FILE), "%s\t", UNALIGNED_INT_ASM_OP); \ ! 644: assemble_name (FILE, LABEL); \ ! 645: fprintf (FILE, "\n"); \ ! 646: } while (0) ! 647: #endif ! 648: ! 649: #ifndef ASM_OUTPUT_DWARF_DATA1 ! 650: #define ASM_OUTPUT_DWARF_DATA1(FILE,VALUE) \ ! 651: fprintf ((FILE), "%s\t0x%x\n", ASM_BYTE_OP, VALUE) ! 652: #endif ! 653: ! 654: #ifndef ASM_OUTPUT_DWARF_DATA2 ! 655: #define ASM_OUTPUT_DWARF_DATA2(FILE,VALUE) \ ! 656: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_SHORT_ASM_OP, (unsigned) VALUE) ! 657: #endif ! 658: ! 659: #ifndef ASM_OUTPUT_DWARF_DATA4 ! 660: #define ASM_OUTPUT_DWARF_DATA4(FILE,VALUE) \ ! 661: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_INT_ASM_OP, (unsigned) VALUE) ! 662: #endif ! 663: ! 664: #ifndef ASM_OUTPUT_DWARF_DATA8 ! 665: #define ASM_OUTPUT_DWARF_DATA8(FILE,HIGH_VALUE,LOW_VALUE) \ ! 666: do { \ ! 667: if (WORDS_BIG_ENDIAN) \ ! 668: { \ ! 669: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \ ! 670: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\ ! 671: } \ ! 672: else \ ! 673: { \ ! 674: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\ ! 675: fprintf ((FILE), "%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \ ! 676: } \ ! 677: } while (0) ! 678: #endif ! 679: ! 680: #ifndef ASM_OUTPUT_DWARF_STRING ! 681: #define ASM_OUTPUT_DWARF_STRING(FILE,P) \ ! 682: ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1) ! 683: #endif ! 684: ! 685: /************************ general utility functions **************************/ ! 686: ! 687: inline char * ! 688: xstrdup (s) ! 689: register char *s; ! 690: { ! 691: register char *p = (char *) xmalloc (strlen (s) + 1); ! 692: ! 693: strcpy (p, s); ! 694: return p; ! 695: } ! 696: ! 697: static char * ! 698: tag_name (tag) ! 699: register unsigned tag; ! 700: { ! 701: switch (tag) ! 702: { ! 703: case TAG_padding: return "TAG_padding"; ! 704: case TAG_array_type: return "TAG_array_type"; ! 705: case TAG_class_type: return "TAG_class_type"; ! 706: case TAG_entry_point: return "TAG_entry_point"; ! 707: case TAG_enumeration_type: return "TAG_enumeration_type"; ! 708: case TAG_formal_parameter: return "TAG_formal_parameter"; ! 709: case TAG_global_subroutine: return "TAG_global_subroutine"; ! 710: case TAG_global_variable: return "TAG_global_variable"; ! 711: case TAG_imported_declaration: return "TAG_imported_declaration"; ! 712: case TAG_label: return "TAG_label"; ! 713: case TAG_lexical_block: return "TAG_lexical_block"; ! 714: case TAG_local_variable: return "TAG_local_variable"; ! 715: case TAG_member: return "TAG_member"; ! 716: case TAG_pointer_type: return "TAG_pointer_type"; ! 717: case TAG_reference_type: return "TAG_reference_type"; ! 718: case TAG_compile_unit: return "TAG_compile_unit"; ! 719: case TAG_string_type: return "TAG_string_type"; ! 720: case TAG_structure_type: return "TAG_structure_type"; ! 721: case TAG_subroutine: return "TAG_subroutine"; ! 722: case TAG_subroutine_type: return "TAG_subroutine_type"; ! 723: case TAG_typedef: return "TAG_typedef"; ! 724: case TAG_union_type: return "TAG_union_type"; ! 725: case TAG_unspecified_parameters: return "TAG_unspecified_parameters"; ! 726: case TAG_variant: return "TAG_variant"; ! 727: case TAG_format: return "TAG_format"; ! 728: case TAG_with_stmt: return "TAG_with_stmt"; ! 729: case TAG_set_type: return "TAG_set_type"; ! 730: default: return "<unknown tag>"; ! 731: } ! 732: } ! 733: ! 734: static char * ! 735: attribute_name (attr) ! 736: register unsigned attr; ! 737: { ! 738: switch (attr) ! 739: { ! 740: case AT_sibling: return "AT_sibling"; ! 741: case AT_location: return "AT_location"; ! 742: case AT_name: return "AT_name"; ! 743: case AT_fund_type: return "AT_fund_type"; ! 744: case AT_mod_fund_type: return "AT_mod_fund_type"; ! 745: case AT_user_def_type: return "AT_user_def_type"; ! 746: case AT_mod_u_d_type: return "AT_mod_u_d_type"; ! 747: case AT_ordering: return "AT_ordering"; ! 748: case AT_subscr_data: return "AT_subscr_data"; ! 749: case AT_byte_size: return "AT_byte_size"; ! 750: case AT_bit_offset: return "AT_bit_offset"; ! 751: case AT_bit_size: return "AT_bit_size"; ! 752: case AT_element_list: return "AT_element_list"; ! 753: case AT_stmt_list: return "AT_stmt_list"; ! 754: case AT_low_pc: return "AT_low_pc"; ! 755: case AT_high_pc: return "AT_high_pc"; ! 756: case AT_language: return "AT_language"; ! 757: case AT_member: return "AT_member"; ! 758: case AT_discr: return "AT_discr"; ! 759: case AT_discr_value: return "AT_discr_value"; ! 760: case AT_visibility: return "AT_visibility"; ! 761: case AT_import: return "AT_import"; ! 762: case AT_string_length: return "AT_string_length"; ! 763: case AT_comp_dir: return "AT_comp_dir"; ! 764: case AT_producer: return "AT_producer"; ! 765: case AT_frame_base: return "AT_frame_base"; ! 766: case AT_start_scope: return "AT_start_scope"; ! 767: case AT_stride_size: return "AT_stride_size"; ! 768: case AT_src_info: return "AT_src_info"; ! 769: case AT_prototyped: return "AT_prototyped"; ! 770: case AT_const_value_block4: return "AT_const_value_block4"; ! 771: case AT_sf_names: return "AT_sf_names"; ! 772: case AT_mac_info: return "AT_mac_info"; ! 773: default: return "<unknown attribute>"; ! 774: } ! 775: } ! 776: ! 777: static char * ! 778: stack_op_name (op) ! 779: register unsigned op; ! 780: { ! 781: switch (op) ! 782: { ! 783: case OP_REG: return "OP_REG"; ! 784: case OP_BASEREG: return "OP_BASEREG"; ! 785: case OP_ADDR: return "OP_ADDR"; ! 786: case OP_CONST: return "OP_CONST"; ! 787: case OP_DEREF2: return "OP_DEREF2"; ! 788: case OP_DEREF4: return "OP_DEREF4"; ! 789: case OP_ADD: return "OP_ADD"; ! 790: default: return "<unknown stack operator>"; ! 791: } ! 792: } ! 793: ! 794: static char * ! 795: modifier_name (mod) ! 796: register unsigned mod; ! 797: { ! 798: switch (mod) ! 799: { ! 800: case MOD_pointer_to: return "MOD_pointer_to"; ! 801: case MOD_reference_to: return "MOD_reference_to"; ! 802: case MOD_const: return "MOD_const"; ! 803: case MOD_volatile: return "MOD_volatile"; ! 804: default: return "<unknown modifier>"; ! 805: } ! 806: } ! 807: ! 808: static char * ! 809: format_byte_name (fmt) ! 810: register unsigned fmt; ! 811: { ! 812: switch (fmt) ! 813: { ! 814: case FMT_FT_C_C: return "FMT_FT_C_C"; ! 815: case FMT_FT_C_X: return "FMT_FT_C_X"; ! 816: case FMT_FT_X_C: return "FMT_FT_X_C"; ! 817: case FMT_FT_X_X: return "FMT_FT_X_X"; ! 818: case FMT_UT_C_C: return "FMT_UT_C_C"; ! 819: case FMT_UT_C_X: return "FMT_UT_C_X"; ! 820: case FMT_UT_X_C: return "FMT_UT_X_C"; ! 821: case FMT_UT_X_X: return "FMT_UT_X_X"; ! 822: case FMT_ET: return "FMT_ET"; ! 823: default: return "<unknown array bound format byte>"; ! 824: } ! 825: } ! 826: static char * ! 827: fundamental_type_name (ft) ! 828: register unsigned ft; ! 829: { ! 830: switch (ft) ! 831: { ! 832: case FT_char: return "FT_char"; ! 833: case FT_signed_char: return "FT_signed_char"; ! 834: case FT_unsigned_char: return "FT_unsigned_char"; ! 835: case FT_short: return "FT_short"; ! 836: case FT_signed_short: return "FT_signed_short"; ! 837: case FT_unsigned_short: return "FT_unsigned_short"; ! 838: case FT_integer: return "FT_integer"; ! 839: case FT_signed_integer: return "FT_signed_integer"; ! 840: case FT_unsigned_integer: return "FT_unsigned_integer"; ! 841: case FT_long: return "FT_long"; ! 842: case FT_signed_long: return "FT_signed_long"; ! 843: case FT_unsigned_long: return "FT_unsigned_long"; ! 844: case FT_pointer: return "FT_pointer"; ! 845: case FT_float: return "FT_float"; ! 846: case FT_dbl_prec_float: return "FT_dbl_prec_float"; ! 847: case FT_ext_prec_float: return "FT_ext_prec_float"; ! 848: case FT_complex: return "FT_complex"; ! 849: case FT_dbl_prec_complex: return "FT_dbl_prec_complex"; ! 850: case FT_void: return "FT_void"; ! 851: case FT_boolean: return "FT_boolean"; ! 852: case FT_long_long: return "FT_long_long"; ! 853: case FT_signed_long_long: return "FT_signed_long_long"; ! 854: case FT_unsigned_long_long: return "FT_unsigned_long_long"; ! 855: default: return "<unknown fundamental type>"; ! 856: } ! 857: } ! 858: ! 859: /**************** utility functions for attribute functions ******************/ ! 860: ! 861: /* Given a pointer to a tree node for some type, return a Dwarf fundamental ! 862: type code for the given type. ! 863: ! 864: This routine must only be called for GCC type nodes that correspond to ! 865: Dwarf fundamental types. ! 866: ! 867: The current Dwarf draft specification calls for Dwarf fundamental types ! 868: to accurately reflect the fact that a given type was either a "plain" ! 869: integral type or an explicitly "signed" integral type. Unfortuantely, ! 870: we can't always do this, because GCC may already have thrown away the ! 871: information about the precise way in which the type was originally ! 872: specified, as in: ! 873: ! 874: typedef signed int field_type; ! 875: ! 876: struct s { field_type f; }; ! 877: ! 878: Since we may be stuck here without enought information to do exactly ! 879: what is called for in the Dwarf draft specification, we do the best ! 880: that we can under the circumstances and always use the "plain" integral ! 881: fundamental type codes for int, short, and long types. That's probably ! 882: good enough. The additional accuracy called for in the current DWARF ! 883: draft specification is probably never even useful in practice. */ ! 884: ! 885: static int ! 886: fundamental_type_code (type) ! 887: register tree type; ! 888: { ! 889: if (TREE_CODE (type) == ERROR_MARK) ! 890: return 0; ! 891: ! 892: switch (TREE_CODE (type)) ! 893: { ! 894: case ERROR_MARK: ! 895: return FT_void; ! 896: ! 897: case VOID_TYPE: ! 898: return FT_void; ! 899: ! 900: case INTEGER_TYPE: ! 901: /* Carefully distinguish all the standard types of C, ! 902: without messing up if the language is not C. ! 903: Note that we check only for the names that contain spaces; ! 904: other names might occur by coincidence in other languages. */ ! 905: if (TYPE_NAME (type) != 0 ! 906: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 907: && DECL_NAME (TYPE_NAME (type)) != 0 ! 908: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) ! 909: { ! 910: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); ! 911: ! 912: if (!strcmp (name, "unsigned char")) ! 913: return FT_unsigned_char; ! 914: if (!strcmp (name, "signed char")) ! 915: return FT_signed_char; ! 916: if (!strcmp (name, "unsigned int")) ! 917: return FT_unsigned_integer; ! 918: if (!strcmp (name, "short int")) ! 919: return FT_short; ! 920: if (!strcmp (name, "short unsigned int")) ! 921: return FT_unsigned_short; ! 922: if (!strcmp (name, "long int")) ! 923: return FT_long; ! 924: if (!strcmp (name, "long unsigned int")) ! 925: return FT_unsigned_long; ! 926: if (!strcmp (name, "long long int")) ! 927: return FT_long_long; /* Not grok'ed by svr4 SDB */ ! 928: if (!strcmp (name, "long long unsigned int")) ! 929: return FT_unsigned_long_long; /* Not grok'ed by svr4 SDB */ ! 930: } ! 931: ! 932: /* Most integer types will be sorted out above, however, for the ! 933: sake of special `array index' integer types, the following code ! 934: is also provided. */ ! 935: ! 936: if (TYPE_PRECISION (type) == INT_TYPE_SIZE) ! 937: return (TREE_UNSIGNED (type) ? FT_unsigned_integer : FT_integer); ! 938: ! 939: if (TYPE_PRECISION (type) == LONG_TYPE_SIZE) ! 940: return (TREE_UNSIGNED (type) ? FT_unsigned_long : FT_long); ! 941: ! 942: if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE) ! 943: return (TREE_UNSIGNED (type) ? FT_unsigned_long_long : FT_long_long); ! 944: ! 945: if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE) ! 946: return (TREE_UNSIGNED (type) ? FT_unsigned_short : FT_short); ! 947: ! 948: if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE) ! 949: return (TREE_UNSIGNED (type) ? FT_unsigned_char : FT_char); ! 950: ! 951: abort (); ! 952: ! 953: case REAL_TYPE: ! 954: /* Carefully distinguish all the standard types of C, ! 955: without messing up if the language is not C. */ ! 956: if (TYPE_NAME (type) != 0 ! 957: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 958: && DECL_NAME (TYPE_NAME (type)) != 0 ! 959: && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE) ! 960: { ! 961: char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))); ! 962: ! 963: /* Note that here we can run afowl of a serious bug in "classic" ! 964: svr4 SDB debuggers. They don't seem to understand the ! 965: FT_ext_prec_float type (even though they should). */ ! 966: ! 967: if (!strcmp (name, "long double")) ! 968: return FT_ext_prec_float; ! 969: } ! 970: ! 971: if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE) ! 972: return FT_dbl_prec_float; ! 973: if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE) ! 974: return FT_float; ! 975: ! 976: /* Note that here we can run afowl of a serious bug in "classic" ! 977: svr4 SDB debuggers. They don't seem to understand the ! 978: FT_ext_prec_float type (even though they should). */ ! 979: ! 980: if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE) ! 981: return FT_ext_prec_float; ! 982: abort (); ! 983: ! 984: case COMPLEX_TYPE: ! 985: return FT_complex; /* GNU FORTRAN COMPLEX type. */ ! 986: ! 987: case CHAR_TYPE: ! 988: return FT_char; /* GNU Pascal CHAR type. Not used in C. */ ! 989: ! 990: case BOOLEAN_TYPE: ! 991: return FT_boolean; /* GNU FORTRAN BOOLEAN type. */ ! 992: ! 993: default: ! 994: abort (); /* No other TREE_CODEs are Dwarf fundamental types. */ ! 995: } ! 996: return 0; ! 997: } ! 998: ! 999: /* Given a pointer to an arbitrary ..._TYPE tree node, return a pointer to ! 1000: the Dwarf "root" type for the given input type. The Dwarf "root" type ! 1001: of a given type is generally the same as the given type, except that if ! 1002: the given type is a pointer or reference type, then the root type of ! 1003: the given type is the root type of the "basis" type for the pointer or ! 1004: reference type. (This definition of the "root" type is recursive.) ! 1005: Also, the root type of a `const' qualified type or a `volatile' ! 1006: qualified type is the root type of the given type without the ! 1007: qualifiers. */ ! 1008: ! 1009: static tree ! 1010: root_type (type) ! 1011: register tree type; ! 1012: { ! 1013: if (TREE_CODE (type) == ERROR_MARK) ! 1014: return error_mark_node; ! 1015: ! 1016: switch (TREE_CODE (type)) ! 1017: { ! 1018: case ERROR_MARK: ! 1019: return error_mark_node; ! 1020: ! 1021: case POINTER_TYPE: ! 1022: case REFERENCE_TYPE: ! 1023: return TYPE_MAIN_VARIANT (root_type (TREE_TYPE (type))); ! 1024: ! 1025: default: ! 1026: return TYPE_MAIN_VARIANT (type); ! 1027: } ! 1028: } ! 1029: ! 1030: /* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence ! 1031: of zero or more Dwarf "type-modifier" bytes applicable to the type. */ ! 1032: ! 1033: static void ! 1034: write_modifier_bytes (type, decl_const, decl_volatile) ! 1035: register tree type; ! 1036: register int decl_const; ! 1037: register int decl_volatile; ! 1038: { ! 1039: if (TREE_CODE (type) == ERROR_MARK) ! 1040: return; ! 1041: ! 1042: if (TYPE_READONLY (type) || decl_const) ! 1043: ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const); ! 1044: if (TYPE_VOLATILE (type) || decl_volatile) ! 1045: ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_volatile); ! 1046: switch (TREE_CODE (type)) ! 1047: { ! 1048: case POINTER_TYPE: ! 1049: ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to); ! 1050: write_modifier_bytes (TREE_TYPE (type), 0, 0); ! 1051: return; ! 1052: ! 1053: case REFERENCE_TYPE: ! 1054: ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to); ! 1055: write_modifier_bytes (TREE_TYPE (type), 0, 0); ! 1056: return; ! 1057: ! 1058: case ERROR_MARK: ! 1059: default: ! 1060: return; ! 1061: } ! 1062: } ! 1063: ! 1064: /* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the ! 1065: given input type is a Dwarf "fundamental" type. Otherwise return zero. */ ! 1066: ! 1067: inline int ! 1068: type_is_fundamental (type) ! 1069: register tree type; ! 1070: { ! 1071: switch (TREE_CODE (type)) ! 1072: { ! 1073: case ERROR_MARK: ! 1074: case VOID_TYPE: ! 1075: case INTEGER_TYPE: ! 1076: case REAL_TYPE: ! 1077: case COMPLEX_TYPE: ! 1078: case BOOLEAN_TYPE: ! 1079: case CHAR_TYPE: ! 1080: return 1; ! 1081: ! 1082: case SET_TYPE: ! 1083: case ARRAY_TYPE: ! 1084: case RECORD_TYPE: ! 1085: case UNION_TYPE: ! 1086: case ENUMERAL_TYPE: ! 1087: case FUNCTION_TYPE: ! 1088: case METHOD_TYPE: ! 1089: case POINTER_TYPE: ! 1090: case REFERENCE_TYPE: ! 1091: case STRING_TYPE: ! 1092: case FILE_TYPE: ! 1093: case OFFSET_TYPE: ! 1094: case LANG_TYPE: ! 1095: return 0; ! 1096: ! 1097: default: ! 1098: abort (); ! 1099: } ! 1100: return 0; ! 1101: } ! 1102: ! 1103: /* Given a pointer to some ..._TYPE tree node, generate an assembly language ! 1104: equate directive which will associate an easily remembered symbolic name ! 1105: with the current DIE. ! 1106: ! 1107: The name used is an artificial label generated from the TYPE_UID number ! 1108: associated with the given type node. The name it gets equated to is the ! 1109: symbolic label that we (previously) output at the start of the DIE that ! 1110: we are currently generating. ! 1111: ! 1112: Calling this function while generating some "type related" form of DIE ! 1113: makes it easy to later refer to the DIE which represents the given type ! 1114: simply by re-generating the alternative name from the ..._TYPE node's ! 1115: UID number. */ ! 1116: ! 1117: inline void ! 1118: equate_type_number_to_die_number (type) ! 1119: register tree type; ! 1120: { ! 1121: char type_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1122: char die_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1123: ! 1124: /* We are generating a DIE to represent the main variant of this type ! 1125: (i.e the type without any const or volatile qualifiers) so in order ! 1126: to get the equate to come out right, we need to get the main variant ! 1127: itself here. */ ! 1128: ! 1129: type = TYPE_MAIN_VARIANT (type); ! 1130: ! 1131: sprintf (type_label, TYPE_NAME_FMT, TYPE_UID (type)); ! 1132: sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum); ! 1133: ASM_OUTPUT_DEF (asm_out_file, type_label, die_label); ! 1134: } ! 1135: ! 1136: /* The following routine is a nice and simple transducer. It converts the ! 1137: RTL for a variable or parameter (resident in memory) into an equivalent ! 1138: Dwarf representation of a mechanism for getting the address of that same ! 1139: variable onto the top of a hypothetical "address evaluation" stack. ! 1140: ! 1141: When creating memory location descriptors, we are effectively trans- ! 1142: forming the RTL for a memory-resident object into its Dwarf postfix ! 1143: expression equivalent. This routine just recursively descends an ! 1144: RTL tree, turning it into Dwarf postfix code as it goes. */ ! 1145: ! 1146: static void ! 1147: output_mem_loc_descriptor (rtl) ! 1148: register rtx rtl; ! 1149: { ! 1150: /* Note that for a dynamically sized array, the location we will ! 1151: generate a description of here will be the lowest numbered location ! 1152: which is actually within the array. That's *not* necessarily the ! 1153: same as the zeroth element of the array. */ ! 1154: ! 1155: switch (GET_CODE (rtl)) ! 1156: { ! 1157: case SUBREG: ! 1158: ! 1159: /* The case of a subreg may arise when we have a local (register) ! 1160: variable or a formal (register) parameter which doesn't quite ! 1161: fill up an entire register. For now, just assume that it is ! 1162: legitimate to make the Dwarf info refer to the whole register ! 1163: which contains the given subreg. */ ! 1164: ! 1165: rtl = XEXP (rtl, 0); ! 1166: /* Drop thru. */ ! 1167: ! 1168: case REG: ! 1169: ! 1170: /* Whenever a register number forms a part of the description of ! 1171: the method for calculating the (dynamic) address of a memory ! 1172: resident object, Dwarf rules require the register number to ! 1173: be referred to as a "base register". This distinction is not ! 1174: based in any way upon what category of register the hardware ! 1175: believes the given register belongs to. This is strictly ! 1176: Dwarf terminology we're dealing with here. */ ! 1177: ! 1178: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_BASEREG); ! 1179: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1180: DBX_REGISTER_NUMBER (REGNO (rtl))); ! 1181: break; ! 1182: ! 1183: case MEM: ! 1184: output_mem_loc_descriptor (XEXP (rtl, 0)); ! 1185: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_DEREF4); ! 1186: break; ! 1187: ! 1188: case CONST: ! 1189: case SYMBOL_REF: ! 1190: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADDR); ! 1191: ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl); ! 1192: break; ! 1193: ! 1194: case PLUS: ! 1195: output_mem_loc_descriptor (XEXP (rtl, 0)); ! 1196: output_mem_loc_descriptor (XEXP (rtl, 1)); ! 1197: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD); ! 1198: break; ! 1199: ! 1200: case CONST_INT: ! 1201: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST); ! 1202: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, INTVAL (rtl)); ! 1203: break; ! 1204: ! 1205: default: ! 1206: abort (); ! 1207: } ! 1208: } ! 1209: ! 1210: /* Output a proper Dwarf location descriptor for a variable or parameter ! 1211: which is either allocated in a register or in a memory location. For ! 1212: a register, we just generate an OP_REG and the register number. For a ! 1213: memory location we provide a Dwarf postfix expression describing how to ! 1214: generate the (dynamic) address of the object onto the address stack. */ ! 1215: ! 1216: static void ! 1217: output_loc_descriptor (rtl) ! 1218: register rtx rtl; ! 1219: { ! 1220: switch (GET_CODE (rtl)) ! 1221: { ! 1222: case SUBREG: ! 1223: ! 1224: /* The case of a subreg may arise when we have a local (register) ! 1225: variable or a formal (register) parameter which doesn't quite ! 1226: fill up an entire register. For now, just assume that it is ! 1227: legitimate to make the Dwarf info refer to the whole register ! 1228: which contains the given subreg. */ ! 1229: ! 1230: rtl = XEXP (rtl, 0); ! 1231: /* Drop thru. */ ! 1232: ! 1233: case REG: ! 1234: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_REG); ! 1235: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1236: DBX_REGISTER_NUMBER (REGNO (rtl))); ! 1237: break; ! 1238: ! 1239: case MEM: ! 1240: output_mem_loc_descriptor (XEXP (rtl, 0)); ! 1241: break; ! 1242: ! 1243: default: ! 1244: abort (); /* Should never happen */ ! 1245: } ! 1246: } ! 1247: ! 1248: /* Given a tree node describing an array bound (either lower or upper) ! 1249: output a representation for that bound. */ ! 1250: ! 1251: static void ! 1252: output_bound_representation (bound, dim_num, u_or_l) ! 1253: register tree bound; ! 1254: register unsigned dim_num; /* For multi-dimensional arrays. */ ! 1255: register char u_or_l; /* Designates upper or lower bound. */ ! 1256: { ! 1257: switch (TREE_CODE (bound)) ! 1258: { ! 1259: ! 1260: case ERROR_MARK: ! 1261: return; ! 1262: ! 1263: /* All fixed-bounds are represented by INTEGER_CST nodes. */ ! 1264: ! 1265: case INTEGER_CST: ! 1266: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1267: (unsigned) TREE_INT_CST_LOW (bound)); ! 1268: break; ! 1269: ! 1270: /* Dynamic bounds may be represented by NOP_EXPR nodes containing ! 1271: SAVE_EXPR nodes. */ ! 1272: ! 1273: case NOP_EXPR: ! 1274: bound = TREE_OPERAND (bound, 0); ! 1275: /* ... fall thru... */ ! 1276: ! 1277: case SAVE_EXPR: ! 1278: { ! 1279: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1280: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1281: ! 1282: sprintf (begin_label, BOUND_BEGIN_LABEL_FMT, ! 1283: current_dienum, dim_num, u_or_l); ! 1284: ! 1285: sprintf (end_label, BOUND_END_LABEL_FMT, ! 1286: current_dienum, dim_num, u_or_l); ! 1287: ! 1288: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1289: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1290: ! 1291: /* If we are working on a bound for a dynamic dimension in C, ! 1292: the dynamic dimension in question had better have a static ! 1293: (zero) lower bound and a dynamic *upper* bound. */ ! 1294: ! 1295: if (u_or_l != 'u') ! 1296: abort (); ! 1297: ! 1298: /* If optimization is turned on, the SAVE_EXPRs that describe ! 1299: how to access the upper bound values are essentially bogus. ! 1300: They only describe (at best) how to get at these values at ! 1301: the points in the generated code right after they have just ! 1302: been computed. Worse yet, in the typical case, the upper ! 1303: bound values will not even *be* computed in the optimized ! 1304: code, so these SAVE_EXPRs are entirely bogus. ! 1305: ! 1306: In order to compensate for this fact, we check here to see ! 1307: if optimization is enabled, and if so, we effectively create ! 1308: an empty location description for the (unknown and unknowable) ! 1309: upper bound. ! 1310: ! 1311: This should not cause too much trouble for existing (stupid?) ! 1312: debuggers because they have to deal with empty upper bounds ! 1313: location descriptions anyway in order to be able to deal with ! 1314: incomplete array types. ! 1315: ! 1316: Of course an intelligent debugger (GDB?) should be able to ! 1317: comprehend that a missing upper bound specification in a ! 1318: array type used for a storage class `auto' local array variable ! 1319: indicates that the upper bound is both unknown (at compile- ! 1320: time) and unknowable (at run-time) due to optimization. ! 1321: */ ! 1322: ! 1323: if (! optimize) ! 1324: output_loc_descriptor ! 1325: (eliminate_regs (SAVE_EXPR_RTL (bound), 0, 0)); ! 1326: ! 1327: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1328: } ! 1329: break; ! 1330: ! 1331: default: ! 1332: abort (); ! 1333: } ! 1334: } ! 1335: ! 1336: /* Recursive function to output a sequence of value/name pairs for ! 1337: enumeration constants in reversed order. This is called from ! 1338: enumeration_type_die. */ ! 1339: ! 1340: static void ! 1341: output_enumeral_list (link) ! 1342: register tree link; ! 1343: { ! 1344: if (link) ! 1345: { ! 1346: output_enumeral_list (TREE_CHAIN (link)); ! 1347: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1348: (unsigned) TREE_INT_CST_LOW (TREE_VALUE (link))); ! 1349: ASM_OUTPUT_DWARF_STRING (asm_out_file, ! 1350: IDENTIFIER_POINTER (TREE_PURPOSE (link))); ! 1351: } ! 1352: } ! 1353: ! 1354: /****************************** attributes *********************************/ ! 1355: ! 1356: /* The following routines are responsible for writing out the various types ! 1357: of Dwarf attributes (and any following data bytes associated with them). ! 1358: These routines are listed in order based on the numerical codes of their ! 1359: associated attributes. */ ! 1360: ! 1361: /* Generate an AT_sibling attribute. */ ! 1362: ! 1363: inline void ! 1364: sibling_attribute () ! 1365: { ! 1366: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1367: ! 1368: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sibling); ! 1369: sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM); ! 1370: ASM_OUTPUT_DWARF_REF (asm_out_file, label); ! 1371: } ! 1372: ! 1373: /* Output the form of location attributes suitable for whole variables and ! 1374: whole parameters. Note that the location attributes for struct fields ! 1375: are generated by the routine `data_member_location_attribute' below. */ ! 1376: ! 1377: static void ! 1378: location_attribute (rtl) ! 1379: register rtx rtl; ! 1380: { ! 1381: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1382: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1383: ! 1384: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location); ! 1385: sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); ! 1386: sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); ! 1387: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1388: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1389: ! 1390: /* Handle a special case. If we are about to output a location descriptor ! 1391: for a variable or parameter which has been optimized out of existance, ! 1392: don't do that. Instead we output a zero-length location descriptor ! 1393: value as part of the location attribute. Note that we cannot simply ! 1394: suppress the entire location attribute, because the absence of a ! 1395: location attribute in certain kinds of DIEs is used to indicate some- ! 1396: thing entirely different... i.e. that the DIE represents an object ! 1397: declaration, but not a definition. So sayeth the PLSIG. */ ! 1398: ! 1399: if (((GET_CODE (rtl) != REG) || (REGNO (rtl) < FIRST_PSEUDO_REGISTER)) ! 1400: && ((GET_CODE (rtl) != SUBREG) ! 1401: || (REGNO (XEXP (rtl, 0)) < FIRST_PSEUDO_REGISTER))) ! 1402: output_loc_descriptor (eliminate_regs (rtl, 0, 0)); ! 1403: ! 1404: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1405: } ! 1406: ! 1407: /* Output the specialized form of location attribute used for data members ! 1408: of struct types. */ ! 1409: ! 1410: static void ! 1411: data_member_location_attribute (decl) ! 1412: register tree decl; ! 1413: { ! 1414: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1415: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1416: ! 1417: if (TREE_CODE (decl) == ERROR_MARK) ! 1418: return; ! 1419: ! 1420: if (TREE_CODE (decl) != FIELD_DECL) ! 1421: abort (); ! 1422: ! 1423: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location); ! 1424: sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); ! 1425: sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); ! 1426: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1427: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1428: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST); ! 1429: ! 1430: /* This is pretty strange, but existing compilers producing DWARF ! 1431: apparently calculate the byte offset of a field differently ! 1432: depending upon whether or not it is a bit-field. If the given ! 1433: field is *not* a bit-field, then the offset is simply the ! 1434: the byte offset of the given field from the beginning of the ! 1435: struct. For bit-fields however, the offset is the offset (in ! 1436: bytes) of the beginning of the *containing word* from the ! 1437: beginning of the whole struct. */ ! 1438: ! 1439: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1440: (DECL_BIT_FIELD_TYPE (decl)) ! 1441: ? BITFIELD_OFFSET_WORDS_IN_UNITS (decl) ! 1442: : BITFIELD_OFFSET_UNITS (decl)); ! 1443: ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD); ! 1444: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1445: } ! 1446: ! 1447: /* Output an AT_const_value attribute for a variable or a parameter which ! 1448: does not have a "location" either in memory or in a register. These ! 1449: things can arise in GNU C when a constant is passed as an actual ! 1450: parameter to an inlined function. They can also arise in C++ where ! 1451: declared constants do not necessarily get memory "homes". */ ! 1452: ! 1453: static void ! 1454: const_value_attribute (rtl) ! 1455: register rtx rtl; ! 1456: { ! 1457: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1458: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1459: ! 1460: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_const_value_block4); ! 1461: sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum); ! 1462: sprintf (end_label, LOC_END_LABEL_FMT, current_dienum); ! 1463: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); ! 1464: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1465: ! 1466: switch (GET_CODE (rtl)) ! 1467: { ! 1468: case CONST_INT: ! 1469: /* Note that a CONST_INT rtx could represent either an integer or ! 1470: a floating-point constant. A CONST_INT is used whenever the ! 1471: constant will fit into a single word. In all such cases, the ! 1472: original mode of the constant value is wiped out, and the ! 1473: CONST_INT rtx is assigned VOIDmode. Since we no longer have ! 1474: precise mode information for these constants, we always just ! 1475: output them using 4 bytes. */ ! 1476: ! 1477: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, (unsigned) INTVAL (rtl)); ! 1478: break; ! 1479: ! 1480: case CONST_DOUBLE: ! 1481: /* Note that a CONST_DOUBLE rtx could represent either an integer ! 1482: or a floating-point constant. A CONST_DOUBLE is used whenever ! 1483: the constant requires more than one word in order to be adequately ! 1484: represented. In all such cases, the original mode of the constant ! 1485: value is preserved as the mode of the CONST_DOUBLE rtx, but for ! 1486: simplicity we always just output CONST_DOUBLEs using 8 bytes. */ ! 1487: ! 1488: ASM_OUTPUT_DWARF_DATA8 (asm_out_file, ! 1489: (unsigned) CONST_DOUBLE_HIGH (rtl), ! 1490: (unsigned) CONST_DOUBLE_LOW (rtl)); ! 1491: break; ! 1492: ! 1493: case CONST_STRING: ! 1494: ASM_OUTPUT_DWARF_STRING (asm_out_file, XSTR (rtl, 0)); ! 1495: break; ! 1496: ! 1497: case SYMBOL_REF: ! 1498: case LABEL_REF: ! 1499: case CONST: ! 1500: ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl); ! 1501: break; ! 1502: } ! 1503: ! 1504: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1505: } ! 1506: ! 1507: /* Generate *either* an AT_location attribute or else an AT_const_value ! 1508: data attribute for a variable or a parameter. We generate the ! 1509: AT_const_value attribute only in those cases where the given ! 1510: variable or parameter does not have a true "location" either in ! 1511: memory or in a register. This can happen (for example) when a ! 1512: constant is passed as an actual argument in a call to an inline ! 1513: function. (It's possible that these things can crop up in other ! 1514: ways also.) Note that one type of constant value which can be ! 1515: passed into an inlined function is a constant pointer. This can ! 1516: happen for example if an actual argument in an inlined function ! 1517: call evaluates to a compile-time constant address. */ ! 1518: ! 1519: static void ! 1520: location_or_const_value_attribute (decl) ! 1521: register tree decl; ! 1522: { ! 1523: register rtx rtl; ! 1524: ! 1525: if (TREE_CODE (decl) == ERROR_MARK) ! 1526: return; ! 1527: ! 1528: if ((TREE_CODE (decl) != VAR_DECL) && (TREE_CODE (decl) != PARM_DECL)) ! 1529: abort (); ! 1530: ! 1531: /* It's not really clear what existing Dwarf debuggers need or expect ! 1532: as regards to location information for formal parameters. A later ! 1533: version of the Dwarf specification should resolve such issues, but ! 1534: for the time being, we assume here that debuggers want information ! 1535: about the location where the parameter was passed into the function. ! 1536: That seems to be what USL's CI5 compiler generates. Note that this ! 1537: will probably be different from the place where the parameter actual ! 1538: resides during function execution. Dwarf Version 2 will provide us ! 1539: with a means to describe that location also, but for now we can only ! 1540: describe the "passing" location. */ ! 1541: ! 1542: #if 0 /* This is probably right, but it leads to a lot of trouble. ! 1543: Fixing one problem has been exposing another, ! 1544: all of which seemed to have no ill effects before. ! 1545: Better to turn this off for now and try fix it later. */ ! 1546: rtl = (TREE_CODE (decl) == PARM_DECL) ! 1547: ? DECL_INCOMING_RTL (decl) ! 1548: : DECL_RTL (decl); ! 1549: #endif ! 1550: rtl = DECL_RTL (decl); ! 1551: ! 1552: if (rtl == NULL) ! 1553: return; ! 1554: ! 1555: switch (GET_CODE (rtl)) ! 1556: { ! 1557: case CONST_INT: ! 1558: case CONST_DOUBLE: ! 1559: case CONST_STRING: ! 1560: case SYMBOL_REF: ! 1561: case LABEL_REF: ! 1562: case CONST: ! 1563: const_value_attribute (rtl); ! 1564: break; ! 1565: ! 1566: case MEM: ! 1567: case REG: ! 1568: case SUBREG: ! 1569: location_attribute (rtl); ! 1570: break; ! 1571: ! 1572: default: ! 1573: abort (); /* Should never happen. */ ! 1574: } ! 1575: } ! 1576: ! 1577: /* Generate an AT_name attribute given some string value to be included as ! 1578: the value of the attribute. If the name is null, don't do anything. */ ! 1579: ! 1580: inline void ! 1581: name_attribute (name_string) ! 1582: register char *name_string; ! 1583: { ! 1584: if (name_string && *name_string) ! 1585: { ! 1586: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name); ! 1587: ASM_OUTPUT_DWARF_STRING (asm_out_file, name_string); ! 1588: } ! 1589: } ! 1590: ! 1591: inline void ! 1592: fund_type_attribute (ft_code) ! 1593: register unsigned ft_code; ! 1594: { ! 1595: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_fund_type); ! 1596: ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, ft_code); ! 1597: } ! 1598: ! 1599: static void ! 1600: mod_fund_type_attribute (type, decl_const, decl_volatile) ! 1601: register tree type; ! 1602: register int decl_const; ! 1603: register int decl_volatile; ! 1604: { ! 1605: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1606: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1607: ! 1608: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_fund_type); ! 1609: sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum); ! 1610: sprintf (end_label, MT_END_LABEL_FMT, current_dienum); ! 1611: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1612: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1613: write_modifier_bytes (type, decl_const, decl_volatile); ! 1614: ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, ! 1615: fundamental_type_code (root_type (type))); ! 1616: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1617: } ! 1618: ! 1619: inline void ! 1620: user_def_type_attribute (type) ! 1621: register tree type; ! 1622: { ! 1623: char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1624: ! 1625: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_user_def_type); ! 1626: sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (type)); ! 1627: ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name); ! 1628: } ! 1629: ! 1630: static void ! 1631: mod_u_d_type_attribute (type, decl_const, decl_volatile) ! 1632: register tree type; ! 1633: register int decl_const; ! 1634: register int decl_volatile; ! 1635: { ! 1636: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1637: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1638: char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1639: ! 1640: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_u_d_type); ! 1641: sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum); ! 1642: sprintf (end_label, MT_END_LABEL_FMT, current_dienum); ! 1643: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1644: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1645: write_modifier_bytes (type, decl_const, decl_volatile); ! 1646: sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (root_type (type))); ! 1647: ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name); ! 1648: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1649: } ! 1650: ! 1651: inline void ! 1652: ordering_attribute (ordering) ! 1653: register unsigned ordering; ! 1654: { ! 1655: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_ordering); ! 1656: ASM_OUTPUT_DWARF_DATA2 (asm_out_file, ordering); ! 1657: } ! 1658: ! 1659: /* Note that the block of subscript information for an array type also ! 1660: includes information about the element type of type given array type. */ ! 1661: ! 1662: static void ! 1663: subscript_data_attribute (type) ! 1664: register tree type; ! 1665: { ! 1666: register unsigned dimension_number; ! 1667: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1668: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1669: ! 1670: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_subscr_data); ! 1671: sprintf (begin_label, SS_BEGIN_LABEL_FMT, current_dienum); ! 1672: sprintf (end_label, SS_END_LABEL_FMT, current_dienum); ! 1673: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1674: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1675: ! 1676: /* The GNU compilers represent multidimensional array types as sequences ! 1677: of one dimensional array types whose element types are themselves array ! 1678: types. Here we squish that down, so that each multidimensional array ! 1679: type gets only one array_type DIE in the Dwarf debugging info. The ! 1680: draft Dwarf specification say that we are allowed to do this kind ! 1681: of compression in C (because there is no difference between an ! 1682: array or arrays and a multidimensional array in C) but for other ! 1683: source languages (e.g. Ada) we probably shouldn't do this. */ ! 1684: ! 1685: for (dimension_number = 0; ! 1686: TREE_CODE (type) == ARRAY_TYPE; ! 1687: type = TREE_TYPE (type), dimension_number++) ! 1688: { ! 1689: register tree domain = TYPE_DOMAIN (type); ! 1690: ! 1691: /* Arrays come in three flavors. Unspecified bounds, fixed ! 1692: bounds, and (in GNU C only) variable bounds. Handle all ! 1693: three forms here. */ ! 1694: ! 1695: if (domain) ! 1696: { ! 1697: /* We have an array type with specified bounds. */ ! 1698: ! 1699: register tree lower = TYPE_MIN_VALUE (domain); ! 1700: register tree upper = TYPE_MAX_VALUE (domain); ! 1701: ! 1702: /* Handle only fundamental types as index types for now. */ ! 1703: ! 1704: if (! type_is_fundamental (domain)) ! 1705: abort (); ! 1706: ! 1707: /* Output the representation format byte for this dimension. */ ! 1708: ! 1709: ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, ! 1710: FMT_CODE (1, ! 1711: TREE_CODE (lower) == INTEGER_CST, ! 1712: TREE_CODE (upper) == INTEGER_CST)); ! 1713: ! 1714: /* Output the index type for this dimension. */ ! 1715: ! 1716: ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, ! 1717: fundamental_type_code (domain)); ! 1718: ! 1719: /* Output the representation for the lower bound. */ ! 1720: ! 1721: output_bound_representation (lower, dimension_number, 'l'); ! 1722: ! 1723: /* Output the representation for the upper bound. */ ! 1724: ! 1725: output_bound_representation (upper, dimension_number, 'u'); ! 1726: } ! 1727: else ! 1728: { ! 1729: /* We have an array type with an unspecified length. For C and ! 1730: C++ we can assume that this really means that (a) the index ! 1731: type is an integral type, and (b) the lower bound is zero. ! 1732: Note that Dwarf defines the representation of an unspecified ! 1733: (upper) bound as being a zero-length location description. */ ! 1734: ! 1735: /* Output the array-bounds format byte. */ ! 1736: ! 1737: ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_FT_C_X); ! 1738: ! 1739: /* Output the (assumed) index type. */ ! 1740: ! 1741: ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, FT_integer); ! 1742: ! 1743: /* Output the (assumed) lower bound (constant) value. */ ! 1744: ! 1745: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 1746: ! 1747: /* Output the (empty) location description for the upper bound. */ ! 1748: ! 1749: ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0); ! 1750: } ! 1751: } ! 1752: ! 1753: /* Output the prefix byte that says that the element type is comming up. */ ! 1754: ! 1755: ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_ET); ! 1756: ! 1757: /* Output a representation of the type of the elements of this array type. */ ! 1758: ! 1759: type_attribute (type, 0, 0); ! 1760: ! 1761: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1762: } ! 1763: ! 1764: static void ! 1765: byte_size_attribute (tree_node) ! 1766: register tree tree_node; ! 1767: { ! 1768: register unsigned size; ! 1769: ! 1770: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_byte_size); ! 1771: switch (TREE_CODE (tree_node)) ! 1772: { ! 1773: case ERROR_MARK: ! 1774: size = 0; ! 1775: break; ! 1776: ! 1777: case ENUMERAL_TYPE: ! 1778: case RECORD_TYPE: ! 1779: case UNION_TYPE: ! 1780: size = int_size_in_bytes (tree_node); ! 1781: break; ! 1782: ! 1783: case FIELD_DECL: ! 1784: { ! 1785: register unsigned words; ! 1786: register unsigned bits; ! 1787: ! 1788: bits = TREE_INT_CST_LOW (DECL_SIZE (tree_node)); ! 1789: words = (bits + (BITS_PER_WORD-1)) / BITS_PER_WORD; ! 1790: size = words * (BITS_PER_WORD / BITS_PER_UNIT); ! 1791: } ! 1792: break; ! 1793: ! 1794: default: ! 1795: abort (); ! 1796: } ! 1797: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size); ! 1798: } ! 1799: ! 1800: /* For a FIELD_DECL node which represents a bit field, output an attribute ! 1801: which specifies the distance in bits from the start of the *word* ! 1802: containing the given field to the first bit of the field. */ ! 1803: ! 1804: inline void ! 1805: bit_offset_attribute (decl) ! 1806: register tree decl; ! 1807: { ! 1808: assert (TREE_CODE (decl) == FIELD_DECL); /* Must be a field. */ ! 1809: assert (DECL_BIT_FIELD_TYPE (decl)); /* Must be a bit field. */ ! 1810: ! 1811: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_offset); ! 1812: ASM_OUTPUT_DWARF_DATA2 (asm_out_file, ! 1813: BITFIELD_OFFSET_BITS (decl) % (unsigned) BITS_PER_WORD); ! 1814: } ! 1815: ! 1816: /* For a FIELD_DECL node which represents a bit field, output an attribute ! 1817: which specifies the length in bits of the given field. */ ! 1818: ! 1819: inline void ! 1820: bit_size_attribute (decl) ! 1821: register tree decl; ! 1822: { ! 1823: assert (TREE_CODE (decl) == FIELD_DECL); /* Must be a field. */ ! 1824: assert (DECL_BIT_FIELD_TYPE (decl)); /* Must be a bit field. */ ! 1825: ! 1826: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_size); ! 1827: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 1828: (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl))); ! 1829: } ! 1830: ! 1831: /* The following routine outputs the `element_list' attribute for enumeration ! 1832: type DIEs. The element_lits attribute includes the names and values of ! 1833: all of the enumeration constants associated with the given enumeration ! 1834: type. */ ! 1835: ! 1836: inline void ! 1837: element_list_attribute (element) ! 1838: register tree element; ! 1839: { ! 1840: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1841: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1842: ! 1843: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_element_list); ! 1844: sprintf (begin_label, EE_BEGIN_LABEL_FMT, current_dienum); ! 1845: sprintf (end_label, EE_END_LABEL_FMT, current_dienum); ! 1846: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); ! 1847: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1848: ! 1849: /* Here we output a list of value/name pairs for each enumeration constant ! 1850: defined for this enumeration type (as required), but we do it in REVERSE ! 1851: order. The order is the one required by the draft #5 Dwarf specification ! 1852: published by the UI/PLSIG. */ ! 1853: ! 1854: output_enumeral_list (element); /* Recursively output the whole list. */ ! 1855: ! 1856: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1857: } ! 1858: ! 1859: /* Generate an AT_stmt_list attribute. These are normally present only in ! 1860: DIEs with a TAG_compile_unit tag. */ ! 1861: ! 1862: inline void ! 1863: stmt_list_attribute (label) ! 1864: register char *label; ! 1865: { ! 1866: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_stmt_list); ! 1867: /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ ! 1868: ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); ! 1869: } ! 1870: ! 1871: /* Generate an AT_low_pc attribute for a label DIE, a lexical_block DIE or ! 1872: for a subroutine DIE. */ ! 1873: ! 1874: inline void ! 1875: low_pc_attribute (asm_low_label) ! 1876: register char *asm_low_label; ! 1877: { ! 1878: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_low_pc); ! 1879: ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_low_label); ! 1880: } ! 1881: ! 1882: /* Generate an AT_high_pc attribute for a lexical_block DIE or for a ! 1883: subroutine DIE. */ ! 1884: ! 1885: inline void ! 1886: high_pc_attribute (asm_high_label) ! 1887: register char *asm_high_label; ! 1888: { ! 1889: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_high_pc); ! 1890: ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_high_label); ! 1891: } ! 1892: ! 1893: /* Generate an AT_language attribute given a LANG value. These attributes ! 1894: are used only within TAG_compile_unit DIEs. */ ! 1895: ! 1896: inline void ! 1897: language_attribute (language_code) ! 1898: register unsigned language_code; ! 1899: { ! 1900: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_language); ! 1901: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, language_code); ! 1902: } ! 1903: ! 1904: inline void ! 1905: member_attribute (context) ! 1906: register tree context; ! 1907: { ! 1908: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1909: ! 1910: /* Generate this attribute only for members in C++. */ ! 1911: ! 1912: if (context != NULL ! 1913: && (TREE_CODE (context) == RECORD_TYPE ! 1914: || TREE_CODE (context) == UNION_TYPE)) ! 1915: { ! 1916: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_member); ! 1917: sprintf (label, TYPE_NAME_FMT, TYPE_UID (context)); ! 1918: ASM_OUTPUT_DWARF_REF (asm_out_file, label); ! 1919: } ! 1920: } ! 1921: ! 1922: inline void ! 1923: string_length_attribute (upper_bound) ! 1924: register tree upper_bound; ! 1925: { ! 1926: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1927: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 1928: ! 1929: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_string_length); ! 1930: sprintf (begin_label, SL_BEGIN_LABEL_FMT, current_dienum); ! 1931: sprintf (end_label, SL_END_LABEL_FMT, current_dienum); ! 1932: ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label); ! 1933: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 1934: output_bound_representation (upper_bound, 0, 'u'); ! 1935: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 1936: } ! 1937: ! 1938: inline void ! 1939: comp_dir_attribute (dirname) ! 1940: register char *dirname; ! 1941: { ! 1942: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_comp_dir); ! 1943: ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname); ! 1944: } ! 1945: ! 1946: inline void ! 1947: sf_names_attribute (sf_names_start_label) ! 1948: register char *sf_names_start_label; ! 1949: { ! 1950: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sf_names); ! 1951: /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ ! 1952: ASM_OUTPUT_DWARF_ADDR (asm_out_file, sf_names_start_label); ! 1953: } ! 1954: ! 1955: inline void ! 1956: src_info_attribute (src_info_start_label) ! 1957: register char *src_info_start_label; ! 1958: { ! 1959: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_info); ! 1960: /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ ! 1961: ASM_OUTPUT_DWARF_ADDR (asm_out_file, src_info_start_label); ! 1962: } ! 1963: ! 1964: inline void ! 1965: mac_info_attribute (mac_info_start_label) ! 1966: register char *mac_info_start_label; ! 1967: { ! 1968: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mac_info); ! 1969: /* Don't use ASM_OUTPUT_DWARF_DATA4 here. */ ! 1970: ASM_OUTPUT_DWARF_ADDR (asm_out_file, mac_info_start_label); ! 1971: } ! 1972: ! 1973: inline void ! 1974: prototyped_attribute (func_type) ! 1975: register tree func_type; ! 1976: { ! 1977: if ((strcmp (language_string, "GNU C") == 0) ! 1978: && (TYPE_ARG_TYPES (func_type) != NULL)) ! 1979: { ! 1980: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_prototyped); ! 1981: ASM_OUTPUT_DWARF_STRING (asm_out_file, ""); ! 1982: } ! 1983: } ! 1984: ! 1985: inline void ! 1986: producer_attribute (producer) ! 1987: register char *producer; ! 1988: { ! 1989: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_producer); ! 1990: ASM_OUTPUT_DWARF_STRING (asm_out_file, producer); ! 1991: } ! 1992: ! 1993: inline void ! 1994: inline_attribute (decl) ! 1995: register tree decl; ! 1996: { ! 1997: if (TREE_INLINE (decl)) ! 1998: { ! 1999: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_inline); ! 2000: ASM_OUTPUT_DWARF_STRING (asm_out_file, ""); ! 2001: } ! 2002: } ! 2003: ! 2004: inline void ! 2005: containing_type_attribute (containing_type) ! 2006: register tree containing_type; ! 2007: { ! 2008: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2009: ! 2010: ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_containing_type); ! 2011: sprintf (label, TYPE_NAME_FMT, TYPE_UID (containing_type)); ! 2012: ASM_OUTPUT_DWARF_REF (asm_out_file, label); ! 2013: } ! 2014: ! 2015: /************************* end of attributes *****************************/ ! 2016: ! 2017: /********************* utility routines for DIEs *************************/ ! 2018: ! 2019: /* Many forms of DIEs contain a "type description" part. The following ! 2020: routine writes out these "type descriptor" parts. */ ! 2021: ! 2022: static void ! 2023: type_attribute (type, decl_const, decl_volatile) ! 2024: register tree type; ! 2025: register int decl_const; ! 2026: register int decl_volatile; ! 2027: { ! 2028: register enum tree_code code = TREE_CODE (type); ! 2029: register int root_type_modified; ! 2030: ! 2031: if (TREE_CODE (type) == ERROR_MARK) ! 2032: return; ! 2033: ! 2034: /* Handle a special case. For functions whose return type is void, ! 2035: we generate *no* type attribute. (Note that no object may have ! 2036: type `void', so this only applies to function return types. */ ! 2037: ! 2038: if (TREE_CODE (type) == VOID_TYPE) ! 2039: return; ! 2040: ! 2041: root_type_modified = (code == POINTER_TYPE || code == REFERENCE_TYPE ! 2042: || decl_const || decl_volatile ! 2043: || TYPE_READONLY (type) || TYPE_VOLATILE (type)); ! 2044: ! 2045: if (type_is_fundamental (root_type (type))) ! 2046: if (root_type_modified) ! 2047: mod_fund_type_attribute (type, decl_const, decl_volatile); ! 2048: else ! 2049: fund_type_attribute (fundamental_type_code (type)); ! 2050: else ! 2051: if (root_type_modified) ! 2052: mod_u_d_type_attribute (type, decl_const, decl_volatile); ! 2053: else ! 2054: user_def_type_attribute (type); ! 2055: } ! 2056: ! 2057: /* Given a tree pointer to a struct, class, union, or enum type node, return ! 2058: a pointer to the (string) tag name for the given type, or zero if the ! 2059: type was declared without a tag. */ ! 2060: ! 2061: static char * ! 2062: type_tag (type) ! 2063: register tree type; ! 2064: { ! 2065: register char *name = 0; ! 2066: ! 2067: if (TYPE_NAME (type) != 0) ! 2068: { ! 2069: register tree t = 0; ! 2070: ! 2071: /* Find the IDENTIFIER_NODE for the type name. */ ! 2072: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! 2073: t = TYPE_NAME (type); ! 2074: #if 0 ! 2075: /* The g++ front end makes the TYPE_NAME of *each* tagged type point ! 2076: to a TYPE_DECL node, regardless of whether or not a `typedef' was ! 2077: involved. This is distinctly different from what the gcc front-end ! 2078: does. It always makes the TYPE_NAME for each tagged type be either ! 2079: NULL (signifying an anonymous tagged type) or else a pointer to an ! 2080: IDENTIFIER_NODE. Obviously, we would like to generate correct Dwarf ! 2081: for both C and C++, but given this inconsistancy in the TREE ! 2082: representation of tagged types for C and C++ in the GNU front-ends, ! 2083: we cannot support both languages correctly unless we introduce some ! 2084: front-end specific code here, and rms objects to that, so we can ! 2085: only generate correct Dwarf for one of these two languages. C is ! 2086: more important, so for now we'll do the right thing for C and let ! 2087: g++ go fish. */ ! 2088: ! 2089: else ! 2090: if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) ! 2091: t = DECL_NAME (TYPE_NAME (type)); ! 2092: #endif ! 2093: /* Now get the name as a string, or invent one. */ ! 2094: if (t != 0) ! 2095: name = IDENTIFIER_POINTER (t); ! 2096: } ! 2097: ! 2098: return (name == 0 || *name == '\0') ? 0 : name; ! 2099: } ! 2100: ! 2101: inline void ! 2102: dienum_push () ! 2103: { ! 2104: /* Start by checking if the pending_sibling_stack needs to be expanded. ! 2105: If necessary, expand it. */ ! 2106: ! 2107: if (pending_siblings == pending_siblings_allocated) ! 2108: { ! 2109: pending_siblings_allocated += PENDING_SIBLINGS_INCREMENT; ! 2110: pending_sibling_stack ! 2111: = (unsigned *) xrealloc (pending_sibling_stack, ! 2112: pending_siblings_allocated * sizeof(unsigned)); ! 2113: } ! 2114: ! 2115: pending_siblings++; ! 2116: NEXT_DIE_NUM = next_unused_dienum++; ! 2117: } ! 2118: ! 2119: /* Pop the sibling stack so that the most recently pushed DIEnum becomes the ! 2120: NEXT_DIE_NUM. */ ! 2121: ! 2122: inline void ! 2123: dienum_pop () ! 2124: { ! 2125: pending_siblings--; ! 2126: } ! 2127: ! 2128: inline tree ! 2129: member_declared_type (member) ! 2130: register tree member; ! 2131: { ! 2132: return (DECL_BIT_FIELD_TYPE (member)) ! 2133: ? DECL_BIT_FIELD_TYPE (member) ! 2134: : TREE_TYPE (member); ! 2135: } ! 2136: ! 2137: /******************************* DIEs ************************************/ ! 2138: ! 2139: /* Output routines for individual types of DIEs. */ ! 2140: ! 2141: /* Note that every type of DIE (except a null DIE) gets a sibling. */ ! 2142: ! 2143: static void ! 2144: output_array_type_die (arg) ! 2145: register void *arg; ! 2146: { ! 2147: register tree type = arg; ! 2148: ! 2149: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_array_type); ! 2150: sibling_attribute (); ! 2151: equate_type_number_to_die_number (type); ! 2152: member_attribute (TYPE_CONTEXT (type)); ! 2153: ! 2154: /* I believe that we can default the array ordering. SDB will probably ! 2155: do the right things even if AT_ordering is not present. It's not ! 2156: even an issue until we start to get into multidimensional arrays ! 2157: anyway. If SDB is shown to do the wrong thing in those cases, then ! 2158: we'll have to put the AT_ordering attribute back in, but only for ! 2159: multidimensional array. (After all, we don't want to waste space ! 2160: in the .debug section now do we?) */ ! 2161: ! 2162: #if 0 ! 2163: ordering_attribute (ORD_row_major); ! 2164: #endif ! 2165: ! 2166: subscript_data_attribute (type); ! 2167: } ! 2168: ! 2169: static void ! 2170: output_set_type_die (arg) ! 2171: register void *arg; ! 2172: { ! 2173: register tree type = arg; ! 2174: ! 2175: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_set_type); ! 2176: sibling_attribute (); ! 2177: equate_type_number_to_die_number (type); ! 2178: member_attribute (TYPE_CONTEXT (type)); ! 2179: type_attribute (TREE_TYPE (type), 0, 0); ! 2180: } ! 2181: ! 2182: #if 0 ! 2183: /* Implement this when there is a GNU FORTRAN or GNU Ada front end. */ ! 2184: static void ! 2185: output_entry_point_die (arg) ! 2186: register void *arg; ! 2187: { ! 2188: register tree decl = arg; ! 2189: register tree type = TREE_TYPE (decl); ! 2190: register tree return_type = TREE_TYPE (type); ! 2191: ! 2192: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_entry_point); ! 2193: sibling_attribute (); ! 2194: dienum_push (); ! 2195: if (DECL_NAME (decl)) ! 2196: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2197: member_attribute (DECL_CONTEXT (decl)); ! 2198: type_attribute (return_type, 0, 0); ! 2199: } ! 2200: #endif ! 2201: ! 2202: /* Output a DIE to represent an enumeration type. Note that these DIEs ! 2203: include all of the information about the enumeration values also. ! 2204: This information is encoded into the element_list attribute. */ ! 2205: ! 2206: static void ! 2207: output_enumeration_type_die (arg) ! 2208: register void *arg; ! 2209: { ! 2210: register tree type = arg; ! 2211: ! 2212: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_enumeration_type); ! 2213: sibling_attribute (); ! 2214: equate_type_number_to_die_number (type); ! 2215: name_attribute (type_tag (type)); ! 2216: member_attribute (TYPE_CONTEXT (type)); ! 2217: ! 2218: /* Handle a GNU C/C++ extension, i.e. incomplete enum types. If the ! 2219: given enum type is incomplete, do not generate the AT_byte_size ! 2220: attribute or the AT_element_list attribute. */ ! 2221: ! 2222: if (TYPE_SIZE (type)) ! 2223: { ! 2224: byte_size_attribute (type); ! 2225: element_list_attribute (TYPE_FIELDS (type)); ! 2226: } ! 2227: } ! 2228: ! 2229: /* Output a DIE to represent either a real live formal parameter decl or ! 2230: to represent just the type of some formal parameter position in some ! 2231: function type. ! 2232: ! 2233: Note that this routine is a bit unusual because its argument may be ! 2234: either a PARM_DECL node or else some sort of a ..._TYPE node. If it's ! 2235: the formar then this function is being called to output a real live ! 2236: formal parameter declaration. If it's the latter, then this function ! 2237: is only being called to output a TAG_formal_parameter DIE to stand as ! 2238: a placeholder for some formal argument type of some subprogram type. */ ! 2239: ! 2240: static void ! 2241: output_formal_parameter_die (arg) ! 2242: register void *arg; ! 2243: { ! 2244: register tree decl = arg; ! 2245: register tree type; ! 2246: ! 2247: if (TREE_CODE (decl) == PARM_DECL) ! 2248: type = TREE_TYPE (decl); ! 2249: else ! 2250: { ! 2251: type = decl; /* we were called with a type, not a decl */ ! 2252: decl = NULL; ! 2253: } ! 2254: ! 2255: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_formal_parameter); ! 2256: sibling_attribute (); ! 2257: if (decl) ! 2258: { ! 2259: if (DECL_NAME (decl)) ! 2260: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2261: type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); ! 2262: location_or_const_value_attribute (decl); ! 2263: } ! 2264: else ! 2265: type_attribute (type, 0, 0); ! 2266: } ! 2267: ! 2268: /* Output a DIE to represent a declared function (either file-scope ! 2269: or block-local) which has "external linkage" (according to ANSI-C). */ ! 2270: ! 2271: static void ! 2272: output_global_subroutine_die (arg) ! 2273: register void *arg; ! 2274: { ! 2275: register tree decl = arg; ! 2276: register tree type = TREE_TYPE (decl); ! 2277: register tree return_type = TREE_TYPE (type); ! 2278: ! 2279: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_subroutine); ! 2280: sibling_attribute (); ! 2281: dienum_push (); ! 2282: if (DECL_NAME (decl)) ! 2283: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2284: inline_attribute (decl); ! 2285: prototyped_attribute (type); ! 2286: member_attribute (DECL_CONTEXT (decl)); ! 2287: type_attribute (return_type, 0, 0); ! 2288: if (!TREE_EXTERNAL (decl)) ! 2289: { ! 2290: char func_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2291: ! 2292: low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2293: sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number); ! 2294: high_pc_attribute (func_end_label); ! 2295: } ! 2296: } ! 2297: ! 2298: /* Output a DIE to represent a declared data object (either file-scope ! 2299: or block-local) which has "external linkage" (according to ANSI-C). */ ! 2300: ! 2301: static void ! 2302: output_global_variable_die (arg) ! 2303: register void *arg; ! 2304: { ! 2305: register tree decl = arg; ! 2306: register tree type = TREE_TYPE (decl); ! 2307: ! 2308: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_variable); ! 2309: sibling_attribute (); ! 2310: if (DECL_NAME (decl)) ! 2311: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2312: member_attribute (DECL_CONTEXT (decl)); ! 2313: type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); ! 2314: if (!TREE_EXTERNAL (decl)) ! 2315: location_or_const_value_attribute (decl); ! 2316: } ! 2317: ! 2318: #if 0 ! 2319: /* TAG_inline_subroutine has been retired by the UI/PLSIG. We're ! 2320: now supposed to use either TAG_subroutine or TAG_global_subroutine ! 2321: (depending on whether or not the function in question has internal ! 2322: or external linkage) and we're supposed to just put in an AT_inline ! 2323: attribute. */ ! 2324: static void ! 2325: output_inline_subroutine_die (arg) ! 2326: register void *arg; ! 2327: { ! 2328: register tree decl = arg; ! 2329: register tree type = TREE_TYPE (decl); ! 2330: register tree return_type = TREE_TYPE (type); ! 2331: ! 2332: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inline_subroutine); ! 2333: sibling_attribute (); ! 2334: dienum_push (); ! 2335: if (DECL_NAME (decl)) ! 2336: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2337: prototyped_attribute (type); ! 2338: member_attribute (DECL_CONTEXT (decl)); ! 2339: type_attribute (return_type, 0, 0); ! 2340: ! 2341: /* Note: For each inline function which gets an out-of-line body ! 2342: generated for it, we want to generate AT_low_pc and AT_high_pc ! 2343: attributes here for the function's out-of-line body. ! 2344: ! 2345: Unfortunately, the decision as to whether or not to generate an ! 2346: out-of-line body for any given inline function may not be made ! 2347: until we reach the end of the containing scope for the given ! 2348: inline function (because only then will it be known if the ! 2349: function was ever even called). ! 2350: ! 2351: For this reason, the output of DIEs representing file-scope inline ! 2352: functions gets delayed until a special post-pass which happens only ! 2353: after we have reached the end of the compilation unit. Because of ! 2354: this mechanism, we can always be sure (by the time we reach here) ! 2355: that TREE_ASM_WRITTEN(decl) will correctly indicate whether or not ! 2356: there was an out-of-line body generated for this inline function. ! 2357: */ ! 2358: ! 2359: if (!TREE_EXTERNAL (decl)) ! 2360: { ! 2361: if (TREE_ASM_WRITTEN (decl)) ! 2362: { ! 2363: char func_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2364: ! 2365: low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2366: sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number); ! 2367: high_pc_attribute (func_end_label); ! 2368: } ! 2369: } ! 2370: } ! 2371: #endif ! 2372: ! 2373: static void ! 2374: output_label_die (arg) ! 2375: register void *arg; ! 2376: { ! 2377: register tree decl = arg; ! 2378: register rtx insn = DECL_RTL (decl); ! 2379: ! 2380: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_label); ! 2381: sibling_attribute (); ! 2382: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2383: ! 2384: /* When optimization is enabled (with -O) the code in jump.c and in flow.c ! 2385: may cause insns representing one of more of the user's own labels to ! 2386: be deleted. This happens whenever it is determined that a given label ! 2387: is unreachable. ! 2388: ! 2389: In such cases, we here generate an abbreviated form of a label DIE. ! 2390: This abbreviated version does *not* have a low_pc attribute. This ! 2391: should signify to the debugger that the label has been optimized away. ! 2392: ! 2393: Note that a CODE_LABEL can get deleted either by begin converted into ! 2394: a NOTE_INSN_DELETED note, or by simply having its INSN_DELETED_P flag ! 2395: set to true. We handle both cases here. ! 2396: */ ! 2397: ! 2398: if (GET_CODE (insn) == CODE_LABEL && ! INSN_DELETED_P (insn)) ! 2399: { ! 2400: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2401: ! 2402: sprintf (label, INSN_LABEL_FMT, current_funcdef_number, ! 2403: (unsigned) INSN_UID (insn)); ! 2404: low_pc_attribute (label); ! 2405: } ! 2406: } ! 2407: ! 2408: static void ! 2409: output_lexical_block_die (arg) ! 2410: register void *arg; ! 2411: { ! 2412: register tree stmt = arg; ! 2413: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2414: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2415: ! 2416: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_lexical_block); ! 2417: sibling_attribute (); ! 2418: dienum_push (); ! 2419: sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number); ! 2420: low_pc_attribute (begin_label); ! 2421: sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number); ! 2422: high_pc_attribute (end_label); ! 2423: } ! 2424: ! 2425: static void ! 2426: output_inlined_subroutine_die (arg) ! 2427: register void *arg; ! 2428: { ! 2429: register tree stmt = arg; ! 2430: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2431: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2432: ! 2433: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inlined_subroutine); ! 2434: sibling_attribute (); ! 2435: dienum_push (); ! 2436: sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number); ! 2437: low_pc_attribute (begin_label); ! 2438: sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number); ! 2439: high_pc_attribute (end_label); ! 2440: } ! 2441: ! 2442: /* Output a DIE to represent a declared data object (either file-scope ! 2443: or block-local) which has "internal linkage" (according to ANSI-C). */ ! 2444: ! 2445: static void ! 2446: output_local_variable_die (arg) ! 2447: register void *arg; ! 2448: { ! 2449: register tree decl = arg; ! 2450: register tree type = TREE_TYPE (decl); ! 2451: ! 2452: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_local_variable); ! 2453: sibling_attribute (); ! 2454: if (DECL_NAME (decl)) ! 2455: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2456: member_attribute (DECL_CONTEXT (decl)); ! 2457: type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); ! 2458: location_or_const_value_attribute (decl); ! 2459: } ! 2460: ! 2461: static void ! 2462: output_member_die (arg) ! 2463: register void *arg; ! 2464: { ! 2465: register tree decl = arg; ! 2466: ! 2467: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_member); ! 2468: sibling_attribute (); ! 2469: if (DECL_NAME (decl)) ! 2470: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2471: member_attribute (DECL_CONTEXT (decl)); ! 2472: type_attribute (member_declared_type (decl), ! 2473: TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); ! 2474: if (DECL_BIT_FIELD_TYPE (decl)) /* If this is a bit field... */ ! 2475: { ! 2476: byte_size_attribute (decl); ! 2477: bit_size_attribute (decl); ! 2478: bit_offset_attribute (decl); ! 2479: } ! 2480: data_member_location_attribute (decl); ! 2481: } ! 2482: ! 2483: #if 0 ! 2484: /* Don't generate either pointer_type DIEs or reference_type DIEs. According ! 2485: to the 4-4-90 Dwarf draft spec (just after requirement #47): ! 2486: ! 2487: These two type entries are not currently generated by any compiler. ! 2488: Since the only way to name a pointer (or reference) type is C or C++ ! 2489: is via a "typedef", an entry with the "typedef" tag is generated ! 2490: instead. ! 2491: ! 2492: We keep this code here just in case these types of DIEs may be needed ! 2493: to represent certain things in other languages (e.g. Pascal) someday. ! 2494: */ ! 2495: ! 2496: static void ! 2497: output_pointer_type_die (arg) ! 2498: register void *arg; ! 2499: { ! 2500: register tree type = arg; ! 2501: ! 2502: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_pointer_type); ! 2503: sibling_attribute (); ! 2504: equate_type_number_to_die_number (type); ! 2505: member_attribute (TYPE_CONTEXT (type)); ! 2506: type_attribute (TREE_TYPE (type), 0, 0); ! 2507: } ! 2508: ! 2509: static void ! 2510: output_reference_type_die (arg) ! 2511: register void *arg; ! 2512: { ! 2513: register tree type = arg; ! 2514: ! 2515: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_reference_type); ! 2516: sibling_attribute (); ! 2517: equate_type_number_to_die_number (type); ! 2518: member_attribute (TYPE_CONTEXT (type)); ! 2519: type_attribute (TREE_TYPE (type), 0, 0); ! 2520: } ! 2521: #endif ! 2522: ! 2523: output_ptr_to_mbr_type_die (arg) ! 2524: register void *arg; ! 2525: { ! 2526: register tree type = arg; ! 2527: ! 2528: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_ptr_to_member_type); ! 2529: sibling_attribute (); ! 2530: equate_type_number_to_die_number (type); ! 2531: member_attribute (TYPE_CONTEXT (type)); ! 2532: containing_type_attribute (TYPE_OFFSET_BASETYPE (type)); ! 2533: type_attribute (TREE_TYPE (type), 0, 0); ! 2534: } ! 2535: ! 2536: static void ! 2537: output_compile_unit_die (arg) ! 2538: register void *arg; ! 2539: { ! 2540: register char *main_input_filename = arg; ! 2541: ! 2542: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_compile_unit); ! 2543: sibling_attribute (); ! 2544: dienum_push (); ! 2545: name_attribute (main_input_filename); ! 2546: ! 2547: { ! 2548: char producer[250]; ! 2549: ! 2550: sprintf (producer, "%s %s", language_string, version_string); ! 2551: producer_attribute (producer); ! 2552: } ! 2553: ! 2554: if (strcmp (language_string, "GNU C++") == 0) ! 2555: language_attribute (LANG_C_PLUS_PLUS); ! 2556: else if (flag_traditional) ! 2557: language_attribute (LANG_C); ! 2558: else ! 2559: language_attribute (LANG_C89); ! 2560: low_pc_attribute (TEXT_BEGIN_LABEL); ! 2561: high_pc_attribute (TEXT_END_LABEL); ! 2562: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 2563: stmt_list_attribute (LINE_BEGIN_LABEL); ! 2564: last_filename = xstrdup (main_input_filename); ! 2565: ! 2566: { ! 2567: register unsigned len = 1024; ! 2568: register char *dirname = (char *) xmalloc (len + 1); ! 2569: ! 2570: /* We don't know how much space the dirname needs, ! 2571: so try bigger and bigger buffers until it fits. */ ! 2572: while (1) ! 2573: { ! 2574: getcwd (dirname, len); /* Being conservative here. */ ! 2575: if (strlen (dirname) < len - 1) /* Being conservative here. */ ! 2576: break; ! 2577: len *= 2; ! 2578: dirname = (char *) xrealloc (dirname, len + 1); ! 2579: } ! 2580: ! 2581: comp_dir_attribute (dirname); ! 2582: free (dirname); ! 2583: } ! 2584: ! 2585: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 2586: { ! 2587: sf_names_attribute (SFNAMES_BEGIN_LABEL); ! 2588: src_info_attribute (SRCINFO_BEGIN_LABEL); ! 2589: if (debug_info_level >= DINFO_LEVEL_VERBOSE) ! 2590: mac_info_attribute (MACINFO_BEGIN_LABEL); ! 2591: } ! 2592: } ! 2593: ! 2594: static void ! 2595: output_string_type_die (arg) ! 2596: register void *arg; ! 2597: { ! 2598: register tree type = arg; ! 2599: ! 2600: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_string_type); ! 2601: sibling_attribute (); ! 2602: member_attribute (TYPE_CONTEXT (type)); ! 2603: ! 2604: /* Fudge the string length attribute for now. */ ! 2605: ! 2606: string_length_attribute ( ! 2607: TYPE_MAX_VALUE (TYPE_DOMAIN (type))); ! 2608: } ! 2609: ! 2610: static void ! 2611: output_structure_type_die (arg) ! 2612: register void *arg; ! 2613: { ! 2614: register tree type = arg; ! 2615: ! 2616: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_structure_type); ! 2617: sibling_attribute (); ! 2618: equate_type_number_to_die_number (type); ! 2619: name_attribute (type_tag (type)); ! 2620: member_attribute (TYPE_CONTEXT (type)); ! 2621: ! 2622: /* If this type has been completed, then give it a byte_size attribute ! 2623: and prepare to give a list of members. Otherwise, don't do either of ! 2624: these things. In the latter case, we will not be generating a list ! 2625: of members (since we don't have any idea what they might be for an ! 2626: incomplete type). */ ! 2627: ! 2628: if (TYPE_SIZE (type)) ! 2629: { ! 2630: dienum_push (); ! 2631: byte_size_attribute (type); ! 2632: } ! 2633: } ! 2634: ! 2635: /* Output a DIE to represent a declared function (either file-scope ! 2636: or block-local) which has "internal linkage" (according to ANSI-C). */ ! 2637: ! 2638: static void ! 2639: output_local_subroutine_die (arg) ! 2640: register void *arg; ! 2641: { ! 2642: register tree decl = arg; ! 2643: register tree type = TREE_TYPE (decl); ! 2644: register tree return_type = TREE_TYPE (type); ! 2645: char func_end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2646: ! 2647: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine); ! 2648: sibling_attribute (); ! 2649: dienum_push (); ! 2650: if (DECL_NAME (decl)) ! 2651: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2652: inline_attribute (decl); ! 2653: prototyped_attribute (type); ! 2654: member_attribute (DECL_CONTEXT (decl)); ! 2655: type_attribute (return_type, 0, 0); ! 2656: ! 2657: /* Avoid getting screwed up in cases where a function was declared static ! 2658: but where no definition was ever given for it. */ ! 2659: ! 2660: if (TREE_ASM_WRITTEN (decl)) ! 2661: { ! 2662: low_pc_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2663: sprintf (func_end_label, FUNC_END_LABEL_FMT, current_funcdef_number); ! 2664: high_pc_attribute (func_end_label); ! 2665: } ! 2666: } ! 2667: ! 2668: static void ! 2669: output_subroutine_type_die (arg) ! 2670: register void *arg; ! 2671: { ! 2672: register tree type = arg; ! 2673: register tree return_type = TREE_TYPE (type); ! 2674: ! 2675: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine_type); ! 2676: sibling_attribute (); ! 2677: dienum_push (); ! 2678: equate_type_number_to_die_number (type); ! 2679: prototyped_attribute (type); ! 2680: member_attribute (TYPE_CONTEXT (type)); ! 2681: type_attribute (return_type, 0, 0); ! 2682: } ! 2683: ! 2684: static void ! 2685: output_typedef_die (arg) ! 2686: register void *arg; ! 2687: { ! 2688: register tree decl = arg; ! 2689: register tree type = TREE_TYPE (decl); ! 2690: ! 2691: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_typedef); ! 2692: sibling_attribute (); ! 2693: if (DECL_NAME (decl)) ! 2694: name_attribute (IDENTIFIER_POINTER (DECL_NAME (decl))); ! 2695: member_attribute (DECL_CONTEXT (decl)); ! 2696: type_attribute (type, TREE_READONLY (decl), TREE_THIS_VOLATILE (decl)); ! 2697: } ! 2698: ! 2699: static void ! 2700: output_union_type_die (arg) ! 2701: register void *arg; ! 2702: { ! 2703: register tree type = arg; ! 2704: ! 2705: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_union_type); ! 2706: sibling_attribute (); ! 2707: equate_type_number_to_die_number (type); ! 2708: name_attribute (type_tag (type)); ! 2709: member_attribute (TYPE_CONTEXT (type)); ! 2710: ! 2711: /* If this type has been completed, then give it a byte_size attribute ! 2712: and prepare to give a list of members. Otherwise, don't do either of ! 2713: these things. In the latter case, we will not be generating a list ! 2714: of members (since we don't have any idea what they might be for an ! 2715: incomplete type). */ ! 2716: ! 2717: if (TYPE_SIZE (type)) ! 2718: { ! 2719: dienum_push (); ! 2720: byte_size_attribute (type); ! 2721: } ! 2722: } ! 2723: ! 2724: /* Generate a special type of DIE used as a stand-in for a trailing ellipsis ! 2725: at the end of an (ANSI prototyped) formal parameters list. */ ! 2726: ! 2727: static void ! 2728: output_unspecified_parameters_die (arg) ! 2729: register void *arg; ! 2730: { ! 2731: register tree decl_or_type = arg; ! 2732: ! 2733: ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_unspecified_parameters); ! 2734: sibling_attribute (); ! 2735: ! 2736: /* This kludge is here only for the sake of being compatible with what ! 2737: the USL CI5 C compiler does. The specification of Dwarf Version 1 ! 2738: doesn't say that TAG_unspecified_parameters DIEs should contain any ! 2739: attributes other than the AT_sibling attribute, but they are certainly ! 2740: allowed to contain additional attributes, and the CI5 compiler ! 2741: generates AT_name, AT_fund_type, and AT_location attributes within ! 2742: TAG_unspecified_parameters DIEs which appear in the child lists for ! 2743: DIEs representing function definitions, so we do likewise here. */ ! 2744: ! 2745: if (TREE_CODE (decl_or_type) == FUNCTION_DECL && DECL_INITIAL (decl_or_type)) ! 2746: { ! 2747: name_attribute ("..."); ! 2748: fund_type_attribute (FT_pointer); ! 2749: /* location_attribute (?); */ ! 2750: } ! 2751: } ! 2752: ! 2753: static void ! 2754: output_padded_null_die (arg) ! 2755: register void *arg; ! 2756: { ! 2757: ASM_OUTPUT_ALIGN (asm_out_file, 2); /* 2**2 == 4 */ ! 2758: } ! 2759: ! 2760: /*************************** end of DIEs *********************************/ ! 2761: ! 2762: /* Generate some type of DIE. This routine generates the generic outer ! 2763: wrapper stuff which goes around all types of DIE's (regardless of their ! 2764: TAGs. All forms of DIEs start with a DIE-specific label, followed by a ! 2765: DIE-length word, followed by the guts of the DIE itself. After the guts ! 2766: of the DIE, there must always be a terminator label for the DIE. */ ! 2767: ! 2768: static void ! 2769: output_die (die_specific_output_function, param) ! 2770: register void (*die_specific_output_function)(); ! 2771: register void *param; ! 2772: { ! 2773: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2774: char end_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2775: ! 2776: current_dienum = NEXT_DIE_NUM; ! 2777: NEXT_DIE_NUM = next_unused_dienum; ! 2778: ! 2779: sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum); ! 2780: sprintf (end_label, DIE_END_LABEL_FMT, current_dienum); ! 2781: ! 2782: /* Write a label which will act as the name for the start of this DIE. */ ! 2783: ! 2784: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 2785: ! 2786: /* Write the DIE-length word. */ ! 2787: ! 2788: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label); ! 2789: ! 2790: /* Fill in the guts of the DIE. */ ! 2791: ! 2792: next_unused_dienum++; ! 2793: die_specific_output_function (param); ! 2794: ! 2795: /* Write a label which will act as the name for the end of this DIE. */ ! 2796: ! 2797: ASM_OUTPUT_LABEL (asm_out_file, end_label); ! 2798: } ! 2799: ! 2800: static void ! 2801: end_sibling_chain () ! 2802: { ! 2803: char begin_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 2804: ! 2805: current_dienum = NEXT_DIE_NUM; ! 2806: NEXT_DIE_NUM = next_unused_dienum; ! 2807: ! 2808: sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum); ! 2809: ! 2810: /* Write a label which will act as the name for the start of this DIE. */ ! 2811: ! 2812: ASM_OUTPUT_LABEL (asm_out_file, begin_label); ! 2813: ! 2814: /* Write the DIE-length word. */ ! 2815: ! 2816: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 4); ! 2817: ! 2818: dienum_pop (); ! 2819: } ! 2820: ! 2821: /* Generate a list of nameless TAG_formal_parameter DIEs (and perhaps a ! 2822: TAG_unspecified_parameters DIE) to represent the types of the formal ! 2823: parameters as specified in some function type specification (except ! 2824: for those which appear as part of a function *definition*). ! 2825: ! 2826: Note that we must be careful here to output all of the parameter DIEs ! 2827: *before* we output any DIEs needed to represent the types of the formal ! 2828: parameters. This keeps svr4 SDB happy because it (incorrectly) thinks ! 2829: that the first non-parameter DIE it sees ends the formal parameter list. ! 2830: */ ! 2831: ! 2832: static void ! 2833: output_formal_types (function_or_method_type) ! 2834: register tree function_or_method_type; ! 2835: { ! 2836: register tree link; ! 2837: register tree formal_type; ! 2838: register tree first_parm_type = TYPE_ARG_TYPES (function_or_method_type); ! 2839: ! 2840: /* In the case where we are generating a formal types list for a C++ ! 2841: non-static member function type, skip over the first thing on the ! 2842: TYPE_ARG_TYPES list because it only represents the type of the ! 2843: hidden `this pointer'. The debugger should be able to figure ! 2844: out (without being explicitly told) that this non-static member ! 2845: function type takes a `this pointer' and should be able to figure ! 2846: what the type of that hidden parameter is from the AT_member ! 2847: attribute of the parent TAG_subroutine_type DIE. */ ! 2848: ! 2849: if (TREE_CODE (function_or_method_type) == METHOD_TYPE) ! 2850: first_parm_type = TREE_CHAIN (first_parm_type); ! 2851: ! 2852: /* Make our first pass over the list of formal parameter types and output ! 2853: a TAG_formal_parameter DIE for each one. */ ! 2854: ! 2855: for (link = first_parm_type; link; link = TREE_CHAIN (link)) ! 2856: { ! 2857: formal_type = TREE_VALUE (link); ! 2858: if (formal_type == void_type_node) ! 2859: break; ! 2860: ! 2861: /* Output a (nameless) DIE to represent the formal parameter itself. */ ! 2862: ! 2863: output_die (output_formal_parameter_die, formal_type); ! 2864: } ! 2865: ! 2866: /* If this function type has an ellipsis, add a TAG_unspecified_parameters ! 2867: DIE to the end of the parameter list. */ ! 2868: ! 2869: if (formal_type != void_type_node) ! 2870: output_die (output_unspecified_parameters_die, function_or_method_type); ! 2871: ! 2872: /* Make our second (and final) pass over the list of formal parameter types ! 2873: and output DIEs to represent those types (as necessary). */ ! 2874: ! 2875: for (link = TYPE_ARG_TYPES (function_or_method_type); ! 2876: link; ! 2877: link = TREE_CHAIN (link)) ! 2878: { ! 2879: formal_type = TREE_VALUE (link); ! 2880: if (formal_type == void_type_node) ! 2881: break; ! 2882: ! 2883: output_type (formal_type, function_or_method_type); ! 2884: } ! 2885: } ! 2886: ! 2887: /* Remember a type in the pending_types_list. */ ! 2888: ! 2889: static void ! 2890: pend_type (type) ! 2891: register tree type; ! 2892: { ! 2893: if (pending_types == pending_types_allocated) ! 2894: { ! 2895: pending_types_allocated += PENDING_TYPES_INCREMENT; ! 2896: pending_types_list ! 2897: = (tree *) xrealloc (pending_types_list, ! 2898: sizeof (tree) * pending_types_allocated); ! 2899: } ! 2900: pending_types_list[pending_types++] = type; ! 2901: ! 2902: /* Mark the pending type as having been output already (even though ! 2903: it hasn't been). This prevents the type from being added to the ! 2904: pending_types_list more than once. */ ! 2905: ! 2906: TREE_ASM_WRITTEN (type) = 1; ! 2907: } ! 2908: ! 2909: /* Return non-zero if it is legitimate to output DIEs to represent a ! 2910: given type while we are generating the list of child DIEs for some ! 2911: DIE associated with a given scope. ! 2912: ! 2913: This function returns non-zero if *either* of the following two conditions ! 2914: is satisfied: ! 2915: ! 2916: o the type actually belongs to the given scope (as evidenced ! 2917: by its TYPE_CONTEXT value), or ! 2918: ! 2919: o the type is anonymous, and the `scope' in question is *not* ! 2920: a RECORD_TYPE or UNION_TYPE. ! 2921: ! 2922: In theory, we should be able to generate DIEs for anonymous types ! 2923: *anywhere* (since the scope of an anonymous type is irrelevant) ! 2924: however svr4 SDB doesn't want to see other type DIEs within the ! 2925: lists of child DIEs for a TAG_structure_type or TAG_union_type DIE. ! 2926: ! 2927: Note that TYPE_CONTEXT(type) may be NULL (to indicate global scope) ! 2928: or it may point to a BLOCK node (for types local to a block), or to a ! 2929: FUNCTION_DECL node (for types local to the heading of some function ! 2930: definition), or to a FUNCTION_TYPE node (for types local to the ! 2931: prototyped parameter list of a function type specification), or to a ! 2932: RECORD_TYPE or UNION_TYPE node (in the case of C++ nested types). ! 2933: ! 2934: The `scope' parameter should likewise be NULL or should point to a ! 2935: BLOCK node, a FUNCTION_DECL node, a FUNCTION_TYPE node, a RECORD_TYPE ! 2936: node, or a UNION_TYPE node. ! 2937: ! 2938: This function is used only for deciding when to "pend" and when to ! 2939: "un-pend" types to/from the pending_types_list. ! 2940: ! 2941: Note that we sometimes make use of this "type pending" feature in a ! 2942: rather twisted way to temporarily delay the production of DIEs for the ! 2943: types of formal parameters. (We do this just to make svr4 SDB happy.) ! 2944: It order to delay the production of DIEs representing types of formal ! 2945: parameters, callers of this function supply `fake_containing_scope' as ! 2946: the `scope' parameter to this function. Given that fake_containing_scope ! 2947: is *not* the containing scope for *any* other type, the desired effect ! 2948: is achieved, i.e. output of DIEs representing types is temporarily ! 2949: suspended, and any type DIEs which would have been output otherwise ! 2950: are instead placed onto the pending_types_list. Later on, we can force ! 2951: these (temporarily pended) types to be output simply by calling ! 2952: `output_pending_types_for_scope' with an actual argument equal to the ! 2953: true scope of the types we temporarily pended. ! 2954: */ ! 2955: ! 2956: static int ! 2957: type_ok_for_scope (type, scope) ! 2958: register tree type; ! 2959: register tree scope; ! 2960: { ! 2961: return (TYPE_CONTEXT (type) == scope ! 2962: || (TYPE_NAME (type) == NULL ! 2963: && TREE_CODE (scope) != RECORD_TYPE ! 2964: && TREE_CODE (scope) != UNION_TYPE)); ! 2965: } ! 2966: ! 2967: /* Output any pending types (from the pending_types list) which we can output ! 2968: now (given the limitations of the scope that we are working on now). ! 2969: ! 2970: For each type output, remove the given type from the pending_types_list ! 2971: *before* we try to output it. ! 2972: ! 2973: Note that we have to process the list in beginning-to-end order, ! 2974: because the call made here to output_type may cause yet more types ! 2975: to be added to the end of the list, and we may have to output some ! 2976: of them too. ! 2977: */ ! 2978: ! 2979: static void ! 2980: output_pending_types_for_scope (containing_scope) ! 2981: register tree containing_scope; ! 2982: { ! 2983: register unsigned i; ! 2984: ! 2985: for (i = 0; i < pending_types; ) ! 2986: { ! 2987: register tree type = pending_types_list[i]; ! 2988: ! 2989: if (type_ok_for_scope (type, containing_scope)) ! 2990: { ! 2991: register tree *mover; ! 2992: register tree *limit; ! 2993: ! 2994: pending_types--; ! 2995: limit = &pending_types_list[pending_types]; ! 2996: for (mover = &pending_types_list[i]; mover < limit; mover++) ! 2997: *mover = *(mover+1); ! 2998: ! 2999: /* Un-mark the type as having been output already (because it ! 3000: hasn't been, really). Then call output_type to generate a ! 3001: Dwarf representation of it. */ ! 3002: ! 3003: TREE_ASM_WRITTEN (type) = 0; ! 3004: output_type (type, containing_scope); ! 3005: ! 3006: /* Don't increment the loop counter in this case because we ! 3007: have shifted all of the subsequent pending types down one ! 3008: element in the pending_types_list array. */ ! 3009: } ! 3010: else ! 3011: i++; ! 3012: } ! 3013: } ! 3014: ! 3015: static void ! 3016: output_type (type, containing_scope) ! 3017: register tree type; ! 3018: register tree containing_scope; ! 3019: { ! 3020: if (type == 0 || type == error_mark_node) ! 3021: return; ! 3022: ! 3023: /* We are going to output a DIE to represent the unqualified version of ! 3024: of this type (i.e. without any const or volatile qualifiers) so get ! 3025: the main variant (i.e. the unqualified version) of this type now. */ ! 3026: ! 3027: type = TYPE_MAIN_VARIANT (type); ! 3028: ! 3029: if (TREE_ASM_WRITTEN (type)) ! 3030: return; ! 3031: ! 3032: /* Don't generate any DIEs for this type now unless it is OK to do so ! 3033: (based upon what `type_ok_for_scope' tells us). */ ! 3034: ! 3035: if (! type_ok_for_scope (type, containing_scope)) ! 3036: { ! 3037: pend_type (type); ! 3038: return; ! 3039: } ! 3040: ! 3041: switch (TREE_CODE (type)) ! 3042: { ! 3043: case ERROR_MARK: ! 3044: break; ! 3045: ! 3046: case POINTER_TYPE: ! 3047: case REFERENCE_TYPE: ! 3048: /* For these types, all that is required is that we output a DIE ! 3049: (or a set of DIEs) to represent that "basis" type. */ ! 3050: output_type (TREE_TYPE (type), containing_scope); ! 3051: break; ! 3052: ! 3053: case OFFSET_TYPE: ! 3054: /* This code is used for C++ pointer-to-data-member types. */ ! 3055: /* Output a description of the relevant class type. */ ! 3056: output_type (TYPE_OFFSET_BASETYPE (type), containing_scope); ! 3057: /* Output a description of the type of the object pointed to. */ ! 3058: output_type (TREE_TYPE (type), containing_scope); ! 3059: /* Now output a DIE to represent this pointer-to-data-member type ! 3060: itself. */ ! 3061: output_die (output_ptr_to_mbr_type_die, type); ! 3062: break; ! 3063: ! 3064: case SET_TYPE: ! 3065: output_type (TREE_TYPE (type), containing_scope); ! 3066: output_die (output_set_type_die, type); ! 3067: break; ! 3068: ! 3069: case FILE_TYPE: ! 3070: output_type (TREE_TYPE (type), containing_scope); ! 3071: abort (); /* No way to reprsent these in Dwarf yet! */ ! 3072: break; ! 3073: ! 3074: case STRING_TYPE: ! 3075: output_type (TREE_TYPE (type), containing_scope); ! 3076: output_die (output_string_type_die, type); ! 3077: break; ! 3078: ! 3079: case FUNCTION_TYPE: ! 3080: /* Force out return type (in case it wasn't forced out already). */ ! 3081: output_type (TREE_TYPE (type), containing_scope); ! 3082: output_die (output_subroutine_type_die, type); ! 3083: output_formal_types (type); ! 3084: end_sibling_chain (); ! 3085: break; ! 3086: ! 3087: case METHOD_TYPE: ! 3088: /* Force out return type (in case it wasn't forced out already). */ ! 3089: output_type (TREE_TYPE (type), containing_scope); ! 3090: output_die (output_subroutine_type_die, type); ! 3091: output_formal_types (type); ! 3092: end_sibling_chain (); ! 3093: break; ! 3094: ! 3095: case ARRAY_TYPE: ! 3096: { ! 3097: register tree element_type; ! 3098: ! 3099: element_type = TREE_TYPE (type); ! 3100: while (TREE_CODE (element_type) == ARRAY_TYPE) ! 3101: element_type = TREE_TYPE (element_type); ! 3102: ! 3103: output_type (element_type, containing_scope); ! 3104: output_die (output_array_type_die, type); ! 3105: } ! 3106: break; ! 3107: ! 3108: case ENUMERAL_TYPE: ! 3109: case RECORD_TYPE: ! 3110: case UNION_TYPE: ! 3111: ! 3112: /* For a non-file-scope tagged type, we can always go ahead and ! 3113: output a Dwarf description of this type right now, even if ! 3114: the type in question is still incomplete, because if this ! 3115: local type *was* ever completed anywhere within its scope, ! 3116: that complete definition would already have been attached to ! 3117: this RECORD_TYPE, UNION_TYPE or ENUMERAL_TYPE node by the ! 3118: time we reach this point. That's true because of the way the ! 3119: front-end does its processing of file-scope declarations (of ! 3120: functions and class types) within which other types might be ! 3121: nested. The C and C++ front-ends always gobble up such "local ! 3122: scope" things en-mass before they try to output *any* debugging ! 3123: information for any of the stuff contained inside them and thus, ! 3124: we get the benefit here of what is (in effect) a pre-resolution ! 3125: of forward references to tagged types in local scopes. ! 3126: ! 3127: Note however that for file-scope tagged types we cannot assume ! 3128: that such pre-resolution of forward references has taken place. ! 3129: A given file-scope tagged type may appear to be incomplete when ! 3130: we reach this point, but it may yet be given a full definition ! 3131: (at file-scope) later on during compilation. In order to avoid ! 3132: generating a premature (and possibly incorrect) set of Dwarf ! 3133: DIEs for such (as yet incomplete) file-scope tagged types, we ! 3134: generate nothing at all for as-yet incomplete file-scope tagged ! 3135: types here unless we are making our special "finalization" pass ! 3136: for file-scope things at the very end of compilation. At that ! 3137: time, we will certainly know as much about each file-scope tagged ! 3138: type as we are ever going to know, so at that point in time, we ! 3139: can safely generate correct Dwarf descriptions for these file- ! 3140: scope tagged types. ! 3141: */ ! 3142: ! 3143: if (TYPE_SIZE (type) == 0 && TYPE_CONTEXT (type) == NULL && !finalizing) ! 3144: return; /* EARLY EXIT! Avoid setting TREE_ASM_WRITTEN. */ ! 3145: ! 3146: /* Prevent infinite recursion in cases where the type of some ! 3147: member of this type is expressed in terms of this type itself. */ ! 3148: ! 3149: TREE_ASM_WRITTEN (type) = 1; ! 3150: ! 3151: /* Output a DIE to represent the tagged type itself. */ ! 3152: ! 3153: switch (TREE_CODE (type)) ! 3154: { ! 3155: case ENUMERAL_TYPE: ! 3156: output_die (output_enumeration_type_die, type); ! 3157: return; /* a special case -- nothing left to do so just return */ ! 3158: ! 3159: case RECORD_TYPE: ! 3160: output_die (output_structure_type_die, type); ! 3161: break; ! 3162: ! 3163: case UNION_TYPE: ! 3164: output_die (output_union_type_die, type); ! 3165: break; ! 3166: } ! 3167: ! 3168: /* If this is not an incomplete type, output descriptions of ! 3169: each of its members. ! 3170: ! 3171: Note that as we output the DIEs necessary to represent the ! 3172: members of this record or union type, we will also be trying ! 3173: to output DIEs to represent the *types* of those members. ! 3174: However the `output_type' function (above) will specifically ! 3175: avoid generating type DIEs for member types *within* the list ! 3176: of member DIEs for this (containing) type execpt for those ! 3177: types (of members) which are explicitly marked as also being ! 3178: members of this (containing) type themselves. The g++ front- ! 3179: end can force any given type to be treated as a member of some ! 3180: other (containing) type by setting the TYPE_CONTEXT of the ! 3181: given (member) type to point to the TREE node representing the ! 3182: appropriate (containing) type. ! 3183: */ ! 3184: ! 3185: if (TYPE_SIZE (type)) ! 3186: { ! 3187: register tree member; ! 3188: ! 3189: /* First output info about the data members and type members. */ ! 3190: ! 3191: for (member = TYPE_FIELDS (type); ! 3192: member; ! 3193: member = TREE_CHAIN (member)) ! 3194: output_decl (member, type); ! 3195: ! 3196: /* Now output info about the function members (if any). */ ! 3197: ! 3198: if (TYPE_METHODS (type)) ! 3199: for (member = TREE_VEC_ELT (TYPE_METHODS (type), 0); ! 3200: member; ! 3201: member = TREE_CHAIN (member)) ! 3202: output_decl (member, type); ! 3203: ! 3204: end_sibling_chain (); /* Terminate member chain. */ ! 3205: } ! 3206: ! 3207: break; ! 3208: ! 3209: case VOID_TYPE: ! 3210: case INTEGER_TYPE: ! 3211: case REAL_TYPE: ! 3212: case COMPLEX_TYPE: ! 3213: case BOOLEAN_TYPE: ! 3214: case CHAR_TYPE: ! 3215: break; /* No DIEs needed for fundamental types. */ ! 3216: ! 3217: case LANG_TYPE: /* No Dwarf representation currently defined. */ ! 3218: break; ! 3219: ! 3220: default: ! 3221: abort (); ! 3222: } ! 3223: ! 3224: TREE_ASM_WRITTEN (type) = 1; ! 3225: } ! 3226: ! 3227: /* Output a TAG_lexical_block DIE followed by DIEs to represent all of ! 3228: the things which are local to the given block. */ ! 3229: ! 3230: static void ! 3231: output_block (stmt) ! 3232: register tree stmt; ! 3233: { ! 3234: register int have_significant_locals = 0; ! 3235: ! 3236: /* Ignore blocks never really used to make RTL. */ ! 3237: ! 3238: if (! stmt || ! TREE_USED (stmt)) ! 3239: return; ! 3240: ! 3241: /* Determine if this block contains any "significant" local declarations ! 3242: which we need to output DIEs for. */ ! 3243: ! 3244: if (BLOCK_INLINE_FUNCTION (stmt)) ! 3245: /* The outer scopes for inlinings *must* always be represented. */ ! 3246: have_significant_locals = 1; ! 3247: else ! 3248: if (debug_info_level > DINFO_LEVEL_TERSE) ! 3249: have_significant_locals = (BLOCK_VARS (stmt) != NULL); ! 3250: else ! 3251: { ! 3252: register tree decl; ! 3253: ! 3254: for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl)) ! 3255: if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl)) ! 3256: { ! 3257: have_significant_locals = 1; ! 3258: break; ! 3259: } ! 3260: } ! 3261: ! 3262: /* It would be a waste of space to generate a Dwarf TAG_lexical_block ! 3263: DIE for any block which contains no significant local declarations ! 3264: at all. Rather, in such cases we just call `output_decls_for_scope' ! 3265: so that any needed Dwarf info for any sub-blocks will get properly ! 3266: generated. Note that in terse mode, our definition of what constitutes ! 3267: a "significant" local declaration gets restricted to include only ! 3268: inlined function instances and local (nested) function definitions. */ ! 3269: ! 3270: if (have_significant_locals) ! 3271: { ! 3272: output_die (BLOCK_INLINE_FUNCTION (stmt) ! 3273: ? output_inlined_subroutine_die ! 3274: : output_lexical_block_die, ! 3275: stmt); ! 3276: output_decls_for_scope (stmt); ! 3277: end_sibling_chain (); ! 3278: } ! 3279: else ! 3280: output_decls_for_scope (stmt); ! 3281: } ! 3282: ! 3283: /* Output all of the decls declared within a given scope (also called ! 3284: a `binding contour') and (recursively) all of it's sub-blocks. */ ! 3285: ! 3286: static void ! 3287: output_decls_for_scope (stmt) ! 3288: register tree stmt; ! 3289: { ! 3290: /* Ignore blocks never really used to make RTL. */ ! 3291: ! 3292: if (! stmt || ! TREE_USED (stmt)) ! 3293: return; ! 3294: ! 3295: next_block_number++; ! 3296: ! 3297: /* Output the DIEs to represent all of the data objects, functions, ! 3298: typedefs, and tagged types declared directly within this block ! 3299: but not within any nested sub-blocks. */ ! 3300: ! 3301: { ! 3302: register tree decl; ! 3303: ! 3304: for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl)) ! 3305: output_decl (decl, stmt); ! 3306: } ! 3307: ! 3308: output_pending_types_for_scope (stmt); ! 3309: ! 3310: /* Output the DIEs to represent all sub-blocks (and the items declared ! 3311: therein) of this block. */ ! 3312: ! 3313: { ! 3314: register tree subblocks; ! 3315: ! 3316: for (subblocks = BLOCK_SUBBLOCKS (stmt); ! 3317: subblocks; ! 3318: subblocks = BLOCK_CHAIN (subblocks)) ! 3319: output_block (subblocks); ! 3320: } ! 3321: } ! 3322: ! 3323: /* Output Dwarf .debug information for a decl described by DECL. */ ! 3324: ! 3325: static void ! 3326: output_decl (decl, containing_scope) ! 3327: register tree decl; ! 3328: register tree containing_scope; ! 3329: { ! 3330: switch (TREE_CODE (decl)) ! 3331: { ! 3332: case ERROR_MARK: ! 3333: break; ! 3334: ! 3335: case CONST_DECL: ! 3336: /* The individual enumerators of an enum type get output when we ! 3337: output the Dwarf representation of the relevant enum type itself. */ ! 3338: break; ! 3339: ! 3340: case FUNCTION_DECL: ! 3341: /* If we are in terse mode, don't output any DIEs to represent ! 3342: mere external function declarations. */ ! 3343: ! 3344: if (TREE_EXTERNAL (decl) && debug_info_level <= DINFO_LEVEL_TERSE) ! 3345: break; ! 3346: ! 3347: /* Before we describe the FUNCTION_DECL itself, make sure that we ! 3348: have described its return type. */ ! 3349: ! 3350: output_type (TREE_TYPE (TREE_TYPE (decl)), containing_scope); ! 3351: ! 3352: /* If the following DIE will represent a function definition for a ! 3353: function with "extern" linkage, output a special "pubnames" DIE ! 3354: label just ahead of the actual DIE. A reference to this label ! 3355: was already generated in the .debug_pubnames section sub-entry ! 3356: for this function definition. */ ! 3357: ! 3358: if (TREE_PUBLIC (decl)) ! 3359: { ! 3360: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3361: ! 3362: sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++); ! 3363: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3364: } ! 3365: ! 3366: /* Now output a DIE to represent the function itself. */ ! 3367: ! 3368: output_die (TREE_PUBLIC (decl) || TREE_EXTERNAL (decl) ! 3369: ? output_global_subroutine_die ! 3370: : output_local_subroutine_die, ! 3371: decl); ! 3372: ! 3373: /* Now output descriptions of the arguments for this function. ! 3374: This gets (unnecessarily?) complex because of the fact that ! 3375: the DECL_ARGUMENT list for a FUNCTION_DECL doesn't indicate ! 3376: cases where there was a trailing `...' at the end of the formal ! 3377: parameter list. In order to find out if there was a trailing ! 3378: ellipsis or not, we must instead look at the type associated ! 3379: with the FUNCTION_DECL. This will be a node of type FUNCTION_TYPE. ! 3380: If the chain of type nodes hanging off of this FUNCTION_TYPE node ! 3381: ends with a void_type_node then there should *not* be an ellipsis ! 3382: at the end. */ ! 3383: ! 3384: /* In the case where we are describing an external function, all ! 3385: we need to do here (and all we *can* do here) is to describe ! 3386: the *types* of its formal parameters. */ ! 3387: ! 3388: if (TREE_EXTERNAL (decl)) ! 3389: output_formal_types (TREE_TYPE (decl)); ! 3390: else ! 3391: { ! 3392: register tree arg_decls = DECL_ARGUMENTS (decl); ! 3393: ! 3394: /* In the case where the FUNCTION_DECL represents a C++ non-static ! 3395: member function, skip over the first thing on the DECL_ARGUMENTS ! 3396: chain. It only represents the hidden `this pointer' parameter ! 3397: and the debugger should know implicitly that non-static member ! 3398: functions have such a thing, and should be able to figure out ! 3399: exactly what the type of each `this pointer' is (from the ! 3400: AT_member attribute of the parent TAG_subroutine DIE) without ! 3401: being explicitly told. */ ! 3402: ! 3403: if (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) ! 3404: arg_decls = TREE_CHAIN (arg_decls); ! 3405: ! 3406: { ! 3407: register tree last_arg; ! 3408: ! 3409: last_arg = (arg_decls && TREE_CODE (arg_decls) != ERROR_MARK) ! 3410: ? tree_last (arg_decls) ! 3411: : NULL; ! 3412: ! 3413: /* Generate DIEs to represent all known formal parameters, but ! 3414: don't do it if this looks like a varargs function. A given ! 3415: function is considered to be a varargs function if (and only ! 3416: if) its last named argument is named `__builtin_va_alist'. */ ! 3417: ! 3418: if (! last_arg ! 3419: || ! DECL_NAME (last_arg) ! 3420: || strcmp (IDENTIFIER_POINTER (DECL_NAME (last_arg)), ! 3421: "__builtin_va_alist")) ! 3422: { ! 3423: register tree parm; ! 3424: ! 3425: /* WARNING! Kludge zone ahead! Here we have a special ! 3426: hack for svr4 SDB compatability. Instead of passing the ! 3427: current FUNCTION_DECL node as the second parameter (i.e. ! 3428: the `containing_scope' parameter) to `output_decl' (as ! 3429: we ought to) we instead pass a pointer to our own private ! 3430: fake_containing_scope node. That node is a RECORD_TYPE ! 3431: node which NO OTHER TYPE may ever actually be a member of. ! 3432: ! 3433: This pointer will ultimately get passed into `output_type' ! 3434: as its `containing_scope' parameter. `Output_type' will ! 3435: then perform its part in the hack... i.e. it will pend ! 3436: the type of the formal parameter onto the pending_types ! 3437: list. Later on, when we are done generating the whole ! 3438: sequence of formal parameter DIEs for this function ! 3439: definition, we will un-pend all previously pended types ! 3440: of formal parameters for this function definition. ! 3441: ! 3442: This whole kludge prevents any type DIEs from being ! 3443: mixed in with the formal parameter DIEs. That's good ! 3444: because svr4 SDB believes that the list of formal ! 3445: parameter DIEs for a function ends wherever the first ! 3446: non-formal-parameter DIE appears. Thus, we have to ! 3447: keep the formal parameter DIEs segregated. They must ! 3448: all appear (consecutively) at the start of the list of ! 3449: children for the DIE representing the function definition. ! 3450: Then (and only then) may we output any additional DIEs ! 3451: needed to represent the types of these formal parameters. ! 3452: */ ! 3453: ! 3454: for (parm = arg_decls; parm; parm = TREE_CHAIN (parm)) ! 3455: if (TREE_CODE (parm) == PARM_DECL) ! 3456: output_decl (parm, fake_containing_scope); ! 3457: ! 3458: /* Now that we have finished generating all of the DIEs to ! 3459: represent the formal parameters themselves, force out ! 3460: any DIEs needed to represent their types. We do this ! 3461: simply by un-pending all previously pended types which ! 3462: can legitimately go into the chain of children DIEs for ! 3463: the current FUNCTION_DECL. */ ! 3464: ! 3465: output_pending_types_for_scope (decl); ! 3466: } ! 3467: } ! 3468: ! 3469: /* Now try to decide if we should put an ellipsis at the end. */ ! 3470: ! 3471: { ! 3472: register int has_ellipsis = TRUE; /* default assumption */ ! 3473: register tree fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); ! 3474: ! 3475: if (fn_arg_types) ! 3476: { ! 3477: /* This function declaration/definition was prototyped. */ ! 3478: ! 3479: /* If the list of formal argument types ends with a ! 3480: void_type_node, then the formals list did *not* end ! 3481: with an ellipsis. */ ! 3482: ! 3483: if (TREE_VALUE (tree_last (fn_arg_types)) == void_type_node) ! 3484: has_ellipsis = FALSE; ! 3485: } ! 3486: else ! 3487: { ! 3488: /* This function declaration/definition was not prototyped. */ ! 3489: ! 3490: /* Note that all non-prototyped function *declarations* are ! 3491: assumed to represent varargs functions (until proven ! 3492: otherwise). */ ! 3493: ! 3494: if (DECL_INITIAL (decl)) /* if this is a func definition */ ! 3495: { ! 3496: if (!arg_decls) ! 3497: has_ellipsis = FALSE; /* no args == (void) */ ! 3498: else ! 3499: { ! 3500: /* For a non-prototyped function definition which ! 3501: declares one or more formal parameters, if the name ! 3502: of the first formal parameter is *not* ! 3503: __builtin_va_alist then we must assume that this ! 3504: is *not* a varargs function. */ ! 3505: ! 3506: if (DECL_NAME (arg_decls) ! 3507: && strcmp (IDENTIFIER_POINTER (DECL_NAME (arg_decls)), ! 3508: "__builtin_va_alist")) ! 3509: has_ellipsis = FALSE; ! 3510: } ! 3511: } ! 3512: } ! 3513: ! 3514: if (has_ellipsis) ! 3515: output_die (output_unspecified_parameters_die, decl); ! 3516: } ! 3517: } ! 3518: ! 3519: /* Output Dwarf info for all of the stuff within the body of the ! 3520: function (if it has one - it may be just a declaration). */ ! 3521: ! 3522: { ! 3523: register tree outer_scope = DECL_INITIAL (decl); ! 3524: ! 3525: if (outer_scope && TREE_CODE (outer_scope) != ERROR_MARK) ! 3526: { ! 3527: /* Note that here, `outer_scope' is a pointer to the outermost ! 3528: BLOCK node created to represent the body of a function. ! 3529: This outermost BLOCK actually represents the outermost ! 3530: binding contour for the function, i.e. the contour in which ! 3531: the function's formal parameters get declared. Just within ! 3532: this contour, there will be another (nested) BLOCK which ! 3533: represents the function's outermost block. We don't want ! 3534: to generate a lexical_block DIE to represent the outermost ! 3535: block of a function body, because that is not really an ! 3536: independent scope according to ANSI C rules. Rather, it is ! 3537: the same scope in which the parameters were declared and ! 3538: for Dwarf, we do not generate a TAG_lexical_block DIE for ! 3539: that scope. We must however see to it that the LABEL_DECLs ! 3540: associated with `outer_scope' get DIEs generated for them. */ ! 3541: ! 3542: { ! 3543: register tree label; ! 3544: ! 3545: for (label = BLOCK_VARS (outer_scope); ! 3546: label; ! 3547: label = TREE_CHAIN (label)) ! 3548: output_decl (label, outer_scope); ! 3549: } ! 3550: ! 3551: output_decls_for_scope (BLOCK_SUBBLOCKS (outer_scope)); ! 3552: ! 3553: /* Finally, force out any pending types which are local to the ! 3554: outermost block of this function definition. These will ! 3555: all have a TYPE_CONTEXT which points to the FUNCTION_DECL ! 3556: node itself. */ ! 3557: ! 3558: output_pending_types_for_scope (decl); ! 3559: } ! 3560: } ! 3561: ! 3562: /* Generate a terminator for the list of stuff `owned' by this ! 3563: function. */ ! 3564: ! 3565: end_sibling_chain (); ! 3566: ! 3567: break; ! 3568: ! 3569: case TYPE_DECL: ! 3570: /* If we are in terse mode, don't generate any DIEs to represent ! 3571: any actual typedefs. Note that even when we are in terse mode, ! 3572: we must still output DIEs to represent those tagged types which ! 3573: are used (directly or indirectly) in the specification of either ! 3574: a return type or a formal parameter type of some function. */ ! 3575: ! 3576: if (debug_info_level <= DINFO_LEVEL_TERSE) ! 3577: if (DECL_NAME (decl) != NULL ! 3578: || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl))) ! 3579: return; ! 3580: ! 3581: output_type (TREE_TYPE (decl), containing_scope); ! 3582: ! 3583: /* Note that unlike the gcc front end (which generates a NULL named ! 3584: TYPE_DECL node for each complete tagged type, each array type, ! 3585: and each function type node created) the g++ front end generates ! 3586: a *named* TYPE_DECL node for each tagged type node created. ! 3587: Unfortunately, these g++ TYPE_DECL nodes cause us to output many ! 3588: superfluous and unnecessary TAG_typedef DIEs here. When g++ is ! 3589: fixed to stop generating these superfluous named TYPE_DECL nodes, ! 3590: the superfluous TAG_typedef DIEs will likewise cease. */ ! 3591: ! 3592: if (DECL_NAME (decl)) ! 3593: /* Output a DIE to represent the typedef itself. */ ! 3594: output_die (output_typedef_die, decl); ! 3595: break; ! 3596: ! 3597: case LABEL_DECL: ! 3598: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 3599: output_die (output_label_die, decl); ! 3600: break; ! 3601: ! 3602: case VAR_DECL: ! 3603: /* If we are in terse mode, don't generate any DIEs to represent ! 3604: any variable declarations or definitions. */ ! 3605: ! 3606: if (debug_info_level <= DINFO_LEVEL_TERSE) ! 3607: break; ! 3608: ! 3609: /* Output any DIEs that are needed to specify the type of this data ! 3610: object. */ ! 3611: ! 3612: output_type (TREE_TYPE (decl), containing_scope); ! 3613: ! 3614: /* If the following DIE will represent a data object definition for a ! 3615: data object with "extern" linkage, output a special "pubnames" DIE ! 3616: label just ahead of the actual DIE. A reference to this label ! 3617: was already generated in the .debug_pubnames section sub-entry ! 3618: for this data object definition. */ ! 3619: ! 3620: if (TREE_PUBLIC (decl)) ! 3621: { ! 3622: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3623: ! 3624: sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++); ! 3625: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3626: } ! 3627: ! 3628: /* Now output the DIE to represent the data object itself. */ ! 3629: ! 3630: output_die (TREE_PUBLIC (decl) || TREE_EXTERNAL (decl) ! 3631: ? output_global_variable_die : output_local_variable_die, ! 3632: decl); ! 3633: break; ! 3634: ! 3635: case FIELD_DECL: ! 3636: /* Ignore the nameless fields that are used to skip bits. */ ! 3637: if (DECL_NAME (decl) != 0) ! 3638: { ! 3639: output_type (member_declared_type (decl), containing_scope); ! 3640: output_die (output_member_die, decl); ! 3641: } ! 3642: break; ! 3643: ! 3644: case PARM_DECL: ! 3645: /* Force out the type of this formal, if it was not forced out yet. ! 3646: Note that here we can run afowl of a bug in "classic" svr4 SDB. ! 3647: It should be able to grok the presence of type DIEs within a list ! 3648: of TAG_formal_parameter DIEs, but it doesn't. */ ! 3649: ! 3650: output_type (TREE_TYPE (decl), containing_scope); ! 3651: output_die (output_formal_parameter_die, decl); ! 3652: break; ! 3653: ! 3654: default: ! 3655: abort (); ! 3656: } ! 3657: } ! 3658: ! 3659: void ! 3660: dwarfout_file_scope_decl (decl, set_finalizing) ! 3661: register tree decl; ! 3662: register int set_finalizing; ! 3663: { ! 3664: switch (TREE_CODE (decl)) ! 3665: { ! 3666: case FUNCTION_DECL: ! 3667: ! 3668: /* Ignore this FUNCTION_DECL if it refers to a builtin function. */ ! 3669: ! 3670: if (TREE_EXTERNAL (decl) && DECL_FUNCTION_CODE (decl)) ! 3671: return; ! 3672: ! 3673: /* Ignore this FUNCTION_DECL if it refers to a file-scope extern ! 3674: function declaration and if the declaration was never even ! 3675: referenced from within this entire compilation unit. We ! 3676: suppress these DIEs in order to save space in the .debug section ! 3677: (by eliminating entries which are probably useless). Note that ! 3678: we must not suppress block-local extern declarations (whether ! 3679: used or not) because that would screw-up the debugger's name ! 3680: lookup mechanism and cause it to miss things which really ought ! 3681: to be in scope at a given point. */ ! 3682: ! 3683: if (TREE_EXTERNAL (decl) && !TREE_USED (decl)) ! 3684: return; ! 3685: ! 3686: if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl)) ! 3687: { ! 3688: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3689: ! 3690: /* Output a .debug_pubnames entry for a public function ! 3691: defined in this compilation unit. */ ! 3692: ! 3693: fputc ('\n', asm_out_file); ! 3694: ASM_DWARF_PUBNAMES_SECTION (asm_out_file); ! 3695: sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number); ! 3696: ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); ! 3697: ASM_OUTPUT_DWARF_STRING (asm_out_file, ! 3698: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 3699: ASM_DWARF_POP_SECTION (asm_out_file); ! 3700: } ! 3701: ! 3702: break; ! 3703: ! 3704: case VAR_DECL: ! 3705: ! 3706: /* Ignore this VAR_DECL if it refers to a file-scope extern data ! 3707: object declaration and if the declaration was never even ! 3708: referenced from within this entire compilation unit. We ! 3709: suppress these DIEs in order to save space in the .debug section ! 3710: (by eliminating entries which are probably useless). Note that ! 3711: we must not suppress block-local extern declarations (whether ! 3712: used or not) because that would screw-up the debugger's name ! 3713: lookup mechanism and cause it to miss things which really ought ! 3714: to be in scope at a given point. */ ! 3715: ! 3716: if (TREE_EXTERNAL (decl) && !TREE_USED (decl)) ! 3717: return; ! 3718: ! 3719: if (TREE_PUBLIC (decl) && ! TREE_EXTERNAL (decl)) ! 3720: { ! 3721: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3722: ! 3723: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 3724: { ! 3725: /* Output a .debug_pubnames entry for a public variable ! 3726: defined in this compilation unit. */ ! 3727: ! 3728: fputc ('\n', asm_out_file); ! 3729: ASM_DWARF_PUBNAMES_SECTION (asm_out_file); ! 3730: sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number); ! 3731: ASM_OUTPUT_DWARF_ADDR (asm_out_file, label); ! 3732: ASM_OUTPUT_DWARF_STRING (asm_out_file, ! 3733: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 3734: ASM_DWARF_POP_SECTION (asm_out_file); ! 3735: } ! 3736: ! 3737: if (DECL_INITIAL (decl) == NULL) ! 3738: { ! 3739: /* Output a .debug_aranges entry for a public variable ! 3740: which is tenatively defined in this compilation unit. */ ! 3741: ! 3742: fputc ('\n', asm_out_file); ! 3743: ASM_DWARF_ARANGES_SECTION (asm_out_file); ! 3744: ASM_OUTPUT_DWARF_ADDR (asm_out_file, ! 3745: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 3746: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, ! 3747: (unsigned) int_size_in_bytes (TREE_TYPE (decl))); ! 3748: ASM_DWARF_POP_SECTION (asm_out_file); ! 3749: } ! 3750: } ! 3751: ! 3752: /* If we are in terse mode, don't generate any DIEs to represent ! 3753: any variable declarations or definitions. */ ! 3754: ! 3755: if (debug_info_level <= DINFO_LEVEL_TERSE) ! 3756: return; ! 3757: ! 3758: break; ! 3759: ! 3760: case TYPE_DECL: ! 3761: /* Don't generate any DIEs to represent the standard built-in types. */ ! 3762: ! 3763: if (DECL_SOURCE_LINE (decl) == 0) ! 3764: return; ! 3765: ! 3766: /* If we are in terse mode, don't generate any DIEs to represent ! 3767: any actual typedefs. Note that even when we are in terse mode, ! 3768: we must still output DIEs to represent those tagged types which ! 3769: are used (directly or indirectly) in the specification of either ! 3770: a return type or a formal parameter type of some function. */ ! 3771: ! 3772: if (debug_info_level <= DINFO_LEVEL_TERSE) ! 3773: if (DECL_NAME (decl) != NULL ! 3774: || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl))) ! 3775: return; ! 3776: ! 3777: break; ! 3778: ! 3779: default: ! 3780: return; ! 3781: } ! 3782: ! 3783: fputc ('\n', asm_out_file); ! 3784: ASM_DWARF_DEBUG_SECTION (asm_out_file); ! 3785: finalizing = set_finalizing; ! 3786: output_decl (decl, NULL); ! 3787: ! 3788: /* NOTE: The call above to `output_decl' may have caused one or more ! 3789: file-scope named types (i.e. tagged types) to be placed onto the ! 3790: pending_types_list. We have to get those types off of that list ! 3791: at some point, and this is the perfect time to do it. If we didn't ! 3792: take them off now, they might still be on the list when cc1 finally ! 3793: exits. That might be OK if it weren't for the fact that when we put ! 3794: types onto the pending_types_list, we set the TREE_ASM_WRITTEN flag ! 3795: for these types, and that causes them never to be output unless ! 3796: `output_pending_types_for_scope' takes them off of the list and un-sets ! 3797: their TREE_ASM_WRITTEN flags. */ ! 3798: ! 3799: output_pending_types_for_scope (NULL); ! 3800: ! 3801: /* The above call should have totally emptied the pending_types_list. */ ! 3802: ! 3803: assert (pending_types == 0); ! 3804: ! 3805: ASM_DWARF_POP_SECTION (asm_out_file); ! 3806: ! 3807: if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL) ! 3808: current_funcdef_number++; ! 3809: } ! 3810: ! 3811: /* Output a marker (i.e. a label) for the beginning of the generated code ! 3812: for a lexical block. */ ! 3813: ! 3814: void ! 3815: dwarfout_begin_block (blocknum) ! 3816: register unsigned blocknum; ! 3817: { ! 3818: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3819: ! 3820: text_section (); ! 3821: sprintf (label, BLOCK_BEGIN_LABEL_FMT, blocknum); ! 3822: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3823: } ! 3824: ! 3825: /* Output a marker (i.e. a label) for the end of the generated code ! 3826: for a lexical block. */ ! 3827: ! 3828: void ! 3829: dwarfout_end_block (blocknum) ! 3830: register unsigned blocknum; ! 3831: { ! 3832: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3833: ! 3834: text_section (); ! 3835: sprintf (label, BLOCK_END_LABEL_FMT, blocknum); ! 3836: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3837: } ! 3838: ! 3839: /* Output a marker (i.e. a label) at a point in the assembly code which ! 3840: corresponds to a given source level label. */ ! 3841: ! 3842: void ! 3843: dwarfout_label (insn) ! 3844: register rtx insn; ! 3845: { ! 3846: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 3847: { ! 3848: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3849: ! 3850: text_section (); ! 3851: sprintf (label, INSN_LABEL_FMT, current_funcdef_number, ! 3852: (unsigned) INSN_UID (insn)); ! 3853: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3854: } ! 3855: } ! 3856: ! 3857: /* Output a marker (i.e. a label) for the absolute end of the generated code ! 3858: for a function definition. This gets called *after* the epilogue code ! 3859: has been generated. */ ! 3860: ! 3861: void ! 3862: dwarfout_end_epilogue () ! 3863: { ! 3864: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3865: ! 3866: /* Output a label to mark the endpoint of the code generated for this ! 3867: function. */ ! 3868: ! 3869: sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number); ! 3870: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3871: } ! 3872: ! 3873: static void ! 3874: shuffle_filename_entry (new_zeroth) ! 3875: register filename_entry *new_zeroth; ! 3876: { ! 3877: filename_entry temp_entry; ! 3878: register filename_entry *limit_p; ! 3879: register filename_entry *move_p; ! 3880: ! 3881: if (new_zeroth == &filename_table[0]) ! 3882: return; ! 3883: ! 3884: temp_entry = *new_zeroth; ! 3885: ! 3886: /* Shift entries up in the table to make room at [0]. */ ! 3887: ! 3888: limit_p = &filename_table[0]; ! 3889: for (move_p = new_zeroth; move_p > limit_p; move_p--) ! 3890: *move_p = *(move_p-1); ! 3891: ! 3892: /* Install the found entry at [0]. */ ! 3893: ! 3894: filename_table[0] = temp_entry; ! 3895: } ! 3896: ! 3897: /* Create a new (string) entry for the .debug_sfnames section. */ ! 3898: ! 3899: static void ! 3900: generate_new_sfname_entry () ! 3901: { ! 3902: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 3903: ! 3904: fputc ('\n', asm_out_file); ! 3905: ASM_DWARF_SFNAMES_SECTION (asm_out_file); ! 3906: sprintf (label, SFNAMES_ENTRY_LABEL_FMT, filename_table[0].number); ! 3907: ASM_OUTPUT_LABEL (asm_out_file, label); ! 3908: ASM_OUTPUT_DWARF_STRING (asm_out_file, ! 3909: filename_table[0].name ! 3910: ? filename_table[0].name ! 3911: : ""); ! 3912: ASM_DWARF_POP_SECTION (asm_out_file); ! 3913: } ! 3914: ! 3915: /* Lookup a filename (in the list of filenames that we know about here in ! 3916: dwarfout.c) and return its "index". The index of each (known) filename ! 3917: is just a unique number which is associated with only that one filename. ! 3918: We need such numbers for the sake of generating labels (in the ! 3919: .debug_sfnames section) and references to those unique labels (in the ! 3920: .debug_srcinfo and .debug_macinfo sections). ! 3921: ! 3922: If the filename given as an argument is not found in our current list, ! 3923: add it to the list and assign it the next available unique index number. ! 3924: ! 3925: Whatever we do (i.e. whether we find a pre-existing filename or add a new ! 3926: one), we shuffle the filename found (or added) up to the zeroth entry of ! 3927: our list of filenames (which is always searched linearly). We do this so ! 3928: as to optimize the most common case for these filename lookups within ! 3929: dwarfout.c. The most common case by far is the case where we call ! 3930: lookup_filename to lookup the very same filename that we did a lookup ! 3931: on the last time we called lookup_filename. We make sure that this ! 3932: common case is fast because such cases will constitute 99.9% of the ! 3933: lookups we ever do (in practice). ! 3934: ! 3935: If we add a new filename entry to our table, we go ahead and generate ! 3936: the corresponding entry in the .debug_sfnames section right away. ! 3937: Doing so allows us to avoid tickling an assembler bug (present in some ! 3938: m68k assemblers) which yields assembly-time errors in cases where the ! 3939: difference of two label addresses is taken and where the two labels ! 3940: are in a section *other* than the one where the difference is being ! 3941: calculated, and where at least one of the two symbol references is a ! 3942: forward reference. (This bug could be tickled by our .debug_srcinfo ! 3943: entries if we don't output their corresponding .debug_sfnames entries ! 3944: before them.) ! 3945: */ ! 3946: ! 3947: static unsigned ! 3948: lookup_filename (file_name) ! 3949: char *file_name; ! 3950: { ! 3951: register filename_entry *search_p; ! 3952: register filename_entry *limit_p = &filename_table[ft_entries]; ! 3953: ! 3954: for (search_p = filename_table; search_p < limit_p; search_p++) ! 3955: if (!strcmp (file_name, search_p->name)) ! 3956: { ! 3957: /* When we get here, we have found the filename that we were ! 3958: looking for in the filename_table. Now we want to make sure ! 3959: that it gets moved to the zero'th entry in the table (if it ! 3960: is not already there) so that subsequent attempts to find the ! 3961: same filename will find it as quickly as possible. */ ! 3962: ! 3963: shuffle_filename_entry (search_p); ! 3964: return filename_table[0].number; ! 3965: } ! 3966: ! 3967: /* We come here whenever we have a new filename which is not registered ! 3968: in the current table. Here we add it to the table. */ ! 3969: ! 3970: /* Prepare to add a new table entry by making sure there is enough space ! 3971: in the table to do so. If not, expand the current table. */ ! 3972: ! 3973: if (ft_entries == ft_entries_allocated) ! 3974: { ! 3975: ft_entries_allocated += FT_ENTRIES_INCREMENT; ! 3976: filename_table ! 3977: = (filename_entry *) ! 3978: xrealloc (filename_table, ! 3979: ft_entries_allocated * sizeof (filename_entry)); ! 3980: } ! 3981: ! 3982: /* Initially, add the new entry at the end of the filename table. */ ! 3983: ! 3984: filename_table[ft_entries].number = ft_entries; ! 3985: filename_table[ft_entries].name = xstrdup (file_name); ! 3986: ! 3987: /* Shuffle the new entry into filename_table[0]. */ ! 3988: ! 3989: shuffle_filename_entry (&filename_table[ft_entries]); ! 3990: ! 3991: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 3992: generate_new_sfname_entry (); ! 3993: ! 3994: ft_entries++; ! 3995: return filename_table[0].number; ! 3996: } ! 3997: ! 3998: static void ! 3999: generate_srcinfo_entry (line_entry_num, files_entry_num) ! 4000: unsigned line_entry_num; ! 4001: unsigned files_entry_num; ! 4002: { ! 4003: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 4004: ! 4005: fputc ('\n', asm_out_file); ! 4006: ASM_DWARF_SRCINFO_SECTION (asm_out_file); ! 4007: sprintf (label, LINE_ENTRY_LABEL_FMT, line_entry_num); ! 4008: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, LINE_BEGIN_LABEL); ! 4009: sprintf (label, SFNAMES_ENTRY_LABEL_FMT, files_entry_num); ! 4010: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, SFNAMES_BEGIN_LABEL); ! 4011: ASM_DWARF_POP_SECTION (asm_out_file); ! 4012: } ! 4013: ! 4014: void ! 4015: dwarfout_line (filename, line) ! 4016: register char *filename; ! 4017: register unsigned line; ! 4018: { ! 4019: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 4020: { ! 4021: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 4022: static unsigned last_line_entry_num = 0; ! 4023: static unsigned prev_file_entry_num = (unsigned) -1; ! 4024: register unsigned this_file_entry_num = lookup_filename (filename); ! 4025: ! 4026: text_section (); ! 4027: sprintf (label, LINE_CODE_LABEL_FMT, ++last_line_entry_num); ! 4028: ASM_OUTPUT_LABEL (asm_out_file, label); ! 4029: ! 4030: fputc ('\n', asm_out_file); ! 4031: ASM_DWARF_LINE_SECTION (asm_out_file); ! 4032: ! 4033: if (this_file_entry_num != prev_file_entry_num) ! 4034: { ! 4035: char line_entry_label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 4036: ! 4037: sprintf (line_entry_label, LINE_ENTRY_LABEL_FMT, last_line_entry_num); ! 4038: ASM_OUTPUT_LABEL (asm_out_file, line_entry_label); ! 4039: } ! 4040: ! 4041: { ! 4042: register char *tail = strrchr (filename, '/'); ! 4043: ! 4044: if (tail != NULL) ! 4045: filename = tail; ! 4046: } ! 4047: ! 4048: fprintf (asm_out_file, "%s\t%u\t%s %s:%u\n", ! 4049: UNALIGNED_INT_ASM_OP, line, ASM_COMMENT_START, ! 4050: filename, line); ! 4051: ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff); ! 4052: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, TEXT_BEGIN_LABEL); ! 4053: ASM_DWARF_POP_SECTION (asm_out_file); ! 4054: ! 4055: if (this_file_entry_num != prev_file_entry_num) ! 4056: generate_srcinfo_entry (last_line_entry_num, this_file_entry_num); ! 4057: prev_file_entry_num = this_file_entry_num; ! 4058: } ! 4059: } ! 4060: ! 4061: /* Generate an entry in the .debug_macinfo section. */ ! 4062: ! 4063: static void ! 4064: generate_macinfo_entry (type_and_offset, string) ! 4065: register char *type_and_offset; ! 4066: register char *string; ! 4067: { ! 4068: fputc ('\n', asm_out_file); ! 4069: ASM_DWARF_MACINFO_SECTION (asm_out_file); ! 4070: fprintf (asm_out_file, "%s\t%s\n", UNALIGNED_INT_ASM_OP, type_and_offset); ! 4071: ASM_OUTPUT_DWARF_STRING (asm_out_file, string); ! 4072: ASM_DWARF_POP_SECTION (asm_out_file); ! 4073: } ! 4074: ! 4075: void ! 4076: dwarfout_start_new_source_file (filename) ! 4077: register char *filename; ! 4078: { ! 4079: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 4080: char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*3]; ! 4081: ! 4082: sprintf (label, SFNAMES_ENTRY_LABEL_FMT, lookup_filename (filename)); ! 4083: sprintf (type_and_offset, "0x%08x+%s-%s", ! 4084: ((unsigned) MACINFO_start << 24), label, SFNAMES_BEGIN_LABEL); ! 4085: generate_macinfo_entry (type_and_offset, ""); ! 4086: } ! 4087: ! 4088: void ! 4089: dwarfout_resume_previous_source_file (lineno) ! 4090: register unsigned lineno; ! 4091: { ! 4092: char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; ! 4093: ! 4094: sprintf (type_and_offset, "0x%08x+%u", ! 4095: ((unsigned) MACINFO_resume << 24), lineno); ! 4096: generate_macinfo_entry (type_and_offset, ""); ! 4097: } ! 4098: ! 4099: /* Called from check_newline in c-parse.y. The `buffer' parameter ! 4100: contains the tail part of the directive line, i.e. the part which ! 4101: is past the initial whitespace, #, whitespace, directive-name, ! 4102: whitespace part. */ ! 4103: ! 4104: void ! 4105: dwarfout_define (lineno, buffer) ! 4106: register unsigned lineno; ! 4107: register char *buffer; ! 4108: { ! 4109: static int initialized = 0; ! 4110: char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; ! 4111: ! 4112: if (!initialized) ! 4113: { ! 4114: dwarfout_start_new_source_file (primary_filename); ! 4115: initialized = 1; ! 4116: } ! 4117: sprintf (type_and_offset, "0x%08x+%u", ! 4118: ((unsigned) MACINFO_define << 24), lineno); ! 4119: generate_macinfo_entry (type_and_offset, buffer); ! 4120: } ! 4121: ! 4122: /* Called from check_newline in c-parse.y. The `buffer' parameter ! 4123: contains the tail part of the directive line, i.e. the part which ! 4124: is past the initial whitespace, #, whitespace, directive-name, ! 4125: whitespace part. */ ! 4126: ! 4127: void ! 4128: dwarfout_undef (lineno, buffer) ! 4129: register unsigned lineno; ! 4130: register char *buffer; ! 4131: { ! 4132: char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2]; ! 4133: ! 4134: sprintf (type_and_offset, "0x%08x+%u", ! 4135: ((unsigned) MACINFO_undef << 24), lineno); ! 4136: generate_macinfo_entry (type_and_offset, buffer); ! 4137: } ! 4138: ! 4139: /* Set up for Dwarf output at the start of compilation. */ ! 4140: ! 4141: void ! 4142: dwarfout_init (asm_out_file, main_input_filename) ! 4143: register FILE *asm_out_file; ! 4144: register char *main_input_filename; ! 4145: { ! 4146: /* Remember the name of the primary input file. */ ! 4147: ! 4148: primary_filename = main_input_filename; ! 4149: ! 4150: /* Allocate the initial hunk of the pending_sibling_stack. */ ! 4151: ! 4152: pending_sibling_stack ! 4153: = (unsigned *) ! 4154: xmalloc (PENDING_SIBLINGS_INCREMENT * sizeof (unsigned)); ! 4155: pending_siblings_allocated = PENDING_SIBLINGS_INCREMENT; ! 4156: pending_siblings = 1; ! 4157: ! 4158: /* Allocate the initial hunk of the filename_table. */ ! 4159: ! 4160: filename_table ! 4161: = (filename_entry *) ! 4162: xmalloc (FT_ENTRIES_INCREMENT * sizeof (filename_entry)); ! 4163: ft_entries_allocated = FT_ENTRIES_INCREMENT; ! 4164: ft_entries = 0; ! 4165: ! 4166: /* Allocate the initial hunk of the pending_types_list. */ ! 4167: ! 4168: pending_types_list ! 4169: = (tree *) xmalloc (PENDING_TYPES_INCREMENT * sizeof (tree)); ! 4170: pending_types_allocated = PENDING_TYPES_INCREMENT; ! 4171: pending_types = 0; ! 4172: ! 4173: /* Create an artificial RECORD_TYPE node which we can use in our hack ! 4174: to get the DIEs representing types of formal parameters to come out ! 4175: only *after* the DIEs for the formal parameters themselves. */ ! 4176: ! 4177: fake_containing_scope = make_node (RECORD_TYPE); ! 4178: ! 4179: /* Output a starting label for the .text section. */ ! 4180: ! 4181: fputc ('\n', asm_out_file); ! 4182: ASM_DWARF_TEXT_SECTION (asm_out_file); ! 4183: ASM_OUTPUT_LABEL (asm_out_file, TEXT_BEGIN_LABEL); ! 4184: ASM_DWARF_POP_SECTION (asm_out_file); ! 4185: ! 4186: /* Output a starting label for the .data section. */ ! 4187: ! 4188: fputc ('\n', asm_out_file); ! 4189: ASM_DWARF_DATA_SECTION (asm_out_file); ! 4190: ASM_OUTPUT_LABEL (asm_out_file, DATA_BEGIN_LABEL); ! 4191: ASM_DWARF_POP_SECTION (asm_out_file); ! 4192: ! 4193: /* Output a starting label for the .data1 section. */ ! 4194: ! 4195: fputc ('\n', asm_out_file); ! 4196: ASM_DWARF_DATA1_SECTION (asm_out_file); ! 4197: ASM_OUTPUT_LABEL (asm_out_file, DATA1_BEGIN_LABEL); ! 4198: ASM_DWARF_POP_SECTION (asm_out_file); ! 4199: ! 4200: /* Output a starting label for the .rodata section. */ ! 4201: ! 4202: fputc ('\n', asm_out_file); ! 4203: ASM_DWARF_RODATA_SECTION (asm_out_file); ! 4204: ASM_OUTPUT_LABEL (asm_out_file, RODATA_BEGIN_LABEL); ! 4205: ASM_DWARF_POP_SECTION (asm_out_file); ! 4206: ! 4207: /* Output a starting label for the .rodata1 section. */ ! 4208: ! 4209: fputc ('\n', asm_out_file); ! 4210: ASM_DWARF_RODATA1_SECTION (asm_out_file); ! 4211: ASM_OUTPUT_LABEL (asm_out_file, RODATA1_BEGIN_LABEL); ! 4212: ASM_DWARF_POP_SECTION (asm_out_file); ! 4213: ! 4214: /* Output a starting label for the .bss section. */ ! 4215: ! 4216: fputc ('\n', asm_out_file); ! 4217: ASM_DWARF_BSS_SECTION (asm_out_file); ! 4218: ASM_OUTPUT_LABEL (asm_out_file, BSS_BEGIN_LABEL); ! 4219: ASM_DWARF_POP_SECTION (asm_out_file); ! 4220: ! 4221: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 4222: { ! 4223: /* Output a starting label and an initial (compilation directory) ! 4224: entry for the .debug_sfnames section. The starting label will be ! 4225: referenced by the initial entry in the .debug_srcinfo section. */ ! 4226: ! 4227: fputc ('\n', asm_out_file); ! 4228: ASM_DWARF_SFNAMES_SECTION (asm_out_file); ! 4229: ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL); ! 4230: { ! 4231: register unsigned len = 1024; ! 4232: register char *dirname = (char *) xmalloc (len + 1); ! 4233: ! 4234: /* We don't know how much space the dirname needs, ! 4235: so try bigger and bigger buffers until it fits. */ ! 4236: for (;;) ! 4237: { ! 4238: getcwd (dirname, len); /* Being conservative here. */ ! 4239: if (strlen (dirname) < len - 1) /* Being conservative here. */ ! 4240: break; ! 4241: len *= 2; ! 4242: dirname = (char *) xrealloc (dirname, len + 1); ! 4243: } ! 4244: strcat (dirname, "/"); ! 4245: ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname); ! 4246: free (dirname); ! 4247: } ! 4248: ASM_DWARF_POP_SECTION (asm_out_file); ! 4249: ! 4250: if (debug_info_level >= DINFO_LEVEL_VERBOSE) ! 4251: { ! 4252: /* Output a starting label for the .debug_macinfo section. This ! 4253: label will be referenced by the AT_mac_info attribute in the ! 4254: TAG_compile_unit DIE. */ ! 4255: ! 4256: fputc ('\n', asm_out_file); ! 4257: ASM_DWARF_MACINFO_SECTION (asm_out_file); ! 4258: ASM_OUTPUT_LABEL (asm_out_file, MACINFO_BEGIN_LABEL); ! 4259: ASM_DWARF_POP_SECTION (asm_out_file); ! 4260: } ! 4261: ! 4262: /* Generate the initial entry for the .line section. */ ! 4263: ! 4264: fputc ('\n', asm_out_file); ! 4265: ASM_DWARF_LINE_SECTION (asm_out_file); ! 4266: ASM_OUTPUT_LABEL (asm_out_file, LINE_BEGIN_LABEL); ! 4267: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, LINE_END_LABEL, LINE_BEGIN_LABEL); ! 4268: ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); ! 4269: ASM_DWARF_POP_SECTION (asm_out_file); ! 4270: ! 4271: /* Generate the initial entry for the .debug_srcinfo section. */ ! 4272: ! 4273: fputc ('\n', asm_out_file); ! 4274: ASM_DWARF_SRCINFO_SECTION (asm_out_file); ! 4275: ASM_OUTPUT_LABEL (asm_out_file, SRCINFO_BEGIN_LABEL); ! 4276: ASM_OUTPUT_DWARF_ADDR (asm_out_file, LINE_BEGIN_LABEL); ! 4277: ASM_OUTPUT_DWARF_ADDR (asm_out_file, SFNAMES_BEGIN_LABEL); ! 4278: ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); ! 4279: ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_END_LABEL); ! 4280: #ifdef DWARF_TIMESTAMPS ! 4281: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, time (NULL)); ! 4282: #else ! 4283: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1); ! 4284: #endif ! 4285: ASM_DWARF_POP_SECTION (asm_out_file); ! 4286: ! 4287: /* Generate the initial entry for the .debug_pubnames section. */ ! 4288: ! 4289: fputc ('\n', asm_out_file); ! 4290: ASM_DWARF_PUBNAMES_SECTION (asm_out_file); ! 4291: ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL); ! 4292: ASM_DWARF_POP_SECTION (asm_out_file); ! 4293: ! 4294: /* Generate the initial entry for the .debug_aranges section. */ ! 4295: ! 4296: fputc ('\n', asm_out_file); ! 4297: ASM_DWARF_ARANGES_SECTION (asm_out_file); ! 4298: ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL); ! 4299: ASM_DWARF_POP_SECTION (asm_out_file); ! 4300: } ! 4301: ! 4302: /* Setup first DIE number == 1. */ ! 4303: NEXT_DIE_NUM = next_unused_dienum++; ! 4304: ! 4305: /* Generate the initial DIE for the .debug section. Note that the ! 4306: (string) value given in the AT_name attribute of the TAG_compile_unit ! 4307: DIE will (typically) be a relative pathname and that this pathname ! 4308: should be taken as being relative to the directory from which the ! 4309: compiler was invoked when the given (base) source file was compiled. */ ! 4310: ! 4311: fputc ('\n', asm_out_file); ! 4312: ASM_DWARF_DEBUG_SECTION (asm_out_file); ! 4313: ASM_OUTPUT_LABEL (asm_out_file, DEBUG_BEGIN_LABEL); ! 4314: output_die (output_compile_unit_die, main_input_filename); ! 4315: ASM_DWARF_POP_SECTION (asm_out_file); ! 4316: ! 4317: fputc ('\n', asm_out_file); ! 4318: } ! 4319: ! 4320: /* Output stuff that dwarf requires at the end of every file. */ ! 4321: ! 4322: void ! 4323: dwarfout_finish () ! 4324: { ! 4325: char label[MAX_ARTIFICIAL_LABEL_BYTES]; ! 4326: ! 4327: fputc ('\n', asm_out_file); ! 4328: ASM_DWARF_DEBUG_SECTION (asm_out_file); ! 4329: ! 4330: /* Mark the end of the chain of siblings which represent all file-scope ! 4331: declarations in this compilation unit. */ ! 4332: ! 4333: /* The (null) DIE which represents the terminator for the (sibling linked) ! 4334: list of file-scope items is *special*. Normally, we would just call ! 4335: end_sibling_chain at this point in order to output a word with the ! 4336: value `4' and that word would act as the terminator for the list of ! 4337: DIEs describing file-scope items. Unfortunately, if we were to simply ! 4338: do that, the label that would follow this DIE in the .debug section ! 4339: (i.e. `..D2') would *not* be properly aligned (as it must be on some ! 4340: machines) to a 4 byte boundary. ! 4341: ! 4342: In order to force the label `..D2' to get aligned to a 4 byte boundary, ! 4343: the trick used is to insert extra (otherwise useless) padding bytes ! 4344: into the (null) DIE that we know must preceed the ..D2 label in the ! 4345: .debug section. The amount of padding required can be anywhere between ! 4346: 0 and 3 bytes. The length word at the start of this DIE (i.e. the one ! 4347: with the padding) would normally contain the value 4, but now it will ! 4348: also have to include the padding bytes, so it will instead have some ! 4349: value in the range 4..7. ! 4350: ! 4351: Fortunately, the rules of Dwarf say that any DIE whose length word ! 4352: contains *any* value less than 8 should be treated as a null DIE, so ! 4353: this trick works out nicely. Clever, eh? Don't give me any credit ! 4354: (or blame). I didn't think of this scheme. I just conformed to it. ! 4355: */ ! 4356: ! 4357: output_die (output_padded_null_die, (void *)0); ! 4358: dienum_pop (); ! 4359: ! 4360: sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM); ! 4361: ASM_OUTPUT_LABEL (asm_out_file, label); /* should be ..D2 */ ! 4362: ASM_DWARF_POP_SECTION (asm_out_file); ! 4363: ! 4364: /* Output a terminator label for the .text section. */ ! 4365: ! 4366: fputc ('\n', asm_out_file); ! 4367: ASM_DWARF_TEXT_SECTION (asm_out_file); ! 4368: ASM_OUTPUT_LABEL (asm_out_file, TEXT_END_LABEL); ! 4369: ASM_DWARF_POP_SECTION (asm_out_file); ! 4370: ! 4371: /* Output a terminator label for the .data section. */ ! 4372: ! 4373: fputc ('\n', asm_out_file); ! 4374: ASM_DWARF_DATA_SECTION (asm_out_file); ! 4375: ASM_OUTPUT_LABEL (asm_out_file, DATA_END_LABEL); ! 4376: ASM_DWARF_POP_SECTION (asm_out_file); ! 4377: ! 4378: /* Output a terminator label for the .data1 section. */ ! 4379: ! 4380: fputc ('\n', asm_out_file); ! 4381: ASM_DWARF_DATA1_SECTION (asm_out_file); ! 4382: ASM_OUTPUT_LABEL (asm_out_file, DATA1_END_LABEL); ! 4383: ASM_DWARF_POP_SECTION (asm_out_file); ! 4384: ! 4385: /* Output a terminator label for the .rodata section. */ ! 4386: ! 4387: fputc ('\n', asm_out_file); ! 4388: ASM_DWARF_RODATA_SECTION (asm_out_file); ! 4389: ASM_OUTPUT_LABEL (asm_out_file, RODATA_END_LABEL); ! 4390: ASM_DWARF_POP_SECTION (asm_out_file); ! 4391: ! 4392: /* Output a terminator label for the .rodata1 section. */ ! 4393: ! 4394: fputc ('\n', asm_out_file); ! 4395: ASM_DWARF_RODATA1_SECTION (asm_out_file); ! 4396: ASM_OUTPUT_LABEL (asm_out_file, RODATA1_END_LABEL); ! 4397: ASM_DWARF_POP_SECTION (asm_out_file); ! 4398: ! 4399: /* Output a terminator label for the .bss section. */ ! 4400: ! 4401: fputc ('\n', asm_out_file); ! 4402: ASM_DWARF_BSS_SECTION (asm_out_file); ! 4403: ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL); ! 4404: ASM_DWARF_POP_SECTION (asm_out_file); ! 4405: ! 4406: if (debug_info_level >= DINFO_LEVEL_NORMAL) ! 4407: { ! 4408: /* Output a terminating entry for the .line section. */ ! 4409: ! 4410: fputc ('\n', asm_out_file); ! 4411: ASM_DWARF_LINE_SECTION (asm_out_file); ! 4412: ASM_OUTPUT_LABEL (asm_out_file, LINE_LAST_ENTRY_LABEL); ! 4413: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 4414: ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff); ! 4415: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL); ! 4416: ASM_OUTPUT_LABEL (asm_out_file, LINE_END_LABEL); ! 4417: ASM_DWARF_POP_SECTION (asm_out_file); ! 4418: ! 4419: /* Output a terminating entry for the .debug_srcinfo section. */ ! 4420: ! 4421: fputc ('\n', asm_out_file); ! 4422: ASM_DWARF_SRCINFO_SECTION (asm_out_file); ! 4423: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, ! 4424: LINE_LAST_ENTRY_LABEL, LINE_BEGIN_LABEL); ! 4425: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1); ! 4426: ASM_DWARF_POP_SECTION (asm_out_file); ! 4427: ! 4428: if (debug_info_level >= DINFO_LEVEL_VERBOSE) ! 4429: { ! 4430: /* Output terminating entries for the .debug_macinfo section. */ ! 4431: ! 4432: dwarfout_resume_previous_source_file (0); ! 4433: ! 4434: fputc ('\n', asm_out_file); ! 4435: ASM_DWARF_MACINFO_SECTION (asm_out_file); ! 4436: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 4437: ASM_OUTPUT_DWARF_STRING (asm_out_file, ""); ! 4438: ASM_DWARF_POP_SECTION (asm_out_file); ! 4439: } ! 4440: ! 4441: /* Generate the terminating entry for the .debug_pubnames section. */ ! 4442: ! 4443: fputc ('\n', asm_out_file); ! 4444: ASM_DWARF_PUBNAMES_SECTION (asm_out_file); ! 4445: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 4446: ASM_OUTPUT_DWARF_STRING (asm_out_file, ""); ! 4447: ASM_DWARF_POP_SECTION (asm_out_file); ! 4448: ! 4449: /* Generate the terminating entries for the .debug_aranges section. ! 4450: ! 4451: Note that we want to do this only *after* we have output the end ! 4452: labels (for the various program sections) which we are going to ! 4453: refer to here. This allows us to work around a bug in the m68k ! 4454: svr4 assembler. That assembler gives bogus assembly-time errors ! 4455: if (within any given section) you try to take the difference of ! 4456: two relocatable symbols, both of which are located within some ! 4457: other section, and if one (or both?) of the symbols involved is ! 4458: being forward-referenced. By generating the .debug_aranges ! 4459: entries at this late point in the assembly output, we skirt the ! 4460: issue simply by avoiding forward-references. ! 4461: */ ! 4462: ! 4463: fputc ('\n', asm_out_file); ! 4464: ASM_DWARF_ARANGES_SECTION (asm_out_file); ! 4465: ! 4466: ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL); ! 4467: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL); ! 4468: ! 4469: ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA_BEGIN_LABEL); ! 4470: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA_END_LABEL, DATA_BEGIN_LABEL); ! 4471: ! 4472: ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA1_BEGIN_LABEL); ! 4473: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA1_END_LABEL, ! 4474: DATA1_BEGIN_LABEL); ! 4475: ! 4476: ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA_BEGIN_LABEL); ! 4477: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA_END_LABEL, ! 4478: RODATA_BEGIN_LABEL); ! 4479: ! 4480: ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA1_BEGIN_LABEL); ! 4481: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA1_END_LABEL, ! 4482: RODATA1_BEGIN_LABEL); ! 4483: ! 4484: ASM_OUTPUT_DWARF_ADDR (asm_out_file, BSS_BEGIN_LABEL); ! 4485: ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, BSS_END_LABEL, BSS_BEGIN_LABEL); ! 4486: ! 4487: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 4488: ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0); ! 4489: ! 4490: ASM_DWARF_POP_SECTION (asm_out_file); ! 4491: } ! 4492: } ! 4493: ! 4494: #endif /* DWARF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.