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

📄 dbxout.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	  current_sym_code = N_LSYM;	  current_sym_value = 0;	}      else if (GET_CODE (DECL_RTL (decl)) == MEM	       && GET_CODE (XEXP (DECL_RTL (decl), 0)) == PLUS	       && GET_CODE (XEXP (XEXP (DECL_RTL (decl), 0), 1)) == CONST_INT)	{	  current_sym_code = N_LSYM;	  /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))	     We want the value of that CONST_INT.  */	  current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));	}      else	/* Address might be a MEM, when DECL is a variable-sized object.	   Or it might be const0_rtx, meaning previous passes	   want us to ignore this variable.  */	break;      /* Ok, start a symtab entry and output the variable name.  */      FORCE_TEXT;      fprintf (asmfile, ".stabs \"%s:",	       IDENTIFIER_POINTER (DECL_NAME (decl)));      if (letter) putc (letter, asmfile);      dbxout_type (type, 0);      dbxout_finish_symbol ();      break;    }}static voiddbxout_finish_symbol (){  fprintf (asmfile, "\",%d,0,0,", current_sym_code);  if (current_sym_addr)    output_addr_const (asmfile, current_sym_addr);  else    fprintf (asmfile, "%d", current_sym_value);  putc ('\n', asmfile);}/* Output definitions of all the decls in a chain.  */static voiddbxout_syms (syms)     tree syms;{  while (syms)    {      dbxout_symbol (syms, 1);      syms = TREE_CHAIN (syms);    }}/* The following two functions output definitions of function parameters.   Each parameter gets a definition locating it in the parameter list.   Each parameter that is a register variable gets a second definition   locating it in the register.   Printing or argument lists in gdb uses the definitions that   locate in the parameter list.  But reference to the variable in   expressions uses preferentially the definition as a register.  *//* Output definitions, referring to storage in the parmlist,   of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */static voiddbxout_parms (parms)     tree parms;{  for (; parms; parms = TREE_CHAIN (parms))    {      if (DECL_OFFSET (parms) >= 0)	{	  current_sym_code = N_PSYM;	  current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;	  current_sym_addr = 0;	  current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));	  FORCE_TEXT;	  fprintf (asmfile, ".stabs \"%s:p",		   IDENTIFIER_POINTER (DECL_NAME (parms)));	  if (GET_CODE (DECL_RTL (parms)) == REG	      && REGNO (DECL_RTL (parms)) >= 0	      && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)	    dbxout_type (DECL_ARG_TYPE (parms), 0);	  else	    {	      /* This is the case where the parm is passed as an int or double		 and it is converted to a char, short or float and stored back		 in the parmlist.  In this case, describe the parm		 with the variable's declared type, and adjust the address		 if the least significant bytes (which we are using) are not		 the first ones.  */#ifdef BYTES_BIG_ENDIAN	      if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))		current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))				      - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));#endif	      if (GET_CODE (DECL_RTL (parms)) == MEM		  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS		  && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT		  && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)		dbxout_type (TREE_TYPE (parms), 0);	      else		{		  current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;		  dbxout_type (DECL_ARG_TYPE (parms), 0);		}	    }	  dbxout_finish_symbol ();	}      /* Parm was passed in registers.	 If it lives in a hard register, output a "regparm" symbol	 for the register it lives in.  */      else if (GET_CODE (DECL_RTL (parms)) == REG	       && REGNO (DECL_RTL (parms)) >= 0	       && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)	{	  current_sym_code = N_RSYM;	  current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));	  current_sym_addr = 0;	  current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));	  FORCE_TEXT;	  fprintf (asmfile, ".stabs \"%s:P",		   IDENTIFIER_POINTER (DECL_NAME (parms)));	  dbxout_type (DECL_ARG_TYPE (parms), 0);	  dbxout_finish_symbol ();	}      else if (GET_CODE (DECL_RTL (parms)) == MEM	       && XEXP (DECL_RTL (parms), 0) != const0_rtx)	{	  current_sym_code = N_LSYM;	  /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).	     We want the value of that CONST_INT.  */	  current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));	  current_sym_addr = 0;	  current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));	  FORCE_TEXT;	  fprintf (asmfile, ".stabs \"%s:p",		   IDENTIFIER_POINTER (DECL_NAME (parms)));#if 0 /* This is actually the case in which a parameter	 is passed in registers but lives on the stack in a local slot.	 The address we are using is already correct, so don't change it.  */	  /* This is the case where the parm is passed as an int or double	     and it is converted to a char, short or float and stored back	     in the parmlist.  In this case, describe the parm	     with the variable's declared type, and adjust the address	     if the least significant bytes (which we are using) are not	     the first ones.  */#ifdef BYTES_BIG_ENDIAN	  if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))	    current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))				  - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));#endif#endif /* 0 */	  dbxout_type (TREE_TYPE (parms), 0);	  dbxout_finish_symbol ();	}    }}/* Output definitions, referring to registers,   of all the parms in PARMS which are stored in registers during the function.   PARMS is a chain of PARM_DECL nodes.  */static voiddbxout_reg_parms (parms)     tree parms;{  while (parms)    {      /* Report parms that live in registers during the function.  */      if (GET_CODE (DECL_RTL (parms)) == REG	  && REGNO (DECL_RTL (parms)) >= 0	  && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER	  && DECL_OFFSET (parms) >= 0)	{	  current_sym_code = N_RSYM;	  current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));	  current_sym_addr = 0;	  current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));	  FORCE_TEXT;	  fprintf (asmfile, ".stabs \"%s:r",		   IDENTIFIER_POINTER (DECL_NAME (parms)));	  dbxout_type (TREE_TYPE (parms), 0);	  dbxout_finish_symbol ();	}      /* Report parms that live in memory but outside the parmlist.  */      else if (GET_CODE (DECL_RTL (parms)) == MEM	       && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS	       && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)	{	  int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;	  /* A parm declared char is really passed as an int,	     so it occupies the least significant bytes.	     On a big-endian machine those are not the low-numbered ones.  */#ifdef BYTES_BIG_ENDIAN	  if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))	    offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))		       - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));#endif	  if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)	    {	      current_sym_code = N_LSYM;	      current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));	      current_sym_addr = 0;	      current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));	      FORCE_TEXT;	      fprintf (asmfile, ".stabs \"%s:",		       IDENTIFIER_POINTER (DECL_NAME (parms)));	      dbxout_type (TREE_TYPE (parms), 0);	      dbxout_finish_symbol ();	    }	}      parms = TREE_CHAIN (parms);    }}/* Given a chain of ..._TYPE nodes (as come in a parameter list),   output definitions of those names, in raw form */voiddbxout_args (args)     tree args;{  while (args)    {      putc (',', asmfile);      dbxout_type (TREE_VALUE (args), 0);      CHARS (1);      args = TREE_CHAIN (args);    }}/* Given a chain of ..._TYPE nodes,   find those which have typedef names and output those names.   This is to ensure those types get output.  */voiddbxout_types (types)     register tree types;{  while (types)    {      if (TYPE_NAME (types)	  && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL	  && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))	dbxout_symbol (TYPE_NAME (types), 1);      types = TREE_CHAIN (types);    }}/* Output the tags (struct, union and enum definitions with names) for a block,   given a list of them (a chain of TREE_LIST nodes) in TAGS.   We must check to include those that have been mentioned already with   only a cross-reference.  */voiddbxout_tags (tags)     tree tags;{  register tree link;  for (link = tags; link; link = TREE_CHAIN (link))    {      register tree type = TYPE_MAIN_VARIANT (TREE_VALUE (link));      if (TREE_PURPOSE (link) != 0	  && ! TREE_ASM_WRITTEN (link)	  && TYPE_SIZE (type) != 0)	{	  TREE_ASM_WRITTEN (link) = 1;	  current_sym_code = N_LSYM;	  current_sym_value = 0;	  current_sym_addr = 0;	  current_sym_nchars = 2 + IDENTIFIER_LENGTH (TREE_PURPOSE (link));	  FORCE_TEXT;	  fprintf (asmfile, ".stabs \"%s:T",		   IDENTIFIER_POINTER (TREE_PURPOSE (link)));	  dbxout_type (type, 1);	  dbxout_finish_symbol ();	}    }}/* Output everything about a symbol block (that is to say, a LET_STMT node   that represents a scope level),   including recursive output of contained blocks.   STMT is the LET_STMT node.   DEPTH is its depth within containing symbol blocks.   ARGS is usually zero; but for the outermost block of the   body of a function, it is a chain of PARM_DECLs for the function parameters.   We output definitions of all the register parms   as if they were local variables of that block.   Actually, STMT may be several statements chained together.   We handle them all in sequence.  */static voiddbxout_block (stmt, depth, args)     register tree stmt;     int depth;     tree args;{  int blocknum;  while (stmt)    {      switch (TREE_CODE (stmt))	{	case COMPOUND_STMT:	case LOOP_STMT:	  dbxout_block (STMT_BODY (stmt), depth, 0);	  break;	case IF_STMT:	  dbxout_block (STMT_THEN (stmt), depth, 0);	  dbxout_block (STMT_ELSE (stmt), depth, 0);	  break;	case LET_STMT:	  /* Ignore LET_STMTs for blocks never really used to make RTL.  */	  if (! TREE_USED (stmt))	    break;	  /* In dbx format, the syms of a block come before the N_LBRAC.  */	  dbxout_tags (STMT_TYPE_TAGS (stmt));	  dbxout_syms (STMT_VARS (stmt));	  if (args)	    dbxout_reg_parms (args);	  /* Now output an N_LBRAC symbol to represent the beginning of	     the block.  Use the block's tree-walk order to generate	     the assembler symbols LBBn and LBEn	     that final will define around the code in this block.  */	  if (depth > 0)	    {	      char buf[20];	      blocknum = next_block_number++;	      ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);	      fprintf (asmfile, ".stabn %d,0,0,", N_LBRAC);	      assemble_name (asmfile, buf);	      fprintf (asmfile, "\n");	    }	  /* Output the subblocks.  */	  dbxout_block (STMT_SUBBLOCKS (stmt), depth + 1, 0);	  /* Refer to the marker for the end of the block.  */	  if (depth > 0)	    {	      char buf[20];	      ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum);	      fprintf (asmfile, ".stabn %d,0,0,", N_RBRAC);	      assemble_name (asmfile, buf);	      fprintf (asmfile, "\n");	    }	}      stmt = TREE_CHAIN (stmt);    }}/* Output dbx data for a function definition.   This includes a definition of the function name itself (a symbol),   definitions of the parameters (locating them in the parameter list)   and then output the block that makes up the function's body   (including all the auto variables of the function).  */voiddbxout_function (decl)     tree decl;{  dbxout_symbol (decl, 0);  dbxout_parms (DECL_ARGUMENTS (decl));  dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));    /* If we made any temporary types in this fn that weren't     output, output them now.  */  dbxout_types (get_temporary_types ());}#else /* not DBX_DEBUGGING_INFO */voiddbxout_init (asm_file, input_file_name)     FILE *asm_file;     char *input_file_name;{}voiddbxout_symbol (decl, local)     tree decl;     int local;{}voiddbxout_types (types)     register tree types;{}voiddbxout_tags (tags)     tree tags;{}voiddbxout_function (decl)     tree decl;{}#endif /* DBX_DEBUGGING_INFO */

⌨️ 快捷键说明

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