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

📄 symout.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	  break;	case REAL_TYPE:	  buffer.code = TYPE_CODE_FLT;	  break;	case VOID_TYPE:	  buffer.code = TYPE_CODE_VOID;	  break;	case POINTER_TYPE:	  buffer.code = TYPE_CODE_PTR;	  break;	case ARRAY_TYPE:	  if (buffer.nfields == 0)	    buffer.code = TYPE_CODE_ARRAY;	  else	    buffer.code = TYPE_CODE_PASCAL_ARRAY;	  break;	case RECORD_TYPE:	  buffer.code = TYPE_CODE_STRUCT;	  break;	case UNION_TYPE:	  buffer.code = TYPE_CODE_UNION;	  break;	case FUNCTION_TYPE:	  buffer.code = TYPE_CODE_FUNC;	  break;	case ENUMERAL_TYPE:	  buffer.code = TYPE_CODE_ENUM;	  break;	default:	  abort ();	}      fwrite (&buffer, sizeof buffer, 1, symfile);      /* Now write the `struct field's that certain kinds of type have.	 This allocates space for the names of those fields,	 incrementing next_address for the names.  */      switch (TREE_CODE (next))	{	case ARRAY_TYPE:	  if (buffer.nfields)	    symout_array_domain (next);	  break;	case RECORD_TYPE:	case UNION_TYPE:	  symout_record_fields (next);	  break;	case ENUMERAL_TYPE:	  symout_enum_values (next);	  break;	case INTEGER_TYPE:	  if (buffer.nfields)	    symout_range_bounds (next);	}    }  /* Now output the strings referred to by the fields of certain types.     (next_address was already updated for these strings.)  */  for (next = types, i = 0;       next;       next = TREE_CHAIN (next), i++)    {      switch (TREE_CODE (next))	{	case RECORD_TYPE:	case UNION_TYPE:	  symout_record_field_names (next);	  break;	case ENUMERAL_TYPE:	  symout_enum_value_names (next);	  break;	}    }}/* Given a list of types TYPES, return a chain of just those   that haven't been written in the symbol table.  */static treefilter_undefined_types (types)     tree types;{  tree new = 0;  tree next;  for (next = types; next; next = TREE_CHAIN (next))    if (TYPE_SYMTAB_ADDRESS (TREE_PURPOSE (next)) == 0)      {	TREE_CHAIN (TREE_PURPOSE (next)) = new;	new = TREE_PURPOSE (next);      }  return new;}/* Return nonzero if TYPE's range of possible values   is not the full range allowed by the number of bits it has.   TYPE is assumed to be an INTEGER_TYPE or ENUMERAL_TYPE.  */static intsubrange_p (type)     tree type;{  int uns = TREE_UNSIGNED (type);  if (TYPE_PRECISION (type) >= HOST_BITS_PER_INT)    {      if (uns)	return integer_zerop (TYPE_MIN_VALUE (type))	  && TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0	    && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))		== (1 << (TYPE_PRECISION (type) - HOST_BITS_PER_INT)) - 1);      return TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0	&& TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == 0	  && (TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type))	      == (-1) << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT))	    && (TREE_INT_CST_HIGH (TYPE_MAX_VALUE (type))		== (1 << (TYPE_PRECISION (type) - 1 - HOST_BITS_PER_INT)) - 1);    }  if (uns)    {      int mask;      if (TYPE_PRECISION (type) == HOST_BITS_PER_INT)	/* Shifting by 32 loses on some machines.  */	mask = -1;      else	mask = (1 << TYPE_PRECISION (type)) - 1;      return (integer_zerop (TYPE_MIN_VALUE (type))	      && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)) == mask));    }  else    return ((TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))	     == (-1) << (TYPE_PRECISION (type) - 1))	    && (TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))		== (1 << (TYPE_PRECISION (type) - 1)) - 1));}/* Functions to output the "fields" of various kinds of types.   These assume that next_address has already been incremented to   cover these fields, and the fields of all the other types being   output in this batch; so next_address can be used to allocate   space to store field names, etc.  */static voidsymout_array_domain (type)     tree type;{  struct field buffer;  buffer.bitpos = 0;  buffer.bitsize = 0;  buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TYPE_DOMAIN (type));  buffer.name = 0;  fwrite (&buffer, sizeof (struct field), 1, symfile);}static voidsymout_range_bounds (type)     tree type;{  struct field buffer;  buffer.bitpos = TREE_INT_CST_LOW (TYPE_MIN_VALUE (type));  buffer.bitsize = 0;  buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);  buffer.name = 0;  fwrite (&buffer, sizeof (struct field), 1, symfile);  buffer.bitpos = TREE_INT_CST_LOW (TYPE_MAX_VALUE (type));  buffer.bitsize = 0;  buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);  buffer.name = 0;  fwrite (&buffer, sizeof (struct field), 1, symfile);}static voidsymout_record_fields (type)     tree type;{  struct field buffer;  register tree field;  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))    {      buffer.bitpos = DECL_OFFSET (field);      buffer.bitsize	= (TREE_PACKED (field)	   ? TREE_INT_CST_LOW (DECL_SIZE (field)) * DECL_SIZE_UNIT (field)	   : 0);      buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (field));      if (DECL_NAME (field))	{	  buffer.name = (char *) next_address;	  symout_strings_skip (0, IDENTIFIER_LENGTH (DECL_NAME (field)), 0, 0);	}      else	buffer.name = 0;      fwrite (&buffer, sizeof (struct field), 1, symfile);    }}static voidsymout_enum_values (type)     tree type;{  struct field buffer;  register tree link, value;  for (link = TYPE_VALUES (type); link; link = TREE_CHAIN (link))    {      value = TREE_VALUE (link);      buffer.bitpos = TREE_INT_CST_LOW (value);      buffer.bitsize = 0;      buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (type);      buffer.name = (char *) next_address;      symout_strings_skip (0, IDENTIFIER_LENGTH (TREE_PURPOSE (link)), 0, 0);      fwrite (&buffer, sizeof buffer, 1, symfile);    }}/* Output field names or value names for the fields of a type.   This is called, for the types that need it, after the fields   have been output for all the types in the batch.   We do not update next_address here, because it has already been    updated for all the names in all the fields in all the types.  */static voidsymout_record_field_names (type)     tree type;{  register tree field;  for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))    if (DECL_NAME (field))      symout_strings_print (IDENTIFIER_POINTER (DECL_NAME (field)),			    IDENTIFIER_LENGTH (DECL_NAME (field)),			    0, 0);}static voidsymout_enum_value_names (type)     tree type;{  register tree value;  for (value = TYPE_VALUES (type); value; value = TREE_CHAIN (value))    symout_strings_print (IDENTIFIER_POINTER (TREE_PURPOSE (value)),			  IDENTIFIER_LENGTH (TREE_PURPOSE (value)),			  0, 0);}/* Output the symbols of a block, given the list of decl nodes.   Store the file addresses at which the symbols are output   into ADDR_BUFFER, a vector which has just the right length.   If FILTER is 1, do only the private symbols in DECLS.   If FILTER is 2, do only the public ones (but no externals).   If FILTER is 0, do all (except external functions).  */static voidsymout_block_symbols (decls, addr_buffer, filter)     tree decls;     int *addr_buffer;     int filter;{  register tree decl;  struct symbol buffer;  register int i;  for (decl = decls, i = 0; decl; decl = TREE_CHAIN (decl))    {      register int name_address = next_address;      if (filter == (TREE_PUBLIC (decl) ? 1 : 2))	continue;      /* Do not mention external functions.	 Let their own files mention them.	 In the top blocks, don't mention external anything.  */      if (TREE_EXTERNAL (decl)	  && (filter || TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE))	continue;      if (TREE_TYPE (decl) == error_mark_node)	continue;      symout_strings (IDENTIFIER_POINTER (DECL_NAME (decl)),		      IDENTIFIER_LENGTH (DECL_NAME (decl)),		      0, 0);      addr_buffer[i] = next_address;      buffer.name = (char *) name_address;      buffer.namespace = VAR_NAMESPACE;      buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (TREE_TYPE (decl));      switch (TREE_CODE (decl))	{	case PARM_DECL:	  buffer.class = LOC_ARG;	  buffer.value.value = DECL_OFFSET (decl) / BITS_PER_UNIT;	  break;	case VAR_DECL:	case RESULT_DECL:	  if (TREE_STATIC (decl) || TREE_EXTERNAL (decl))	    {	      if (! TREE_PUBLIC (decl) || DECL_INITIAL (decl))		{		  char *str = XSTR (XEXP (DECL_RTL (decl), 0), 0);		  fprintf (asmfile, "\t.gdbsym ");		  ASM_OUTPUT_LABELREF (asmfile, str);		  fprintf (asmfile, ",%d\n",			   next_address + (char *)&buffer.value - (char *)&buffer);		  buffer.class = LOC_STATIC;		}	      else		/* Uninitialized public symbols are output as .comm;		   Tell GDB to get address from loader global symbol.		   Also come here for symbols declared extern.  */		buffer.class = LOC_EXTERNAL;	    }	  else	    {	      if (GET_CODE (DECL_RTL (decl)) == REG)		{		  buffer.class = LOC_REGISTER;		  buffer.value.value = REGNO (DECL_RTL (decl));		  /* Detect vars that were optimized entirely away.  */		  if (buffer.value.value == -1)		    buffer.class = LOC_CONST;		}	      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.		   If we have a pointer-type (which we should, for an array),		   output the variable as a pointer.		   Otherwise ignore it, since it is hard to create the ptr		   type now and output it, and -gg is being retired.  */		{		  tree ptype = TYPE_POINTER_TO (TREE_TYPE (TREE_TYPE (decl)));		  if (ptype == 0		      || TYPE_OUTPUT_ADDRESS (ptype) == 0)		    continue;		  buffer.type = (struct type *) TYPE_OUTPUT_ADDRESS (ptype);		  if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)		    {		      buffer.class = LOC_REGISTER;		      buffer.value.value = REGNO (DECL_RTL (decl));		      /* Detect vars that were optimized entirely away.  */		      if (buffer.value.value == -1)			buffer.class = LOC_CONST;		    }		  else		    {		      register rtx addr = XEXP (DECL_RTL (decl), 0);		      if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)			abort ();		      if (GET_CODE (XEXP (addr, 1)) != CONST_INT)			abort ();		      buffer.class = LOC_LOCAL;		      buffer.value.value = INTVAL (XEXP (addr, 1));		      if (GET_CODE (addr) == MINUS)			buffer.value.value = - buffer.value.value;		    }		}	      /* Locals in memory are expected to be addressed as		 (PLUS (REG ...) (CONST_INT ...)).		 Bomb out if that is not so.  */	      else if (GET_CODE (DECL_RTL (decl)) == MEM)		{		  register rtx addr = XEXP (DECL_RTL (decl), 0);		  if (GET_CODE (addr) != PLUS && GET_CODE (addr) != MINUS)		    abort ();		  if (GET_CODE (XEXP (addr, 1)) != CONST_INT)		    abort ();		  buffer.class = LOC_LOCAL;		  buffer.value.value = INTVAL (XEXP (addr, 1));		  if (GET_CODE (addr) == MINUS)		    buffer.value.value = - buffer.value.value;		}	      else		abort ();	    }	  break;	case TYPE_DECL:	  buffer.class = LOC_TYPEDEF;	  buffer.value.value = 0;	  break;	case CONST_DECL:	  buffer.class = LOC_CONST;	  buffer.value.value = TREE_INT_CST_LOW (DECL_INITIAL (decl));	  break;	case FUNCTION_DECL:	  if (DECL_INITIAL (decl))	    {

⌨️ 快捷键说明

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