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

📄 dbxout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
     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;  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.     (Actually it should no longer matter what their numbers are.     Also, if any types with tags have been defined, dbxout_symbol     will output them first, so the numbers won't be 1 and 2.  That     happens in C++.  So it's a good thing it should no longer matter).  */#ifdef DBX_OUTPUT_STANDARD_TYPES  DBX_OUTPUT_STANDARD_TYPES (syms);#else  dbxout_symbol (TYPE_NAME (integer_type_node), 0);  dbxout_symbol (TYPE_NAME (char_type_node), 0);#endif  /* Get all permanent types that have typedef names,     and output them all, except for those already output.  */  dbxout_typedefs (syms);}/* Output any typedef names for types described by TYPE_DECLs in SYMS,   in the reverse order from that which is found in SYMS.  */static voiddbxout_typedefs (syms)     tree syms;{  if (syms)    {      dbxout_typedefs (TREE_CHAIN (syms));      if (TREE_CODE (syms) == TYPE_DECL)	{	  tree type = TREE_TYPE (syms);	  if (TYPE_NAME (type)	      && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	      && ! TREE_ASM_WRITTEN (TYPE_NAME (type)))	    dbxout_symbol (TYPE_NAME (type), 0);	}    }}/* Output debugging info to FILE to switch to sourcefile FILENAME.  */voiddbxout_source_file (file, filename)     FILE *file;     char *filename;{  char ltext_label_name[100];  if (filename && (lastfile == 0 || strcmp (filename, lastfile)))    {#ifdef DBX_OUTPUT_SOURCE_FILENAME      DBX_OUTPUT_SOURCE_FILENAME (file, filename);#else      ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0);      fprintf (file, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP,	       filename, N_SOL, &ltext_label_name[1]);#endif      lastfile = filename;    }}/* Output a line number symbol entry into output stream FILE,    for source file FILENAME and line number LINENO.  */voiddbxout_source_line (file, filename, lineno)     FILE *file;     char *filename;     int lineno;{  dbxout_source_file (file, filename);#ifdef ASM_OUTPUT_SOURCE_LINE  ASM_OUTPUT_SOURCE_LINE (file, lineno);#else  fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno);#endif}/* At the end of compilation, finish writing the symbol table.   Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is   to do nothing. */voiddbxout_finish (file, filename)     FILE *file;     char *filename;{#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END  DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename);#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */}/* 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 (NULL_TREE);  fprintf (asmfile, "%s \"", ASM_STABS_OP);  current_sym_nchars = 0;}/* Subroutine of `dbxout_type'.  Output the type fields of TYPE.   This must be a separate function because anonymous unions require   recursive calls.  */static voiddbxout_type_fields (type)     tree type;{  tree tem;  /* Output the name, type, position (in bits), size (in bits) of each     field.  */  for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))    {      /* For nameless subunions and subrecords, treat their fields as ours.  */      if (DECL_NAME (tem) == NULL_TREE	  && (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE	      || TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE))	dbxout_type_fields (TREE_TYPE (tem));      /* Omit here local type decls until we know how to support them.  */      else if (TREE_CODE (tem) == TYPE_DECL)	continue;      /* Omit here the nameless fields that are used to skip bits.  */      else if (DECL_NAME (tem) != 0 && TREE_CODE (tem) != CONST_DECL)	{	  /* Continue the line if necessary,	     but not before the first field.  */	  if (tem != TYPE_FIELDS (type))	    CONTIN;	  if (use_gnu_debug_info_extensions	      && flag_minimal_debug	      && TREE_CODE (tem) == FIELD_DECL	      && DECL_VIRTUAL_P (tem)	      && DECL_ASSEMBLER_NAME (tem))	    {	      have_used_extensions = 1;	      CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem)))));	      fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile);	      dbxout_type (DECL_FCONTEXT (tem), 0, 0);	      fprintf (asmfile, ":");	      dbxout_type (TREE_TYPE (tem), 0, 0);	      fprintf (asmfile, ",%d;",		       TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));	      continue;	    }	  fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));	  CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));	  if (use_gnu_debug_info_extensions	      && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)		  || TREE_CODE (tem) != FIELD_DECL))	    {	      have_used_extensions = 1;	      putc ('/', asmfile);	      putc ((TREE_PRIVATE (tem) ? '0'		     : TREE_PROTECTED (tem) ? '1' : '2'),		    asmfile);	      CHARS (2);	    }	  dbxout_type ((TREE_CODE (tem) == FIELD_DECL			&& DECL_BIT_FIELD_TYPE (tem))		       ? DECL_BIT_FIELD_TYPE (tem)		       : TREE_TYPE (tem), 0, 0);	  if (TREE_CODE (tem) == VAR_DECL)	    {	      if (TREE_STATIC (tem) && use_gnu_debug_info_extensions)		{		  char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));		  have_used_extensions = 1;		  fprintf (asmfile, ":%s;", name);		  CHARS (strlen (name));		}	      else		{		  /* If TEM is non-static, GDB won't understand it.  */		  fprintf (asmfile, ",0,0;");		}	    }	  else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)	    {	      fprintf (asmfile, ",%d,%d;",		       TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)),		       TREE_INT_CST_LOW (DECL_SIZE (tem)));	    }	  else	    /* This has yet to be implemented.  */	    abort ();	  CHARS (23);	}    }}/* Subroutine of `dbxout_type_methods'.  Output debug info about the   method described DECL.  DEBUG_NAME is an encoding of the method's   type signature.  ??? We may be able to do without DEBUG_NAME altogether   now.  */static voiddbxout_type_method_1 (decl, debug_name)     tree decl;     char *debug_name;{  tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)));  char c1 = 'A', c2;  if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)    c2 = '?';  else /* it's a METHOD_TYPE.  */    {      /* A for normal functions.	 B for `const' member functions.	 C for `volatile' member functions.	 D for `const volatile' member functions.  */      if (TYPE_READONLY (TREE_TYPE (firstarg)))	c1 += 1;      if (TYPE_VOLATILE (TREE_TYPE (firstarg)))	c1 += 2;      if (DECL_VINDEX (decl))	c2 = '*';      else	c2 = '.';    }  fprintf (asmfile, ":%s;%c%c%c", debug_name,	   TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2);  CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6	 - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));  if (DECL_VINDEX (decl))    {      fprintf (asmfile, "%d;",	       TREE_INT_CST_LOW (DECL_VINDEX (decl)));      dbxout_type (DECL_CONTEXT (decl), 0, 0);      fprintf (asmfile, ";");      CHARS (8);    }}/* Subroutine of `dbxout_type'.  Output debug info about the methods defined   in TYPE.  */static voiddbxout_type_methods (type)     register tree type;{  /* C++: put out the method names and their parameter lists */  tree methods = TYPE_METHODS (type);  tree type_encoding;  register tree fndecl;  register tree last;  char formatted_type_identifier_length[16];  register int type_identifier_length;  if (methods == NULL_TREE)    return;  type_encoding = DECL_NAME (TYPE_NAME (type));  /* C++: Template classes break some assumptions made by this code about     the class names, constructor names, and encodings for assembler     label names.  For now, disable output of dbx info for them.  */  {    char *ptr = IDENTIFIER_POINTER (type_encoding);    /* This should use index.  (mrs) */    while (*ptr && *ptr != '<') ptr++;    if (*ptr != 0)      {	static int warned;	if (!warned)	  {	    warned = 1;	    warning ("dbx info for template class methods not yet supported");	  }	return;      }  }  type_identifier_length = IDENTIFIER_LENGTH (type_encoding);  sprintf(formatted_type_identifier_length, "%d", type_identifier_length);  if (TREE_CODE (methods) == FUNCTION_DECL)    fndecl = methods;  else if (TREE_VEC_ELT (methods, 0) != NULL_TREE)    fndecl = TREE_VEC_ELT (methods, 0);  else    fndecl = TREE_VEC_ELT (methods, 1);  while (fndecl)    {      tree name = DECL_NAME (fndecl);      int need_prefix = 1;      /* Group together all the methods for the same operation.	 These differ in the types of the arguments.  */      for (last = NULL_TREE;	   fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));	   fndecl = TREE_CHAIN (fndecl))	/* Output the name of the field (after overloading), as	   well as the name of the field before overloading, along	   with its parameter list */	{	  /* This is the "mangled" name of the method.	     It encodes the argument types.  */	  char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));	  int destructor = 0;	  CONTIN;	  last = fndecl;	  if (DECL_IGNORED_P (fndecl))	    continue;	  if (flag_minimal_debug)	    {	      /* Detect ordinary methods because their mangled names		 start with the operation name.  */	      if (!strncmp (IDENTIFIER_POINTER (name), debug_name,			    IDENTIFIER_LENGTH (name)))		{		  debug_name += IDENTIFIER_LENGTH (name);		  if (debug_name[0] == '_' && debug_name[1] == '_')		    {		      char *method_name = debug_name + 2;		      char *length_ptr = formatted_type_identifier_length;		      /* Get past const and volatile qualifiers.  */		      while (*method_name == 'C' || *method_name == 'V')			method_name++;		      /* Skip digits for length of type_encoding. */		      while (*method_name == *length_ptr && *length_ptr)			  length_ptr++, method_name++;		      if (! strncmp (method_name,				     IDENTIFIER_POINTER (type_encoding),				     type_identifier_length))			method_name += type_identifier_length;		      debug_name = method_name;		    }		}	      /* Detect constructors by their style of name mangling.  */	      else if (debug_name[0] == '_' && debug_name[1] == '_')		{		  char *ctor_name = debug_name + 2;		  char *length_ptr = formatted_type_identifier_length;		  while (*ctor_name == 'C' || *ctor_name == 'V')		    ctor_name++;		  /* Skip digits for length of type_encoding. */		  while (*ctor_name == *length_ptr && *length_ptr)		      length_ptr++, ctor_name++;		  if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name,				type_identifier_length))		    debug_name = ctor_name + type_identifier_length;		}	      /* The other alternative is a destructor.  */	      else		destructor = 1;	      /* Output the operation name just once, for the first method		 that we output.  */	      if (need_prefix)		{		  fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name));		  CHARS (IDENTIFIER_LENGTH (name) + 2);		  need_prefix = 0;		}	    }	  dbxout_type (TREE_TYPE (fndecl), 0, destructor);	  dbxout_type_method_1 (fndecl, debug_name);	}      if (!need_prefix)	{          putc (';', asmfile);	  CHARS (1);	}    }}/* 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.   If SHOW_ARG_TYPES is nonzero, we output a description of the argument   types for a METHOD_TYPE.  */static voiddbxout_type (type, full, show_arg_types)     tree type;     int full;     int show_arg_types;{  register tree tem;  static int anonymous_type_number = 0;

⌨️ 快捷键说明

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