⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dbxout.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Output dbx-format symbol table information from GNU compiler.   Copyright (C) 1987, 1988 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, 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 "tree.h"#include "rtl.h"#include "flags.h"#include <stdio.h>#include <sys/param.h>#include <errno.h>#ifndef errnoextern int errno;#endif/* Virtually every UN*X system now in common use (except for pre-4.3-tahoe   BSD systems) now provides getcwd as called for by POSIX.  Allow for   the few exceptions to the general rule here.  */#if !(defined (USG) || defined (VMS))extern char *getwd ();#define getcwd(buf,len) getwd(buf)#define GUESSPATHLEN (MAXPATHLEN + 1)#else /* (defined (USG) || defined (VMS)) */extern char *getcwd ();/* We actually use this as a starting point, not a limit.  */#define GUESSPATHLEN 100#endif /* (defined (USG) || defined (VMS)) *//* Typical USG systems don't have stab.h, and they also have   no use for DBX-format debugging info.  */#ifdef DBX_DEBUGGING_INFO#ifdef DEBUG_SYMS_TEXT#define FORCE_TEXT text_section ();#else#define FORCE_TEXT#endif#ifdef USG#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.  */#endif /* not USG *//* Stream for writing to assembler file.  */static FILE *asmfile;enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};/* Vector recording the status of describing 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.   The vector element says whether we have yet output   the definition of the type.  TYPE_XREF says we have   output it as a cross-reference only.  */enum typestatus *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;/* 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 int 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_tags ();void dbxout_args ();void dbxout_symbol ();static void dbxout_type_name ();static void dbxout_type ();static void dbxout_finish_symbol ();static void dbxout_continue ();/* 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)     FILE *asm_file;     char *input_file_name;{  asmfile = asm_file;  typevec_len = 100;  typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);  bzero (typevec, typevec_len * sizeof typevec[0]);  /* Put the current working directory in an N_SO symbol.  */  {    static char *cwd;    static enum {not_gotten, gotten, error_getting} cwd_status = not_gotten;    int size;    if (cwd_status == not_gotten)      {	char *value;	/* Read the working directory, avoiding arbitrary limit.  */	size = GUESSPATHLEN;	while (1)	  {	    cwd = (char *) xmalloc (size);	    value = getcwd (cwd, size);	    if (value != 0 || errno != ERANGE)	      break;	    free (cwd);	    size *= 2;	  }	if (value != 0)	  cwd_status = gotten;	else	  cwd_status = error_getting;      }    if (cwd_status == gotten)      {#ifdef ASM_OUTPUT_MAIN_SOURCE_DIRECTORY	ASM_OUTPUT_MAIN_SOURCE_DIRECTORY (asmfile, cwd);#else /* no ASM_OUTPUT_MAIN_SOURCE_DIRECTORY */	fprintf (asmfile, "%s \"%s/\",%d,0,0,%s\n", ".stabs",		 cwd, N_SO, "Ltext");#endif /* no ASM_OUTPUT_MAIN_SOURCE_DIRECTORY */      }  }  /* Used to put `Ltext:' before the reference, but that loses on sun 4.  */  fprintf (asmfile,	   "\t.stabs \"%s\",%d,0,0,Ltext\nLtext:\n",	   input_file_name, N_SO);  next_type_number = 1;  next_block_number = 2;  /* Make sure that types `int' and `char' have numbers 1 and 2.     Definitions of other integer types will refer to those numbers.  */  dbxout_symbol (TYPE_NAME (integer_type_node), 0);  dbxout_symbol (TYPE_NAME (char_type_node), 0);  /* Get all permanent types not yet gotten, and output them.  */  dbxout_types (get_permanent_types ());}/* Continue a symbol-description that gets too big.   End one symbol table entry with a double-backslash   and start a new one, eventually producing something like   .stabs "start......\\",code,0,value   .stabs "...rest",code,0,value   */static voiddbxout_continue (){#ifdef DBX_CONTIN_CHAR  fprintf (asmfile, "%c", DBX_CONTIN_CHAR);#else  fprintf (asmfile, "\\\\");#endif  dbxout_finish_symbol ();  fprintf (asmfile, ".stabs \"");  current_sym_nchars = 0;}/* Output a reference to a type.  If the type has not yet been   described in the dbx output, output its definition now.   For a type already defined, just refer to its definition   using the type number.   If FULL is nonzero, and the type has been described only with   a forward-reference, output the definition now.   If FULL is zero in this case, just refer to the forward-reference   using the number previously allocated.  */static voiddbxout_type (type, full)     tree type;     int full;{  register tree tem;  /* If there was an input error and we don't really have a type,     avoid crashing and write something that is at least valid     by assuming `int'.  */  if (type == error_mark_node)    type = integer_type_node;  else    type = TYPE_MAIN_VARIANT (type);  if (TYPE_SYMTAB_ADDRESS (type) == 0)    {      /* Type has no dbx number assigned.  Assign next available number.  */      TYPE_SYMTAB_ADDRESS (type) = next_type_number++;      /* Make sure type vector is long enough to record about this type.  */      if (next_type_number == typevec_len)	{	  typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);	  bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);	  typevec_len *= 2;	}    }  /* Output the number of this type, to refer to it.  */  fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));  CHARS (3);  /* If this type's definition has been output or is now being output,     that is all.  */  switch (typevec[TYPE_SYMTAB_ADDRESS (type)])    {    case TYPE_UNSEEN:      break;    case TYPE_XREF:      if (! full)	return;      break;    case TYPE_DEFINED:      return;    }#ifdef DBX_NO_XREFS  /* For systems where dbx output does not allow the `=xsNAME:' syntax,     leave the type-number completely undefined rather than output     a cross-reference.  */  if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE      || TREE_CODE (type) == ENUMERAL_TYPE)    if ((TYPE_NAME (type) != 0 && !full)	|| TYPE_SIZE (type) == 0)      {	typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	return;      }#endif  /* Output a definition now.  */  fprintf (asmfile, "=");  CHARS (1);  /* Mark it as defined, so that if it is self-referent     we will not get into an infinite recursion of definitions.  */  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;  switch (TREE_CODE (type))    {    case VOID_TYPE:      /* For a void type, just define it as itself; ie, "5=5".	 This makes us consider it defined	 without saying what it is.  The debugger will make it	 a void type when the reference is seen, and nothing will	 ever override that default.  */      fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));      CHARS (3);      break;    case INTEGER_TYPE:      if (type == char_type_node && ! TREE_UNSIGNED (type))	/* Output the type `char' as a subrange of itself!	   I don't understand this definition, just copied it	   from the output of pcc.  */	fprintf (asmfile, "r2;0;127;");      else	/* Output other integer types as subranges of `int'.  */	fprintf (asmfile, "r1;%d;%d;",		 TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)),		 TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));      CHARS (25);      break;    case REAL_TYPE:      /* This must be magic.  */      fprintf (asmfile, "r1;%d;0;",	       TREE_INT_CST_LOW (size_in_bytes (type)));      CHARS (16);      break;    case ARRAY_TYPE:      /* Output "a" followed by a range type definition	 for the index type of the array	 followed by a reference to the target-type.	 ar1;0;N;M for an array of type M and size N.  */      fprintf (asmfile, "ar1;0;%d;",	       (TYPE_DOMAIN (type)		? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))	        : -1));      CHARS (17);      dbxout_type (TREE_TYPE (type), 0);      break;    case RECORD_TYPE:    case UNION_TYPE:      /* Output a structure type.  */      if ((TYPE_NAME (type) != 0 && !full)	  || TYPE_SIZE (type) == 0)	{	  /* If the type is just a cross reference, output one

⌨️ 快捷键说明

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