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