dbxout.c

来自「GCC编译器源代码」· C语言 代码 · 共 2,183 行 · 第 1/5 页

C
2,183
字号
/* Output dbx-format symbol table information from GNU compiler.   Copyright (C) 1987, 88, 92-96, 1997 Free Software Foundation, Inc.This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe 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 ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING.  If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA.  *//* Output dbx-format symbol table data.   This consists of many symbol table entries, each of them   a .stabs assembler pseudo-op with four operands:   a "name" which is really a description of one symbol and its type,   a "code", which is a symbol defined in stab.h whose name starts with N_,   an unused operand always 0,   and a "value" which is an address or an offset.   The name is enclosed in doublequote characters.   Each function, variable, typedef, and structure tag   has a symbol table entry to define it.   The beginning and end of each level of name scoping within   a function are also marked by special symbol table entries.   The "name" consists of the symbol name, a colon, a kind-of-symbol letter,   and a data type number.  The data type number may be followed by   "=" and a type definition; normally this will happen the first time   the type number is mentioned.  The type definition may refer to   other types by number, and those type numbers may be followed   by "=" and nested definitions.   This can make the "name" quite long.   When a name is more than 80 characters, we split the .stabs pseudo-op   into two .stabs pseudo-ops, both sharing the same "code" and "value".   The first one is marked as continued with a double-backslash at the   end of its "name".   The kind-of-symbol letter distinguished function names from global   variables from file-scope variables from parameters from auto   variables in memory from typedef names from register variables.   See `dbxout_symbol'.   The "code" is mostly redundant with the kind-of-symbol letter   that goes in the "name", but not entirely: for symbols located   in static storage, the "code" says which segment the address is in,   which controls how it is relocated.   The "value" for a symbol in static storage   is the core address of the symbol (actually, the assembler   label for the symbol).  For a symbol located in a stack slot   it is the stack offset; for one in a register, the register number.   For a typedef symbol, it is zero.   If DEBUG_SYMS_TEXT is defined, all debugging symbols must be   output while in the text section.   For more on data type definitions, see `dbxout_type'.  */#include "config.h"#include <stdio.h>#include <errno.h>#include "tree.h"#include "rtl.h"#include "flags.h"#include "regs.h"#include "insn-config.h"#include "reload.h"#include "defaults.h"#include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions.  */#ifndef errnoextern int errno;#endif#ifdef XCOFF_DEBUGGING_INFO#include "xcoffout.h"#endif#ifndef ASM_STABS_OP#define ASM_STABS_OP ".stabs"#endif#ifndef ASM_STABN_OP#define ASM_STABN_OP ".stabn"#endif#ifndef DBX_TYPE_DECL_STABS_CODE#define DBX_TYPE_DECL_STABS_CODE N_LSYM#endif#ifndef DBX_STATIC_CONST_VAR_CODE#define DBX_STATIC_CONST_VAR_CODE N_FUN#endif#ifndef DBX_REGPARM_STABS_CODE#define DBX_REGPARM_STABS_CODE N_RSYM#endif#ifndef DBX_REGPARM_STABS_LETTER#define DBX_REGPARM_STABS_LETTER 'P'#endif/* This is used for parameters passed by invisible reference in a register.  */#ifndef GDB_INV_REF_REGPARM_STABS_LETTER#define GDB_INV_REF_REGPARM_STABS_LETTER 'a'#endif#ifndef DBX_MEMPARM_STABS_LETTER#define DBX_MEMPARM_STABS_LETTER 'p'#endif#ifndef FILE_NAME_JOINER#define FILE_NAME_JOINER "/"#endif/* Nonzero means if the type has methods, only output debugging   information if methods are actually written to the asm file.  This   optimization only works if the debugger can detect the special C++   marker.  */#define MINIMAL_DEBUG 1#ifdef NO_DOLLAR_IN_LABEL#ifdef NO_DOT_IN_LABEL#undef MINIMAL_DEBUG#define MINIMAL_DEBUG 0#endif#endifstatic int flag_minimal_debug = MINIMAL_DEBUG;/* Nonzero if we have actually used any of the GDB extensions   to the debugging format.  The idea is that we use them for the   first time only if there's a strong reason, but once we have done that,   we use them whenever convenient.  */static int have_used_extensions = 0;/* Number for the next N_SOL filename stabs label.  The number 0 is reserved   for the N_SO filename stabs label.  */static int source_label_number = 1;static int scope_labelno = 0;char *getpwd ();/* Typical USG systems don't have stab.h, and they also have   no use for DBX-format debugging info.  */#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)#ifdef DEBUG_SYMS_TEXT#define FORCE_TEXT text_section ();#else#define FORCE_TEXT#endif#if defined (USG) || defined (NO_STAB_H) || defined (CROSS_COMPILE)#include "gstab.h"  /* If doing DBX on sysV, use our own stab.h.  */#else#include <stab.h>  /* On BSD, use the system's stab.h.  *//* This is a GNU extension we need to reference in this file.  */#ifndef N_CATCH#define N_CATCH 0x54#endif#endif /* not USG */#ifdef __GNU_STAB__#define STAB_CODE_TYPE enum __stab_debug_code#else#define STAB_CODE_TYPE int#endif/* 1 if PARM is passed to this function in memory.  */#define PARM_PASSED_IN_MEMORY(PARM) \ (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)/* A C expression for the integer offset value of an automatic variable   (N_LSYM) having address X (an RTX).  */#ifndef DEBUGGER_AUTO_OFFSET#define DEBUGGER_AUTO_OFFSET(X) \  (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)#endif/* A C expression for the integer offset value of an argument (N_PSYM)   having address X (an RTX).  The nominal offset is OFFSET.  */#ifndef DEBUGGER_ARG_OFFSET#define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)#endif/* Stream for writing to assembler file.  */static FILE *asmfile;/* Last source file name mentioned in a NOTE insn.  */static char *lastfile;/* Current working directory.  */static char *cwd;enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};/* Structure recording information about a C data type.   The status element says whether we have yet output   the definition of the type.  TYPE_XREF says we have   output it as a cross-reference only.   The file_number and type_number elements are used if DBX_USE_BINCL   is defined.  */struct typeinfo{  enum typestatus status;#ifdef DBX_USE_BINCL  int file_number;  int type_number;#endif};/* Vector recording information about C data types.   When we first notice a data type (a tree node),   we assign it a number using next_type_number.   That is its index in this vector.  */struct typeinfo *typevec;/* Number of elements of space allocated in `typevec'.  */static int typevec_len;/* In dbx output, each type gets a unique number.   This is the number for the next type output.   The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field.  */static int next_type_number;#ifdef DBX_USE_BINCL/* When using N_BINCL in dbx output, each type number is actually a   pair of the file number and the type number within the file.   This is a stack of input files.  */struct dbx_file{  struct dbx_file *next;  int file_number;  int next_type_number;};/* This is the top of the stack.  */static struct dbx_file *current_file;/* This is the next file number to use.  */static int next_file_number;#endif /* DBX_USE_BINCL *//* In dbx output, we must assign symbol-blocks id numbers   in the order in which their beginnings are encountered.   We output debugging info that refers to the beginning and   end of the ranges of code in each block   with assembler labels LBBn and LBEn, where n is the block number.   The labels are generated in final, which assigns numbers to the   blocks in the same way.  */static int next_block_number;/* These variables are for dbxout_symbol to communicate to   dbxout_finish_symbol.   current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.   current_sym_value and current_sym_addr are two ways to address the   value to store in the symtab entry.   current_sym_addr if nonzero represents the value as an rtx.   If that is zero, current_sym_value is used.  This is used   when the value is an offset (such as for auto variables,   register variables and parms).  */static STAB_CODE_TYPE current_sym_code;static int current_sym_value;static rtx current_sym_addr;/* Number of chars of symbol-description generated so far for the   current symbol.  Used by CHARS and CONTIN.  */static int current_sym_nchars;/* Report having output N chars of the current symbol-description.  */#define CHARS(N) (current_sym_nchars += (N))/* Break the current symbol-description, generating a continuation,   if it has become long.  */#ifndef DBX_CONTIN_LENGTH#define DBX_CONTIN_LENGTH 80#endif#if DBX_CONTIN_LENGTH > 0#define CONTIN  \  do {if (current_sym_nchars > DBX_CONTIN_LENGTH) dbxout_continue ();} while (0)#else#define CONTIN#endifvoid dbxout_types ();void dbxout_args ();void dbxout_symbol ();static void dbxout_function_end		PROTO((void));static void dbxout_typedefs		PROTO((tree));static void dbxout_type_index		PROTO((tree));static void dbxout_continue		PROTO((void));static void dbxout_type_fields		PROTO((tree));static void dbxout_type_method_1	PROTO((tree, char *));static void dbxout_type_methods		PROTO((tree));static void dbxout_range_type		PROTO((tree));static void dbxout_type			PROTO((tree, int, int));static void print_int_cst_octal		PROTO((tree));static void print_octal			PROTO((unsigned HOST_WIDE_INT, int));static void dbxout_type_name		PROTO((tree));static void dbxout_symbol_location	PROTO((tree, tree, char *, rtx));static void dbxout_symbol_name		PROTO((tree, char *, int));static void dbxout_prepare_symbol	PROTO((tree));static void dbxout_finish_symbol	PROTO((tree));static void dbxout_block		PROTO((tree, int, tree));static void dbxout_really_begin_function PROTO((tree));static voiddbxout_function_end (){  char lscope_label_name[100];  /* Convert Ltext into the appropriate format for local labels in case     the system doesn't insert underscores in front of user generated     labels.  */  ASM_GENERATE_INTERNAL_LABEL (lscope_label_name, "Lscope", scope_labelno);  ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Lscope", scope_labelno);  scope_labelno++;  /* By convention, GCC will mark the end of a function with an N_FUN     symbol and an empty string.  */  fprintf (asmfile, "%s \"\",%d,0,0,", ASM_STABS_OP, N_FUN);  assemble_name (asmfile, lscope_label_name);  fputc ('-', asmfile);  assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));  fprintf (asmfile, "\n");}/* At the beginning of compilation, start writing the symbol table.   Initialize `typevec' and output the standard data types of C.  */voiddbxout_init (asm_file, input_file_name, syms)     FILE *asm_file;     char *input_file_name;     tree syms;{  char ltext_label_name[100];  asmfile = asm_file;  typevec_len = 100;  typevec = (struct typeinfo *) xmalloc (typevec_len * sizeof typevec[0]);  bzero ((char *) typevec, typevec_len * sizeof typevec[0]);  /* Convert Ltext into the appropriate format for local labels in case     the system doesn't insert underscores in front of user generated     labels.  */  ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);  /* Put the current working directory in an N_SO symbol.  */#ifndef DBX_WORKING_DIRECTORY /* Only some versions of DBX want this,				 but GDB always does.  */  if (use_gnu_debug_info_extensions)#endif    {      if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/'))	{	  char *wdslash = xmalloc (strlen (cwd) + sizeof (FILE_NAME_JOINER));	  sprintf (wdslash, "%s%s", cwd, FILE_NAME_JOINER);	  cwd = wdslash;	}      if (cwd)	{#ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY	  DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asmfile, cwd);#else /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */	  fprintf (asmfile, "%s ", ASM_STABS_OP);	  output_quoted_string (asmfile, cwd);	  fprintf (asmfile, ",%d,0,0,%s\n", N_SO, &ltext_label_name[1]);#endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */	}    }#ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME  /* This should NOT be DBX_OUTPUT_SOURCE_FILENAME. That     would give us an N_SOL, and we want an N_SO.  */  DBX_OUTPUT_MAIN_SOURCE_FILENAME (asmfile, input_file_name);#else /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */  /* We include outputting `Ltext:' here,     because that gives you a way to override it.  */  /* Used to put `Ltext:' before the reference, but that loses on sun 4.  */  fprintf (asmfile, "%s ", ASM_STABS_OP);  output_quoted_string (asmfile, input_file_name);  fprintf (asmfile, ",%d,0,0,%s\n", 	   N_SO, &ltext_label_name[1]);  text_section ();  ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0);#endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */  /* Possibly output something to inform GDB that this compilation was by     GCC.  It's easier for GDB to parse it when after the N_SO's.  This     is used in Solaris 2.  */#ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE  ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile);#endif  lastfile = input_file_name;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?