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

📄 sdbout.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Output sdb-format symbol table information from GNU compiler.   Copyright (C) 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.  */#define SDB_NO_FORWARD_REFS#include "config.h"#ifdef SDB_DEBUGGING_INFO#include "tree.h"#include "rtl.h"#include <stdio.h>#if defined(USG) && !defined(MIPS_DEBUGGING_INFO)#include <syms.h>/* #include <storclass.h>  used to be this instead of syms.h.  */#else/* For cross compilation, use the portable defintions from the COFF   documentation.  */#define  C_EFCN          -1#define  C_NULL          0#define  C_AUTO          1#define  C_EXT           2#define  C_STAT          3#define  C_REG           4#define  C_EXTDEF        5#define  C_LABEL         6#define  C_ULABEL        7#define  C_MOS           8#define  C_ARG           9#define  C_STRTAG        10#define  C_MOU           11#define  C_UNTAG         12#define  C_TPDEF         13#define  C_USTATIC       14#define  C_ENTAG         15#define  C_MOE           16#define  C_REGPARM       17#define  C_FIELD         18#define  C_BLOCK         100#define  C_FCN           101#define  C_EOS           102#define  C_FILE          103#define  C_LINE          104#define  C_ALIAS         105#define  C_HIDDEN        106#define  T_NULL     0#define  T_ARG      1#define  T_CHAR     2#define  T_SHORT    3#define  T_INT      4#define  T_LONG     5#define  T_FLOAT    6#define  T_DOUBLE   7#define  T_STRUCT   8#define  T_UNION    9#define  T_ENUM     10#define  T_MOE      11#define  T_UCHAR    12#define  T_USHORT   13#define  T_UINT     14#define  T_ULONG    15#define  DT_NON      0#define  DT_PTR      1#define  DT_FCN      2#define  DT_ARY      3#define  N_BTMASK     017#define  N_TMASK      060#define  N_TMASK1     0300#define  N_TMASK2     0360#define  N_BTSHFT     4#define  N_TSHIFT     2#endif/* Line number of beginning of current function, minus one.   Negative means not in a function or not using sdb.  */int sdb_begin_function_line = -1;/* Counter to generate unique "names" for nameless struct members.  */static int unnamed_struct_number = 0;extern FILE *asm_out_file;extern tree current_function_decl;void sdbout_init ();void sdbout_symbol ();void sdbout_tags();void sdbout_types();static void sdbout_syms ();static void sdbout_one_type ();static int plain_type_1 ();/* Random macros describing parts of SDB data.  *//* Put something here if lines get too long */#define CONTIN/* Maximum number of dimensions the assembler will allow.  */#ifndef SDB_MAX_DIM#define SDB_MAX_DIM 4#endif#ifndef PUT_SDB_SCL#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d;", (a))#endif#ifndef PUT_SDB_INT_VAL#define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\t.val\t%d;", (a))#endif#ifndef PUT_SDB_VAL#define PUT_SDB_VAL(a)				\( fputs ("\t.val\t", asm_out_file),		\  output_addr_const (asm_out_file, (a)),	\  fputc (';', asm_out_file))#endif#ifndef PUT_SDB_DEF#define PUT_SDB_DEF(a)				\do { fprintf (asm_out_file, "\t.def\t");	\     ASM_OUTPUT_LABELREF (asm_out_file, a); 	\     fprintf (asm_out_file, ";"); } while (0)#endif#ifndef PUT_SDB_PLAIN_DEF#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s;",a)#endif#ifndef PUT_SDB_ENDEF#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file)#endif#ifndef PUT_SDB_TYPE#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o;", a)#endif#ifndef PUT_SDB_SIZE#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\t.size\t%d;", a)#endif#ifndef PUT_SDB_START_DIM#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t")#endif#ifndef PUT_SDB_NEXT_DIM#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)#endif#ifndef PUT_SDB_LAST_DIM#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)#endif#ifndef PUT_SDB_TAG#define PUT_SDB_TAG(a)				\do { fprintf (asm_out_file, "\t.tag\t");	\     ASM_OUTPUT_LABELREF (asm_out_file, a);	\     fprintf (asm_out_file, ";"); } while (0)#endif#ifndef PUT_SDB_BLOCK_START#define PUT_SDB_BLOCK_START(LINE)		\  fprintf (asm_out_file,			\	   "\t.def\t.bb;\t.val\t.;\t.scl\t100;\t.line\t%d;\t.endef\n",	\	   (LINE))#endif#ifndef PUT_SDB_BLOCK_END#define PUT_SDB_BLOCK_END(LINE)			\  fprintf (asm_out_file,			\	   "\t.def\t.eb;.val\t.;\t.scl\t100;\t.line\t%d;\t.endef\n",	\	   (LINE))#endif#ifndef PUT_SDB_FUNCTION_START#define PUT_SDB_FUNCTION_START(LINE)		\  fprintf (asm_out_file,			\	   "\t.def\t.bf;\t.val\t.;\t.scl\t101;\t.line\t%d;\t.endef\n",	\	   (LINE))#endif#ifndef PUT_SDB_FUNCTION_END#define PUT_SDB_FUNCTION_END(LINE)		\  fprintf (asm_out_file,			\	   "\t.def\t.ef;\t.val\t.;\t.scl\t101;\t.line\t%d;\t.endef\n",	\	   (LINE))#endif#ifndef PUT_SDB_EPILOGUE_END#define PUT_SDB_EPILOGUE_END(NAME)		\  fprintf (asm_out_file,			\	   "\t.def\t%s;\t.val\t.;\t.scl\t-1;\t.endef\n",	\	   (NAME))#endif#ifndef SDB_GENERATE_FAKE#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \  sprintf ((BUFFER), ".%dfake", (NUMBER));#endif/* Return the sdb tag identifier string for TYPE   if TYPE has already been defined; otherwise return a null pointer.   */  #define KNOWN_TYPE_TAG(type) (char *)(TYPE_SYMTAB_ADDRESS (type))/* Set the sdb tag identifier string for TYPE to NAME.  */#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \  (TYPE_SYMTAB_ADDRESS (TYPE) = (int)(NAME))/* Return the name (a string) of the struct, union or enum tag   described by the TREE_LIST node LINK.  This is 0 for an anonymous one.  */#define TAG_NAME(link) \  (((link) && TREE_PURPOSE ((link)) \    && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \   ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)/* Ensure we don't output a negative line number.  */#define MAKE_LINE_SAFE(line)  \  if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1/* Tell the assembler the source file name.   On systems that use SDB, this is done whether or not -g,   so it is called by ASM_FILE_START.   ASM_FILE is the assembler code output file,   INPUT_NAME is the name of the main input file.  */voidsdbout_filename (asm_file, input_name)     FILE *asm_file;     char *input_name;{  int len = strlen (input_name);  char *na = input_name + len;  /* NA gets INPUT_NAME sans directory names.  */  while (na > input_name)    {      if (na[-1] == '/')	break;      na--;    }#ifdef ASM_OUTPUT_SOURCE_FILENAME  ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);#else  fprintf (asm_file, "\t.file\t\"%s\"\n", na);#endif}/* Set up for SDB output at the start of compilation.  */voidsdbout_init (){  /* Output all the initial permanent types.  */  sdbout_types (nreverse (get_permanent_types ()));}#if 0/* return the tag identifier for type */{char *tag_of_ru_type (type,link)     tree type,link;{  if (TYPE_SYMTAB_ADDRESS (type))    return (char *)TYPE_SYMTAB_ADDRESS (type);  if (link &&      TREE_PURPOSE (link)      && IDENTIFIER_POINTER (TREE_PURPOSE (link)))    TYPE_SYMTAB_ADDRESS (type) =      (int)IDENTIFIER_POINTER (TREE_PURPOSE (link));  else    return (char *) TYPE_SYMTAB_ADDRESS (type);}#endif/* Return a unique string to name an anonymous type.  */static char *gen_fake_label (){  char label[10];  char *labelstr;  SDB_GENERATE_FAKE (label, unnamed_struct_number);  unnamed_struct_number++;  labelstr = (char *) permalloc (strlen (label) + 1);  strcpy (labelstr, label);  return labelstr;}/* Return the number which describes TYPE for SDB.   For pointers, etc., this function is recursive.   Each record, union or enumeral type must already have had a   tag number output.  *//* The number is given by d6d5d4d3d2d1bbbb    where bbbb is 4 bit basic type, and di indicate  one of notype,ptr,fn,array.   Thus, char *foo () has bbbb=T_CHAR			  d1=D_FCN			  d2=D_PTR N_BTMASK=     017       1111     basic type field. N_TSHIFT=       2                derived type shift N_BTSHFT=       4                Basic type shift *//* Produce the number that describes a pointer, function or array type.   PREV is the number describing the target, value or element type.   DT_type describes how to transform that type.  */#define PUSH_DERIVED_LEVEL(DT_type,PREV) \  ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))/* Number of elements used in sdb_dims.  */static int sdb_n_dims = 0;/* Table of array dimensions of current type.  */static int sdb_dims[SDB_MAX_DIM];/* Size of outermost array currently being processed.  */static int sdb_type_size = -1;static intplain_type (type)     tree type;{  int val = plain_type_1 (type);  /* If we have already saved up some array dimensions, print them now.  */  if (sdb_n_dims > 0)    {      int i;      PUT_SDB_START_DIM;      for (i = sdb_n_dims - 1; i > 0; i--)	PUT_SDB_NEXT_DIM (sdb_dims[i]);      PUT_SDB_LAST_DIM (sdb_dims[0]);      sdb_n_dims = 0;      sdb_type_size = int_size_in_bytes (type);      /* Don't kill sdb if type is not laid out or has variable size.  */      if (sdb_type_size < 0)	sdb_type_size = 0;    }  /* If we have computed the size of an array containing this type,     print it now.  */  if (sdb_type_size >= 0)    {      PUT_SDB_SIZE (sdb_type_size);      sdb_type_size = -1;    }  return val;}static voidsdbout_record_type_name (type)     tree type;{  char *name = 0;  if (KNOWN_TYPE_TAG (type))    return;  if (TYPE_NAME (type) != 0)     {      tree t = 0;      /* Find the IDENTIFIER_NODE for the type name.  */      if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)	{	  t = TYPE_NAME (type);	}      else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)	{	  t = DECL_NAME (TYPE_NAME (type));	}      /* Now get the name as a string, or invent one.  */      if (t != 0)	name = IDENTIFIER_POINTER (t);    }  if (name == 0)    name = gen_fake_label ();  SET_KNOWN_TYPE_TAG (type, name);}static intplain_type_1 (type)     tree type;{  if (type == 0)      type = void_type_node;  if (type == error_mark_node)    type = integer_type_node;  type = TYPE_MAIN_VARIANT (type);  switch (TREE_CODE (type))    {    case VOID_TYPE:      return T_INT;    case INTEGER_TYPE:      switch (int_size_in_bytes (type))	{	case 4:	  return (TREE_UNSIGNED (type) ? T_UINT : T_INT);	case 1:	  return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);	case 2:	  return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);	default:	  return 0;	}    case REAL_TYPE:      switch (int_size_in_bytes (type))	{	case 4:	  return T_FLOAT;	default:	  return T_DOUBLE;	}    case ARRAY_TYPE:      {	int m;	m = plain_type_1 (TREE_TYPE (type));	if (sdb_n_dims < SDB_MAX_DIM)	  sdb_dims[sdb_n_dims++]	    = (TYPE_DOMAIN (type)	       ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1	       : 0);	return PUSH_DERIVED_LEVEL (DT_ARY, m);      }    case RECORD_TYPE:    case UNION_TYPE:    case ENUMERAL_TYPE:      {	char *tag;#ifndef SDB_NO_FORWARD_REFS /* Taken out because this sets KNOWN_TYPE_TAG.		 If we don't want forward references,		 this is clearly not needed.  */	sdbout_record_type_name (type);#endif	if (TREE_ASM_WRITTEN (type)#ifdef SDB_NO_FORWARD_REFS	    && KNOWN_TYPE_TAG (type)#endif	    )	  {	    /* Output the referenced structure tag name	       only if the .def has already been output.	       At least on 386, the Unix assembler	       cannot handle forward references to tags.  */	    tag = KNOWN_TYPE_TAG (type);	    PUT_SDB_TAG (tag);	  }	sdb_type_size = int_size_in_bytes (type);	if (sdb_type_size < 0)	  sdb_type_size = 0;	return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT		: (TREE_CODE (type) == UNION_TYPE) ? T_UNION		: T_ENUM);      }    case POINTER_TYPE:    case REFERENCE_TYPE:      {	int m = plain_type_1 (TREE_TYPE (type));	return PUSH_DERIVED_LEVEL (DT_PTR, m);      }    case FUNCTION_TYPE:    case METHOD_TYPE:      {	int m = plain_type_1 (TREE_TYPE (type));	return PUSH_DERIVED_LEVEL (DT_FCN, m);      }    default:      return 0;    }}/* 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,   counting blocks, until it finds the desired block.  */static int do_block = 0;static int next_block_number;static voidsdbout_block (stmt)     register tree stmt;{  while (stmt)    {      switch (TREE_CODE (stmt))	{	case COMPOUND_STMT:	case LOOP_STMT:	  sdbout_block (STMT_BODY (stmt));	  break;	case IF_STMT:	  sdbout_block (STMT_THEN (stmt));	  sdbout_block (STMT_ELSE (stmt));	  break;	case LET_STMT:	  /* Ignore LET_STMTs for blocks never really used to make RTL.  */	  if (! TREE_USED (stmt))	    break;	  /* When we reach the specified block, output its symbols.  */	  if (next_block_number == do_block)	    {	      sdbout_tags (STMT_TYPE_TAGS (stmt));	      sdbout_syms (STMT_VARS (stmt));	    }	  /* If we are past the specified block, stop the scan.  */	  if (next_block_number > do_block)	    return;	  next_block_number++;	  /* Scan the blocks within this block.  */	  sdbout_block (STMT_SUBBLOCKS (stmt));	}      stmt = TREE_CHAIN (stmt);

⌨️ 快捷键说明

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