|
|
1.1 root 1: /* Output xcoff-format symbol table information from GNU compiler. 1.1.1.6 ! root 2: Copyright (C) 1992, 1994, 1995 Free Software Foundation, Inc. 1.1 root 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 1.1.1.6 ! root 18: the Free Software Foundation, 59 Temple Place - Suite 330, ! 19: Boston, MA 02111-1307, USA. */ 1.1 root 20: 21: 22: /* Output xcoff-format symbol table data. The main functionality is contained 23: in dbxout.c. This file implements the sdbout-like parts of the xcoff 24: interface. Many functions are very similar to their counterparts in 25: sdbout.c. */ 26: 27: /* Include this first, because it may define MIN and MAX. */ 28: #include <stdio.h> 29: 30: #include "config.h" 31: #include "tree.h" 32: #include "rtl.h" 33: #include "flags.h" 34: 35: #ifdef XCOFF_DEBUGGING_INFO 36: 37: /* This defines the C_* storage classes. */ 38: #include <dbxstclass.h> 39: 40: #include "xcoffout.h" 41: 42: #if defined (USG) || defined (NO_STAB_H) 43: #include "gstab.h" 44: #else 45: #include <stab.h> 46: 47: /* This is a GNU extension we need to reference in this file. */ 48: #ifndef N_CATCH 49: #define N_CATCH 0x54 50: #endif 51: #endif 52: 53: /* Line number of beginning of current function, minus one. 54: Negative means not in a function or not using xcoff. */ 55: 56: int xcoff_begin_function_line = -1; 1.1.1.6 ! root 57: int xcoff_inlining = 0; 1.1 root 58: 59: /* Name of the current include file. */ 60: 61: char *xcoff_current_include_file; 62: 63: /* Name of the current function file. This is the file the `.bf' is 64: emitted from. In case a line is emitted from a different file, 65: (by including that file of course), then the line number will be 66: absolute. */ 67: 68: char *xcoff_current_function_file; 69: 70: /* Names of bss and data sections. These should be unique names for each 71: compilation unit. */ 72: 73: char *xcoff_bss_section_name; 74: char *xcoff_private_data_section_name; 75: char *xcoff_read_only_section_name; 1.1.1.5 root 76: 77: /* Last source file name mentioned in a NOTE insn. */ 78: 79: char *xcoff_lastfile; 1.1 root 80: 81: /* Macro definitions used below. */ 1.1.1.5 root 82: 83: #define ABS_OR_RELATIVE_LINENO(LINENO) \ 1.1.1.6 ! root 84: ((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line) 1.1.1.5 root 85: 86: /* Output source line numbers via ".line" rather than ".stabd". */ 87: #define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \ 88: do { \ 89: if (xcoff_begin_function_line >= 0) \ 90: fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \ 91: } while (0) 1.1 root 92: 93: #define ASM_OUTPUT_LFB(FILE,LINENUM) \ 94: { \ 95: if (xcoff_begin_function_line == -1) \ 96: { \ 97: xcoff_begin_function_line = (LINENUM) - 1;\ 98: fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \ 99: } \ 100: xcoff_current_function_file \ 101: = (xcoff_current_include_file \ 102: ? xcoff_current_include_file : main_input_filename); \ 103: } 104: 105: #define ASM_OUTPUT_LFE(FILE,LINENUM) \ 106: do { \ 1.1.1.5 root 107: fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \ 1.1 root 108: xcoff_begin_function_line = -1; \ 109: } while (0) 110: 111: #define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \ 1.1.1.5 root 112: fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) 1.1 root 113: 114: #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \ 1.1.1.5 root 115: fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) 1.1 root 116: 117: /* Support routines for XCOFF debugging info. */ 118: 119: /* Assign NUMBER as the stabx type number for the type described by NAME. 120: Search all decls in the list SYMS to find the type NAME. */ 121: 122: static void 123: assign_type_number (syms, name, number) 124: tree syms; 125: char *name; 126: int number; 127: { 128: tree decl; 129: 130: for (decl = syms; decl; decl = TREE_CHAIN (decl)) 1.1.1.3 root 131: if (DECL_NAME (decl) 132: && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0) 1.1 root 133: { 134: TREE_ASM_WRITTEN (decl) = 1; 135: TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number; 136: } 137: } 138: 139: /* Setup gcc primitive types to use the XCOFF built-in type numbers where 140: possible. */ 141: 142: void 143: xcoff_output_standard_types (syms) 144: tree syms; 145: { 146: /* Handle built-in C types here. */ 147: 1.1.1.6 ! root 148: assign_type_number (syms, "int", (TARGET_64BIT ? -31 : -1)); 1.1 root 149: assign_type_number (syms, "char", -2); 150: assign_type_number (syms, "short int", -3); 1.1.1.6 ! root 151: assign_type_number (syms, "long int", (TARGET_64BIT ? -31 : -4)); 1.1 root 152: assign_type_number (syms, "unsigned char", -5); 153: assign_type_number (syms, "signed char", -6); 154: assign_type_number (syms, "short unsigned int", -7); 1.1.1.6 ! root 155: assign_type_number (syms, "unsigned int", (TARGET_64BIT ? -32 : -8)); 1.1 root 156: /* No such type "unsigned". */ 1.1.1.6 ! root 157: assign_type_number (syms, "long unsigned int", (TARGET_64BIT ? -32 : -10)); 1.1 root 158: assign_type_number (syms, "void", -11); 159: assign_type_number (syms, "float", -12); 160: assign_type_number (syms, "double", -13); 161: assign_type_number (syms, "long double", -14); 162: /* Pascal and Fortran types run from -15 to -29. */ 1.1.1.6 ! root 163: assign_type_number (syms, "wchar", -30); ! 164: assign_type_number (syms, "long long int", -31); ! 165: assign_type_number (syms, "long long unsigned int", -32); ! 166: /* Additional Fortran types run from -33 to -37. */ 1.1 root 167: 168: /* ??? Should also handle built-in C++ and Obj-C types. There perhaps 169: aren't any that C doesn't already have. */ 170: } 171: 172: /* Print an error message for unrecognized stab codes. */ 173: 174: #define UNKNOWN_STAB(STR) \ 175: do { \ 176: fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \ 177: fflush (stderr); \ 178: } while (0) 179: 180: /* Conversion routine from BSD stabs to AIX storage classes. */ 181: 182: int 183: stab_to_sclass (stab) 184: int stab; 185: { 186: switch (stab) 187: { 188: case N_GSYM: 189: return C_GSYM; 190: 191: case N_FNAME: 192: UNKNOWN_STAB ("N_FNAME"); 193: abort(); 194: 195: case N_FUN: 196: return C_FUN; 197: 198: case N_STSYM: 199: case N_LCSYM: 200: return C_STSYM; 201: 1.1.1.4 root 202: #ifdef N_MAIN 1.1 root 203: case N_MAIN: 204: UNKNOWN_STAB ("N_MAIN"); 205: abort (); 1.1.1.4 root 206: #endif 1.1 root 207: 208: case N_RSYM: 209: return C_RSYM; 210: 211: case N_SSYM: 212: UNKNOWN_STAB ("N_SSYM"); 213: abort (); 214: 215: case N_RPSYM: 216: return C_RPSYM; 217: 218: case N_PSYM: 219: return C_PSYM; 220: case N_LSYM: 221: return C_LSYM; 222: case N_DECL: 223: return C_DECL; 224: case N_ENTRY: 225: return C_ENTRY; 226: 227: case N_SO: 228: UNKNOWN_STAB ("N_SO"); 229: abort (); 230: 231: case N_SOL: 232: UNKNOWN_STAB ("N_SOL"); 233: abort (); 234: 235: case N_SLINE: 236: UNKNOWN_STAB ("N_SLINE"); 237: abort (); 238: 1.1.1.4 root 239: #ifdef N_DSLINE 1.1 root 240: case N_DSLINE: 241: UNKNOWN_STAB ("N_DSLINE"); 242: abort (); 1.1.1.4 root 243: #endif 1.1 root 244: 1.1.1.4 root 245: #ifdef N_BSLINE 1.1 root 246: case N_BSLINE: 247: UNKNOWN_STAB ("N_BSLINE"); 248: abort (); 1.1.1.4 root 249: #endif 1.1 root 250: #if 0 251: /* This has the same value as N_BSLINE. */ 252: case N_BROWS: 253: UNKNOWN_STAB ("N_BROWS"); 254: abort (); 255: #endif 256: 1.1.1.4 root 257: #ifdef N_BINCL 1.1 root 258: case N_BINCL: 259: UNKNOWN_STAB ("N_BINCL"); 260: abort (); 1.1.1.4 root 261: #endif 1.1 root 262: 1.1.1.4 root 263: #ifdef N_EINCL 1.1 root 264: case N_EINCL: 265: UNKNOWN_STAB ("N_EINCL"); 266: abort (); 1.1.1.4 root 267: #endif 1.1 root 268: 1.1.1.4 root 269: #ifdef N_EXCL 1.1 root 270: case N_EXCL: 271: UNKNOWN_STAB ("N_EXCL"); 272: abort (); 1.1.1.4 root 273: #endif 1.1 root 274: 275: case N_LBRAC: 276: UNKNOWN_STAB ("N_LBRAC"); 277: abort (); 278: 279: case N_RBRAC: 280: UNKNOWN_STAB ("N_RBRAC"); 281: abort (); 282: 283: case N_BCOMM: 284: return C_BCOMM; 285: case N_ECOMM: 286: return C_ECOMM; 287: case N_ECOML: 288: return C_ECOML; 289: 290: case N_LENG: 291: UNKNOWN_STAB ("N_LENG"); 292: abort (); 293: 294: case N_PC: 295: UNKNOWN_STAB ("N_PC"); 296: abort (); 297: 1.1.1.4 root 298: #ifdef N_M2C 1.1 root 299: case N_M2C: 300: UNKNOWN_STAB ("N_M2C"); 301: abort (); 1.1.1.4 root 302: #endif 1.1 root 303: 1.1.1.4 root 304: #ifdef N_SCOPE 1.1 root 305: case N_SCOPE: 306: UNKNOWN_STAB ("N_SCOPE"); 307: abort (); 1.1.1.4 root 308: #endif 1.1 root 309: 310: case N_CATCH: 311: UNKNOWN_STAB ("N_CATCH"); 312: abort (); 313: 314: default: 315: UNKNOWN_STAB ("default"); 316: abort (); 317: } 318: } 1.1.1.5 root 319: 320: /* Output debugging info to FILE to switch to sourcefile FILENAME. 321: INLINE_P is true if this is from an inlined function. */ 322: 323: void 324: xcoffout_source_file (file, filename, inline_p) 325: FILE *file; 326: char *filename; 327: int inline_p; 328: { 329: if (filename 330: && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile) 1.1.1.6 ! root 331: || (inline_p && ! xcoff_inlining) ! 332: || (! inline_p && xcoff_inlining))) 1.1.1.5 root 333: { 334: if (xcoff_current_include_file) 335: { 336: fprintf (file, "\t.ei\t"); 337: output_quoted_string (file, xcoff_current_include_file); 338: fprintf (file, "\n"); 339: xcoff_current_include_file = NULL; 340: } 1.1.1.6 ! root 341: xcoff_inlining=inline_p; 1.1.1.5 root 342: if (strcmp (main_input_filename, filename) || inline_p) 343: { 344: fprintf (file, "\t.bi\t"); 345: output_quoted_string (file, filename); 346: fprintf (file, "\n"); 347: xcoff_current_include_file = filename; 348: } 349: 350: xcoff_lastfile = filename; 351: } 352: } 353: 354: /* Output a line number symbol entry into output stream FILE, 355: for source file FILENAME and line number NOTE. */ 356: 357: void 358: xcoffout_source_line (file, filename, note) 359: FILE *file; 360: char *filename; 361: rtx note; 362: { 363: xcoffout_source_file (file, filename, RTX_INTEGRATED_P (note)); 364: 365: ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (note)); 366: } 367: 1.1 root 368: /* Output the symbols defined in block number DO_BLOCK. 369: Set NEXT_BLOCK_NUMBER to 0 before calling. 370: 371: This function works by walking the tree structure of blocks, 372: counting blocks until it finds the desired block. */ 373: 374: static int do_block = 0; 375: 376: static int next_block_number; 377: 378: static void 379: xcoffout_block (block, depth, args) 380: register tree block; 381: int depth; 382: tree args; 383: { 384: while (block) 385: { 386: /* Ignore blocks never expanded or otherwise marked as real. */ 387: if (TREE_USED (block)) 388: { 389: /* When we reach the specified block, output its symbols. */ 390: if (next_block_number == do_block) 391: { 392: /* Output the syms of the block. */ 393: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) 394: dbxout_syms (BLOCK_VARS (block)); 395: if (args) 396: dbxout_reg_parms (args); 397: 398: /* We are now done with the block. Don't go to inner blocks. */ 399: return; 400: } 401: /* If we are past the specified block, stop the scan. */ 402: else if (next_block_number >= do_block) 403: return; 404: 405: next_block_number++; 406: 407: /* Output the subblocks. */ 1.1.1.3 root 408: xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); 1.1 root 409: } 410: block = BLOCK_CHAIN (block); 411: } 412: } 413: 414: /* Describe the beginning of an internal block within a function. 415: Also output descriptions of variables defined in this block. 416: 417: N is the number of the block, by order of beginning, counting from 1, 418: and not counting the outermost (function top-level) block. 419: The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), 420: if the count starts at 0 for the outermost one. */ 421: 422: void 423: xcoffout_begin_block (file, line, n) 424: FILE *file; 425: int line; 426: int n; 427: { 428: tree decl = current_function_decl; 429: 1.1.1.5 root 430: 431: /* The IBM AIX compiler does not emit a .bb for the function level scope, 432: so we avoid it here also. */ 433: if (n != 1) 434: ASM_OUTPUT_LBB (file, line, n); 1.1 root 435: 436: do_block = n; 437: next_block_number = 0; 438: xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); 439: } 440: 441: /* Describe the end line-number of an internal block within a function. */ 442: 443: void 444: xcoffout_end_block (file, line, n) 445: FILE *file; 446: int line; 447: int n; 448: { 1.1.1.5 root 449: if (n != 1) 450: ASM_OUTPUT_LBE (file, line, n); 1.1 root 451: } 452: 1.1.1.2 root 453: /* Called at beginning of function (before prologue). 454: Declare function as needed for debugging. */ 455: 456: void 457: xcoffout_declare_function (file, decl, name) 458: FILE *file; 459: tree decl; 460: char *name; 461: { 462: char *n = name; 463: int i; 464: 1.1.1.6 ! root 465: if (*n == '*') ! 466: n++; ! 467: else ! 468: for (i = 0; name[i]; ++i) ! 469: { ! 470: if (name[i] == '[') ! 471: { ! 472: n = (char *) alloca (i + 1); ! 473: strncpy (n, name, i); ! 474: n[i] = '\0'; ! 475: break; ! 476: } ! 477: } 1.1.1.2 root 478: 1.1.1.6 ! root 479: /* Any pending .bi or .ei must occur before the .function pseudo op. 1.1.1.4 root 480: Otherwise debuggers will think that the function is in the previous 481: file and/or at the wrong line number. */ 1.1.1.5 root 482: xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0); 1.1.1.2 root 483: dbxout_symbol (decl, 0); 484: fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n); 485: } 486: 1.1 root 487: /* Called at beginning of function body (after prologue). 488: Record the function's starting line number, so we can output 489: relative line numbers for the other lines. 490: Record the file name that this function is contained in. */ 491: 492: void 493: xcoffout_begin_function (file, last_linenum) 494: FILE *file; 495: int last_linenum; 496: { 497: ASM_OUTPUT_LFB (file, last_linenum); 1.1.1.6 ! root 498: dbxout_parms (DECL_ARGUMENTS (current_function_decl)); ! 499: ASM_OUTPUT_SOURCE_LINE (file, last_linenum); 1.1 root 500: } 501: 502: /* Called at end of function (before epilogue). 503: Describe end of outermost block. */ 504: 505: void 506: xcoffout_end_function (file, last_linenum) 507: FILE *file; 508: int last_linenum; 509: { 510: ASM_OUTPUT_LFE (file, last_linenum); 511: } 512: 513: /* Output xcoff info for the absolute end of a function. 514: Called after the epilogue is output. */ 515: 516: void 517: xcoffout_end_epilogue (file) 518: FILE *file; 519: { 520: /* We need to pass the correct function size to .function, otherwise, 521: the xas assembler can't figure out the correct size for the function 522: aux entry. So, we emit a label after the last instruction which can 1.1.1.2 root 523: be used by the .function pseudo op to calculate the function size. */ 1.1 root 524: 525: char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); 526: if (*fname == '*') 527: ++fname; 1.1.1.2 root 528: fprintf (file, "FE.."); 1.1 root 529: ASM_OUTPUT_LABEL (file, fname); 530: } 531: #endif /* XCOFF_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.