|
|
1.1 ! root 1: /* Output xcoff-format symbol table information from GNU compiler. ! 2: Copyright (C) 1992 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: /* Output xcoff-format symbol table data. The main functionality is contained ! 22: in dbxout.c. This file implements the sdbout-like parts of the xcoff ! 23: interface. Many functions are very similar to their counterparts in ! 24: sdbout.c. */ ! 25: ! 26: /* Include this first, because it may define MIN and MAX. */ ! 27: #include <stdio.h> ! 28: ! 29: #include "config.h" ! 30: #include "tree.h" ! 31: #include "rtl.h" ! 32: #include "flags.h" ! 33: ! 34: #ifdef XCOFF_DEBUGGING_INFO ! 35: ! 36: /* This defines the C_* storage classes. */ ! 37: #include <dbxstclass.h> ! 38: ! 39: #include "xcoffout.h" ! 40: ! 41: #if defined (USG) || defined (NO_STAB_H) ! 42: #include "gstab.h" ! 43: #else ! 44: #include <stab.h> ! 45: ! 46: /* This is a GNU extension we need to reference in this file. */ ! 47: #ifndef N_CATCH ! 48: #define N_CATCH 0x54 ! 49: #endif ! 50: #endif ! 51: ! 52: /* These are GNU extensions we need to reference in this file. */ ! 53: #ifndef N_DSLINE ! 54: #define N_DSLINE 0x46 ! 55: #endif ! 56: #ifndef N_BSLINE ! 57: #define N_BSLINE 0x48 ! 58: #endif ! 59: ! 60: /* Line number of beginning of current function, minus one. ! 61: Negative means not in a function or not using xcoff. */ ! 62: ! 63: int xcoff_begin_function_line = -1; ! 64: ! 65: /* Name of the current include file. */ ! 66: ! 67: char *xcoff_current_include_file; ! 68: ! 69: /* Name of the current function file. This is the file the `.bf' is ! 70: emitted from. In case a line is emitted from a different file, ! 71: (by including that file of course), then the line number will be ! 72: absolute. */ ! 73: ! 74: char *xcoff_current_function_file; ! 75: ! 76: /* Names of bss and data sections. These should be unique names for each ! 77: compilation unit. */ ! 78: ! 79: char *xcoff_bss_section_name; ! 80: char *xcoff_private_data_section_name; ! 81: char *xcoff_read_only_section_name; ! 82: ! 83: /* Macro definitions used below. */ ! 84: /* Ensure we don't output a negative line number. */ ! 85: #define MAKE_LINE_SAFE(LINE) \ ! 86: if (LINE <= xcoff_begin_function_line) \ ! 87: LINE = xcoff_begin_function_line + 1 \ ! 88: ! 89: #define ASM_OUTPUT_LFB(FILE,LINENUM) \ ! 90: { \ ! 91: if (xcoff_begin_function_line == -1) \ ! 92: { \ ! 93: xcoff_begin_function_line = (LINENUM) - 1;\ ! 94: fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \ ! 95: } \ ! 96: xcoff_current_function_file \ ! 97: = (xcoff_current_include_file \ ! 98: ? xcoff_current_include_file : main_input_filename); \ ! 99: } ! 100: ! 101: #define ASM_OUTPUT_LFE(FILE,LINENUM) \ ! 102: do { \ ! 103: int linenum = LINENUM; \ ! 104: MAKE_LINE_SAFE (linenum); \ ! 105: fprintf (FILE, "\t.ef\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \ ! 106: xcoff_begin_function_line = -1; \ ! 107: } while (0) ! 108: ! 109: #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \ ! 110: do { \ ! 111: int linenum = LINENUM; \ ! 112: MAKE_LINE_SAFE (linenum); \ ! 113: fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \ ! 114: } while (0) ! 115: ! 116: #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \ ! 117: do { \ ! 118: int linenum = LINENUM; \ ! 119: MAKE_LINE_SAFE (linenum); \ ! 120: fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \ ! 121: } while (0) ! 122: ! 123: /* Support routines for XCOFF debugging info. */ ! 124: ! 125: /* Assign NUMBER as the stabx type number for the type described by NAME. ! 126: Search all decls in the list SYMS to find the type NAME. */ ! 127: ! 128: static void ! 129: assign_type_number (syms, name, number) ! 130: tree syms; ! 131: char *name; ! 132: int number; ! 133: { ! 134: tree decl; ! 135: ! 136: for (decl = syms; decl; decl = TREE_CHAIN (decl)) ! 137: if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name)) ! 138: { ! 139: TREE_ASM_WRITTEN (decl) = 1; ! 140: TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number; ! 141: } ! 142: } ! 143: ! 144: /* Setup gcc primitive types to use the XCOFF built-in type numbers where ! 145: possible. */ ! 146: ! 147: void ! 148: xcoff_output_standard_types (syms) ! 149: tree syms; ! 150: { ! 151: /* Handle built-in C types here. */ ! 152: ! 153: assign_type_number (syms, "int", -1); ! 154: assign_type_number (syms, "char", -2); ! 155: assign_type_number (syms, "short int", -3); ! 156: assign_type_number (syms, "long int", -4); ! 157: assign_type_number (syms, "unsigned char", -5); ! 158: assign_type_number (syms, "signed char", -6); ! 159: assign_type_number (syms, "short unsigned int", -7); ! 160: assign_type_number (syms, "unsigned int", -8); ! 161: /* No such type "unsigned". */ ! 162: assign_type_number (syms, "long unsigned int", -10); ! 163: assign_type_number (syms, "void", -11); ! 164: assign_type_number (syms, "float", -12); ! 165: assign_type_number (syms, "double", -13); ! 166: assign_type_number (syms, "long double", -14); ! 167: /* Pascal and Fortran types run from -15 to -29. */ ! 168: /* No such type "wchar". */ ! 169: ! 170: /* "long long int", and "long long unsigned int", are not handled here, ! 171: because there are no predefined types that match them. */ ! 172: ! 173: /* ??? Should also handle built-in C++ and Obj-C types. There perhaps ! 174: aren't any that C doesn't already have. */ ! 175: } ! 176: ! 177: /* Print an error message for unrecognized stab codes. */ ! 178: ! 179: #define UNKNOWN_STAB(STR) \ ! 180: do { \ ! 181: fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \ ! 182: fflush (stderr); \ ! 183: } while (0) ! 184: ! 185: /* Conversion routine from BSD stabs to AIX storage classes. */ ! 186: ! 187: int ! 188: stab_to_sclass (stab) ! 189: int stab; ! 190: { ! 191: switch (stab) ! 192: { ! 193: case N_GSYM: ! 194: return C_GSYM; ! 195: ! 196: case N_FNAME: ! 197: UNKNOWN_STAB ("N_FNAME"); ! 198: abort(); ! 199: ! 200: case N_FUN: ! 201: return C_FUN; ! 202: ! 203: case N_STSYM: ! 204: case N_LCSYM: ! 205: return C_STSYM; ! 206: ! 207: case N_MAIN: ! 208: UNKNOWN_STAB ("N_MAIN"); ! 209: abort (); ! 210: ! 211: case N_RSYM: ! 212: return C_RSYM; ! 213: ! 214: case N_SSYM: ! 215: UNKNOWN_STAB ("N_SSYM"); ! 216: abort (); ! 217: ! 218: case N_RPSYM: ! 219: return C_RPSYM; ! 220: ! 221: case N_PSYM: ! 222: return C_PSYM; ! 223: case N_LSYM: ! 224: return C_LSYM; ! 225: case N_DECL: ! 226: return C_DECL; ! 227: case N_ENTRY: ! 228: return C_ENTRY; ! 229: ! 230: case N_SO: ! 231: UNKNOWN_STAB ("N_SO"); ! 232: abort (); ! 233: ! 234: case N_SOL: ! 235: UNKNOWN_STAB ("N_SOL"); ! 236: abort (); ! 237: ! 238: case N_SLINE: ! 239: UNKNOWN_STAB ("N_SLINE"); ! 240: abort (); ! 241: ! 242: case N_DSLINE: ! 243: UNKNOWN_STAB ("N_DSLINE"); ! 244: abort (); ! 245: ! 246: case N_BSLINE: ! 247: UNKNOWN_STAB ("N_BSLINE"); ! 248: abort (); ! 249: #if 0 ! 250: /* This has the same value as N_BSLINE. */ ! 251: case N_BROWS: ! 252: UNKNOWN_STAB ("N_BROWS"); ! 253: abort (); ! 254: #endif ! 255: ! 256: case N_BINCL: ! 257: UNKNOWN_STAB ("N_BINCL"); ! 258: abort (); ! 259: ! 260: case N_EINCL: ! 261: UNKNOWN_STAB ("N_EINCL"); ! 262: abort (); ! 263: ! 264: case N_EXCL: ! 265: UNKNOWN_STAB ("N_EXCL"); ! 266: abort (); ! 267: ! 268: case N_LBRAC: ! 269: UNKNOWN_STAB ("N_LBRAC"); ! 270: abort (); ! 271: ! 272: case N_RBRAC: ! 273: UNKNOWN_STAB ("N_RBRAC"); ! 274: abort (); ! 275: ! 276: case N_BCOMM: ! 277: return C_BCOMM; ! 278: case N_ECOMM: ! 279: return C_ECOMM; ! 280: case N_ECOML: ! 281: return C_ECOML; ! 282: ! 283: case N_LENG: ! 284: UNKNOWN_STAB ("N_LENG"); ! 285: abort (); ! 286: ! 287: case N_PC: ! 288: UNKNOWN_STAB ("N_PC"); ! 289: abort (); ! 290: ! 291: case N_M2C: ! 292: UNKNOWN_STAB ("N_M2C"); ! 293: abort (); ! 294: ! 295: case N_SCOPE: ! 296: UNKNOWN_STAB ("N_SCOPE"); ! 297: abort (); ! 298: ! 299: case N_CATCH: ! 300: UNKNOWN_STAB ("N_CATCH"); ! 301: abort (); ! 302: ! 303: default: ! 304: UNKNOWN_STAB ("default"); ! 305: abort (); ! 306: } ! 307: } ! 308: ! 309: /* In XCOFF, we have to have this .bf before the function prologue. ! 310: Rely on the value of `dbx_begin_function_line' not to duplicate .bf. */ ! 311: ! 312: void ! 313: xcoffout_output_first_source_line (file, last_linenum) ! 314: FILE *file; ! 315: int last_linenum; ! 316: { ! 317: ASM_OUTPUT_LFB (file, last_linenum); ! 318: dbxout_parms (DECL_ARGUMENTS (current_function_decl)); ! 319: ASM_OUTPUT_SOURCE_LINE (file, last_linenum); ! 320: } ! 321: ! 322: /* Output the symbols defined in block number DO_BLOCK. ! 323: Set NEXT_BLOCK_NUMBER to 0 before calling. ! 324: ! 325: This function works by walking the tree structure of blocks, ! 326: counting blocks until it finds the desired block. */ ! 327: ! 328: static int do_block = 0; ! 329: ! 330: static int next_block_number; ! 331: ! 332: static void ! 333: xcoffout_block (block, depth, args) ! 334: register tree block; ! 335: int depth; ! 336: tree args; ! 337: { ! 338: while (block) ! 339: { ! 340: /* Ignore blocks never expanded or otherwise marked as real. */ ! 341: if (TREE_USED (block)) ! 342: { ! 343: /* When we reach the specified block, output its symbols. */ ! 344: if (next_block_number == do_block) ! 345: { ! 346: /* Output the syms of the block. */ ! 347: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) ! 348: dbxout_syms (BLOCK_VARS (block)); ! 349: if (args) ! 350: dbxout_reg_parms (args); ! 351: ! 352: /* We are now done with the block. Don't go to inner blocks. */ ! 353: return; ! 354: } ! 355: /* If we are past the specified block, stop the scan. */ ! 356: else if (next_block_number >= do_block) ! 357: return; ! 358: ! 359: next_block_number++; ! 360: ! 361: /* Output the subblocks. */ ! 362: xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, 0); ! 363: } ! 364: block = BLOCK_CHAIN (block); ! 365: } ! 366: } ! 367: ! 368: /* Describe the beginning of an internal block within a function. ! 369: Also output descriptions of variables defined in this block. ! 370: ! 371: N is the number of the block, by order of beginning, counting from 1, ! 372: and not counting the outermost (function top-level) block. ! 373: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), ! 374: if the count starts at 0 for the outermost one. */ ! 375: ! 376: void ! 377: xcoffout_begin_block (file, line, n) ! 378: FILE *file; ! 379: int line; ! 380: int n; ! 381: { ! 382: tree decl = current_function_decl; ! 383: ! 384: ASM_OUTPUT_LBB (file, line, n); ! 385: ! 386: do_block = n; ! 387: next_block_number = 0; ! 388: xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); ! 389: } ! 390: ! 391: /* Describe the end line-number of an internal block within a function. */ ! 392: ! 393: void ! 394: xcoffout_end_block (file, line, n) ! 395: FILE *file; ! 396: int line; ! 397: int n; ! 398: { ! 399: ASM_OUTPUT_LBE (file, line, n); ! 400: } ! 401: ! 402: /* Called at beginning of function body (after prologue). ! 403: Record the function's starting line number, so we can output ! 404: relative line numbers for the other lines. ! 405: Record the file name that this function is contained in. */ ! 406: ! 407: void ! 408: xcoffout_begin_function (file, last_linenum) ! 409: FILE *file; ! 410: int last_linenum; ! 411: { ! 412: ASM_OUTPUT_LFB (file, last_linenum); ! 413: } ! 414: ! 415: /* Called at end of function (before epilogue). ! 416: Describe end of outermost block. */ ! 417: ! 418: void ! 419: xcoffout_end_function (file, last_linenum) ! 420: FILE *file; ! 421: int last_linenum; ! 422: { ! 423: ASM_OUTPUT_LFE (file, last_linenum); ! 424: } ! 425: ! 426: /* Output xcoff info for the absolute end of a function. ! 427: Called after the epilogue is output. */ ! 428: ! 429: void ! 430: xcoffout_end_epilogue (file) ! 431: FILE *file; ! 432: { ! 433: /* We need to pass the correct function size to .function, otherwise, ! 434: the xas assembler can't figure out the correct size for the function ! 435: aux entry. So, we emit a label after the last instruction which can ! 436: be used by the .function psuedo op to calculate the function size. */ ! 437: ! 438: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); ! 439: if (*fname == '*') ! 440: ++fname; ! 441: fprintf (file, "L..end_"); ! 442: ASM_OUTPUT_LABEL (file, fname); ! 443: } ! 444: #endif /* XCOFF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.