Annotation of gcc/xcoffout.c, revision 1.1.1.2

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: 
1.1.1.2 ! root      402: /* Called at beginning of function (before prologue).
        !           403:    Declare function as needed for debugging.  */
        !           404: 
        !           405: void
        !           406: xcoffout_declare_function (file, decl, name)
        !           407:      FILE *file;
        !           408:      tree decl;
        !           409:      char *name;
        !           410: {
        !           411:   char *n = name;
        !           412:   int i;
        !           413: 
        !           414:   for (i = 0; name[i]; ++i)
        !           415:     {
        !           416:       if (name[i] == '[')
        !           417:        {
        !           418:          n = alloca (i + 1);
        !           419:          strncpy (n, name, i);
        !           420:          n[i] = '\0';
        !           421:          break;
        !           422:        }
        !           423:     }
        !           424: 
        !           425:   dbxout_symbol (decl, 0);
        !           426:   fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, n);
        !           427: }
        !           428: 
1.1       root      429: /* Called at beginning of function body (after prologue).
                    430:    Record the function's starting line number, so we can output
                    431:    relative line numbers for the other lines.
                    432:    Record the file name that this function is contained in.  */
                    433: 
                    434: void
                    435: xcoffout_begin_function (file, last_linenum)
                    436:      FILE *file;
                    437:      int last_linenum;
                    438: {
                    439:   ASM_OUTPUT_LFB (file, last_linenum);
                    440: }
                    441: 
                    442: /* Called at end of function (before epilogue).
                    443:    Describe end of outermost block.  */
                    444: 
                    445: void
                    446: xcoffout_end_function (file, last_linenum)
                    447:      FILE *file;
                    448:      int last_linenum;
                    449: {
                    450:   ASM_OUTPUT_LFE (file, last_linenum);
                    451: }
                    452: 
                    453: /* Output xcoff info for the absolute end of a function.
                    454:    Called after the epilogue is output.  */
                    455: 
                    456: void
                    457: xcoffout_end_epilogue (file)
                    458:      FILE *file;
                    459: {
                    460:   /* We need to pass the correct function size to .function, otherwise,
                    461:      the xas assembler can't figure out the correct size for the function
                    462:      aux entry.  So, we emit a label after the last instruction which can
1.1.1.2 ! root      463:      be used by the .function pseudo op to calculate the function size.  */
1.1       root      464: 
                    465:   char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
                    466:   if (*fname == '*')
                    467:     ++fname;
1.1.1.2 ! root      468:   fprintf (file, "FE..");
1.1       root      469:   ASM_OUTPUT_LABEL (file, fname);
                    470: }
                    471: #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.