Annotation of gcc/xcoffout.c, revision 1.1

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

unix.superglobalmegacorp.com

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