diff options
author | Michael Meissner <meissner@gcc.gnu.org> | 1992-03-11 22:24:26 +0000 |
---|---|---|
committer | Michael Meissner <meissner@gcc.gnu.org> | 1992-03-11 22:24:26 +0000 |
commit | 265cc84ad124940778dd69dd9b3d8632c43363a9 (patch) | |
tree | 7ad603bbe9791a5b5a390f58a41f5e00ae7e4934 /gcc | |
parent | ad3f8945c508a5eb8ef07d9056482efef4f29887 (diff) | |
download | gcc-265cc84ad124940778dd69dd9b3d8632c43363a9.zip gcc-265cc84ad124940778dd69dd9b3d8632c43363a9.tar.gz gcc-265cc84ad124940778dd69dd9b3d8632c43363a9.tar.bz2 |
Initial revision
From-SVN: r443
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/xcoffout.c | 444 |
1 files changed, 444 insertions, 0 deletions
diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c new file mode 100644 index 0000000..1adbb7a --- /dev/null +++ b/gcc/xcoffout.c @@ -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; + +/* 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) + +/* 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 */ |