summaryrefslogtreecommitdiffstats
path: root/contrib/gcc/xcoffout.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-09-18 05:35:50 +0000
committerpeter <peter@FreeBSD.org>1996-09-18 05:35:50 +0000
commitd4691e641ba47cb86eef80f5c879e13f9d961724 (patch)
tree5b7ea73fc49c8998d9dc87d3eeff5b96439e6856 /contrib/gcc/xcoffout.c
downloadFreeBSD-src-d4691e641ba47cb86eef80f5c879e13f9d961724.zip
FreeBSD-src-d4691e641ba47cb86eef80f5c879e13f9d961724.tar.gz
Import of unmodified (but trimmed) gcc-2.7.2. The bigger parts of the
non-i386, non-unix, and generatable files have been trimmed, but can easily be added in later if needed. gcc-2.7.2.1 will follow shortly, it's a very small delta to this and it's handy to have both available for reference for such little cost. The freebsd-specific changes will then be committed, and once the dust has settled, the bmakefiles will be committed to use this code.
Diffstat (limited to 'contrib/gcc/xcoffout.c')
-rw-r--r--contrib/gcc/xcoffout.c531
1 files changed, 531 insertions, 0 deletions
diff --git a/contrib/gcc/xcoffout.c b/contrib/gcc/xcoffout.c
new file mode 100644
index 0000000..14ebce8
--- /dev/null
+++ b/contrib/gcc/xcoffout.c
@@ -0,0 +1,531 @@
+/* Output xcoff-format symbol table information from GNU compiler.
+ Copyright (C) 1992, 1994, 1995 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, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, 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 "xcoffout.h"
+
+#if defined (USG) || defined (NO_STAB_H)
+#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
+
+/* 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;
+int xcoff_inlining = 0;
+
+/* 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;
+
+/* Last source file name mentioned in a NOTE insn. */
+
+char *xcoff_lastfile;
+
+/* Macro definitions used below. */
+
+#define ABS_OR_RELATIVE_LINENO(LINENO) \
+((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line)
+
+/* Output source line numbers via ".line" rather than ".stabd". */
+#define ASM_OUTPUT_SOURCE_LINE(FILE,LINENUM) \
+ do { \
+ if (xcoff_begin_function_line >= 0) \
+ fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \
+ } while (0)
+
+#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 { \
+ fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \
+ xcoff_begin_function_line = -1; \
+ } while (0)
+
+#define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \
+ fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
+
+#define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \
+ fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM))
+
+/* 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 (DECL_NAME (decl)
+ && strcmp (IDENTIFIER_POINTER (DECL_NAME (decl)), name) == 0)
+ {
+ 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", (TARGET_64BIT ? -31 : -1));
+ assign_type_number (syms, "char", -2);
+ assign_type_number (syms, "short int", -3);
+ assign_type_number (syms, "long int", (TARGET_64BIT ? -31 : -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", (TARGET_64BIT ? -32 : -8));
+ /* No such type "unsigned". */
+ assign_type_number (syms, "long unsigned int", (TARGET_64BIT ? -32 : -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. */
+ assign_type_number (syms, "wchar", -30);
+ assign_type_number (syms, "long long int", -31);
+ assign_type_number (syms, "long long unsigned int", -32);
+ /* Additional Fortran types run from -33 to -37. */
+
+ /* ??? 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;
+
+#ifdef N_MAIN
+ case N_MAIN:
+ UNKNOWN_STAB ("N_MAIN");
+ abort ();
+#endif
+
+ 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 ();
+
+#ifdef N_DSLINE
+ case N_DSLINE:
+ UNKNOWN_STAB ("N_DSLINE");
+ abort ();
+#endif
+
+#ifdef N_BSLINE
+ case N_BSLINE:
+ UNKNOWN_STAB ("N_BSLINE");
+ abort ();
+#endif
+#if 0
+ /* This has the same value as N_BSLINE. */
+ case N_BROWS:
+ UNKNOWN_STAB ("N_BROWS");
+ abort ();
+#endif
+
+#ifdef N_BINCL
+ case N_BINCL:
+ UNKNOWN_STAB ("N_BINCL");
+ abort ();
+#endif
+
+#ifdef N_EINCL
+ case N_EINCL:
+ UNKNOWN_STAB ("N_EINCL");
+ abort ();
+#endif
+
+#ifdef N_EXCL
+ case N_EXCL:
+ UNKNOWN_STAB ("N_EXCL");
+ abort ();
+#endif
+
+ 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 ();
+
+#ifdef N_M2C
+ case N_M2C:
+ UNKNOWN_STAB ("N_M2C");
+ abort ();
+#endif
+
+#ifdef N_SCOPE
+ case N_SCOPE:
+ UNKNOWN_STAB ("N_SCOPE");
+ abort ();
+#endif
+
+ case N_CATCH:
+ UNKNOWN_STAB ("N_CATCH");
+ abort ();
+
+ default:
+ UNKNOWN_STAB ("default");
+ abort ();
+ }
+}
+
+/* Output debugging info to FILE to switch to sourcefile FILENAME.
+ INLINE_P is true if this is from an inlined function. */
+
+void
+xcoffout_source_file (file, filename, inline_p)
+ FILE *file;
+ char *filename;
+ int inline_p;
+{
+ if (filename
+ && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile)
+ || (inline_p && ! xcoff_inlining)
+ || (! inline_p && xcoff_inlining)))
+ {
+ if (xcoff_current_include_file)
+ {
+ fprintf (file, "\t.ei\t");
+ output_quoted_string (file, xcoff_current_include_file);
+ fprintf (file, "\n");
+ xcoff_current_include_file = NULL;
+ }
+ xcoff_inlining=inline_p;
+ if (strcmp (main_input_filename, filename) || inline_p)
+ {
+ fprintf (file, "\t.bi\t");
+ output_quoted_string (file, filename);
+ fprintf (file, "\n");
+ xcoff_current_include_file = filename;
+ }
+
+ xcoff_lastfile = filename;
+ }
+}
+
+/* Output a line number symbol entry into output stream FILE,
+ for source file FILENAME and line number NOTE. */
+
+void
+xcoffout_source_line (file, filename, note)
+ FILE *file;
+ char *filename;
+ rtx note;
+{
+ xcoffout_source_file (file, filename, RTX_INTEGRATED_P (note));
+
+ ASM_OUTPUT_SOURCE_LINE (file, NOTE_LINE_NUMBER (note));
+}
+
+/* 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, NULL_TREE);
+ }
+ 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;
+
+
+ /* The IBM AIX compiler does not emit a .bb for the function level scope,
+ so we avoid it here also. */
+ if (n != 1)
+ 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;
+{
+ if (n != 1)
+ ASM_OUTPUT_LBE (file, line, n);
+}
+
+/* Called at beginning of function (before prologue).
+ Declare function as needed for debugging. */
+
+void
+xcoffout_declare_function (file, decl, name)
+ FILE *file;
+ tree decl;
+ char *name;
+{
+ char *n = name;
+ int i;
+
+ if (*n == '*')
+ n++;
+ else
+ for (i = 0; name[i]; ++i)
+ {
+ if (name[i] == '[')
+ {
+ n = (char *) alloca (i + 1);
+ strncpy (n, name, i);
+ n[i] = '\0';
+ break;
+ }
+ }
+
+ /* Any pending .bi or .ei must occur before the .function pseudo op.
+ Otherwise debuggers will think that the function is in the previous
+ file and/or at the wrong line number. */
+ xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0);
+ dbxout_symbol (decl, 0);
+ fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", n, n, n, 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);
+ dbxout_parms (DECL_ARGUMENTS (current_function_decl));
+ ASM_OUTPUT_SOURCE_LINE (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 pseudo op to calculate the function size. */
+
+ char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0);
+ if (*fname == '*')
+ ++fname;
+ fprintf (file, "FE..");
+ ASM_OUTPUT_LABEL (file, fname);
+}
+#endif /* XCOFF_DEBUGGING_INFO */
OpenPOWER on IntegriCloud