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

📄 values.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
      struct type *error_type = (struct type *)xmalloc (sizeof (struct type));      memcpy (error_type, VALUE_TYPE (arg), sizeof (struct type));      TYPE_NAME (error_type) = savestring ("suspicious *", sizeof ("suspicious *"));      VALUE_TYPE (arg) = error_type;      return arg;    }  /* Now search through the virtual function table.  */  entry = value_ind (vtbl);  nelems = longest_to_int (value_as_long (value_field (entry, 2)));  for (i = 1; i <= nelems; i++)    {      entry = value_subscript (vtbl, value_from_longest (builtin_type_int, 						      (LONGEST) i));      offset = longest_to_int (value_as_long (value_field (entry, 0)));      /* If we use '<=' we can handle single inheritance       * where all offsets are zero - just use the first entry found. */      if (offset <= best_offset)	{	  best_offset = offset;	  best_entry = entry;	}    }  /* Move the pointer according to BEST_ENTRY's offset, and figure     out what type we should return as the new pointer.  */  if (best_entry == 0)    {      /* An alternative method (which should no longer be necessary).       * But we leave it in for future use, when we will hopefully       * have optimizes the vtable to use thunks instead of offsets. */      /* Use the name of vtable itself to extract a base type. */      demangled_name += 4;  /* Skip _vt$ prefix. */    }  else    {      pc_for_sym = value_as_pointer (value_field (best_entry, 2));      sym = find_pc_function (pc_for_sym);      demangled_name = cplus_demangle (SYMBOL_NAME (sym), DMGL_ANSI);      *(strchr (demangled_name, ':')) = '\0';    }  sym = lookup_symbol (demangled_name, 0, VAR_NAMESPACE, 0, 0);  if (sym == 0)    error ("could not find type declaration for `%s'", SYMBOL_NAME (sym));  if (best_entry)    {      free (demangled_name);      arg = value_add (value_cast (builtin_type_int, arg),		       value_field (best_entry, 0));    }  VALUE_TYPE (arg) = lookup_pointer_type (SYMBOL_TYPE (sym));  return arg;}/* ARG is a pointer object of type TYPE.  If TYPE has virtual   function tables, probe ARG's tables (including the vtables   of its baseclasses) to figure out the most derived type that ARG   could actually be a pointer to.  */valuevalue_from_vtable_info (arg, type)     value arg;     struct type *type;{  /* Take care of preliminaries.  */  if (TYPE_VPTR_FIELDNO (type) < 0)    fill_in_vptr_fieldno (type);  if (TYPE_VPTR_FIELDNO (type) < 0 || VALUE_REPEATED (arg))    return 0;  return value_headof (arg, 0, type);}/* Compute the offset of the baseclass which is   the INDEXth baseclass of class TYPE, for a value ARG,   wih extra offset of OFFSET.   The result is the offste of the baseclass value relative   to (the address of)(ARG) + OFFSET.   -1 is returned on error. */intbaseclass_offset (type, index, arg, offset)     struct type *type;     int index;     value arg;     int offset;{  struct type *basetype = TYPE_BASECLASS (type, index);  if (BASETYPE_VIA_VIRTUAL (type, index))    {      /* Must hunt for the pointer to this virtual baseclass.  */      register int i, len = TYPE_NFIELDS (type);      register int n_baseclasses = TYPE_N_BASECLASSES (type);      char *vbase_name, *type_name = type_name_no_tag (basetype);      vbase_name = (char *)alloca (strlen (type_name) + 8);      sprintf (vbase_name, "_vb%c%s", CPLUS_MARKER, type_name);      /* First look for the virtual baseclass pointer	 in the fields.  */      for (i = n_baseclasses; i < len; i++)	{	  if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i)))	    {	      CORE_ADDR addr		= unpack_pointer (TYPE_FIELD_TYPE (type, i),				  VALUE_CONTENTS (arg) + VALUE_OFFSET (arg)				  + offset				  + (TYPE_FIELD_BITPOS (type, i) / 8));	      if (VALUE_LVAL (arg) != lval_memory)		  return -1;	      return addr -		  (LONGEST) (VALUE_ADDRESS (arg) + VALUE_OFFSET (arg) + offset);	    }	}      /* Not in the fields, so try looking through the baseclasses.  */      for (i = index+1; i < n_baseclasses; i++)	{	  int boffset =	      baseclass_offset (type, i, arg, offset);	  if (boffset)	    return boffset;	}      /* Not found.  */      return -1;    }  /* Baseclass is easily computed.  */  return TYPE_BASECLASS_BITPOS (type, index) / 8;}/* Compute the address of the baseclass which is   the INDEXth baseclass of class TYPE.  The TYPE base   of the object is at VALADDR.   If ERRP is non-NULL, set *ERRP to be the errno code of any error,   or 0 if no error.  In that case the return value is not the address   of the baseclasss, but the address which could not be read   successfully.  *//* FIXME Fix remaining uses of baseclass_addr to use baseclass_offset */char *baseclass_addr (type, index, valaddr, valuep, errp)     struct type *type;     int index;     char *valaddr;     value *valuep;     int *errp;{  struct type *basetype = TYPE_BASECLASS (type, index);  if (errp)    *errp = 0;  if (BASETYPE_VIA_VIRTUAL (type, index))    {      /* Must hunt for the pointer to this virtual baseclass.  */      register int i, len = TYPE_NFIELDS (type);      register int n_baseclasses = TYPE_N_BASECLASSES (type);      char *vbase_name, *type_name = type_name_no_tag (basetype);      vbase_name = (char *)alloca (strlen (type_name) + 8);      sprintf (vbase_name, "_vb$%s", type_name);      /* First look for the virtual baseclass pointer	 in the fields.  */      for (i = n_baseclasses; i < len; i++)	{	  if (! strcmp (vbase_name, TYPE_FIELD_NAME (type, i)))	    {	      value val = allocate_value (basetype);	      CORE_ADDR addr;	      int status;	      addr		= unpack_pointer (TYPE_FIELD_TYPE (type, i),				  valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));	      status = target_read_memory (addr,					   VALUE_CONTENTS_RAW (val),					   TYPE_LENGTH (basetype));	      VALUE_LVAL (val) = lval_memory;	      VALUE_ADDRESS (val) = addr;	      if (status != 0)		{		  if (valuep)		    *valuep = NULL;		  release_value (val);		  value_free (val);		  if (errp)		    *errp = status;		  return (char *)addr;		}	      else		{		  if (valuep)		    *valuep = val;		  return (char *) VALUE_CONTENTS (val);		}	    }	}      /* Not in the fields, so try looking through the baseclasses.  */      for (i = index+1; i < n_baseclasses; i++)	{	  char *baddr;	  baddr = baseclass_addr (type, i, valaddr, valuep, errp);	  if (baddr)	    return baddr;	}      /* Not found.  */      if (valuep)	*valuep = 0;      return 0;    }  /* Baseclass is easily computed.  */  if (valuep)    *valuep = 0;  return valaddr + TYPE_BASECLASS_BITPOS (type, index) / 8;}/* Unpack a field FIELDNO of the specified TYPE, from the anonymous object at   VALADDR.   Extracting bits depends on endianness of the machine.  Compute the   number of least significant bits to discard.  For big endian machines,   we compute the total number of bits in the anonymous object, subtract   off the bit count from the MSB of the object to the MSB of the   bitfield, then the size of the bitfield, which leaves the LSB discard   count.  For little endian machines, the discard count is simply the   number of bits from the LSB of the anonymous object to the LSB of the   bitfield.   If the field is signed, we also do sign extension. */LONGESTunpack_field_as_long (type, valaddr, fieldno)     struct type *type;     char *valaddr;     int fieldno;{  unsigned LONGEST val;  unsigned LONGEST valmask;  int bitpos = TYPE_FIELD_BITPOS (type, fieldno);  int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);  int lsbcount;  memcpy (&val, valaddr + bitpos / 8, sizeof (val));  SWAP_TARGET_AND_HOST (&val, sizeof (val));  /* Extract bits.  See comment above. */#if BITS_BIG_ENDIAN  lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);#else  lsbcount = (bitpos % 8);#endif  val >>= lsbcount;  /* If the field does not entirely fill a LONGEST, then zero the sign bits.     If the field is signed, and is negative, then sign extend. */  if ((bitsize > 0) && (bitsize < 8 * sizeof (val)))    {      valmask = (((unsigned LONGEST) 1) << bitsize) - 1;      val &= valmask;      if (!TYPE_UNSIGNED (TYPE_FIELD_TYPE (type, fieldno)))	{	  if (val & (valmask ^ (valmask >> 1)))	    {	      val |= ~valmask;	    }	}    }  return (val);}/* Modify the value of a bitfield.  ADDR points to a block of memory in   target byte order; the bitfield starts in the byte pointed to.  FIELDVAL   is the desired value of the field, in host byte order.  BITPOS and BITSIZE   indicate which bits (in target bit order) comprise the bitfield.  */voidmodify_field (addr, fieldval, bitpos, bitsize)     char *addr;     int fieldval;     int bitpos, bitsize;{  long oword;  /* Reject values too big to fit in the field in question,     otherwise adjoining fields may be corrupted.  */  if (bitsize < (8 * sizeof (fieldval))      && 0 != (fieldval & ~((1<<bitsize)-1)))    error ("Value %d does not fit in %d bits.", fieldval, bitsize);    memcpy (&oword, addr, sizeof oword);  SWAP_TARGET_AND_HOST (&oword, sizeof oword);		/* To host format */  /* Shifting for bit field depends on endianness of the target machine.  */#if BITS_BIG_ENDIAN  bitpos = sizeof (oword) * 8 - bitpos - bitsize;#endif  /* Mask out old value, while avoiding shifts >= longword size */  if (bitsize < 8 * sizeof (oword))    oword &= ~(((((unsigned long)1) << bitsize) - 1) << bitpos);  else    oword &= ~((-1) << bitpos);  oword |= fieldval << bitpos;  SWAP_TARGET_AND_HOST (&oword, sizeof oword);		/* To target format */  memcpy (addr, &oword, sizeof oword);}/* Convert C numbers into newly allocated values */valuevalue_from_longest (type, num)     struct type *type;     register LONGEST num;{  register value val = allocate_value (type);  register enum type_code code = TYPE_CODE (type);  register int len = TYPE_LENGTH (type);  /* FIXME, we assume that pointers have the same form and byte order as     integers, and that all pointers have the same form.  */  if (code == TYPE_CODE_INT  || code == TYPE_CODE_ENUM ||       code == TYPE_CODE_CHAR || code == TYPE_CODE_PTR ||      code == TYPE_CODE_REF)    {      if (len == sizeof (char))	* (char *) VALUE_CONTENTS_RAW (val) = num;      else if (len == sizeof (short))	* (short *) VALUE_CONTENTS_RAW (val) = num;      else if (len == sizeof (int))	* (int *) VALUE_CONTENTS_RAW (val) = num;      else if (len == sizeof (long))	* (long *) VALUE_CONTENTS_RAW (val) = num;#ifdef LONG_LONG      else if (len == sizeof (long long))	* (long long *) VALUE_CONTENTS_RAW (val) = num;#endif      else	error ("Integer type encountered with unexpected data length.");    }  else    error ("Unexpected type encountered for integer constant.");  /* num was in host byte order.  So now put the value's contents     into target byte order.  */  SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (val), len);  return val;}valuevalue_from_double (type, num)     struct type *type;     double num;{  register value val = allocate_value (type);  register enum type_code code = TYPE_CODE (type);  register int len = TYPE_LENGTH (type);  if (code == TYPE_CODE_FLT)    {      if (len == sizeof (float))	* (float *) VALUE_CONTENTS_RAW (val) = num;      else if (len == sizeof (double))	* (double *) VALUE_CONTENTS_RAW (val) = num;      else	error ("Floating type encountered with unexpected data length.");    }  else    error ("Unexpected type encountered for floating constant.");  /* num was in host byte order.  So now put the value's contents     into target byte order.  */  SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (val), len);  return val;}/* Deal with the value that is "about to be returned".  *//* Return the value that a function returning now   would be returning to its caller, assuming its type is VALTYPE.   RETBUF is where we look for what ought to be the contents   of the registers (in raw form).  This is because it is often   desirable to restore old values to those registers   after saving the contents of interest, and then call   this function using the saved values.   struct_return is non-zero when the function in question is   using the structure return conventions on the machine in question;   0 when it is using the value returning conventions (this often   means returning pointer to where structure is vs. returning value). */valuevalue_being_returned (valtype, retbuf, struct_return)     register struct type *valtype;     char retbuf[REGISTER_BYTES];     int struct_return;     /*ARGSUSED*/{  register value val;  CORE_ADDR addr;#if defined (EXTRACT_STRUCT_VALUE_ADDRESS)  /* If this is not defined, just use EXTRACT_RETURN_VALUE instead.  */  if (struct_return) {    addr = EXTRACT_STRUCT_VALUE_ADDRESS (retbuf);    if (!addr)      error ("Function return value unknown");    return value_at (valtype, addr);  }#endif  val = allocate_value (valtype);  EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS_RAW (val));  return val;}/* Should we use EXTRACT_STRUCT_VALUE_ADDRESS instead of   EXTRACT_RETURN_VALUE?  GCC_P is true if compiled with gcc   and TYPE is the type (which is known to be struct, union or array).   On most machines, the struct convention is used unless we are   using gcc and the type is of a special size.  */#if !defined (USE_STRUCT_CONVENTION)#define USE_STRUCT_CONVENTION(gcc_p, type)\  (!((gcc_p) && (TYPE_LENGTH (value_type) == 1                \		 || TYPE_LENGTH (value_type) == 2             \	         || TYPE_LENGTH (value_type) == 4             \		 || TYPE_LENGTH (value_type) == 8             \		 )                                            \     ))#endif/* Return true if the function specified is using the structure returning   convention on this machine to return arguments, or 0 if it is using   the value returning convention.  FUNCTION is the value representing   the function, FUNCADDR is the address of the function, and VALUE_TYPE   is the type returned by the function.  GCC_P is nonzero if compiled   with GCC.  */intusing_struct_return (function, funcaddr, value_type, gcc_p)     value function;     CORE_ADDR funcaddr;     struct type *value_type;     int gcc_p;     /*ARGSUSED*/{  register enum type_code code = TYPE_CODE (value_type);  if (code == TYPE_CODE_ERROR)    error ("Function return type unknown.");  if (code == TYPE_CODE_STRUCT ||      code == TYPE_CODE_UNION ||      code == TYPE_CODE_ARRAY)    return USE_STRUCT_CONVENTION (gcc_p, value_type);  return 0;}/* Store VAL so it will be returned if a function returns now.   Does not verify that VAL's type matches what the current   function wants to return.  */voidset_return_value (val)     value val;{  register enum type_code code = TYPE_CODE (VALUE_TYPE (val));  double dbuf;  LONGEST lbuf;  if (code == TYPE_CODE_ERROR)    error ("Function return type unknown.");  if (   code == TYPE_CODE_STRUCT      || code == TYPE_CODE_UNION)	/* FIXME, implement struct return.  */    error ("GDB does not support specifying a struct or union return value.");  /* FIXME, this is bogus.  We don't know what the return conventions     are, or how values should be promoted.... */  if (code == TYPE_CODE_FLT)    {      dbuf = value_as_double (val);      STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&dbuf);    }  else    {      lbuf = value_as_long (val);      STORE_RETURN_VALUE (VALUE_TYPE (val), (char *)&lbuf);    }}void_initialize_values (){  add_cmd ("convenience", no_class, show_convenience,	    "Debugger convenience (\"$foo\") variables.\n\These variables are created when you assign them values;\n\thus, \"print $foo=1\" gives \"$foo\" the value 1.  Values may be any type.\n\n\A few convenience variables are given values automatically:\n\\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\\"$__\" holds the contents of the last address examined with \"x\".",	   &showlist);  add_cmd ("values", no_class, show_values,	   "Elements of value history around item number IDX (or last ten).",	   &showlist);}

⌨️ 快捷键说明

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