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

📄 values.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* This coerces arrays and functions, which is necessary (e.g.     in disassemble_command).  It also dereferences references, which     I suspect is the most logical thing to do.  */  if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM)    COERCE_ARRAY (val);  return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));}doublevalue_as_double (val)     register value val;{  double foo;  int inv;    foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);  if (inv)    error ("Invalid floating value found in program.");  return foo;}/* Extract a value as a C pointer.   Does not deallocate the value.  */CORE_ADDRvalue_as_pointer (val)     value val;{  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure     whether we want this to be true eventually.  */  return ADDR_BITS_REMOVE(value_as_long (val));}/* Unpack raw data (copied from debugee, target byte order) at VALADDR   as a long, or as a double, assuming the raw data is described   by type TYPE.  Knows how to convert different sizes of values   and can convert between fixed and floating point.  We don't assume   any alignment for the raw data.  Return value is in host byte order.   If you want functions and arrays to be coerced to pointers, and   references to be dereferenced, call value_as_long() instead.   C++: It is assumed that the front-end has taken care of   all matters concerning pointers to members.  A pointer   to member which reaches here is considered to be equivalent   to an INT (or some size).  After all, it is only an offset.  *//* FIXME:  This should be rewritten as a switch statement for speed and   ease of comprehension.  */LONGESTunpack_long (type, valaddr)     struct type *type;     char *valaddr;{  register enum type_code code = TYPE_CODE (type);  register int len = TYPE_LENGTH (type);  register int nosign = TYPE_UNSIGNED (type);  if (code == TYPE_CODE_ENUM || code == TYPE_CODE_BOOL)    code = TYPE_CODE_INT;  if (code == TYPE_CODE_FLT)    {      if (len == sizeof (float))	{	  float retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (double))	{	  double retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      else	{	  error ("Unexpected type of floating point number.");	}    }  else if (code == TYPE_CODE_INT && nosign)    {      if (len == sizeof (char))	{	  unsigned char retval = * (unsigned char *) valaddr;	  /* SWAP_TARGET_AND_HOST (&retval, sizeof (unsigned char)); */	  return retval;	}      if (len == sizeof (short))	{	  unsigned short retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (int))	{	  unsigned int retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (long))	{	  unsigned long retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}#ifdef LONG_LONG      if (len == sizeof (long long))	{	  unsigned long long retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}#endif      else	{	  error ("That operation is not possible on an integer of that size.");	}    }  else if (code == TYPE_CODE_INT)    {      if (len == sizeof (char))	{	  SIGNED char retval;	/* plain chars might be unsigned on host */	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (short))	{	  short retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (int))	{	  int retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (long))	{	  long retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}#ifdef LONG_LONG      if (len == sizeof (long long))	{	  long long retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}#endif      else	{	  error ("That operation is not possible on an integer of that size.");	}    }  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure     whether we want this to be true eventually.  */  else if (code == TYPE_CODE_PTR	   || code == TYPE_CODE_REF)    {      if (len == sizeof(long))      {	unsigned long retval;	memcpy (&retval, valaddr, sizeof(retval));	SWAP_TARGET_AND_HOST (&retval, sizeof(retval));	return retval;      }      else if (len == sizeof(short))      {	unsigned short retval;	memcpy (&retval, valaddr, len);	SWAP_TARGET_AND_HOST (&retval, len);	return retval;      }    }  else if (code == TYPE_CODE_MEMBER)    error ("not implemented: member types in unpack_long");  else if (code == TYPE_CODE_CHAR)    return *(unsigned char *)valaddr;  error ("Value not integer or pointer.");  return 0; 	/* For lint -- never reached */}/* Return a double value from the specified type and address.   INVP points to an int which is set to 0 for valid value,   1 for invalid value (bad float format).  In either case,   the returned double is OK to use.  Argument is in target   format, result is in host format.  */doubleunpack_double (type, valaddr, invp)     struct type *type;     char *valaddr;     int *invp;{  register enum type_code code = TYPE_CODE (type);  register int len = TYPE_LENGTH (type);  register int nosign = TYPE_UNSIGNED (type);  *invp = 0;			/* Assume valid.   */  if (code == TYPE_CODE_FLT)    {      if (INVALID_FLOAT (valaddr, len))	{	  *invp = 1;	  return 1.234567891011121314;	}      if (len == sizeof (float))	{	  float retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      if (len == sizeof (double))	{	  double retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      else	{	  error ("Unexpected type of floating point number.");	  return 0; /* Placate lint.  */	}    }  else if (nosign) {   /* Unsigned -- be sure we compensate for signed LONGEST.  */#ifdef LONG_LONG   return (unsigned long long) unpack_long (type, valaddr);#else   return (unsigned long     ) unpack_long (type, valaddr);#endif  } else {    /* Signed -- we are OK with unpack_long.  */    return unpack_long (type, valaddr);  }}/* Unpack raw data (copied from debugee, target byte order) at VALADDR   as a CORE_ADDR, assuming the raw data is described by type TYPE.   We don't assume any alignment for the raw data.  Return value is in   host byte order.   If you want functions and arrays to be coerced to pointers, and   references to be dereferenced, call value_as_pointer() instead.   C++: It is assumed that the front-end has taken care of   all matters concerning pointers to members.  A pointer   to member which reaches here is considered to be equivalent   to an INT (or some size).  After all, it is only an offset.  */CORE_ADDRunpack_pointer (type, valaddr)     struct type *type;     char *valaddr;{#if 0  /* The user should be able to use an int (e.g. 0x7892) in contexts     where a pointer is expected.  So this doesn't do enough.  */  register enum type_code code = TYPE_CODE (type);  register int len = TYPE_LENGTH (type);  if (code == TYPE_CODE_PTR      || code == TYPE_CODE_REF)    {      if (len == sizeof (CORE_ADDR))	{	  CORE_ADDR retval;	  memcpy (&retval, valaddr, sizeof (retval));	  SWAP_TARGET_AND_HOST (&retval, sizeof (retval));	  return retval;	}      error ("Unrecognized pointer size.");    }  else if (code == TYPE_CODE_MEMBER)    error ("not implemented: member types in unpack_pointer");  error ("Value is not a pointer.");  return 0; 	/* For lint -- never reached */#else  /* Assume a CORE_ADDR can fit in a LONGEST (for now).  Not sure     whether we want this to be true eventually.  */  return unpack_long (type, valaddr);#endif}/* Given a value ARG1 (offset by OFFSET bytes)   of a struct or union type ARG_TYPE,   extract and return the value of one of its fields.   FIELDNO says which field.   For C++, must also be able to return values from static fields */valuevalue_primitive_field (arg1, offset, fieldno, arg_type)     register value arg1;     int offset;     register int fieldno;     register struct type *arg_type;{  register value v;  register struct type *type;  check_stub_type (arg_type);  type = TYPE_FIELD_TYPE (arg_type, fieldno);  /* Handle packed fields */  offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;  if (TYPE_FIELD_BITSIZE (arg_type, fieldno))    {      v = value_from_longest (type,			   unpack_field_as_long (arg_type,						 VALUE_CONTENTS (arg1),						 fieldno));      VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (arg_type, fieldno) % 8;      VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (arg_type, fieldno);    }  else    {      v = allocate_value (type);      if (VALUE_LAZY (arg1))	VALUE_LAZY (v) = 1;      else	memcpy (VALUE_CONTENTS_RAW (v), VALUE_CONTENTS_RAW (arg1) + offset,		TYPE_LENGTH (type));    }  VALUE_LVAL (v) = VALUE_LVAL (arg1);  if (VALUE_LVAL (arg1) == lval_internalvar)    VALUE_LVAL (v) = lval_internalvar_component;  VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);  VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);  return v;}/* Given a value ARG1 of a struct or union type,   extract and return the value of one of its fields.   FIELDNO says which field.   For C++, must also be able to return values from static fields */valuevalue_field (arg1, fieldno)     register value arg1;     register int fieldno;{  return value_primitive_field (arg1, 0, fieldno, VALUE_TYPE (arg1));}/* Return a non-virtual function as a value.   F is the list of member functions which contains the desired method.   J is an index into F which provides the desired method. */valuevalue_fn_field (arg1p, f, j, type, offset)     value *arg1p;     struct fn_field *f;     int j;     struct type *type;     int offset;{  register value v;  register struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);  struct symbol *sym;  sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j),		       0, VAR_NAMESPACE, 0, NULL);  if (! sym) error ("Internal error: could not find physical method named %s",		    TYPE_FN_FIELD_PHYSNAME (f, j));    v = allocate_value (ftype);  VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));  VALUE_TYPE (v) = ftype;  if (arg1p)   {    if (type != VALUE_TYPE (*arg1p))      *arg1p = value_ind (value_cast (lookup_pointer_type (type),				      value_addr (*arg1p)));    /* Move the `this' pointer according to the offset. */    VALUE_OFFSET (*arg1p) += offset;    }  return v;}/* Return a virtual function as a value.   ARG1 is the object which provides the virtual function   table pointer.  *ARG1P is side-effected in calling this function.   F is the list of member functions which contains the desired virtual   function.   J is an index into F which provides the desired virtual function.   TYPE is the type in which F is located.  */valuevalue_virtual_fn_field (arg1p, f, j, type, offset)     value *arg1p;     struct fn_field *f;     int j;     struct type *type;     int offset;{  value arg1 = *arg1p;  /* First, get the virtual function table pointer.  That comes     with a strange type, so cast it to type `pointer to long' (which     should serve just fine as a function type).  Then, index into     the table, and convert final value to appropriate function type.  */  value entry, vfn, vtbl;  value vi = value_from_longest (builtin_type_int, 			      (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));  struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j);  struct type *context;  if (fcontext == NULL)   /* We don't have an fcontext (e.g. the program was compiled with      g++ version 1).  Try to get the vtbl from the TYPE_VPTR_BASETYPE.      This won't work right for multiple inheritance, but at least we      should do as well as GDB 3.x did.  */    fcontext = TYPE_VPTR_BASETYPE (type);  context = lookup_pointer_type (fcontext);  /* Now context is a pointer to the basetype containing the vtbl.  */  if (TYPE_TARGET_TYPE (context) != VALUE_TYPE (arg1))    arg1 = value_ind (value_cast (context, value_addr (arg1)));  context = VALUE_TYPE (arg1);  /* Now context is the basetype containing the vtbl.  */  /* This type may have been defined before its virtual function table     was.  If so, fill in the virtual function table entry for the     type now.  */  if (TYPE_VPTR_FIELDNO (context) < 0)    fill_in_vptr_fieldno (context);  /* The virtual function table is now an array of structures     which have the form { int16 offset, delta; void *pfn; }.  */  vtbl = value_ind (value_primitive_field (arg1, 0, 					   TYPE_VPTR_FIELDNO (context),					   TYPE_VPTR_BASETYPE (context)));  /* Index into the virtual function table.  This is hard-coded because     looking up a field is not cheap, and it may be important to save     time, e.g. if the user has set a conditional breakpoint calling     a virtual function.  */  entry = value_subscript (vtbl, vi);  /* Move the `this' pointer according to the virtual function table.  */  VALUE_OFFSET (arg1) += value_as_long (value_field (entry, 0)) + offset;  if (! VALUE_LAZY (arg1))    {      VALUE_LAZY (arg1) = 1;      value_fetch_lazy (arg1);    }  vfn = value_field (entry, 2);  /* Reinstantiate the function pointer with the correct type.  */  VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));  *arg1p = arg1;  return vfn;}/* ARG is a pointer to an object we know to be at least   a DTYPE.  BTYPE is the most derived basetype that has   already been searched (and need not be searched again).   After looking at the vtables between BTYPE and DTYPE,   return the most derived type we find.  The caller must   be satisfied when the return value == DTYPE.   FIXME-tiemann: should work with dossier entries as well.  */static valuevalue_headof (arg, btype, dtype)     value arg;     struct type *btype, *dtype;{  /* First collect the vtables we must look at for this object.  */  /* FIXME-tiemann: right now, just look at top-most vtable.  */  value vtbl, entry, best_entry = 0;  int i, nelems;  int offset, best_offset = 0;  struct symbol *sym;  CORE_ADDR pc_for_sym;  char *demangled_name;  struct minimal_symbol *msymbol;  btype = TYPE_VPTR_BASETYPE (dtype);  check_stub_type (btype);  if (btype != dtype)    vtbl = value_cast (lookup_pointer_type (btype), arg);  else    vtbl = arg;  vtbl = value_ind (value_field (value_ind (vtbl), TYPE_VPTR_FIELDNO (btype)));  /* Check that VTBL looks like it points to a virtual function table.  */  msymbol = lookup_minimal_symbol_by_pc (VALUE_ADDRESS (vtbl));  if (msymbol == NULL      || !VTBL_PREFIX_P (demangled_name = msymbol -> name))    {      /* If we expected to find a vtable, but did not, let the user	 know that we aren't happy, but don't throw an error.	 FIXME: there has to be a better way to do this.  */

⌨️ 快捷键说明

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