]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Initial revision
authorMichael Meissner <meissner@gcc.gnu.org>
Wed, 11 Mar 1992 22:24:26 +0000 (22:24 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Wed, 11 Mar 1992 22:24:26 +0000 (22:24 +0000)
From-SVN: r443

gcc/xcoffout.c [new file with mode: 0644]

diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c
new file mode 100644 (file)
index 0000000..1adbb7a
--- /dev/null
@@ -0,0 +1,444 @@
+/* Output xcoff-format symbol table information from GNU compiler.
+   Copyright (C) 1992 Free Software Foundation, Inc.
+
+This file is part of GNU CC.
+
+GNU CC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU CC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU CC; see the file COPYING.  If not, write to
+the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+
+/* Output xcoff-format symbol table data.  The main functionality is contained
+   in dbxout.c.  This file implements the sdbout-like parts of the xcoff
+   interface.  Many functions are very similar to their counterparts in
+   sdbout.c.  */
+
+/* Include this first, because it may define MIN and MAX.  */
+#include <stdio.h>
+
+#include "config.h"
+#include "tree.h"
+#include "rtl.h"
+#include "flags.h"
+
+#ifdef XCOFF_DEBUGGING_INFO
+
+/* This defines the C_* storage classes.  */
+#include <dbxstclass.h>
+
+#include "xcoff.h"
+
+#ifdef USG
+#include "gstab.h"
+#else
+#include <stab.h>
+
+/* This is a GNU extension we need to reference in this file.  */
+#ifndef N_CATCH
+#define N_CATCH 0x54
+#endif
+#endif
+
+/* These are GNU extensions we need to reference in this file.  */
+#ifndef N_DSLINE
+#define N_DSLINE 0x46
+#endif
+#ifndef N_BSLINE
+#define N_BSLINE 0x48
+#endif
+
+/* Line number of beginning of current function, minus one.
+   Negative means not in a function or not using xcoff.  */
+
+int xcoff_begin_function_line = -1;
+
+/* Name of the current include file.  */
+
+char *xcoff_current_include_file;
+
+/* Name of the current function file.  This is the file the `.bf' is
+   emitted from.  In case a line is emitted from a different file,
+   (by including that file of course), then the line number will be
+   absolute.  */
+
+char *xcoff_current_function_file;
+
+/* Names of bss and data sections.  These should be unique names for each
+   compilation unit.  */
+
+char *xcoff_bss_section_name;
+char *xcoff_private_data_section_name;
+char *xcoff_read_only_section_name;
+\f
+/* Macro definitions used below.  */
+/* Ensure we don't output a negative line number.  */
+#define MAKE_LINE_SAFE(LINE)  \
+  if (LINE <= xcoff_begin_function_line)       \
+    LINE = xcoff_begin_function_line + 1       \
+
+#define ASM_OUTPUT_LFB(FILE,LINENUM) \
+{                                              \
+  if (xcoff_begin_function_line == -1)         \
+    {                                          \
+      xcoff_begin_function_line = (LINENUM) - 1;\
+      fprintf (FILE, "\t.bf\t%d\n", (LINENUM));        \
+    }                                          \
+  xcoff_current_function_file                  \
+    = (xcoff_current_include_file              \
+       ? xcoff_current_include_file : main_input_filename); \
+}
+
+#define ASM_OUTPUT_LFE(FILE,LINENUM) \
+  do {                                         \
+    int linenum = LINENUM;                             \
+    MAKE_LINE_SAFE (linenum);                  \
+    fprintf (FILE, "\t.ef\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
+    xcoff_begin_function_line = -1;            \
+  } while (0)
+
+#define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
+  do {                                         \
+    int linenum = LINENUM;                             \
+    MAKE_LINE_SAFE (linenum);                  \
+    fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
+  } while (0)
+
+#define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
+  do {                                         \
+    int linenum = LINENUM;                             \
+    MAKE_LINE_SAFE (linenum);                  \
+    fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (linenum)); \
+  } while (0)
+\f
+/* Support routines for XCOFF debugging info.  */
+
+/* Assign NUMBER as the stabx type number for the type described by NAME.
+   Search all decls in the list SYMS to find the type NAME.  */
+
+static void
+assign_type_number (syms, name, number)
+     tree syms;
+     char *name;
+     int number;
+{
+  tree decl;
+
+  for (decl = syms; decl; decl = TREE_CHAIN (decl))
+    if (!strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name))
+      {
+       TREE_ASM_WRITTEN (decl) = 1;
+       TYPE_SYMTAB_ADDRESS (TREE_TYPE (decl)) = number;
+      }
+}
+
+/* Setup gcc primitive types to use the XCOFF built-in type numbers where
+   possible.  */
+
+void
+xcoff_output_standard_types (syms)
+     tree syms;
+{
+  /* Handle built-in C types here.  */
+
+  assign_type_number (syms, "int", -1);
+  assign_type_number (syms, "char", -2);
+  assign_type_number (syms, "short int", -3);
+  assign_type_number (syms, "long int", -4);
+  assign_type_number (syms, "unsigned char", -5);
+  assign_type_number (syms, "signed char", -6);
+  assign_type_number (syms, "short unsigned int", -7);
+  assign_type_number (syms, "unsigned int", -8);
+  /* No such type "unsigned".  */
+  assign_type_number (syms, "long unsigned int", -10);
+  assign_type_number (syms, "void", -11);
+  assign_type_number (syms, "float", -12);
+  assign_type_number (syms, "double", -13);
+  assign_type_number (syms, "long double", -14);
+  /* Pascal and Fortran types run from -15 to -29.  */
+  /* No such type "wchar".  */
+
+  /* "long long int", and "long long unsigned int", are not handled here,
+     because there are no predefined types that match them.  */
+
+  /* ??? Should also handle built-in C++ and Obj-C types.  There perhaps
+     aren't any that C doesn't already have.  */
+}
+
+/* Print an error message for unrecognized stab codes.  */
+
+#define UNKNOWN_STAB(STR)      \
+   do { \
+     fprintf(stderr, "Error, unknown stab %s: : 0x%x\n", STR, stab); \
+     fflush (stderr);  \
+   } while (0)
+
+/* Conversion routine from BSD stabs to AIX storage classes.  */
+
+int
+stab_to_sclass (stab)
+     int stab;
+{
+  switch (stab)
+    {
+    case N_GSYM:
+      return C_GSYM;
+
+    case N_FNAME:
+      UNKNOWN_STAB ("N_FNAME"); 
+      abort();
+
+    case N_FUN:
+      return C_FUN;
+
+    case N_STSYM:
+    case N_LCSYM:
+      return C_STSYM;
+
+    case N_MAIN:
+      UNKNOWN_STAB ("N_MAIN"); 
+      abort ();
+
+    case N_RSYM:
+      return C_RSYM;
+
+    case N_SSYM:
+      UNKNOWN_STAB ("N_SSYM"); 
+      abort ();
+
+    case N_RPSYM:
+      return C_RPSYM;
+
+    case N_PSYM:
+      return C_PSYM;
+    case N_LSYM:
+      return C_LSYM;
+    case N_DECL:
+      return C_DECL;
+    case N_ENTRY:
+      return C_ENTRY;
+
+    case N_SO:
+      UNKNOWN_STAB ("N_SO"); 
+      abort ();
+
+    case N_SOL:
+      UNKNOWN_STAB ("N_SOL"); 
+      abort ();
+
+    case N_SLINE:
+      UNKNOWN_STAB ("N_SLINE"); 
+      abort ();
+
+    case N_DSLINE:
+      UNKNOWN_STAB ("N_DSLINE"); 
+      abort ();
+
+    case N_BSLINE:
+      UNKNOWN_STAB ("N_BSLINE"); 
+      abort ();
+#if 0
+      /* This has the same value as N_BSLINE.  */
+    case N_BROWS:
+      UNKNOWN_STAB ("N_BROWS"); 
+      abort ();
+#endif
+
+    case N_BINCL:
+      UNKNOWN_STAB ("N_BINCL"); 
+      abort ();
+
+    case N_EINCL:
+      UNKNOWN_STAB ("N_EINCL"); 
+      abort ();
+
+    case N_EXCL:
+      UNKNOWN_STAB ("N_EXCL"); 
+      abort ();
+
+    case N_LBRAC:
+      UNKNOWN_STAB ("N_LBRAC"); 
+      abort ();
+
+    case N_RBRAC:
+      UNKNOWN_STAB ("N_RBRAC"); 
+      abort ();
+
+    case N_BCOMM:
+      return C_BCOMM;
+    case N_ECOMM:
+      return C_ECOMM;
+    case N_ECOML:
+      return C_ECOML;
+
+    case N_LENG:
+      UNKNOWN_STAB ("N_LENG"); 
+      abort ();
+
+    case N_PC:
+      UNKNOWN_STAB ("N_PC"); 
+      abort ();
+
+    case N_M2C:
+      UNKNOWN_STAB ("N_M2C"); 
+      abort ();
+
+    case N_SCOPE:
+      UNKNOWN_STAB ("N_SCOPE"); 
+      abort ();
+
+    case N_CATCH:
+      UNKNOWN_STAB ("N_CATCH"); 
+      abort ();
+
+    default:
+      UNKNOWN_STAB ("default"); 
+      abort ();
+  }
+}
+
+/* In XCOFF, we have to have this .bf before the function prologue.
+   Rely on the value of `dbx_begin_function_line' not to duplicate .bf.  */
+
+void
+xcoffout_output_first_source_line (file, last_linenum)
+     FILE *file;
+     int last_linenum;
+{
+  ASM_OUTPUT_LFB (file, last_linenum);
+  dbxout_parms (DECL_ARGUMENTS (current_function_decl));
+  ASM_OUTPUT_SOURCE_LINE (file, last_linenum);
+}
+
+/* Output the symbols defined in block number DO_BLOCK.
+   Set NEXT_BLOCK_NUMBER to 0 before calling.
+
+   This function works by walking the tree structure of blocks,
+   counting blocks until it finds the desired block.  */
+
+static int do_block = 0;
+
+static int next_block_number;
+
+static void
+xcoffout_block (block, depth, args)
+     register tree block;
+     int depth;
+     tree args;
+{
+  while (block)
+    {
+      /* Ignore blocks never expanded or otherwise marked as real.  */
+      if (TREE_USED (block))
+       {
+         /* When we reach the specified block, output its symbols.  */
+         if (next_block_number == do_block)
+           {
+             /* Output the syms of the block.  */
+             if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
+               dbxout_syms (BLOCK_VARS (block));
+             if (args)
+               dbxout_reg_parms (args);
+
+             /* We are now done with the block.  Don't go to inner blocks.  */
+             return;
+           }
+         /* If we are past the specified block, stop the scan.  */
+         else if (next_block_number >= do_block)
+           return;
+
+         next_block_number++;
+
+         /* Output the subblocks.  */
+         xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, 0);
+       }
+      block = BLOCK_CHAIN (block);
+    }
+}
+
+/* Describe the beginning of an internal block within a function.
+   Also output descriptions of variables defined in this block.
+
+   N is the number of the block, by order of beginning, counting from 1,
+   and not counting the outermost (function top-level) block.
+   The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
+   if the count starts at 0 for the outermost one.  */
+
+void
+xcoffout_begin_block (file, line, n)
+     FILE *file;
+     int line;
+     int n;
+{
+  tree decl = current_function_decl;
+
+  ASM_OUTPUT_LBB (file, line, n);
+
+  do_block = n;
+  next_block_number = 0;
+  xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
+}
+
+/* Describe the end line-number of an internal block within a function.  */
+
+void
+xcoffout_end_block (file, line, n)
+     FILE *file;
+     int line;
+     int n;
+{
+  ASM_OUTPUT_LBE (file, line, n);
+}
+
+/* Called at beginning of function body (after prologue).
+   Record the function's starting line number, so we can output
+   relative line numbers for the other lines.
+   Record the file name that this function is contained in.  */
+
+void
+xcoffout_begin_function (file, last_linenum)
+     FILE *file;
+     int last_linenum;
+{
+  ASM_OUTPUT_LFB (file, last_linenum);
+}
+
+/* Called at end of function (before epilogue).
+   Describe end of outermost block.  */
+
+void
+xcoffout_end_function (file, last_linenum)
+     FILE *file;
+     int last_linenum;
+{
+  ASM_OUTPUT_LFE (file, last_linenum);
+}
+
+/* Output xcoff info for the absolute end of a function.
+   Called after the epilogue is output.  */
+
+void
+xcoffout_end_epilogue (file)
+     FILE *file;
+{
+  /* We need to pass the correct function size to .function, otherwise,
+     the xas assembler can't figure out the correct size for the function
+     aux entry.  So, we emit a label after the last instruction which can
+     be used by the .function psuedo op to calculate the function size.  */
+
+  char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+  if (*fname == '*')
+    ++fname;
+  fprintf (file, "L..end_");
+  ASM_OUTPUT_LABEL (file, fname);
+}
+#endif /* XCOFF_DEBUGGING_INFO */