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

📄 dbxout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
static voidprint_int_cst_octal (c)     tree c;{  unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c);  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c);  int excess = (3 - (HOST_BITS_PER_WIDE_INT % 3));  fprintf (asmfile, "0");  if (excess == 3)    {      print_octal (high, HOST_BITS_PER_WIDE_INT / 3);      print_octal (low, HOST_BITS_PER_WIDE_INT / 3);    }  else    {      unsigned HOST_WIDE_INT beg = high >> excess;      unsigned HOST_WIDE_INT middle	= ((high & (((HOST_WIDE_INT) 1 << excess) - 1)) << (3 - excess)	   | (low >> (HOST_BITS_PER_WIDE_INT / 3 * 3)));      unsigned HOST_WIDE_INT end	= low & (((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT / 3 * 3)) - 1);      fprintf (asmfile, "%o%01o", beg, middle);      print_octal (end, HOST_BITS_PER_WIDE_INT / 3);    }}static voidprint_octal (value, digits)     unsigned HOST_WIDE_INT value;     int digits;{  int i;  for (i = digits - 1; i >= 0; i--)    fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7));}/* Output the name of type TYPE, with no punctuation.   Such names can be set up either by typedef declarations   or by struct, enum and union tags.  */static voiddbxout_type_name (type)     register tree type;{  tree t;  if (TYPE_NAME (type) == 0)    abort ();  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));    }  else    abort ();  fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));  CHARS (IDENTIFIER_LENGTH (t));}/* Output a .stabs for the symbol defined by DECL,   which must be a ..._DECL node in the normal namespace.   It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.   LOCAL is nonzero if the scope is less than the entire file.  */voiddbxout_symbol (decl, local)     tree decl;     int local;{  int letter = 0;  tree type = TREE_TYPE (decl);  tree context = NULL_TREE;  int regno = -1;  /* Cast avoids warning in old compilers.  */  current_sym_code = (STAB_CODE_TYPE) 0;  current_sym_value = 0;  current_sym_addr = 0;  /* Ignore nameless syms, but don't ignore type tags.  */  if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)      || DECL_IGNORED_P (decl))    return;  dbxout_prepare_symbol (decl);  /* The output will always start with the symbol name,     so always count that in the length-output-so-far.  */  if (DECL_NAME (decl) != 0)    current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));  switch (TREE_CODE (decl))    {    case CONST_DECL:      /* Enum values are defined by defining the enum type.  */      break;    case FUNCTION_DECL:      if (DECL_RTL (decl) == 0)	return;      if (DECL_EXTERNAL (decl))	break;      /* Don't mention a nested function under its parent.  */      context = decl_function_context (decl);      if (context == current_function_decl)	break;      if (GET_CODE (DECL_RTL (decl)) != MEM	  || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)	break;      FORCE_TEXT;      fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,	       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),	       TREE_PUBLIC (decl) ? 'F' : 'f');      current_sym_code = N_FUN;      current_sym_addr = XEXP (DECL_RTL (decl), 0);      if (TREE_TYPE (type))	dbxout_type (TREE_TYPE (type), 0, 0);      else	dbxout_type (void_type_node, 0, 0);      /* For a nested function, when that function is compiled,	 mention the containing function name	 as well as (since dbx wants it) our own assembler-name.  */      if (context != 0)	fprintf (asmfile, ",%s,%s",		 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),		 IDENTIFIER_POINTER (DECL_NAME (context)));      dbxout_finish_symbol (decl);      break;    case TYPE_DECL:#if 0      /* This seems all wrong.  Outputting most kinds of types gives no name	 at all.  A true definition gives no name; a cross-ref for a	 structure can give the tag name, but not a type name.	 It seems that no typedef name is defined by outputting a type.  */      /* If this typedef name was defined by outputting the type,	 don't duplicate it.  */      if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED	  && TYPE_NAME (TREE_TYPE (decl)) == decl)	return;#endif      /* Don't output the same typedef twice.         And don't output what language-specific stuff doesn't want output.  */      if (TREE_ASM_WRITTEN (decl) || DECL_IGNORED_P (decl))	return;      FORCE_TEXT;      {	int tag_needed = 1;	int did_output = 0;	if (DECL_NAME (decl))	  {	    /* Nonzero means we must output a tag as well as a typedef.  */	    tag_needed = 0;	    /* Handle the case of a C++ structure or union	       where the TYPE_NAME is a TYPE_DECL	       which gives both a typedef name and a tag.  */	    /* dbx requires the tag first and the typedef second.  */	    if ((TREE_CODE (type) == RECORD_TYPE		 || TREE_CODE (type) == UNION_TYPE)		&& TYPE_NAME (type) == decl		&& !(use_gnu_debug_info_extensions && have_used_extensions)		&& !TREE_ASM_WRITTEN (TYPE_NAME (type))		/* Distinguish the implicit typedefs of C++		   from explicit ones that might be found in C.  */		&& DECL_SOURCE_LINE (decl) == 0)	      {		tree name = TYPE_NAME (type);		if (TREE_CODE (name) == TYPE_DECL)		  name = DECL_NAME (name);		current_sym_code = DBX_TYPE_DECL_STABS_CODE;		current_sym_value = 0;		current_sym_addr = 0;		current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);		fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,			 IDENTIFIER_POINTER (name));		dbxout_type (type, 1, 0);		dbxout_finish_symbol (NULL_TREE);	      }	    /* Output typedef name.  */	    fprintf (asmfile, "%s \"%s:", ASM_STABS_OP,		     IDENTIFIER_POINTER (DECL_NAME (decl)));	    /* Short cut way to output a tag also.  */	    if ((TREE_CODE (type) == RECORD_TYPE		 || TREE_CODE (type) == UNION_TYPE)		&& TYPE_NAME (type) == decl)	      {		if (use_gnu_debug_info_extensions && have_used_extensions)		  {		    putc ('T', asmfile);		    TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;		  }#if 0 /* Now we generate the tag for this case up above.  */		else		  tag_needed = 1;#endif	      }	    putc ('t', asmfile);	    current_sym_code = DBX_TYPE_DECL_STABS_CODE;	    dbxout_type (type, 1, 0);	    dbxout_finish_symbol (decl);	    did_output = 1;	  }	if (tag_needed && TYPE_NAME (type) != 0	    && !TREE_ASM_WRITTEN (TYPE_NAME (type)))	  {	    /* For a TYPE_DECL with no name, but the type has a name,	       output a tag.	       This is what represents `struct foo' with no typedef.  */	    /* In C++, the name of a type is the corresponding typedef.	       In C, it is an IDENTIFIER_NODE.  */	    tree name = TYPE_NAME (type);	    if (TREE_CODE (name) == TYPE_DECL)	      name = DECL_NAME (name);	    current_sym_code = DBX_TYPE_DECL_STABS_CODE;	    current_sym_value = 0;	    current_sym_addr = 0;	    current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);	    fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,		     IDENTIFIER_POINTER (name));	    dbxout_type (type, 1, 0);	    dbxout_finish_symbol (NULL_TREE);	    did_output = 1;	  }	/* If an enum type has no name, it cannot be referred to,	   but we must output it anyway, since the enumeration constants	   can be referred to.  */	if (!did_output && TREE_CODE (type) == ENUMERAL_TYPE)	  {	    current_sym_code = DBX_TYPE_DECL_STABS_CODE;	    current_sym_value = 0;	    current_sym_addr = 0;	    current_sym_nchars = 2;	    /* Some debuggers fail when given NULL names, so give this a	       harmless name of ` '.  */	    fprintf (asmfile, "%s \" :T", ASM_STABS_OP);	    dbxout_type (type, 1, 0);	    dbxout_finish_symbol (NULL_TREE);	  }	/* Prevent duplicate output of a typedef.  */	TREE_ASM_WRITTEN (decl) = 1;	break;      }    case PARM_DECL:      /* Parm decls go in their own separate chains	 and are output by dbxout_reg_parms and dbxout_parms.  */      abort ();    case RESULT_DECL:      /* Named return value, treat like a VAR_DECL.  */    case VAR_DECL:      if (DECL_RTL (decl) == 0)	return;      /* Don't mention a variable that is external.	 Let the file that defines it describe it.  */      if (DECL_EXTERNAL (decl))	break;      /* If the variable is really a constant	 and not written in memory, inform the debugger.  */      if (TREE_STATIC (decl) && TREE_READONLY (decl)	  && DECL_INITIAL (decl) != 0	  && ! TREE_ASM_WRITTEN (decl)	  && (DECL_FIELD_CONTEXT (decl) == NULL_TREE	      || TREE_CODE (DECL_FIELD_CONTEXT (decl)) == BLOCK))	{	  if (TREE_PUBLIC (decl) == 0)	    {	      /* The sun4 assembler does not grok this.  */	      char *name = IDENTIFIER_POINTER (DECL_NAME (decl));	      if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE		  || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)		{		  HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));#ifdef DBX_OUTPUT_CONSTANT_SYMBOL		  DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);#else		  fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n",			   ASM_STABS_OP, name, ival, N_LSYM);#endif		  return;		}	      else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)		{		  /* don't know how to do this yet.  */		}	      break;	    }	  /* else it is something we handle like a normal variable.  */	}      DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, 0);#ifdef LEAF_REG_REMAP      if (leaf_function)	leaf_renumber_regs_insn (DECL_RTL (decl));#endif      /* Don't mention a variable at all	 if it was completely optimized into nothingness.	 If DECL was from an inline function, then it's rtl	 is not identically the rtl that was used in this	 particular compilation.  */      if (GET_CODE (DECL_RTL (decl)) == REG)	{	  regno = REGNO (DECL_RTL (decl));	  if (regno >= FIRST_PSEUDO_REGISTER)	    return;	}      else if (GET_CODE (DECL_RTL (decl)) == SUBREG)	{	  rtx value = DECL_RTL (decl);	  int offset = 0;	  while (GET_CODE (value) == SUBREG)	    {	      offset += SUBREG_WORD (value);	      value = SUBREG_REG (value);	    }	  if (GET_CODE (value) == REG)	    {	      regno = REGNO (value);	      if (regno >= FIRST_PSEUDO_REGISTER)		return;	      regno += offset;	    }	  alter_subreg (DECL_RTL (decl));	}      /* The kind-of-variable letter depends on where	 the variable is and on the scope of its name:	 G and N_GSYM for static storage and global scope,	 S for static storage and file scope,	 V for static storage and local scope,	    for those two, use N_LCSYM if data is in bss segment,	    N_STSYM if in data segment, N_FUN otherwise.	    (We used N_FUN originally, then changed to N_STSYM	    to please GDB.  However, it seems that confused ld.	    Now GDB has been fixed to like N_FUN, says Kingdon.)	 no letter at all, and N_LSYM, for auto variable,	 r and N_RSYM for register variable.  */      if (GET_CODE (DECL_RTL (decl)) == MEM	  && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)	{	  if (TREE_PUBLIC (decl))	    {	      letter = 'G';	      current_sym_code = N_GSYM;	    }	  else	    {	      current_sym_addr = XEXP (DECL_RTL (decl), 0);	      letter = decl_function_context (decl) ? 'V' : 'S';	      if (!DECL_INITIAL (decl))		current_sym_code = N_LCSYM;	      else if (TREE_READONLY (decl) && ! TREE_THIS_VOLATILE (decl))		/* This is not quite right, but it's the closest		   of all the codes that Unix defines.  */		current_sym_code = DBX_STATIC_CONST_VAR_CODE;	      else		{/* Ultrix `as' seems to need this.  */#ifdef DBX_STATIC_STAB_DATA_SECTION		  data_section ();#endif		  current_sym_code = N_STSYM;		}	    }	}      else if (regno >= 0)	{	  letter = 'r';	  current_sym_code = N_RSYM;	  current_sym_value = DBX_REGISTER_NUMBER (regno);	}      else if (GET_CODE (DECL_RTL (decl)) == MEM	       && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM		   || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG		       && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))	/* If the value is indirect by memory or by a register	   that isn't the frame pointer	   then it means the object is variable-sized and address through	   that register or stack slot.  DBX has no way to represent this	   so all we can do is output the variable as a pointer.	   If it's not a parameter, ignore it.	   (VAR_DECLs like this can be made by integrate.c.)  */	{	  if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)	    {	      letter = 'r';	      current_sym_code = N_RSYM;	      current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));	    }	  else	    {	      current_sym_code = N_LSYM;	      /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).

⌨️ 快捷键说明

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