Annotation of gcc/xcoffout.c, revision 1.1.1.6

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.