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

📄 valprint.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	      /* Bitfields require special handling, especially due to byte		 order problems.  */	      v = value_from_longest (TYPE_FIELD_TYPE (type, i),				   unpack_field_as_long (type, valaddr, i));	      val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0,			 stream, format, 0, recurse + 1, pretty);	    }	  else	    {	      val_print (TYPE_FIELD_TYPE (type, i), 			 valaddr + TYPE_FIELD_BITPOS (type, i) / 8,			 0, stream, format, 0, recurse + 1, pretty);	    }	}      if (pretty)	{	  fprintf_filtered (stream, "\n");	  print_spaces_filtered (2 * recurse, stream);	}    }  fprintf_filtered (stream, "}");}/* Special val_print routine to avoid printing multiple copies of virtual   baseclasses.  */static voidcplus_val_print (type, valaddr, stream, format, recurse, pretty, dont_print)     struct type *type;     char *valaddr;     FILE *stream;     int format;     int recurse;     enum val_prettyprint pretty;     struct type **dont_print;{  struct obstack tmp_obstack;  struct type **last_dont_print    = (struct type **)obstack_next_free (&dont_print_obstack);  int i, n_baseclasses = TYPE_N_BASECLASSES (type);  if (dont_print == 0)    {      /* If we're at top level, carve out a completely fresh	 chunk of the obstack and use that until this particular	 invocation returns.  */      tmp_obstack = dont_print_obstack;      /* Bump up the high-water mark.  Now alpha is omega.  */      obstack_finish (&dont_print_obstack);    }  for (i = 0; i < n_baseclasses; i++)    {      char *baddr;      int err;      if (BASETYPE_VIA_VIRTUAL (type, i))	{	  struct type **first_dont_print	    = (struct type **)obstack_base (&dont_print_obstack);	  int j = (struct type **)obstack_next_free (&dont_print_obstack)	    - first_dont_print;	  while (--j >= 0)	    if (TYPE_BASECLASS (type, i) == first_dont_print[j])	      goto flush_it;	  obstack_ptr_grow (&dont_print_obstack, TYPE_BASECLASS (type, i));	}      /* Fix to use baseclass_offset instead. FIXME */      baddr = baseclass_addr (type, i, valaddr, 0, &err);      if (err == 0 && baddr == 0)	error ("could not find virtual baseclass `%s'\n",	       type_name_no_tag (TYPE_BASECLASS (type, i)));      if (pretty)	{	  fprintf_filtered (stream, "\n");	  print_spaces_filtered (2 * recurse, stream);	}      fputs_filtered ("<", stream);      fputs_filtered (type_name_no_tag (TYPE_BASECLASS (type, i)), stream);      fputs_filtered ("> = ", stream);      if (err != 0)	fprintf_filtered (stream, "<invalid address 0x%x>", baddr);      else	val_print_fields (TYPE_BASECLASS (type, i), baddr, stream, format,			  recurse, pretty,			  (struct type **)obstack_base (&dont_print_obstack));      fputs_filtered (", ", stream);    flush_it:      ;    }  if (dont_print == 0)    {      /* Free the space used to deal with the printing	 of this type from top level.  */      obstack_free (&dont_print_obstack, last_dont_print);      /* Reset watermark so that we can continue protecting	 ourselves from whatever we were protecting ourselves.  */      dont_print_obstack = tmp_obstack;    }}static voidprint_class_member (valaddr, domain, stream, prefix)     char *valaddr;     struct type *domain;     FILE *stream;     char *prefix;{    /* VAL is a byte offset into the structure type DOMAIN.     Find the name of the field for that offset and     print it.  */  int extra = 0;  int bits = 0;  register unsigned int i;  unsigned len = TYPE_NFIELDS (domain);  /* @@ Make VAL into bit offset */  LONGEST val = unpack_long (builtin_type_int, valaddr) << 3;  for (i = TYPE_N_BASECLASSES (domain); i < len; i++)    {      int bitpos = TYPE_FIELD_BITPOS (domain, i);      QUIT;      if (val == bitpos)	break;      if (val < bitpos && i != 0)	{	  /* Somehow pointing into a field.  */	  i -= 1;	  extra = (val - TYPE_FIELD_BITPOS (domain, i));	  if (extra & 0x7)	    bits = 1;	  else	    extra >>= 3;	  break;	}    }  if (i < len)    {      char *name;      fprintf_filtered (stream, prefix);      name = type_name_no_tag (domain);      if (name)        fputs_filtered (name, stream);      else	type_print_base (domain, stream, 0, 0);      fprintf_filtered (stream, "::");      fputs_filtered (TYPE_FIELD_NAME (domain, i), stream);      if (extra)	fprintf_filtered (stream, " + %d bytes", extra);      if (bits)	fprintf_filtered (stream, " (offset in bits)");    }  else    fprintf_filtered (stream, "%d", val >> 3);}/* Print data of type TYPE located at VALADDR (within GDB),   which came from the inferior at address ADDRESS,   onto stdio stream STREAM according to FORMAT   (a letter or 0 for natural format).  The data at VALADDR   is in target byte order.   If the data are a string pointer, returns the number of   sting characters printed.   if DEREF_REF is nonzero, then dereference references,   otherwise just print them like pointers.   The PRETTY parameter controls prettyprinting.  */intval_print (type, valaddr, address, stream, format, deref_ref, recurse, pretty)     struct type *type;     char *valaddr;     CORE_ADDR address;     FILE *stream;     int format;     int deref_ref;     int recurse;     enum val_prettyprint pretty;{  register unsigned int i;  unsigned len;  struct type *elttype;  unsigned eltlen;  LONGEST val;  unsigned char c;  if (pretty == Val_pretty_default)    {      pretty = prettyprint ? Val_prettyprint : Val_no_prettyprint;    }    QUIT;  check_stub_type (type);    if (TYPE_FLAGS (type) & TYPE_FLAG_STUB)    {      fprintf_filtered (stream, "<unknown struct>");      fflush (stream);      return 0;    }    switch (TYPE_CODE (type))    {    case TYPE_CODE_ARRAY:      if (TYPE_LENGTH (type) > 0	  && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)	{	  elttype = TYPE_TARGET_TYPE (type);	  eltlen = TYPE_LENGTH (elttype);	  len = TYPE_LENGTH (type) / eltlen;	  if (arrayprint)	    print_spaces_filtered (2 + 2 * recurse, stream);	  fprintf_filtered (stream, "{");	  /* For an array of chars, print with string syntax.  */	  if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT	      && (format == 0 || format == 's') )	    print_string (stream, valaddr, len, 0);	  else	    {	      unsigned int things_printed = 0;	      	      /* If this is a virtual function table, print the 0th		 entry specially, and the rest of the members normally.  */	      if (is_vtbl_ptr_type (elttype))		{		  fprintf_filtered (stream, "%d vtable entries", len-1);		  i = 1;		}	      else		i = 0;	      for (; i < len && things_printed < print_max; i++)		{		  /* Position of the array element we are examining to see		     whether it is repeated.  */		  unsigned int rep1;		  /* Number of repetitions we have detected so far.  */		  unsigned int reps;		  		  if (i != 0)		    if (arrayprint)		      {		        fprintf_filtered (stream, ",\n");	                print_spaces_filtered (2 + 2 * recurse, stream);		      }		    else		      fprintf_filtered (stream, ", ");		    wrap_here (n_spaces (2 + 2 * recurse));		  		  rep1 = i + 1;		  reps = 1;		  while (rep1 < len			 && !memcmp (valaddr + i * eltlen,				     valaddr + rep1 * eltlen, eltlen))		    {		      ++reps;		      ++rep1;		    }		  if (reps > REPEAT_COUNT_THRESHOLD)		    {		      val_print (elttype, valaddr + i * eltlen,				 0, stream, format, deref_ref,				 recurse + 1, pretty);		      fprintf_filtered (stream, " <repeats %u times>", reps);		      i = rep1 - 1;		      things_printed += REPEAT_COUNT_THRESHOLD;		    }		  else		    {		      val_print (elttype, valaddr + i * eltlen,				 0, stream, format, deref_ref,				 recurse + 1, pretty);		      things_printed++;		    }		}	      if (i < len)		fprintf_filtered (stream, "...");	    }	  fprintf_filtered (stream, "}");	  break;	}      /* Array of unspecified length: treat like pointer to first elt.  */      valaddr = (char *) &address;    case TYPE_CODE_PTR:      if (format && format != 's')	{	  print_scalar_formatted (valaddr, type, format, 0, stream);	  break;	}      if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)	{	  struct type *domain, *ttype;	  struct fn_field *f;	  int j, len2;	  char *kind = "";	  CORE_ADDR addr;	  ttype = TYPE_TARGET_TYPE (type);	  if (ttype == 0 || (domain = TYPE_DOMAIN_TYPE(ttype)) == 0) {		  printf("<bug workaround: can't print ptr to method>\n");		  break;	  }	  addr = unpack_pointer (lookup_pointer_type (builtin_type_void),				valaddr);	  if (METHOD_PTR_IS_VIRTUAL(addr))	    {	      int offset = METHOD_PTR_TO_VOFFSET(addr);	      len = TYPE_NFN_FIELDS (domain);	      for (i = 0; i < len; i++)		{		  f = TYPE_FN_FIELDLIST1 (domain, i);		  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);		  for (j = 0; j < len2; j++)		    {		      QUIT;		      if (TYPE_FN_FIELD_VOFFSET (f, j) == offset)			{			  kind = "virtual ";			  goto common;			}		    }		}	    }	  else	    {	      struct symbol *sym = find_pc_function (addr);	      if (sym == 0)		error ("invalid pointer to member function");	      len = TYPE_NFN_FIELDS (domain);	      for (i = 0; i < len; i++)		{		  f = TYPE_FN_FIELDLIST1 (domain, i);		  len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);		  for (j = 0; j < len2; j++)		    {		      QUIT;		      if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))			goto common;		    }		}	    }	common:	  if (i < len)	    {	      fprintf_filtered (stream, "&");	      type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);	      fprintf (stream, kind);	      if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'		  && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == CPLUS_MARKER)		type_print_method_args		  (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",		   TYPE_FN_FIELDLIST_NAME (domain, i), 0, stream);	      else		type_print_method_args		  (TYPE_FN_FIELD_ARGS (f, j), "",		   TYPE_FN_FIELDLIST_NAME (domain, i), 0, stream);	      break;	    }	  fprintf_filtered (stream, "(");  	  type_print (type, "", stream, -1);	  fprintf_filtered (stream, ") %d", (int) addr >> 3);	}      else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)	{	  print_class_member (valaddr,			      TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),			      stream, "&");	}      else	{	  CORE_ADDR addr = unpack_pointer (type, valaddr);	  elttype = TYPE_TARGET_TYPE (type);	  if (TYPE_CODE (elttype) == TYPE_CODE_FUNC)	    {	      /* Try to print what function it points to.  */	      print_address_demangle (addr, stream, demangle);	      /* Return value is irrelevant except for string pointers.  */	      return 0;	    }	  if (addressprint && format != 's')	    fprintf_filtered (stream, "0x%x", addr);	  /* For a pointer to char or unsigned char,	     also print the string pointed to, unless pointer is null.  */	  i = 0;		/* Number of characters printed.  */	  if (TYPE_LENGTH (elttype) == 1 	      && TYPE_CODE (elttype) == TYPE_CODE_INT	      && (format == 0 || format == 's')	      && addr != 0	      /* If print_max is UINT_MAX, the alloca below will fail.	         In that case don't try to print the string.  */	      && print_max < UINT_MAX)	    {	      int first_addr_err = 0;	      int errcode = 0;	      	      /* Get first character.  */	      errcode = target_read_memory (addr, (char *)&c, 1);	      if (errcode != 0)		{		  /* First address out of bounds.  */		  first_addr_err = 1;		}	      else		{		  /* A real string.  */		  char *string = (char *) alloca (print_max);		  /* If the loop ends by us hitting print_max characters,		     we need to have elipses at the end.  */		  int force_ellipses = 1;		  /* This loop always fetches print_max characters, even		     though print_string might want to print more or fewer		     (with repeated characters).  This is so that		     we don't spend forever fetching if we print		     a long string consisting of the same character		     repeated.  Also so we can do it all in one memory		     operation, which is faster.  However, this will be		     slower if print_max is set high, e.g. if you set		     print_max to 1000, not only will it take a long		     time to fetch short strings, but if you are near		     the end of the address space, it might not work. */		  QUIT;		  errcode = target_read_memory (addr, string, print_max);		  if (errcode != 0)		    {		      /* Try reading just one character.  If that succeeds,			 assume we hit the end of the address space, but			 the initial part of the string is probably safe. */		      char x[1];		      errcode = target_read_memory (addr, x, 1);		    }		  if (errcode != 0)		      force_ellipses = 0;		  else 		    for (i = 0; i < print_max; i++)		      if (string[i] == '\0')			{			  force_ellipses = 0;			  break;		        }		  QUIT;		  if (addressprint)		    fputs_filtered (" ", stream);		  print_string (stream, string, i, force_ellipses);		}	      if (errcode != 0)		{		  if (errcode == EIO)		    {		      fprintf_filtered (stream,					(" <Address 0x%x out of bounds>"					 + first_addr_err),					addr + i);		    }		  else		    {		      error ("Error reading memory address 0x%x: %s.",			     addr + i, safe_strerror (errcode));		    }		}	      fflush (stream);	    }	  else /* print vtbl's nicely */ 	  if (is_vtbl_member(type))  	    {	      CORE_ADDR vt_address = unpack_pointer (type, valaddr);	      struct minimal_symbol *msymbol =		lookup_minimal_symbol_by_pc (vt_address);	      if ((msymbol != NULL) && (vt_address == msymbol -> address))		{		  fputs_filtered (" <", stream);		  fputs_demangled (msymbol -> name, stream,				   DMGL_ANSI | DMGL_PARAMS);		  fputs_filtered (">", stream);		}	      if (vtblprint)	        {		  value vt_val;		  vt_val = value_at (TYPE_TARGET_TYPE (type), vt_address);		  val_print (VALUE_TYPE (vt_val), VALUE_CONTENTS (vt_val),			     VALUE_ADDRESS (vt_val), stream, format,			     deref_ref, recurse + 1, pretty);		  if (pretty)		    {		      fprintf_filtered (stream, "\n");		      print_spaces_filtered (2 + 2 * recurse, stream);		    }	        }	      }	  /* Return number of characters printed, plus one for the	     terminating null if we have "reached the end".  */	  return i + (print_max && i != print_max);	}      break;    case TYPE_CODE_MEMBER:      error ("not implemented: member type in val_print");      break;    case TYPE_CODE_REF:      {	CORE_ADDR addr = unpack_long (builtin_type_int, valaddr);	if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)	  {	    print_class_member (valaddr,				TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)),				stream, "");	    break;	  }	if (addressprint)	  {	    fprintf_filtered (stream, "@0x%lx", addr);	    if (deref_ref)	      fputs_filtered (": ", stream);	  }	/* De-reference the reference.  */	if (deref_ref)	  {	    if (target_read_memory(addr, (char *)&c, 1))	     {	       fprintf_filtered (stream, "<Address out of bounds>");	       break;	     }	    if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)	      {		value deref_val = value_at (TYPE_TARGET_TYPE (type), addr);		val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val),			   VALUE_ADDRESS (deref_val), stream, format,			   deref_ref, recurse + 1, pretty);	      }

⌨️ 快捷键说明

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