xcoffout.c revision 259065
133965Sjdp/* Output xcoff-format symbol table information from GNU compiler. 233965Sjdp Copyright (C) 1992, 1994, 1995, 1997, 1998, 1999, 2000, 2002, 2003, 2004 333965Sjdp Free Software Foundation, Inc. 433965Sjdp 533965SjdpThis file is part of GCC. 633965Sjdp 733965SjdpGCC is free software; you can redistribute it and/or modify it under 833965Sjdpthe terms of the GNU General Public License as published by the Free 933965SjdpSoftware Foundation; either version 2, or (at your option) any later 1033965Sjdpversion. 1133965Sjdp 1233965SjdpGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1333965SjdpWARRANTY; without even the implied warranty of MERCHANTABILITY or 1433965SjdpFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1533965Sjdpfor more details. 1633965Sjdp 1733965SjdpYou should have received a copy of the GNU General Public License 1833965Sjdpalong with GCC; see the file COPYING. If not, write to the Free 1933965SjdpSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2033965Sjdp02110-1301, USA. */ 2133965Sjdp 2233965Sjdp/* Output xcoff-format symbol table data. The main functionality is contained 2333965Sjdp in dbxout.c. This file implements the sdbout-like parts of the xcoff 2433965Sjdp interface. Many functions are very similar to their counterparts in 2533965Sjdp sdbout.c. */ 2633965Sjdp 2733965Sjdp#include "config.h" 2833965Sjdp#include "system.h" 2933965Sjdp#include "coretypes.h" 3033965Sjdp#include "tm.h" 3133965Sjdp#include "tree.h" 3233965Sjdp#include "rtl.h" 3333965Sjdp#include "flags.h" 3433965Sjdp#include "toplev.h" 3533965Sjdp#include "output.h" 3633965Sjdp#include "ggc.h" 3733965Sjdp#include "target.h" 3833965Sjdp 3933965Sjdp#ifdef XCOFF_DEBUGGING_INFO 4033965Sjdp 4133965Sjdp/* This defines the C_* storage classes. */ 4233965Sjdp#include "xcoff.h" 4333965Sjdp#include "xcoffout.h" 4433965Sjdp#include "dbxout.h" 4533965Sjdp#include "gstab.h" 4633965Sjdp 4733965Sjdp/* Line number of beginning of current function, minus one. 4833965Sjdp Negative means not in a function or not using xcoff. */ 4933965Sjdp 5033965Sjdpstatic int xcoff_begin_function_line = -1; 5133965Sjdpstatic int xcoff_inlining = 0; 5233965Sjdp 5333965Sjdp/* Name of the current include file. */ 5433965Sjdp 5533965Sjdpconst char *xcoff_current_include_file; 5633965Sjdp 5733965Sjdp/* Name of the current function file. This is the file the `.bf' is 5833965Sjdp emitted from. In case a line is emitted from a different file, 5933965Sjdp (by including that file of course), then the line number will be 6033965Sjdp absolute. */ 6133965Sjdp 6233965Sjdpstatic const char *xcoff_current_function_file; 6333965Sjdp 6433965Sjdp/* Names of bss and data sections. These should be unique names for each 6533965Sjdp compilation unit. */ 6633965Sjdp 6733965Sjdpchar *xcoff_bss_section_name; 6833965Sjdpchar *xcoff_private_data_section_name; 6933965Sjdpchar *xcoff_read_only_section_name; 7033965Sjdp 7133965Sjdp/* Last source file name mentioned in a NOTE insn. */ 7233965Sjdp 7333965Sjdpconst char *xcoff_lastfile; 7433965Sjdp 7533965Sjdp/* Macro definitions used below. */ 7633965Sjdp 7733965Sjdp#define ABS_OR_RELATIVE_LINENO(LINENO) \ 7833965Sjdp((xcoff_inlining) ? (LINENO) : (LINENO) - xcoff_begin_function_line) 7933965Sjdp 8033965Sjdp/* Output source line numbers via ".line". */ 8133965Sjdp#define ASM_OUTPUT_LINE(FILE,LINENUM) \ 8233965Sjdp do \ 8333965Sjdp { \ 8433965Sjdp if (xcoff_begin_function_line >= 0) \ 8533965Sjdp fprintf (FILE, "\t.line\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)); \ 8633965Sjdp } \ 8733965Sjdp while (0) 8833965Sjdp 8933965Sjdp#define ASM_OUTPUT_LFB(FILE,LINENUM) \ 9033965Sjdp{ \ 9133965Sjdp if (xcoff_begin_function_line == -1) \ 9233965Sjdp { \ 9333965Sjdp xcoff_begin_function_line = (LINENUM) - 1;\ 9433965Sjdp fprintf (FILE, "\t.bf\t%d\n", (LINENUM)); \ 9533965Sjdp } \ 9633965Sjdp xcoff_current_function_file \ 9733965Sjdp = (xcoff_current_include_file \ 9833965Sjdp ? xcoff_current_include_file : main_input_filename); \ 9933965Sjdp} 10033965Sjdp 10133965Sjdp#define ASM_OUTPUT_LFE(FILE,LINENUM) \ 10233965Sjdp do \ 10333965Sjdp { \ 10433965Sjdp fprintf (FILE, "\t.ef\t%d\n", (LINENUM)); \ 10533965Sjdp xcoff_begin_function_line = -1; \ 10633965Sjdp } \ 10733965Sjdp while (0) 10833965Sjdp 10933965Sjdp#define ASM_OUTPUT_LBB(FILE,LINENUM,BLOCKNUM) \ 11033965Sjdp fprintf (FILE, "\t.bb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) 11133965Sjdp 11233965Sjdp#define ASM_OUTPUT_LBE(FILE,LINENUM,BLOCKNUM) \ 11333965Sjdp fprintf (FILE, "\t.eb\t%d\n", ABS_OR_RELATIVE_LINENO (LINENUM)) 11433965Sjdp 11533965Sjdpstatic void xcoffout_block (tree, int, tree); 11633965Sjdpstatic void xcoffout_source_file (FILE *, const char *, int); 11733965Sjdp 11833965Sjdp/* Support routines for XCOFF debugging info. */ 11933965Sjdp 12033965Sjdpstruct xcoff_type_number 12133965Sjdp{ 12233965Sjdp const char *name; 12333965Sjdp int number; 12433965Sjdp}; 12533965Sjdpstatic const struct xcoff_type_number xcoff_type_numbers[] = { 12633965Sjdp { "int", -1 }, 12733965Sjdp { "char", -2 }, 12833965Sjdp { "short int", -3 }, 12933965Sjdp { "long int", -4 }, /* fiddled to -31 if 64 bits */ 13033965Sjdp { "unsigned char", -5 }, 13133965Sjdp { "signed char", -6 }, 13233965Sjdp { "short unsigned int", -7 }, 13333965Sjdp { "unsigned int", -8 }, 13433965Sjdp /* No such type "unsigned". */ 13533965Sjdp { "long unsigned int", -10 }, /* fiddled to -32 if 64 bits */ 13633965Sjdp { "void", -11 }, 13733965Sjdp { "float", -12 }, 13833965Sjdp { "double", -13 }, 13933965Sjdp { "long double", -14 }, 14033965Sjdp /* Pascal and Fortran types run from -15 to -29. */ 14133965Sjdp { "wchar", -30 }, /* XXX Should be "wchar_t" ? */ 14233965Sjdp { "long long int", -31 }, 14333965Sjdp { "long long unsigned int", -32 }, 14433965Sjdp /* Additional Fortran types run from -33 to -37. */ 14533965Sjdp 14633965Sjdp /* ??? Should also handle built-in C++ and Obj-C types. There perhaps 14733965Sjdp aren't any that C doesn't already have. */ 14833965Sjdp}; 14933965Sjdp 15033965Sjdp/* Returns an XCOFF fundamental type number for DECL (assumed to be a 15133965Sjdp TYPE_DECL), or 0 if dbxout.c should assign a type number normally. */ 15233965Sjdpint 15333965Sjdpxcoff_assign_fundamental_type_number (tree decl) 15433965Sjdp{ 15533965Sjdp const char *name; 15633965Sjdp size_t i; 15733965Sjdp 15833965Sjdp /* Do not waste time searching the list for non-intrinsic types. */ 15933965Sjdp if (DECL_NAME (decl) == 0 || ! DECL_IS_BUILTIN (decl)) 16033965Sjdp return 0; 16133965Sjdp 16233965Sjdp name = IDENTIFIER_POINTER (DECL_NAME (decl)); 16333965Sjdp 16433965Sjdp /* Linear search, blech, but the list is too small to bother 16533965Sjdp doing anything else. */ 16633965Sjdp for (i = 0; i < ARRAY_SIZE (xcoff_type_numbers); i++) 16733965Sjdp if (!strcmp (xcoff_type_numbers[i].name, name)) 16833965Sjdp goto found; 16933965Sjdp return 0; 17033965Sjdp 17133965Sjdp found: 17233965Sjdp /* -4 and -10 should be replaced with -31 and -32, respectively, 17333965Sjdp when used for a 64-bit type. */ 17433965Sjdp if (int_size_in_bytes (TREE_TYPE (decl)) == 8) 17533965Sjdp { 17633965Sjdp if (xcoff_type_numbers[i].number == -4) 17733965Sjdp return -31; 17833965Sjdp if (xcoff_type_numbers[i].number == -10) 17933965Sjdp return -32; 18033965Sjdp } 18133965Sjdp return xcoff_type_numbers[i].number; 18233965Sjdp} 18333965Sjdp 18433965Sjdp/* Print an error message for unrecognized stab codes. */ 18533965Sjdp 18633965Sjdp#define UNKNOWN_STAB(STR) \ 18733965Sjdp internal_error ("no sclass for %s stab (0x%x)", STR, stab) 18833965Sjdp 18933965Sjdp/* Conversion routine from BSD stabs to AIX storage classes. */ 19033965Sjdp 19133965Sjdpint 19233965Sjdpstab_to_sclass (int stab) 19333965Sjdp{ 19433965Sjdp switch (stab) 19533965Sjdp { 19633965Sjdp case N_GSYM: 19733965Sjdp return C_GSYM; 19833965Sjdp 19933965Sjdp case N_FNAME: 20033965Sjdp UNKNOWN_STAB ("N_FNAME"); 20133965Sjdp 20233965Sjdp case N_FUN: 20333965Sjdp return C_FUN; 20433965Sjdp 20533965Sjdp case N_STSYM: 20633965Sjdp case N_LCSYM: 20733965Sjdp return C_STSYM; 20833965Sjdp 20933965Sjdp case N_MAIN: 21033965Sjdp UNKNOWN_STAB ("N_MAIN"); 21133965Sjdp 21233965Sjdp case N_RSYM: 21333965Sjdp return C_RSYM; 21433965Sjdp 21533965Sjdp case N_SSYM: 21633965Sjdp UNKNOWN_STAB ("N_SSYM"); 21733965Sjdp 21833965Sjdp case N_RPSYM: 21933965Sjdp return C_RPSYM; 22033965Sjdp 22133965Sjdp case N_PSYM: 22233965Sjdp return C_PSYM; 22333965Sjdp case N_LSYM: 22433965Sjdp return C_LSYM; 22533965Sjdp case N_DECL: 22633965Sjdp return C_DECL; 22733965Sjdp case N_ENTRY: 22833965Sjdp return C_ENTRY; 22933965Sjdp 23033965Sjdp case N_SO: 23133965Sjdp UNKNOWN_STAB ("N_SO"); 23233965Sjdp 23333965Sjdp case N_SOL: 23433965Sjdp UNKNOWN_STAB ("N_SOL"); 23533965Sjdp 23633965Sjdp case N_SLINE: 23733965Sjdp UNKNOWN_STAB ("N_SLINE"); 23833965Sjdp 23933965Sjdp case N_DSLINE: 24033965Sjdp UNKNOWN_STAB ("N_DSLINE"); 24133965Sjdp 24233965Sjdp case N_BSLINE: 24333965Sjdp UNKNOWN_STAB ("N_BSLINE"); 24433965Sjdp 24533965Sjdp case N_BINCL: 24633965Sjdp UNKNOWN_STAB ("N_BINCL"); 24733965Sjdp 24833965Sjdp case N_EINCL: 24933965Sjdp UNKNOWN_STAB ("N_EINCL"); 25033965Sjdp 25133965Sjdp case N_EXCL: 25233965Sjdp UNKNOWN_STAB ("N_EXCL"); 25333965Sjdp 25433965Sjdp case N_LBRAC: 25533965Sjdp UNKNOWN_STAB ("N_LBRAC"); 25633965Sjdp 25733965Sjdp case N_RBRAC: 25833965Sjdp UNKNOWN_STAB ("N_RBRAC"); 25933965Sjdp 26033965Sjdp case N_BCOMM: 26133965Sjdp return C_BCOMM; 26233965Sjdp case N_ECOMM: 26333965Sjdp return C_ECOMM; 26433965Sjdp case N_ECOML: 26533965Sjdp return C_ECOML; 26633965Sjdp 26733965Sjdp case N_LENG: 26833965Sjdp UNKNOWN_STAB ("N_LENG"); 26933965Sjdp 27033965Sjdp case N_PC: 27133965Sjdp UNKNOWN_STAB ("N_PC"); 27233965Sjdp 27333965Sjdp case N_M2C: 27433965Sjdp UNKNOWN_STAB ("N_M2C"); 27533965Sjdp 27633965Sjdp case N_SCOPE: 27733965Sjdp UNKNOWN_STAB ("N_SCOPE"); 27833965Sjdp 27933965Sjdp case N_CATCH: 28033965Sjdp UNKNOWN_STAB ("N_CATCH"); 28133965Sjdp 28233965Sjdp case N_OPT: 28333965Sjdp UNKNOWN_STAB ("N_OPT"); 28433965Sjdp 28533965Sjdp default: 28633965Sjdp UNKNOWN_STAB ("?"); 28733965Sjdp } 28833965Sjdp} 28933965Sjdp 29033965Sjdp/* Output debugging info to FILE to switch to sourcefile FILENAME. 29133965Sjdp INLINE_P is true if this is from an inlined function. */ 29233965Sjdp 29333965Sjdpstatic void 29433965Sjdpxcoffout_source_file (FILE *file, const char *filename, int inline_p) 29533965Sjdp{ 29633965Sjdp if (filename 29733965Sjdp && (xcoff_lastfile == 0 || strcmp (filename, xcoff_lastfile) 29833965Sjdp || (inline_p && ! xcoff_inlining) 29933965Sjdp || (! inline_p && xcoff_inlining))) 30033965Sjdp { 30133965Sjdp if (xcoff_current_include_file) 30233965Sjdp { 30333965Sjdp fprintf (file, "\t.ei\t"); 30433965Sjdp output_quoted_string (file, xcoff_current_include_file); 30533965Sjdp fprintf (file, "\n"); 30633965Sjdp xcoff_current_include_file = NULL; 30733965Sjdp } 30833965Sjdp xcoff_inlining = inline_p; 30933965Sjdp if (strcmp (main_input_filename, filename) || inline_p) 31033965Sjdp { 31133965Sjdp fprintf (file, "\t.bi\t"); 31233965Sjdp output_quoted_string (file, filename); 31333965Sjdp fprintf (file, "\n"); 31433965Sjdp xcoff_current_include_file = filename; 31533965Sjdp } 31633965Sjdp xcoff_lastfile = filename; 31733965Sjdp } 31833965Sjdp} 31933965Sjdp 32033965Sjdp/* Output a line number symbol entry for location (FILENAME, LINE). */ 32133965Sjdp 32233965Sjdpvoid 32333965Sjdpxcoffout_source_line (unsigned int line, const char *filename) 32433965Sjdp{ 32533965Sjdp bool inline_p = (strcmp (xcoff_current_function_file, filename) != 0 32633965Sjdp || (int) line < xcoff_begin_function_line); 32733965Sjdp 32833965Sjdp xcoffout_source_file (asm_out_file, filename, inline_p); 32933965Sjdp 33033965Sjdp ASM_OUTPUT_LINE (asm_out_file, line); 33133965Sjdp} 33233965Sjdp 33333965Sjdp/* Output the symbols defined in block number DO_BLOCK. 33433965Sjdp 33533965Sjdp This function works by walking the tree structure of blocks, 33633965Sjdp counting blocks until it finds the desired block. */ 33733965Sjdp 33833965Sjdpstatic int do_block = 0; 33933965Sjdp 34033965Sjdpstatic void 34133965Sjdpxcoffout_block (tree block, int depth, tree args) 34233965Sjdp{ 34333965Sjdp while (block) 34433965Sjdp { 34533965Sjdp /* Ignore blocks never expanded or otherwise marked as real. */ 34633965Sjdp if (TREE_USED (block)) 34733965Sjdp { 34833965Sjdp /* When we reach the specified block, output its symbols. */ 34933965Sjdp if (BLOCK_NUMBER (block) == do_block) 35033965Sjdp { 35133965Sjdp /* Output the syms of the block. */ 35233965Sjdp if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) 35333965Sjdp dbxout_syms (BLOCK_VARS (block)); 35433965Sjdp if (args) 35533965Sjdp dbxout_reg_parms (args); 35633965Sjdp 35733965Sjdp /* We are now done with the block. Don't go to inner blocks. */ 35833965Sjdp return; 35933965Sjdp } 36033965Sjdp /* If we are past the specified block, stop the scan. */ 36133965Sjdp else if (BLOCK_NUMBER (block) >= do_block) 36233965Sjdp return; 36333965Sjdp 36433965Sjdp /* Output the subblocks. */ 36533965Sjdp xcoffout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); 36633965Sjdp } 36733965Sjdp block = BLOCK_CHAIN (block); 36833965Sjdp } 36933965Sjdp} 37033965Sjdp 37133965Sjdp/* Describe the beginning of an internal block within a function. 37233965Sjdp Also output descriptions of variables defined in this block. 37333965Sjdp 37433965Sjdp N is the number of the block, by order of beginning, counting from 1, 37533965Sjdp and not counting the outermost (function top-level) block. 37633965Sjdp The blocks match the BLOCKs in DECL_INITIAL (current_function_decl), 37733965Sjdp if the count starts at 0 for the outermost one. */ 37833965Sjdp 37933965Sjdpvoid 38033965Sjdpxcoffout_begin_block (unsigned int line, unsigned int n) 38133965Sjdp{ 38233965Sjdp tree decl = current_function_decl; 38333965Sjdp 38433965Sjdp /* The IBM AIX compiler does not emit a .bb for the function level scope, 38533965Sjdp so we avoid it here also. */ 38633965Sjdp if (n != 1) 38733965Sjdp ASM_OUTPUT_LBB (asm_out_file, line, n); 38833965Sjdp 38933965Sjdp do_block = n; 39033965Sjdp xcoffout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); 39133965Sjdp} 39233965Sjdp 39333965Sjdp/* Describe the end line-number of an internal block within a function. */ 39433965Sjdp 39533965Sjdpvoid 39633965Sjdpxcoffout_end_block (unsigned int line, unsigned int n) 39733965Sjdp{ 39833965Sjdp if (n != 1) 39933965Sjdp ASM_OUTPUT_LBE (asm_out_file, line, n); 40033965Sjdp} 40133965Sjdp 40233965Sjdp/* Called at beginning of function (before prologue). 40333965Sjdp Declare function as needed for debugging. */ 40433965Sjdp 40533965Sjdpvoid 40633965Sjdpxcoffout_declare_function (FILE *file, tree decl, const char *name) 40733965Sjdp{ 40833965Sjdp size_t len; 40933965Sjdp 41033965Sjdp if (*name == '*') 41133965Sjdp name++; 41233965Sjdp len = strlen (name); 41333965Sjdp if (name[len - 1] == ']') 41433965Sjdp { 41533965Sjdp char *n = alloca (len - 3); 41633965Sjdp memcpy (n, name, len - 4); 41733965Sjdp n[len - 4] = '\0'; 41833965Sjdp name = n; 41933965Sjdp } 42033965Sjdp 42133965Sjdp /* Any pending .bi or .ei must occur before the .function pseudo op. 42233965Sjdp Otherwise debuggers will think that the function is in the previous 42333965Sjdp file and/or at the wrong line number. */ 42433965Sjdp xcoffout_source_file (file, DECL_SOURCE_FILE (decl), 0); 42533965Sjdp dbxout_symbol (decl, 0); 42633965Sjdp 42733965Sjdp /* .function NAME, TOP, MAPPING, TYPE, SIZE 42833965Sjdp 16 and 044 are placeholders for backwards compatibility */ 42933965Sjdp fprintf (file, "\t.function .%s,.%s,16,044,FE..%s-.%s\n", 43033965Sjdp name, name, name, name); 43133965Sjdp} 43233965Sjdp 43333965Sjdp/* Called at beginning of function body (at start of prologue). 43433965Sjdp Record the function's starting line number, so we can output 43533965Sjdp relative line numbers for the other lines. 43633965Sjdp Record the file name that this function is contained in. */ 43733965Sjdp 43833965Sjdpvoid 43933965Sjdpxcoffout_begin_prologue (unsigned int line, 44033965Sjdp const char *file ATTRIBUTE_UNUSED) 44133965Sjdp{ 44233965Sjdp ASM_OUTPUT_LFB (asm_out_file, line); 44333965Sjdp dbxout_parms (DECL_ARGUMENTS (current_function_decl)); 44433965Sjdp 44533965Sjdp /* Emit the symbols for the outermost BLOCK's variables. sdbout.c does this 44633965Sjdp in sdbout_begin_block, but there is no guarantee that there will be any 44733965Sjdp inner block 1, so we must do it here. This gives a result similar to 44833965Sjdp dbxout, so it does make some sense. */ 44933965Sjdp do_block = BLOCK_NUMBER (DECL_INITIAL (current_function_decl)); 45033965Sjdp xcoffout_block (DECL_INITIAL (current_function_decl), 0, 45133965Sjdp DECL_ARGUMENTS (current_function_decl)); 45233965Sjdp 45333965Sjdp ASM_OUTPUT_LINE (asm_out_file, line); 45433965Sjdp} 45533965Sjdp 45633965Sjdp/* Called at end of function (before epilogue). 45733965Sjdp Describe end of outermost block. */ 45833965Sjdp 45933965Sjdpvoid 46033965Sjdpxcoffout_end_function (unsigned int last_linenum) 46133965Sjdp{ 46233965Sjdp ASM_OUTPUT_LFE (asm_out_file, last_linenum); 46333965Sjdp} 46433965Sjdp 46533965Sjdp/* Output xcoff info for the absolute end of a function. 46633965Sjdp Called after the epilogue is output. */ 46733965Sjdp 46833965Sjdpvoid 46933965Sjdpxcoffout_end_epilogue (unsigned int line ATTRIBUTE_UNUSED, 47033965Sjdp const char *file ATTRIBUTE_UNUSED) 47133965Sjdp{ 47233965Sjdp /* We need to pass the correct function size to .function, otherwise, 47333965Sjdp the xas assembler can't figure out the correct size for the function 47433965Sjdp aux entry. So, we emit a label after the last instruction which can 47533965Sjdp be used by the .function pseudo op to calculate the function size. */ 47633965Sjdp 47733965Sjdp const char *fname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); 47833965Sjdp if (*fname == '*') 47933965Sjdp ++fname; 48033965Sjdp fprintf (asm_out_file, "FE.."); 48133965Sjdp ASM_OUTPUT_LABEL (asm_out_file, fname); 48233965Sjdp} 48333965Sjdp#endif /* XCOFF_DEBUGGING_INFO */ 48433965Sjdp