X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fxcoffout.c;h=326a6927c7532b0bcc9c4e2fa668003918f9066a;hp=1416708ccaecb9f307ff7a5ce31fdb5e4fddde38;hb=e783c30e5a75676e144f25efeaaad46f28f1378e;hpb=aa331680a5dd7c00b18b97fcb9a17b7f482f484d diff --git a/gcc/xcoffout.c b/gcc/xcoffout.c index 1416708ccae..326a6927c75 100644 --- a/gcc/xcoffout.c +++ b/gcc/xcoffout.c @@ -1,5 +1,6 @@ /* Output xcoff-format symbol table information from GNU compiler. - Copyright (C) 1992 Free Software Foundation, Inc. + Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -15,55 +16,47 @@ 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. */ - +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 - #include "config.h" +#include "system.h" #include "tree.h" #include "rtl.h" #include "flags.h" +#include "toplev.h" +#include "output.h" +#include "ggc.h" #ifdef XCOFF_DEBUGGING_INFO /* This defines the C_* storage classes. */ -#include - +#include "dbxstclass.h" #include "xcoffout.h" - -#if defined (USG) || defined (NO_STAB_H) +#include "dbxout.h" #include "gstab.h" -#else -#include - -/* 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; +static int xcoff_begin_function_line = -1; +static int xcoff_inlining = 0; /* Name of the current include file. */ -char *xcoff_current_include_file; +const 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; +static const char *xcoff_current_function_file; /* Names of bss and data sections. These should be unique names for each compilation unit. */ @@ -71,9 +64,23 @@ char *xcoff_current_function_file; 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. */ + +const 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) \ @@ -97,6 +104,10 @@ char *xcoff_read_only_section_name; #define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \ fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) + +static void assign_type_number PARAMS ((tree, const char *, int)); +static void xcoffout_block PARAMS ((tree, int, tree)); +static void xcoffout_source_file PARAMS ((FILE *, const char *, int)); /* Support routines for XCOFF debugging info. */ @@ -106,7 +117,7 @@ char *xcoff_read_only_section_name; static void assign_type_number (syms, name, number) tree syms; - char *name; + const char *name; int number; { tree decl; @@ -132,22 +143,22 @@ xcoff_output_standard_types (syms) 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, "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", -8); /* No such type "unsigned". */ - assign_type_number (syms, "long unsigned int", -10); + 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. */ - /* 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. */ + 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. */ @@ -156,10 +167,7 @@ xcoff_output_standard_types (syms) /* 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) + internal_error ("No sclass for %s stab (0x%x)\n", STR, stab) /* Conversion routine from BSD stabs to AIX storage classes. */ @@ -173,8 +181,7 @@ stab_to_sclass (stab) return C_GSYM; case N_FNAME: - UNKNOWN_STAB ("N_FNAME"); - abort(); + UNKNOWN_STAB ("N_FNAME"); case N_FUN: return C_FUN; @@ -183,18 +190,14 @@ stab_to_sclass (stab) case N_LCSYM: return C_STSYM; -#ifdef N_MAIN case N_MAIN: - UNKNOWN_STAB ("N_MAIN"); - abort (); -#endif + UNKNOWN_STAB ("N_MAIN"); case N_RSYM: return C_RSYM; case N_SSYM: - UNKNOWN_STAB ("N_SSYM"); - abort (); + UNKNOWN_STAB ("N_SSYM"); case N_RPSYM: return C_RPSYM; @@ -209,60 +212,34 @@ stab_to_sclass (stab) return C_ENTRY; case N_SO: - UNKNOWN_STAB ("N_SO"); - abort (); + UNKNOWN_STAB ("N_SO"); case N_SOL: - UNKNOWN_STAB ("N_SOL"); - abort (); + UNKNOWN_STAB ("N_SOL"); case N_SLINE: - UNKNOWN_STAB ("N_SLINE"); - abort (); + UNKNOWN_STAB ("N_SLINE"); -#ifdef N_DSLINE case N_DSLINE: - UNKNOWN_STAB ("N_DSLINE"); - abort (); -#endif + UNKNOWN_STAB ("N_DSLINE"); -#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 + UNKNOWN_STAB ("N_BSLINE"); + case N_BINCL: - UNKNOWN_STAB ("N_BINCL"); - abort (); -#endif + UNKNOWN_STAB ("N_BINCL"); -#ifdef N_EINCL case N_EINCL: - UNKNOWN_STAB ("N_EINCL"); - abort (); -#endif + UNKNOWN_STAB ("N_EINCL"); -#ifdef N_EXCL case N_EXCL: - UNKNOWN_STAB ("N_EXCL"); - abort (); -#endif + UNKNOWN_STAB ("N_EXCL"); case N_LBRAC: - UNKNOWN_STAB ("N_LBRAC"); - abort (); + UNKNOWN_STAB ("N_LBRAC"); case N_RBRAC: - UNKNOWN_STAB ("N_RBRAC"); - abort (); + UNKNOWN_STAB ("N_RBRAC"); case N_BCOMM: return C_BCOMM; @@ -272,58 +249,82 @@ stab_to_sclass (stab) return C_ECOML; case N_LENG: - UNKNOWN_STAB ("N_LENG"); - abort (); + UNKNOWN_STAB ("N_LENG"); case N_PC: - UNKNOWN_STAB ("N_PC"); - abort (); + UNKNOWN_STAB ("N_PC"); -#ifdef N_M2C case N_M2C: - UNKNOWN_STAB ("N_M2C"); - abort (); -#endif + UNKNOWN_STAB ("N_M2C"); -#ifdef N_SCOPE case N_SCOPE: - UNKNOWN_STAB ("N_SCOPE"); - abort (); -#endif + UNKNOWN_STAB ("N_SCOPE"); case N_CATCH: - UNKNOWN_STAB ("N_CATCH"); - abort (); + UNKNOWN_STAB ("N_CATCH"); + + case N_OPT: + UNKNOWN_STAB ("N_OPT"); default: - UNKNOWN_STAB ("default"); - abort (); - } + UNKNOWN_STAB ("?"); + } +} + +/* Output debugging info to FILE to switch to sourcefile FILENAME. + INLINE_P is true if this is from an inlined function. */ + +static void +xcoffout_source_file (file, filename, inline_p) + FILE *file; + const 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; + } } -/* 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. */ +/* Output a line number symbol entry into output stream FILE, + for source file FILENAME and line number NOTE. */ void -xcoffout_output_first_source_line (file, last_linenum) +xcoffout_source_line (file, filename, note) FILE *file; - int last_linenum; + const char *filename; + rtx note; { - ASM_OUTPUT_LFB (file, last_linenum); - dbxout_parms (DECL_ARGUMENTS (current_function_decl)); - ASM_OUTPUT_SOURCE_LINE (file, last_linenum); -} + 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; @@ -336,7 +337,7 @@ xcoffout_block (block, depth, args) if (TREE_USED (block)) { /* When we reach the specified block, output its symbols. */ - if (next_block_number == do_block) + if (BLOCK_NUMBER (block) == do_block) { /* Output the syms of the block. */ if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) @@ -348,11 +349,9 @@ xcoffout_block (block, depth, args) return; } /* If we are past the specified block, stop the scan. */ - else if (next_block_number >= do_block) + else if (BLOCK_NUMBER (block) >= do_block) return; - next_block_number++; - /* Output the subblocks. */ xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); } @@ -376,14 +375,12 @@ xcoffout_begin_block (file, line, 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)); } @@ -406,28 +403,35 @@ void xcoffout_declare_function (file, decl, name) FILE *file; tree decl; - char *name; + const char *name; { - char *n = name; int i; - for (i = 0; name[i]; ++i) - { - if (name[i] == '[') - { - n = (char *) alloca (i + 1); - strncpy (n, name, i); - n[i] = '\0'; - break; - } - } + if (*name == '*') + name++; + else + for (i = 0; name[i]; ++i) + { + if (name[i] == '[') + { + char *n = (char *) alloca (i + 1); + strncpy (n, name, i); + n[i] = '\0'; + name = n; + break; + } + } - /* Any pending .bi or .ei must occur before the .function psuedo op. + /* 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. */ - dbxout_source_file (file, DECL_SOURCE_FILE (decl)); + 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); + + /* .function NAME, TOP, MAPPING, TYPE, SIZE + 16 and 044 are placeholders for backwards compatibility */ + fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", + name, name, name, name); } /* Called at beginning of function body (after prologue). @@ -441,6 +445,17 @@ xcoffout_begin_function (file, last_linenum) int last_linenum; { ASM_OUTPUT_LFB (file, last_linenum); + dbxout_parms (DECL_ARGUMENTS (current_function_decl)); + + /* Emit the symbols for the outermost BLOCK's variables. sdbout.c does this + in sdbout_begin_block, but there is no guarantee that there will be any + inner block 1, so we must do it here. This gives a result similar to + dbxout, so it does make some sense. */ + do_block = BLOCK_NUMBER (DECL_INITIAL (current_function_decl)); + xcoffout_block (DECL_INITIAL (current_function_decl), 0, + DECL_ARGUMENTS (current_function_decl)); + + ASM_OUTPUT_SOURCE_LINE (file, last_linenum); } /* Called at end of function (before epilogue). @@ -466,7 +481,7 @@ xcoffout_end_epilogue (file) 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); + const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); if (*fname == '*') ++fname; fprintf (file, "FE..");