コード例 #1
0
static struct value *
gnuv3_get_vtable (struct gdbarch *gdbarch, struct value *container)
{
  struct type *vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
  struct type *vtable_pointer_type;
  struct value *vtable_pointer;
  CORE_ADDR vtable_pointer_address, vtable_address;

  /* We do not consult the debug information to find the virtual table.
     The ABI specifies that it is always at offset zero in any class,
     and debug information may not represent it.  We won't issue an
     error if there's a class with virtual functions but no virtual table
     pointer, but something's already gone seriously wrong if that
     happens.

     We avoid using value_contents on principle, because the object might
     be large.  */

  /* Find the type "pointer to virtual table".  */
  vtable_pointer_type = lookup_pointer_type (vtable_type);

  /* Load it from the start of the class.  */
  vtable_pointer_address = value_as_address (value_addr (container));
  vtable_pointer = value_at (vtable_pointer_type, vtable_pointer_address);
  vtable_address = value_as_address (vtable_pointer);

  /* Correct it to point at the start of the virtual table, rather
     than the address point.  */
  return value_at_lazy (vtable_type,
			vtable_address - vtable_address_point_offset (gdbarch));
}
コード例 #2
0
ファイル: main.c プロジェクト: 2asoft/freebsd
/*
 * Parse an expression and return its value.  If 'quiet' is true, then
 * any error messages from the parser are masked.
 */
CORE_ADDR
kgdb_parse_1(const char *exp, int quiet)
{
	struct ui_file *old_stderr;
	struct cleanup *old_chain;
	struct expression *expr;
	struct value *val;
	char *s;
	CORE_ADDR n;

	old_stderr = gdb_stderr;
	if (quiet)
		gdb_stderr = parse_gdberr;
	n = 0;
	s = xstrdup(exp);
	old_chain = make_cleanup(xfree, s);
	if (gdb_parse_exp_1(&s, NULL, 0, &expr) && *s == '\0') {
		make_cleanup(free_current_contents, &expr);
		if (gdb_evaluate_expression(expr, &val))
		    n = value_as_address(val);
	}
	do_cleanups(old_chain);
	gdb_stderr = old_stderr;
	return (n);
}
コード例 #3
0
ファイル: gnu-v3-abi.c プロジェクト: nds32/binutils
static struct value *
gnuv3_get_vtable (struct gdbarch *gdbarch,
		  struct type *container_type, CORE_ADDR container_addr)
{
  struct type *vtable_type = gdbarch_data (gdbarch,
					   vtable_type_gdbarch_data);
  struct type *vtable_pointer_type;
  struct value *vtable_pointer;
  CORE_ADDR vtable_address;

  /* If this type does not have a virtual table, don't read the first
     field.  */
  if (!gnuv3_dynamic_class (check_typedef (container_type)))
    return NULL;

  /* We do not consult the debug information to find the virtual table.
     The ABI specifies that it is always at offset zero in any class,
     and debug information may not represent it.

     We avoid using value_contents on principle, because the object might
     be large.  */

  /* Find the type "pointer to virtual table".  */
  vtable_pointer_type = lookup_pointer_type (vtable_type);

  /* Load it from the start of the class.  */
  vtable_pointer = value_at (vtable_pointer_type, container_addr);
  vtable_address = value_as_address (vtable_pointer);

  /* Correct it to point at the start of the virtual table, rather
     than the address point.  */
  return value_at_lazy (vtable_type,
			vtable_address
			- vtable_address_point_offset (gdbarch));
}
コード例 #4
0
ファイル: macosx-nat-info.c プロジェクト: HoMeCracKeR/gdb-ng
void
info_mach_region_command (char *exp, int from_tty)
{
  struct expression *expr;
  struct value *val;

  vm_address_t address;

  expr = parse_expression (exp);
  val = evaluate_expression (expr);
  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
    {
      val = value_ind (val);
    }
  /* In rvalue contexts, such as this, functions are coerced into
     pointers to functions. */
  if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
      && VALUE_LVAL (val) == lval_memory)
    {
      address = VALUE_ADDRESS (val);
    }
  else
    {
      address = value_as_address (val);
    }

  if ((!macosx_status) || (macosx_status->task == TASK_NULL))
    {
      error ("Inferior not available");
    }

  macosx_debug_region (macosx_status->task, address);
}
コード例 #5
0
ファイル: py-utils.c プロジェクト: abidh/gdb
int
get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
{
  if (gdbpy_is_value_object (obj))
    *addr = value_as_address (value_object_to_value (obj));
  else
    {
      PyObject *num = PyNumber_Long (obj);
      gdb_py_ulongest val;

      if (num == NULL)
	return 0;

      val = gdb_py_long_as_ulongest (num);
      Py_XDECREF (num);
      if (PyErr_Occurred ())
	return 0;

      if (sizeof (val) > sizeof (CORE_ADDR) && ((CORE_ADDR) val) != val)
	{
	  PyErr_SetString (PyExc_ValueError,
			   _("Overflow converting to address."));
	  return 0;
	}

      *addr = val;
    }

  return 1;
}
コード例 #6
0
ファイル: gnu-v3-abi.c プロジェクト: nds32/binutils
static struct value *
gnuv3_get_virtual_fn (struct gdbarch *gdbarch, struct value *container,
		      struct type *fntype, int vtable_index)
{
  struct value *vtable, *vfn;

  /* Every class with virtual functions must have a vtable.  */
  vtable = gnuv3_get_vtable (gdbarch, value_type (container),
			     value_as_address (value_addr (container)));
  gdb_assert (vtable != NULL);

  /* Fetch the appropriate function pointer from the vtable.  */
  vfn = value_subscript (value_field (vtable, vtable_field_virtual_functions),
                         vtable_index);

  /* If this architecture uses function descriptors directly in the vtable,
     then the address of the vtable entry is actually a "function pointer"
     (i.e. points to the descriptor).  We don't need to scale the index
     by the size of a function descriptor; GCC does that before outputing
     debug information.  */
  if (gdbarch_vtable_function_descriptors (gdbarch))
    vfn = value_addr (vfn);

  /* Cast the function pointer to the appropriate type.  */
  vfn = value_cast (lookup_pointer_type (fntype), vfn);

  return vfn;
}
コード例 #7
0
ファイル: jv-lang.c プロジェクト: NalaGinrut/gdb
/* Check if CLASS_IS_PRIMITIVE(value of clas): */
static int
java_class_is_primitive (struct value *clas)
{
  struct value *vtable = value_struct_elt (&clas, NULL, "vtable",
					   NULL, "struct");
  CORE_ADDR i = value_as_address (vtable);

  return (int) (i & 0x7fffffff) == (int) 0x7fffffff;
}
コード例 #8
0
ファイル: jv-lang.c プロジェクト: NalaGinrut/gdb
struct value *
java_class_from_object (struct value *obj_val)
{
  /* This is all rather inefficient, since the offsets of vtable and
     class are fixed.  FIXME */
  struct value *vtable_val;

  if (TYPE_CODE (value_type (obj_val)) == TYPE_CODE_PTR
      && TYPE_LENGTH (TYPE_TARGET_TYPE (value_type (obj_val))) == 0)
    obj_val = value_at (get_java_object_type (),
			value_as_address (obj_val));

  vtable_val = value_struct_elt (&obj_val, NULL, "vtable", NULL, "structure");
  return value_struct_elt (&vtable_val, NULL, "class", NULL, "structure");
}
コード例 #9
0
ファイル: py-utils.c プロジェクト: Winter3un/ctf_task
int
get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
{
  if (gdbpy_is_value_object (obj))
    {

      TRY
	{
	  *addr = value_as_address (value_object_to_value (obj));
	}
      CATCH (except, RETURN_MASK_ALL)
	{
	  GDB_PY_SET_HANDLE_EXCEPTION (except);
	}
      END_CATCH
    }
コード例 #10
0
ファイル: valarith.c プロジェクト: AhmadTux/DragonFlyBSD
struct value *
value_ptradd (struct value *arg1, LONGEST arg2)
{
  struct type *valptrtype;
  LONGEST sz;
  struct value *result;

  arg1 = coerce_array (arg1);
  valptrtype = check_typedef (value_type (arg1));
  sz = find_size_for_pointer_math (valptrtype);

  result = value_from_pointer (valptrtype,
			       value_as_address (arg1) + sz * arg2);
  if (VALUE_LVAL (result) != lval_internalvar)
    set_value_component_location (result, arg1);
  return result;
}
コード例 #11
0
ファイル: ada-varobj.c プロジェクト: CromFr/gdb
static void
ada_varobj_ind (struct value *parent_value,
		struct type *parent_type,
		struct value **child_value,
		struct type **child_type)
{
  struct value *value = NULL;
  struct type *type = NULL;

  if (ada_is_array_descriptor_type (parent_type))
    {
      /* This can only happen when PARENT_VALUE is NULL.  Otherwise,
	 ada_get_decoded_value would have transformed our parent_type
	 into a simple array pointer type.  */
      gdb_assert (parent_value == NULL);
      gdb_assert (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF);

      /* Decode parent_type by the equivalent pointer to (decoded)
	 array.  */
      while (TYPE_CODE (parent_type) == TYPE_CODE_TYPEDEF)
	parent_type = TYPE_TARGET_TYPE (parent_type);
      parent_type = ada_coerce_to_simple_array_type (parent_type);
      parent_type = lookup_pointer_type (parent_type);
    }

  /* If parent_value is a null pointer, then only perform static
     dereferencing.  We cannot dereference null pointers.  */
  if (parent_value && value_as_address (parent_value) == 0)
    parent_value = NULL;

  if (parent_value)
    {
      value = ada_value_ind (parent_value);
      type = value_type (value);
    }
  else
    type = TYPE_TARGET_TYPE (parent_type);

  if (child_value)
    *child_value = value;
  if (child_type)
    *child_type = type;
}
コード例 #12
0
int
get_addr_from_python (PyObject *obj, CORE_ADDR *addr)
{
  if (gdbpy_is_value_object (obj))
    *addr = value_as_address (value_object_to_value (obj));
  else if (PyLong_Check (obj))
    {
      /* Assume CORE_ADDR corresponds to unsigned long.  */
      *addr = PyLong_AsUnsignedLong (obj);
      if (PyErr_Occurred () != NULL)
	return 0;
    }
  else if (PyInt_Check (obj))
    {
      long val;

      /* Assume CORE_ADDR corresponds to unsigned long.  */
      val = PyInt_AsLong (obj);

      if (val >= 0)
	*addr = val;
      else
      {
	/* If no error ocurred, VAL is indeed negative.  */
	if (PyErr_Occurred () != NULL)
	  return 0;

	PyErr_SetString (PyExc_ValueError,
			 _("Supplied address is negative."));
	return 0;
      }
    }
  else
    {
      PyErr_SetString (PyExc_TypeError,
		       _("Invalid type for address."));
      return 0;
    }

  return 1;
}
コード例 #13
0
ファイル: darwin-nat-info.c プロジェクト: kraj/binutils-gdb
static void
info_mach_region_command (char *exp, int from_tty)
{
  struct value *val;
  mach_vm_address_t address;
  struct inferior *inf;

  expression_up expr = parse_expression (exp);
  val = evaluate_expression (expr.get ());
  if (TYPE_CODE (value_type (val)) == TYPE_CODE_REF)
    {
      val = value_ind (val);
    }
  address = value_as_address (val);

  if (ptid_equal (inferior_ptid, null_ptid))
    error (_("Inferior not available"));

  inf = current_inferior ();
  darwin_debug_region (inf->priv->task, address);
}
コード例 #14
0
static void info_embedded_symbol_command (char *exp, int from_tty)
{
  struct expression *expr;
  struct value *val;
  CORE_ADDR address;
  struct embedded_symbol *sym;

  expr = parse_expression (exp);
  val = evaluate_expression (expr);
  if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF)
    val = value_ind (val);
  if ((TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC) && (VALUE_LVAL (val) == lval_memory))
    address = VALUE_ADDRESS (val);
  else
    address = value_as_address (val);

  sym = search_for_embedded_symbol (address);
  if (sym != NULL)
    fprintf_unfiltered
      (gdb_stderr, "Symbol at 0x%lx is \"%s\".\n", (unsigned long) address, sym->name);
  else
    fprintf_unfiltered
      (gdb_stderr, "Symbol at 0x%lx is unknown.\n", (unsigned long) address);
}
コード例 #15
0
ファイル: infcall.c プロジェクト: ChrisG0x20/gdb
CORE_ADDR
find_function_addr (struct value *function, struct type **retval_type)
{
  struct type *ftype = check_typedef (value_type (function));
  struct gdbarch *gdbarch = get_type_arch (ftype);
  struct type *value_type = NULL;
  /* Initialize it just to avoid a GCC false warning.  */
  CORE_ADDR funaddr = 0;

  /* If it's a member function, just look at the function
     part of it.  */

  /* Determine address to call.  */
  if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
      || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
    funaddr = value_address (function);
  else if (TYPE_CODE (ftype) == TYPE_CODE_PTR)
    {
      funaddr = value_as_address (function);
      ftype = check_typedef (TYPE_TARGET_TYPE (ftype));
      if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
	  || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
	funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
						      &current_target);
    }
  if (TYPE_CODE (ftype) == TYPE_CODE_FUNC
      || TYPE_CODE (ftype) == TYPE_CODE_METHOD)
    {
      value_type = TYPE_TARGET_TYPE (ftype);

      if (TYPE_GNU_IFUNC (ftype))
	{
	  funaddr = gnu_ifunc_resolve_addr (gdbarch, funaddr);

	  /* Skip querying the function symbol if no RETVAL_TYPE has been
	     asked for.  */
	  if (retval_type)
	    value_type = find_function_return_type (funaddr);
	}
    }
  else if (TYPE_CODE (ftype) == TYPE_CODE_INT)
    {
      /* Handle the case of functions lacking debugging info.
         Their values are characters since their addresses are char.  */
      if (TYPE_LENGTH (ftype) == 1)
	funaddr = value_as_address (value_addr (function));
      else
	{
	  /* Handle function descriptors lacking debug info.  */
	  int found_descriptor = 0;

	  funaddr = 0;	/* pacify "gcc -Werror" */
	  if (VALUE_LVAL (function) == lval_memory)
	    {
	      CORE_ADDR nfunaddr;

	      funaddr = value_as_address (value_addr (function));
	      nfunaddr = funaddr;
	      funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr,
							    &current_target);
	      if (funaddr != nfunaddr)
		found_descriptor = 1;
	    }
	  if (!found_descriptor)
	    /* Handle integer used as address of a function.  */
	    funaddr = (CORE_ADDR) value_as_long (function);
	}
    }
  else
    error (_("Invalid data type for function to be called."));

  if (retval_type != NULL)
    *retval_type = value_type;
  return funaddr + gdbarch_deprecated_function_start_offset (gdbarch);
}
コード例 #16
0
CORE_ADDR
ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
				struct regcache *regcache, CORE_ADDR bp_addr,
				int nargs, struct value **args, CORE_ADDR sp,
				int struct_return, CORE_ADDR struct_addr)
{
  CORE_ADDR func_addr = find_function_addr (function, NULL);
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  ULONGEST back_chain;
  /* See for-loop comment below.  */
  int write_pass;
  /* Size of the Altivec's vector parameter region, the final value is
     computed in the for-loop below.  */
  LONGEST vparam_size = 0;
  /* Size of the general parameter region, the final value is computed
     in the for-loop below.  */
  LONGEST gparam_size = 0;
  /* Kevin writes ... I don't mind seeing tdep->wordsize used in the
     calls to align_up(), align_down(), etc.  because this makes it
     easier to reuse this code (in a copy/paste sense) in the future,
     but it is a 64-bit ABI and asserting that the wordsize is 8 bytes
     at some point makes it easier to verify that this function is
     correct without having to do a non-local analysis to figure out
     the possible values of tdep->wordsize.  */
  gdb_assert (tdep->wordsize == 8);

  /* This function exists to support a calling convention that
     requires floating-point registers.  It shouldn't be used on
     processors that lack them.  */
  gdb_assert (ppc_floating_point_unit_p (gdbarch));

  /* By this stage in the proceedings, SP has been decremented by "red
     zone size" + "struct return size".  Fetch the stack-pointer from
     before this and use that as the BACK_CHAIN.  */
  regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch),
				 &back_chain);

  /* Go through the argument list twice.

     Pass 1: Compute the function call's stack space and register
     requirements.

     Pass 2: Replay the same computation but this time also write the
     values out to the target.  */

  for (write_pass = 0; write_pass < 2; write_pass++)
    {
      int argno;
      /* Next available floating point register for float and double
         arguments.  */
      int freg = 1;
      /* Next available general register for non-vector (but possibly
         float) arguments.  */
      int greg = 3;
      /* Next available vector register for vector arguments.  */
      int vreg = 2;
      /* The address, at which the next general purpose parameter
         (integer, struct, float, ...) should be saved.  */
      CORE_ADDR gparam;
      /* Address, at which the next Altivec vector parameter should be
         saved.  */
      CORE_ADDR vparam;

      if (!write_pass)
	{
	  /* During the first pass, GPARAM and VPARAM are more like
	     offsets (start address zero) than addresses.  That way
	     they accumulate the total stack space each region
	     requires.  */
	  gparam = 0;
	  vparam = 0;
	}
      else
	{
	  /* Decrement the stack pointer making space for the Altivec
	     and general on-stack parameters.  Set vparam and gparam
	     to their corresponding regions.  */
	  vparam = align_down (sp - vparam_size, 16);
	  gparam = align_down (vparam - gparam_size, 16);
	  /* Add in space for the TOC, link editor double word,
	     compiler double word, LR save area, CR save area.  */
	  sp = align_down (gparam - 48, 16);
	}

      /* If the function is returning a `struct', then there is an
         extra hidden parameter (which will be passed in r3)
         containing the address of that struct..  In that case we
         should advance one word and start from r4 register to copy
         parameters.  This also consumes one on-stack parameter slot.  */
      if (struct_return)
	{
	  if (write_pass)
	    regcache_cooked_write_signed (regcache,
					  tdep->ppc_gp0_regnum + greg,
					  struct_addr);
	  greg++;
	  gparam = align_up (gparam + tdep->wordsize, tdep->wordsize);
	}

      for (argno = 0; argno < nargs; argno++)
	{
	  struct value *arg = args[argno];
	  struct type *type = check_typedef (value_type (arg));
	  const bfd_byte *val = value_contents (arg);

	  if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8)
	    {
	      /* Floats and Doubles go in f1 .. f13.  They also
	         consume a left aligned GREG,, and can end up in
	         memory.  */
	      if (write_pass)
		{
		  gdb_byte regval[MAX_REGISTER_SIZE];
		  const gdb_byte *p;

		  /* Version 1.7 of the 64-bit PowerPC ELF ABI says:

		     "Single precision floating point values are mapped to
		     the first word in a single doubleword."

		     And version 1.9 says:

		     "Single precision floating point values are mapped to
		     the second word in a single doubleword."

		     GDB then writes single precision floating point values
		     at both words in a doubleword, to support both ABIs.  */
		  if (TYPE_LENGTH (type) == 4)
		    {
		      memcpy (regval, val, 4);
		      memcpy (regval + 4, val, 4);
		      p = regval;
		    }
		  else
		    p = val;

		  /* Write value in the stack's parameter save area.  */
		  write_memory (gparam, p, 8);

		  if (freg <= 13)
		    {
		      struct type *regtype
                        = register_type (gdbarch, tdep->ppc_fp0_regnum);

		      convert_typed_floating (val, type, regval, regtype);
		      regcache_cooked_write (regcache,
                                             tdep->ppc_fp0_regnum + freg,
					     regval);
		    }
		  if (greg <= 10)
		    regcache_cooked_write (regcache,
					   tdep->ppc_gp0_regnum + greg,
					   regval);
		}

	      freg++;
	      greg++;
	      /* Always consume parameter stack space.  */
	      gparam = align_up (gparam + 8, tdep->wordsize);
	    }
	  else if (TYPE_CODE (type) == TYPE_CODE_FLT
		   && TYPE_LENGTH (type) == 16
		   && (gdbarch_long_double_format (gdbarch)
		       == floatformats_ibm_long_double))
	    {
	      /* IBM long double stored in two doublewords of the
		 parameter save area and corresponding registers.  */
	      if (write_pass)
		{
		  if (!tdep->soft_float && freg <= 13)
		    {
		      regcache_cooked_write (regcache,
                                             tdep->ppc_fp0_regnum + freg,
					     val);
		      if (freg <= 12)
			regcache_cooked_write (regcache,
					       tdep->ppc_fp0_regnum + freg + 1,
					       val + 8);
		    }
		  if (greg <= 10)
		    {
		      regcache_cooked_write (regcache,
					     tdep->ppc_gp0_regnum + greg,
					     val);
		      if (greg <= 9)
			regcache_cooked_write (regcache,
					       tdep->ppc_gp0_regnum + greg + 1,
					       val + 8);
		    }
		  write_memory (gparam, val, TYPE_LENGTH (type));
		}
	      freg += 2;
	      greg += 2;
	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
	    }
	  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT
		   && TYPE_LENGTH (type) <= 8)
	    {
	      /* 32-bit and 64-bit decimal floats go in f1 .. f13.  They can
	         end up in memory.  */
	      if (write_pass)
		{
		  gdb_byte regval[MAX_REGISTER_SIZE];
		  const gdb_byte *p;

		  /* 32-bit decimal floats are right aligned in the
		     doubleword.  */
		  if (TYPE_LENGTH (type) == 4)
		    {
		      memcpy (regval + 4, val, 4);
		      p = regval;
		    }
		  else
		    p = val;

		  /* Write value in the stack's parameter save area.  */
		  write_memory (gparam, p, 8);

		  if (freg <= 13)
		    regcache_cooked_write (regcache,
					   tdep->ppc_fp0_regnum + freg, p);
		}

	      freg++;
	      greg++;
	      /* Always consume parameter stack space.  */
	      gparam = align_up (gparam + 8, tdep->wordsize);
	    }
	  else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT &&
		   TYPE_LENGTH (type) == 16)
	    {
	      /* 128-bit decimal floats go in f2 .. f12, always in even/odd
	         pairs.  They can end up in memory, using two doublewords.  */
	      if (write_pass)
		{
		  if (freg <= 12)
		    {
		      /* Make sure freg is even.  */
		      freg += freg & 1;
		      regcache_cooked_write (regcache,
                                             tdep->ppc_fp0_regnum + freg, val);
		      regcache_cooked_write (regcache,
			  tdep->ppc_fp0_regnum + freg + 1, val + 8);
		    }

		  write_memory (gparam, val, TYPE_LENGTH (type));
		}

	      freg += 2;
	      greg += 2;
	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
	    }
	  else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)
		   && TYPE_CODE (type) == TYPE_CODE_ARRAY
		   && tdep->ppc_vr0_regnum >= 0)
	    {
	      /* In the Altivec ABI, vectors go in the vector
	         registers v2 .. v13, or when that runs out, a vector
	         annex which goes above all the normal parameters.
	         NOTE: cagney/2003-09-21: This is a guess based on the
	         PowerOpen Altivec ABI.  */
	      if (vreg <= 13)
		{
		  if (write_pass)
		    regcache_cooked_write (regcache,
					   tdep->ppc_vr0_regnum + vreg, val);
		  vreg++;
		}
	      else
		{
		  if (write_pass)
		    write_memory (vparam, val, TYPE_LENGTH (type));
		  vparam = align_up (vparam + TYPE_LENGTH (type), 16);
		}
	    }
	  else if ((TYPE_CODE (type) == TYPE_CODE_INT
		    || TYPE_CODE (type) == TYPE_CODE_ENUM
		    || TYPE_CODE (type) == TYPE_CODE_BOOL
		    || TYPE_CODE (type) == TYPE_CODE_CHAR
		    || TYPE_CODE (type) == TYPE_CODE_PTR
		    || TYPE_CODE (type) == TYPE_CODE_REF)
		   && TYPE_LENGTH (type) <= 8)
	    {
	      /* Scalars and Pointers get sign[un]extended and go in
	         gpr3 .. gpr10.  They can also end up in memory.  */
	      if (write_pass)
		{
		  /* Sign extend the value, then store it unsigned.  */
		  ULONGEST word = unpack_long (type, val);
		  /* Convert any function code addresses into
		     descriptors.  */
		  if (TYPE_CODE (type) == TYPE_CODE_PTR
		      || TYPE_CODE (type) == TYPE_CODE_REF)
		    {
		      struct type *target_type;
		      target_type = check_typedef (TYPE_TARGET_TYPE (type));

		      if (TYPE_CODE (target_type) == TYPE_CODE_FUNC
			  || TYPE_CODE (target_type) == TYPE_CODE_METHOD)
			{
			  CORE_ADDR desc = word;
			  convert_code_addr_to_desc_addr (word, &desc);
			  word = desc;
			}
		    }
		  if (greg <= 10)
		    regcache_cooked_write_unsigned (regcache,
						    tdep->ppc_gp0_regnum +
						    greg, word);
		  write_memory_unsigned_integer (gparam, tdep->wordsize,
						 byte_order, word);
		}
	      greg++;
	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
	    }
	  else
	    {
	      int byte;
	      for (byte = 0; byte < TYPE_LENGTH (type);
		   byte += tdep->wordsize)
		{
		  if (write_pass && greg <= 10)
		    {
		      gdb_byte regval[MAX_REGISTER_SIZE];
		      int len = TYPE_LENGTH (type) - byte;
		      if (len > tdep->wordsize)
			len = tdep->wordsize;
		      memset (regval, 0, sizeof regval);
		      /* The ABI (version 1.9) specifies that values
			 smaller than one doubleword are right-aligned
			 and those larger are left-aligned.  GCC
			 versions before 3.4 implemented this
			 incorrectly; see
			 <http://gcc.gnu.org/gcc-3.4/powerpc-abi.html>.  */
		      if (byte == 0)
			memcpy (regval + tdep->wordsize - len,
				val + byte, len);
		      else
			memcpy (regval, val + byte, len);
		      regcache_cooked_write (regcache, greg, regval);
		    }
		  greg++;
		}
	      if (write_pass)
		{
		  /* WARNING: cagney/2003-09-21: Strictly speaking, this
		     isn't necessary, unfortunately, GCC appears to get
		     "struct convention" parameter passing wrong putting
		     odd sized structures in memory instead of in a
		     register.  Work around this by always writing the
		     value to memory.  Fortunately, doing this
		     simplifies the code.  */
		  int len = TYPE_LENGTH (type);
		  if (len < tdep->wordsize)
		    write_memory (gparam + tdep->wordsize - len, val, len);
		  else
		    write_memory (gparam, val, len);
		}
	      if (freg <= 13
		  && TYPE_CODE (type) == TYPE_CODE_STRUCT
		  && TYPE_NFIELDS (type) == 1
		  && TYPE_LENGTH (type) <= 16)
		{
		  /* The ABI (version 1.9) specifies that structs
		     containing a single floating-point value, at any
		     level of nesting of single-member structs, are
		     passed in floating-point registers.  */
		  while (TYPE_CODE (type) == TYPE_CODE_STRUCT
			 && TYPE_NFIELDS (type) == 1)
		    type = check_typedef (TYPE_FIELD_TYPE (type, 0));
		  if (TYPE_CODE (type) == TYPE_CODE_FLT)
		    {
		      if (TYPE_LENGTH (type) <= 8)
			{
			  if (write_pass)
			    {
			      gdb_byte regval[MAX_REGISTER_SIZE];
			      struct type *regtype
				= register_type (gdbarch,
						 tdep->ppc_fp0_regnum);
			      convert_typed_floating (val, type, regval,
						      regtype);
			      regcache_cooked_write (regcache,
						     (tdep->ppc_fp0_regnum
						      + freg),
						     regval);
			    }
			  freg++;
			}
		      else if (TYPE_LENGTH (type) == 16
			       && (gdbarch_long_double_format (gdbarch)
				   == floatformats_ibm_long_double))
			{
			  if (write_pass)
			    {
			      regcache_cooked_write (regcache,
						     (tdep->ppc_fp0_regnum
						      + freg),
						     val);
			      if (freg <= 12)
				regcache_cooked_write (regcache,
						       (tdep->ppc_fp0_regnum
							+ freg + 1),
						       val + 8);
			    }
			  freg += 2;
			}
		    }
		}
	      /* Always consume parameter stack space.  */
	      gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize);
	    }
	}

      if (!write_pass)
	{
	  /* Save the true region sizes ready for the second pass.  */
	  vparam_size = vparam;
	  /* Make certain that the general parameter save area is at
	     least the minimum 8 registers (or doublewords) in size.  */
	  if (greg < 8)
	    gparam_size = 8 * tdep->wordsize;
	  else
	    gparam_size = gparam;
	}
    }

  /* Update %sp.   */
  regcache_cooked_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp);

  /* Write the backchain (it occupies WORDSIZED bytes).  */
  write_memory_signed_integer (sp, tdep->wordsize, byte_order, back_chain);

  /* Point the inferior function call's return address at the dummy's
     breakpoint.  */
  regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr);

  /* Use the func_addr to find the descriptor, and use that to find
     the TOC.  If we're calling via a function pointer, the pointer
     itself identifies the descriptor.  */
  {
    struct type *ftype = check_typedef (value_type (function));
    CORE_ADDR desc_addr = value_as_address (function);

    if (TYPE_CODE (ftype) == TYPE_CODE_PTR
	|| convert_code_addr_to_desc_addr (func_addr, &desc_addr))
      {
	/* The TOC is the second double word in the descriptor.  */
	CORE_ADDR toc =
	  read_memory_unsigned_integer (desc_addr + tdep->wordsize,
					tdep->wordsize, byte_order);
	regcache_cooked_write_unsigned (regcache,
					tdep->ppc_gp0_regnum + 2, toc);
      }
  }

  return sp;
}
コード例 #17
0
/* Compute the offset of the baseclass which is
   the INDEXth baseclass of class TYPE,
   for value at VALADDR (in host) at ADDRESS (in target).
   The result is the offset of the baseclass value relative
   to (the address of)(ARG) + OFFSET.

   -1 is returned on error. */
static int
gnuv3_baseclass_offset (struct type *type, int index, const bfd_byte *valaddr,
			CORE_ADDR address)
{
  struct gdbarch *gdbarch;
  struct type *vtable_type;
  struct type *ptr_type;
  struct value *vtable;
  struct type *vbasetype;
  struct value *offset_val, *vbase_array;
  CORE_ADDR vtable_address;
  long int cur_base_offset, base_offset;
  int vbasetype_vptr_fieldno;

  /* Determine architecture.  */
  gdbarch = get_class_arch (type);
  vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);
  ptr_type = builtin_type (gdbarch)->builtin_data_ptr;

  /* If it isn't a virtual base, this is easy.  The offset is in the
     type definition.  */
  if (!BASETYPE_VIA_VIRTUAL (type, index))
    return TYPE_BASECLASS_BITPOS (type, index) / 8;

  /* To access a virtual base, we need to use the vbase offset stored in
     our vtable.  Recent GCC versions provide this information.  If it isn't
     available, we could get what we needed from RTTI, or from drawing the
     complete inheritance graph based on the debug info.  Neither is
     worthwhile.  */
  cur_base_offset = TYPE_BASECLASS_BITPOS (type, index) / 8;
  if (cur_base_offset >= - vtable_address_point_offset (gdbarch))
    error (_("Expected a negative vbase offset (old compiler?)"));

  cur_base_offset = cur_base_offset + vtable_address_point_offset (gdbarch);
  if ((- cur_base_offset) % TYPE_LENGTH (ptr_type) != 0)
    error (_("Misaligned vbase offset."));
  cur_base_offset = cur_base_offset / ((int) TYPE_LENGTH (ptr_type));

  /* We're now looking for the cur_base_offset'th entry (negative index)
     in the vcall_and_vbase_offsets array.  We used to cast the object to
     its TYPE_VPTR_BASETYPE, and reference the vtable as TYPE_VPTR_FIELDNO;
     however, that cast can not be done without calling baseclass_offset again
     if the TYPE_VPTR_BASETYPE is a virtual base class, as described in the
     v3 C++ ABI Section 2.4.I.2.b.  Fortunately the ABI guarantees that the
     vtable pointer will be located at the beginning of the object, so we can
     bypass the casting.  Verify that the TYPE_VPTR_FIELDNO is in fact at the
     start of whichever baseclass it resides in, as a sanity measure - iff
     we have debugging information for that baseclass.  */

  vbasetype = check_typedef (TYPE_VPTR_BASETYPE (type));
  vbasetype_vptr_fieldno = get_vptr_fieldno (vbasetype, NULL);

  if (vbasetype_vptr_fieldno >= 0
      && TYPE_FIELD_BITPOS (vbasetype, vbasetype_vptr_fieldno) != 0)
    error (_("Illegal vptr offset in class %s"),
	   TYPE_NAME (vbasetype) ? TYPE_NAME (vbasetype) : "<unknown>");

  vtable_address = value_as_address (value_at_lazy (ptr_type, address));
  vtable
    = value_at_lazy (vtable_type,
		     vtable_address - vtable_address_point_offset (gdbarch));
  offset_val = value_from_longest (builtin_type_int32, cur_base_offset);
  vbase_array = value_field (vtable, vtable_field_vcall_and_vbase_offsets);
  base_offset = value_as_long (value_subscript (vbase_array, offset_val));
  return base_offset;
}
コード例 #18
0
ファイル: c-valprint.c プロジェクト: nds32/binutils
void
c_value_print (struct value *val, struct ui_file *stream, 
	       const struct value_print_options *options)
{
  struct type *type, *real_type, *val_type;
  int full, top, using_enc;
  struct value_print_options opts = *options;

  opts.deref_ref = 1;

  /* If it is a pointer, indicate what it points to.

     Print type also if it is a reference.

     C++: if it is a member pointer, we will take care
     of that when we print it.  */

  /* Preserve the original type before stripping typedefs.  We prefer
     to pass down the original type when possible, but for local
     checks it is better to look past the typedefs.  */
  val_type = value_type (val);
  type = check_typedef (val_type);

  if (TYPE_CODE (type) == TYPE_CODE_PTR
      || TYPE_CODE (type) == TYPE_CODE_REF)
    {
      /* Hack:  remove (char *) for char strings.  Their
         type is indicated by the quoted string anyway.
         (Don't use c_textual_element_type here; quoted strings
         are always exactly (char *), (wchar_t *), or the like.  */
      if (TYPE_CODE (val_type) == TYPE_CODE_PTR
	  && TYPE_NAME (val_type) == NULL
	  && TYPE_NAME (TYPE_TARGET_TYPE (val_type)) != NULL
	  && (strcmp (TYPE_NAME (TYPE_TARGET_TYPE (val_type)),
		      "char") == 0
	      || textual_name (TYPE_NAME (TYPE_TARGET_TYPE (val_type)))))
	{
	  /* Print nothing.  */
	}
      else if (options->objectprint
	       && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS))
	{
	  int is_ref = TYPE_CODE (type) == TYPE_CODE_REF;

	  if (is_ref)
	    val = value_addr (val);

	  /* Pointer to class, check real type of object.  */
	  fprintf_filtered (stream, "(");

	  if (value_entirely_available (val))
 	    {
	      real_type = value_rtti_indirect_type (val, &full, &top,
						    &using_enc);
	      if (real_type)
		{
		  /* RTTI entry found.  */
		  type = real_type;

		  /* Need to adjust pointer value.  */
		  val = value_from_pointer (real_type,
					    value_as_address (val) - top);

		  if (is_ref)
		    {
		      val = value_ref (value_ind (val));
		      type = value_type (val);
		    }

		  /* Note: When we look up RTTI entries, we don't get
		     any information on const or volatile
		     attributes.  */
		}
	    }
          type_print (type, "", stream, -1);
	  fprintf_filtered (stream, ") ");
	  val_type = type;
	}
      else
	{
	  /* normal case */
	  fprintf_filtered (stream, "(");
	  type_print (value_type (val), "", stream, -1);
	  fprintf_filtered (stream, ") ");
	}
    }

  if (!value_initialized (val))
    fprintf_filtered (stream, " [uninitialized] ");

  if (options->objectprint && (TYPE_CODE (type) == TYPE_CODE_CLASS))
    {
      /* Attempt to determine real type of object.  */
      real_type = value_rtti_type (val, &full, &top, &using_enc);
      if (real_type)
	{
	  /* We have RTTI information, so use it.  */
	  val = value_full_object (val, real_type, 
				   full, top, using_enc);
	  fprintf_filtered (stream, "(%s%s) ",
			    TYPE_NAME (real_type),
			    full ? "" : _(" [incomplete object]"));
	  /* Print out object: enclosing type is same as real_type if
	     full.  */
	  val_print (value_enclosing_type (val),
		     value_contents_for_printing (val), 0,
		     value_address (val), stream, 0,
		     val, &opts, current_language);
	  return;
          /* Note: When we look up RTTI entries, we don't get any
             information on const or volatile attributes.  */
	}
      else if (type != check_typedef (value_enclosing_type (val)))
	{
	  /* No RTTI information, so let's do our best.  */
	  fprintf_filtered (stream, "(%s ?) ",
			    TYPE_NAME (value_enclosing_type (val)));
	  val_print (value_enclosing_type (val),
		     value_contents_for_printing (val), 0,
		     value_address (val), stream, 0,
		     val, &opts, current_language);
	  return;
	}
      /* Otherwise, we end up at the return outside this "if".  */
    }

  val_print (val_type, value_contents_for_printing (val),
	     value_embedded_offset (val),
	     value_address (val),
	     stream, 0,
	     val, &opts, current_language);
}
コード例 #19
0
int
java_value_print (struct value *val, struct ui_file *stream, 
		  const struct value_print_options *options)
{
  struct gdbarch *gdbarch = get_type_arch (value_type (val));
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct type *type;
  CORE_ADDR address;
  int i;
  char *name;
  struct value_print_options opts;

  type = value_type (val);
  address = value_address (val);

  if (is_object_type (type))
    {
      CORE_ADDR obj_addr;

      /* Get the run-time type, and cast the object into that */

      obj_addr = unpack_pointer (type, value_contents (val));

      if (obj_addr != 0)
	{
	  type = type_from_class (gdbarch, java_class_from_object (val));
	  type = lookup_pointer_type (type);

	  val = value_at (type, address);
	}
    }

  if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val))
    type_print (TYPE_TARGET_TYPE (type), "", stream, -1);

  name = TYPE_TAG_NAME (type);
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
      && (i = strlen (name), name[i - 1] == ']'))
    {
      gdb_byte buf4[4];
      long length;
      unsigned int things_printed = 0;
      int reps;
      struct type *el_type
	= java_primitive_type_from_name (gdbarch, name, i - 2);
      i = 0;
      read_memory (address + get_java_object_header_size (gdbarch), buf4, 4);

      length = (long) extract_signed_integer (buf4, 4, byte_order);
      fprintf_filtered (stream, "{length: %ld", length);

      if (el_type == NULL)
	{
	  CORE_ADDR element;
	  CORE_ADDR next_element = -1; /* dummy initial value */

	  /* Skip object header and length. */
	  address += get_java_object_header_size (gdbarch) + 4;

	  while (i < length && things_printed < options->print_max)
	    {
	      gdb_byte *buf;

	      buf = alloca (gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT);
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		element = next_element;
	      else
		{
		  read_memory (address, buf, sizeof (buf));
		  address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT;
		  /* FIXME: cagney/2003-05-24: Bogus or what.  It
                     pulls a host sized pointer out of the target and
                     then extracts that as an address (while assuming
                     that the address is unsigned)!  */
		  element = extract_unsigned_integer (buf, sizeof (buf),
						      byte_order);
		}

	      for (reps = 1; i + reps < length; reps++)
		{
		  read_memory (address, buf, sizeof (buf));
		  address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT;
		  /* FIXME: cagney/2003-05-24: Bogus or what.  It
                     pulls a host sized pointer out of the target and
                     then extracts that as an address (while assuming
                     that the address is unsigned)!  */
		  next_element = extract_unsigned_integer (buf, sizeof (buf),
							   byte_order);
		  if (next_element != element)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      if (element == 0)
		fprintf_filtered (stream, "null");
	      else
		fprintf_filtered (stream, "@%s", paddress (gdbarch, element));

	      things_printed++;
	      i += reps;
	    }
	}
      else
	{
	  struct value *v = allocate_value (el_type);
	  struct value *next_v = allocate_value (el_type);

	  set_value_address (v, (address
				 + get_java_object_header_size (gdbarch) + 4));
	  set_value_address (next_v, value_raw_address (v));

	  while (i < length && things_printed < options->print_max)
	    {
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		{
		  struct value *tmp;

		  tmp = next_v;
		  next_v = v;
		  v = tmp;
		}
	      else
		{
		  set_value_lazy (v, 1);
		  set_value_offset (v, 0);
		}

	      set_value_offset (next_v, value_offset (v));

	      for (reps = 1; i + reps < length; reps++)
		{
		  set_value_lazy (next_v, 1);
		  set_value_offset (next_v, value_offset (next_v) + TYPE_LENGTH (el_type));
		  if (memcmp (value_contents (v), value_contents (next_v),
			      TYPE_LENGTH (el_type)) != 0)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      opts = *options;
	      opts.deref_ref = 1;
	      common_val_print (v, stream, 1, &opts, current_language);

	      things_printed++;
	      i += reps;
	    }
	}

      if (i < length)
	fprintf_filtered (stream, "...");

      fprintf_filtered (stream, "}");

      return 0;
    }

  /* If it's type String, print it */

  if (TYPE_CODE (type) == TYPE_CODE_PTR
      && TYPE_TARGET_TYPE (type)
      && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type))
      && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)),
		 "java.lang.String") == 0
      && (options->format == 0 || options->format == 's')
      && address != 0
      && value_as_address (val) != 0)
    {
      struct type *char_type;
      struct value *data_val;
      CORE_ADDR data;
      struct value *boffset_val;
      unsigned long boffset;
      struct value *count_val;
      unsigned long count;
      struct value *mark;

      mark = value_mark ();	/* Remember start of new values */

      data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
      data = value_as_address (data_val);

      boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
      boffset = value_as_address (boffset_val);

      count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
      count = value_as_address (count_val);

      value_free_to_mark (mark);	/* Release unnecessary values */

      char_type = builtin_java_type (gdbarch)->builtin_char;
      val_print_string (char_type, data + boffset, count, stream, options);

      return 0;
    }

  opts = *options;
  opts.deref_ref = 1;
  return common_val_print (val, stream, 0, &opts, current_language);
}
コード例 #20
0
ファイル: gnu-v3-abi.c プロジェクト: nds32/binutils
static struct type *
gnuv3_rtti_type (struct value *value,
                 int *full_p, int *top_p, int *using_enc_p)
{
  struct gdbarch *gdbarch;
  struct type *values_type = check_typedef (value_type (value));
  struct value *vtable;
  struct minimal_symbol *vtable_symbol;
  const char *vtable_symbol_name;
  const char *class_name;
  struct type *run_time_type;
  LONGEST offset_to_top;
  char *atsign;

  /* We only have RTTI for class objects.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
    return NULL;

  /* Java doesn't have RTTI following the C++ ABI.  */
  if (TYPE_CPLUS_REALLY_JAVA (values_type))
    return NULL;

  /* Determine architecture.  */
  gdbarch = get_type_arch (values_type);

  if (using_enc_p)
    *using_enc_p = 0;

  vtable = gnuv3_get_vtable (gdbarch, value_type (value),
			     value_as_address (value_addr (value)));
  if (vtable == NULL)
    return NULL;

  /* Find the linker symbol for this vtable.  */
  vtable_symbol
    = lookup_minimal_symbol_by_pc (value_address (vtable)
                                   + value_embedded_offset (vtable)).minsym;
  if (! vtable_symbol)
    return NULL;
  
  /* The symbol's demangled name should be something like "vtable for
     CLASS", where CLASS is the name of the run-time type of VALUE.
     If we didn't like this approach, we could instead look in the
     type_info object itself to get the class name.  But this way
     should work just as well, and doesn't read target memory.  */
  vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol);
  if (vtable_symbol_name == NULL
      || strncmp (vtable_symbol_name, "vtable for ", 11))
    {
      warning (_("can't find linker symbol for virtual table for `%s' value"),
	       TYPE_SAFE_NAME (values_type));
      if (vtable_symbol_name)
	warning (_("  found `%s' instead"), vtable_symbol_name);
      return NULL;
    }
  class_name = vtable_symbol_name + 11;

  /* Strip off @plt and version suffixes.  */
  atsign = strchr (class_name, '@');
  if (atsign != NULL)
    {
      char *copy;

      copy = alloca (atsign - class_name + 1);
      memcpy (copy, class_name, atsign - class_name);
      copy[atsign - class_name] = '\0';
      class_name = copy;
    }

  /* Try to look up the class name as a type name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465.  */
  run_time_type = cp_lookup_rtti_type (class_name, NULL);
  if (run_time_type == NULL)
    return NULL;

  /* Get the offset from VALUE to the top of the complete object.
     NOTE: this is the reverse of the meaning of *TOP_P.  */
  offset_to_top
    = value_as_long (value_field (vtable, vtable_field_offset_to_top));

  if (full_p)
    *full_p = (- offset_to_top == value_embedded_offset (value)
               && (TYPE_LENGTH (value_enclosing_type (value))
                   >= TYPE_LENGTH (run_time_type)));
  if (top_p)
    *top_p = - offset_to_top;
  return run_time_type;
}
コード例 #21
0
ファイル: c-lang.c プロジェクト: mattstock/binutils-bexkat1
void
c_get_string (struct value *value, gdb::unique_xmalloc_ptr<gdb_byte> *buffer,
	      int *length, struct type **char_type,
	      const char **charset)
{
  int err, width;
  unsigned int fetchlimit;
  struct type *type = check_typedef (value_type (value));
  struct type *element_type = TYPE_TARGET_TYPE (type);
  int req_length = *length;
  enum bfd_endian byte_order
    = gdbarch_byte_order (get_type_arch (type));

  if (element_type == NULL)
    goto error;

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      /* If we know the size of the array, we can use it as a limit on
	 the number of characters to be fetched.  */
      if (TYPE_NFIELDS (type) == 1
	  && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
	{
	  LONGEST low_bound, high_bound;

	  get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
			       &low_bound, &high_bound);
	  fetchlimit = high_bound - low_bound + 1;
	}
      else
	fetchlimit = UINT_MAX;
    }
  else if (TYPE_CODE (type) == TYPE_CODE_PTR)
    fetchlimit = UINT_MAX;
  else
    /* We work only with arrays and pointers.  */
    goto error;

  if (! c_textual_element_type (element_type, 0))
    goto error;
  classify_type (element_type, get_type_arch (element_type), charset);
  width = TYPE_LENGTH (element_type);

  /* If the string lives in GDB's memory instead of the inferior's,
     then we just need to copy it to BUFFER.  Also, since such strings
     are arrays with known size, FETCHLIMIT will hold the size of the
     array.  */
  if ((VALUE_LVAL (value) == not_lval
       || VALUE_LVAL (value) == lval_internalvar)
      && fetchlimit != UINT_MAX)
    {
      int i;
      const gdb_byte *contents = value_contents (value);

      /* If a length is specified, use that.  */
      if (*length >= 0)
	i  = *length;
      else
 	/* Otherwise, look for a null character.  */
 	for (i = 0; i < fetchlimit; i++)
	  if (extract_unsigned_integer (contents + i * width,
					width, byte_order) == 0)
 	    break;
  
      /* I is now either a user-defined length, the number of non-null
 	 characters, or FETCHLIMIT.  */
      *length = i * width;
      buffer->reset ((gdb_byte *) xmalloc (*length));
      memcpy (buffer->get (), contents, *length);
      err = 0;
    }
  else
    {
      CORE_ADDR addr = value_as_address (value);

      /* Prior to the fix for PR 16196 read_string would ignore fetchlimit
	 if length > 0.  The old "broken" behaviour is the behaviour we want:
	 The caller may want to fetch 100 bytes from a variable length array
	 implemented using the common idiom of having an array of length 1 at
	 the end of a struct.  In this case we want to ignore the declared
	 size of the array.  However, it's counterintuitive to implement that
	 behaviour in read_string: what does fetchlimit otherwise mean if
	 length > 0.  Therefore we implement the behaviour we want here:
	 If *length > 0, don't specify a fetchlimit.  This preserves the
	 previous behaviour.  We could move this check above where we know
	 whether the array is declared with a fixed size, but we only want
	 to apply this behaviour when calling read_string.  PR 16286.  */
      if (*length > 0)
	fetchlimit = UINT_MAX;

      err = read_string (addr, *length, width, fetchlimit,
			 byte_order, buffer, length);
      if (err != 0)
	memory_error (TARGET_XFER_E_IO, addr);
    }

  /* If the LENGTH is specified at -1, we want to return the string
     length up to the terminating null character.  If an actual length
     was specified, we want to return the length of exactly what was
     read.  */
  if (req_length == -1)
    /* If the last character is null, subtract it from LENGTH.  */
    if (*length > 0
	&& extract_unsigned_integer (buffer->get () + *length - width,
				     width, byte_order) == 0)
      *length -= width;
  
  /* The read_string function will return the number of bytes read.
     If length returned from read_string was > 0, return the number of
     characters read by dividing the number of bytes by width.  */
  if (*length != 0)
     *length = *length / width;

  *char_type = element_type;

  return;

 error:
  {
    std::string type_str = type_to_string (type);
    if (!type_str.empty ())
      {
	error (_("Trying to read string with inappropriate type `%s'."),
	       type_str.c_str ());
      }
    else
      error (_("Trying to read string with inappropriate type."));
  }
}
コード例 #22
0
ファイル: jv-valprint.c プロジェクト: jichu4n/prc-tools-remix
int
java_value_print (struct value *val, struct ui_file *stream, int format,
		  enum val_prettyprint pretty)
{
  struct type *type;
  CORE_ADDR address;
  int i;
  char *name;

  type = VALUE_TYPE (val);
  address = VALUE_ADDRESS (val) + VALUE_OFFSET (val);

  if (is_object_type (type))
    {
      CORE_ADDR obj_addr;

      /* Get the run-time type, and cast the object into that */

      obj_addr = unpack_pointer (type, VALUE_CONTENTS (val));

      if (obj_addr != 0)
	{
	  type = type_from_class (java_class_from_object (val));
	  type = lookup_pointer_type (type);

	  val = value_at (type, address, NULL);
	}
    }

  if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val))
    type_print (TYPE_TARGET_TYPE (type), "", stream, -1);

  name = TYPE_TAG_NAME (type);
  if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL
      && (i = strlen (name), name[i - 1] == ']'))
    {
      char buf4[4];
      long length;
      unsigned int things_printed = 0;
      int reps;
      struct type *el_type = java_primitive_type_from_name (name, i - 2);

      i = 0;
      read_memory (address + JAVA_OBJECT_SIZE, buf4, 4);

      length = (long) extract_signed_integer (buf4, 4);
      fprintf_filtered (stream, "{length: %ld", length);

      if (el_type == NULL)
	{
	  CORE_ADDR element;
	  CORE_ADDR next_element = -1; /* dummy initial value */

	  address += JAVA_OBJECT_SIZE + 4;	/* Skip object header and length. */

	  while (i < length && things_printed < print_max)
	    {
	      char *buf;

	      buf = alloca (TARGET_PTR_BIT / HOST_CHAR_BIT);
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		element = next_element;
	      else
		{
		  read_memory (address, buf, sizeof (buf));
		  address += TARGET_PTR_BIT / HOST_CHAR_BIT;
		  element = extract_address (buf, sizeof (buf));
		}

	      for (reps = 1; i + reps < length; reps++)
		{
		  read_memory (address, buf, sizeof (buf));
		  address += TARGET_PTR_BIT / HOST_CHAR_BIT;
		  next_element = extract_address (buf, sizeof (buf));
		  if (next_element != element)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      if (element == 0)
		fprintf_filtered (stream, "null");
	      else
		fprintf_filtered (stream, "@%s", paddr_nz (element));

	      things_printed++;
	      i += reps;
	    }
	}
      else
	{
	  struct value *v = allocate_value (el_type);
	  struct value *next_v = allocate_value (el_type);

	  VALUE_ADDRESS (v) = address + JAVA_OBJECT_SIZE + 4;
	  VALUE_ADDRESS (next_v) = VALUE_ADDRESS (v);

	  while (i < length && things_printed < print_max)
	    {
	      fputs_filtered (", ", stream);
	      wrap_here (n_spaces (2));

	      if (i > 0)
		{
		  struct value *tmp;

		  tmp = next_v;
		  next_v = v;
		  v = tmp;
		}
	      else
		{
		  VALUE_LAZY (v) = 1;
		  VALUE_OFFSET (v) = 0;
		}

	      VALUE_OFFSET (next_v) = VALUE_OFFSET (v);

	      for (reps = 1; i + reps < length; reps++)
		{
		  VALUE_LAZY (next_v) = 1;
		  VALUE_OFFSET (next_v) += TYPE_LENGTH (el_type);
		  if (memcmp (VALUE_CONTENTS (v), VALUE_CONTENTS (next_v),
			      TYPE_LENGTH (el_type)) != 0)
		    break;
		}

	      if (reps == 1)
		fprintf_filtered (stream, "%d: ", i);
	      else
		fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1);

	      val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, 0,
			 stream, format, 2, 1, pretty);

	      things_printed++;
	      i += reps;
	    }
	}

      if (i < length)
	fprintf_filtered (stream, "...");

      fprintf_filtered (stream, "}");

      return 0;
    }

  /* If it's type String, print it */

  if (TYPE_CODE (type) == TYPE_CODE_PTR
      && TYPE_TARGET_TYPE (type)
      && TYPE_NAME (TYPE_TARGET_TYPE (type))
      && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0
      && (format == 0 || format == 's')
      && address != 0
      && value_as_address (val) != 0)
    {
      struct value *data_val;
      CORE_ADDR data;
      struct value *boffset_val;
      unsigned long boffset;
      struct value *count_val;
      unsigned long count;
      struct value *mark;

      mark = value_mark ();	/* Remember start of new values */

      data_val = value_struct_elt (&val, NULL, "data", NULL, NULL);
      data = value_as_address (data_val);

      boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL);
      boffset = value_as_address (boffset_val);

      count_val = value_struct_elt (&val, NULL, "count", NULL, NULL);
      count = value_as_address (count_val);

      value_free_to_mark (mark);	/* Release unnecessary values */

      val_print_string (data + boffset, count, 2, stream);

      return 0;
    }

  return (val_print (type, VALUE_CONTENTS (val), 0, address,
		     stream, format, 1, 0, pretty));
}
コード例 #23
0
ファイル: jv-lang.c プロジェクト: NalaGinrut/gdb
static struct value *
evaluate_subexp_java (struct type *expect_type, struct expression *exp,
		      int *pos, enum noside noside)
{
  int pc = *pos;
  int i;
  const char *name;
  enum exp_opcode op = exp->elts[*pos].opcode;
  struct value *arg1;
  struct value *arg2;
  struct type *type;

  switch (op)
    {
    case UNOP_IND:
      if (noside == EVAL_SKIP)
	goto standard;
      (*pos)++;
      arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL);
      if (is_object_type (value_type (arg1)))
	{
	  struct type *type;

	  type = type_from_class (exp->gdbarch, java_class_from_object (arg1));
	  arg1 = value_cast (lookup_pointer_type (type), arg1);
	}
      return value_ind (arg1);

    case BINOP_SUBSCRIPT:
      (*pos)++;
      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);
      arg2 = evaluate_subexp_with_coercion (exp, pos, noside);
      if (noside == EVAL_SKIP)
	goto nosideret;
      /* If the user attempts to subscript something that is not an
         array or pointer type (like a plain int variable for example),
         then report this as an error.  */

      arg1 = coerce_ref (arg1);
      type = check_typedef (value_type (arg1));
      if (TYPE_CODE (type) == TYPE_CODE_PTR)
	type = check_typedef (TYPE_TARGET_TYPE (type));
      name = TYPE_NAME (type);
      if (name == NULL)
	name = TYPE_TAG_NAME (type);
      i = name == NULL ? 0 : strlen (name);
      if (TYPE_CODE (type) == TYPE_CODE_STRUCT
	  && i > 2 && name[i - 1] == ']')
	{
	  enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch);
	  CORE_ADDR address;
	  long length, index;
	  struct type *el_type;
	  gdb_byte buf4[4];

	  struct value *clas = java_class_from_object (arg1);
	  struct value *temp = clas;
	  /* Get CLASS_ELEMENT_TYPE of the array type.  */
	  temp = value_struct_elt (&temp, NULL, "methods",
				   NULL, "structure");
	  deprecated_set_value_type (temp, value_type (clas));
	  el_type = type_from_class (exp->gdbarch, temp);
	  if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT)
	    el_type = lookup_pointer_type (el_type);

	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
	    return value_zero (el_type, VALUE_LVAL (arg1));
	  address = value_as_address (arg1);
	  address += get_java_object_header_size (exp->gdbarch);
	  read_memory (address, buf4, 4);
	  length = (long) extract_signed_integer (buf4, 4, byte_order);
	  index = (long) value_as_long (arg2);
	  if (index >= length || index < 0)
	    error (_("array index (%ld) out of bounds (length: %ld)"),
		   index, length);
	  address = (address + 4) + index * TYPE_LENGTH (el_type);
	  return value_at (el_type, address);
	}
      else if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
	{
	  if (noside == EVAL_AVOID_SIDE_EFFECTS)
	    return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1));
	  else
	    return value_subscript (arg1, value_as_long (arg2));
	}
      if (name)
	error (_("cannot subscript something of type `%s'"), name);
      else
	error (_("cannot subscript requested type"));

    case OP_STRING:
      (*pos)++;
      i = longest_to_int (exp->elts[pc + 1].longconst);
      (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1);
      if (noside == EVAL_SKIP)
	goto nosideret;
      return java_value_string (&exp->elts[pc + 2].string, i);

    case STRUCTOP_PTR:
      arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside);
      /* Convert object field (such as TYPE.class) to reference.  */
      if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT)
	arg1 = value_addr (arg1);
      return arg1;
    default:
      break;
    }
standard:
  return evaluate_subexp_standard (expect_type, exp, pos, noside);
nosideret:
  return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
}
コード例 #24
0
static void
parse_find_args (char *args, ULONGEST *max_countp,
		 char **pattern_bufp, ULONGEST *pattern_lenp,
		 CORE_ADDR *start_addrp, ULONGEST *search_space_lenp,
		 bfd_boolean big_p)
{
  /* Default to using the specified type.  */
  char size = '\0';
  ULONGEST max_count = ~(ULONGEST) 0;
  /* Buffer to hold the search pattern.  */
  char *pattern_buf;
  /* Current size of search pattern buffer.
     We realloc space as needed.  */
#define INITIAL_PATTERN_BUF_SIZE 100
  ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE;
  /* Pointer to one past the last in-use part of pattern_buf.  */
  char *pattern_buf_end;
  ULONGEST pattern_len;
  CORE_ADDR start_addr;
  ULONGEST search_space_len;
  char *s = args;
  struct cleanup *old_cleanups;
  struct value *v;

  if (args == NULL)
    error (_("Missing search parameters."));

  pattern_buf = xmalloc (pattern_buf_size);
  pattern_buf_end = pattern_buf;
  old_cleanups = make_cleanup (free_current_contents, &pattern_buf);

  /* Get search granularity and/or max count if specified.
     They may be specified in either order, together or separately.  */

  while (*s == '/')
    {
      ++s;

      while (*s != '\0' && *s != '/' && !isspace (*s))
	{
	  if (isdigit (*s))
	    {
	      max_count = atoi (s);
	      while (isdigit (*s))
		++s;
	      continue;
	    }

	  switch (*s)
	    {
	    case 'b':
	    case 'h':
	    case 'w':
	    case 'g':
	      size = *s++;
	      break;
	    default:
	      error (_("Invalid size granularity."));
	    }
	}

      while (isspace (*s))
	++s;
    }

  /* Get the search range.  */

  v = parse_to_comma_and_eval (&s);
  start_addr = value_as_address (v);

  if (*s == ',')
    ++s;
  while (isspace (*s))
    ++s;

  if (*s == '+')
    {
      LONGEST len;
      ++s;
      v = parse_to_comma_and_eval (&s);
      len = value_as_long (v);
      if (len == 0)
	{
	  printf_filtered (_("Empty search range.\n"));
	  return;
	}
      if (len < 0)
	error (_("Invalid length."));
      /* Watch for overflows.  */
      if (len > CORE_ADDR_MAX
	  || (start_addr + len - 1) < start_addr)
	error (_("Search space too large."));
      search_space_len = len;
    }
  else
    {
      CORE_ADDR end_addr;
      v = parse_to_comma_and_eval (&s);
      end_addr = value_as_address (v);
      if (start_addr > end_addr)
	error (_("Invalid search space, end preceeds start."));
      search_space_len = end_addr - start_addr + 1;
      /* We don't support searching all of memory
	 (i.e. start=0, end = 0xff..ff).
	 Bail to avoid overflows later on.  */
      if (search_space_len == 0)
	error (_("Overflow in address range computation, choose smaller range."));
    }

  if (*s == ',')
    ++s;

  /* Fetch the search string.  */

  while (*s != '\0')
    {
      LONGEST x;
      int val_bytes;

      while (isspace (*s))
	++s;

      v = parse_to_comma_and_eval (&s);
      val_bytes = TYPE_LENGTH (value_type (v));

      /* Keep it simple and assume size == 'g' when watching for when we
	 need to grow the pattern buf.  */
      if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t)))
	  > pattern_buf_size)
	{
	  size_t current_offset = pattern_buf_end - pattern_buf;
	  pattern_buf_size *= 2;
	  pattern_buf = xrealloc (pattern_buf, pattern_buf_size);
	  pattern_buf_end = pattern_buf + current_offset;
	}

      if (size != '\0')
	{
	  x = value_as_long (v);
	  switch (size)
	    {
	    case 'b':
	      *pattern_buf_end++ = x;
	      break;
	    case 'h':
	      put_bits (x, pattern_buf_end, 16, big_p);
	      pattern_buf_end += sizeof (int16_t);
	      break;
	    case 'w':
	      put_bits (x, pattern_buf_end, 32, big_p);
	      pattern_buf_end += sizeof (int32_t);
	      break;
	    case 'g':
	      put_bits (x, pattern_buf_end, 64, big_p);
	      pattern_buf_end += sizeof (int64_t);
	      break;
	    }
	}
      else
	{
	  memcpy (pattern_buf_end, value_contents_raw (v), val_bytes);
	  pattern_buf_end += val_bytes;
	}

      if (*s == ',')
	++s;
      while (isspace (*s))
	++s;
    }

  if (pattern_buf_end == pattern_buf)
    error (_("Missing search pattern."));

  pattern_len = pattern_buf_end - pattern_buf;

  if (search_space_len < pattern_len)
    error (_("Search space too small to contain pattern."));

  *max_countp = max_count;
  *pattern_bufp = pattern_buf;
  *pattern_lenp = pattern_len;
  *start_addrp = start_addr;
  *search_space_lenp = search_space_len;

  /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF
     to the caller now.  */
  discard_cleanups (old_cleanups);
}
コード例 #25
0
ファイル: c-lang.c プロジェクト: NalaGinrut/gdb
void
c_get_string (struct value *value, gdb_byte **buffer,
	      int *length, struct type **char_type,
	      const char **charset)
{
  int err, width;
  unsigned int fetchlimit;
  struct type *type = check_typedef (value_type (value));
  struct type *element_type = TYPE_TARGET_TYPE (type);
  int req_length = *length;
  enum bfd_endian byte_order
    = gdbarch_byte_order (get_type_arch (type));

  if (element_type == NULL)
    goto error;

  if (TYPE_CODE (type) == TYPE_CODE_ARRAY)
    {
      /* If we know the size of the array, we can use it as a limit on
	 the number of characters to be fetched.  */
      if (TYPE_NFIELDS (type) == 1
	  && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE)
	{
	  LONGEST low_bound, high_bound;

	  get_discrete_bounds (TYPE_FIELD_TYPE (type, 0),
			       &low_bound, &high_bound);
	  fetchlimit = high_bound - low_bound + 1;
	}
      else
	fetchlimit = UINT_MAX;
    }
  else if (TYPE_CODE (type) == TYPE_CODE_PTR)
    fetchlimit = UINT_MAX;
  else
    /* We work only with arrays and pointers.  */
    goto error;

  if (! c_textual_element_type (element_type, 0))
    goto error;
  classify_type (element_type, get_type_arch (element_type), charset);
  width = TYPE_LENGTH (element_type);

  /* If the string lives in GDB's memory instead of the inferior's,
     then we just need to copy it to BUFFER.  Also, since such strings
     are arrays with known size, FETCHLIMIT will hold the size of the
     array.  */
  if ((VALUE_LVAL (value) == not_lval
       || VALUE_LVAL (value) == lval_internalvar)
      && fetchlimit != UINT_MAX)
    {
      int i;
      const gdb_byte *contents = value_contents (value);

      /* If a length is specified, use that.  */
      if (*length >= 0)
	i  = *length;
      else
 	/* Otherwise, look for a null character.  */
 	for (i = 0; i < fetchlimit; i++)
	  if (extract_unsigned_integer (contents + i * width,
					width, byte_order) == 0)
 	    break;
  
      /* I is now either a user-defined length, the number of non-null
 	 characters, or FETCHLIMIT.  */
      *length = i * width;
      *buffer = xmalloc (*length);
      memcpy (*buffer, contents, *length);
      err = 0;
    }
  else
    {
      CORE_ADDR addr = value_as_address (value);

      err = read_string (addr, *length, width, fetchlimit,
			 byte_order, buffer, length);
      if (err)
	{
	  xfree (*buffer);
	  memory_error (err, addr);
	}
    }

  /* If the LENGTH is specified at -1, we want to return the string
     length up to the terminating null character.  If an actual length
     was specified, we want to return the length of exactly what was
     read.  */
  if (req_length == -1)
    /* If the last character is null, subtract it from LENGTH.  */
    if (*length > 0
 	&& extract_unsigned_integer (*buffer + *length - width,
				     width, byte_order) == 0)
      *length -= width;
  
  /* The read_string function will return the number of bytes read.
     If length returned from read_string was > 0, return the number of
     characters read by dividing the number of bytes by width.  */
  if (*length != 0)
     *length = *length / width;

  *char_type = element_type;

  return;

 error:
  {
    char *type_str;

    type_str = type_to_string (type);
    if (type_str)
      {
	make_cleanup (xfree, type_str);
	error (_("Trying to read string with inappropriate type `%s'."),
	       type_str);
      }
    else
      error (_("Trying to read string with inappropriate type."));
  }
}
コード例 #26
0
static struct type *
gnuv3_rtti_type (struct value *value,
                 int *full_p, int *top_p, int *using_enc_p)
{
  struct gdbarch *gdbarch;
  struct type *vtable_type;
  struct type *values_type = check_typedef (value_type (value));
  CORE_ADDR vtable_address;
  struct value *vtable;
  struct minimal_symbol *vtable_symbol;
  const char *vtable_symbol_name;
  const char *class_name;
  struct type *run_time_type;
  struct type *base_type;
  LONGEST offset_to_top;
  struct type *values_type_vptr_basetype;
  int values_type_vptr_fieldno;

  /* We only have RTTI for class objects.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
    return NULL;

  /* This routine may be called for Java types that do not have
     a proper objfile.  Just return NULL for those.  */
  if (!TYPE_OBJFILE (values_type)
      || !TYPE_OBJFILE (values_type)->obfd)
    return NULL;

  /* Determine architecture.  */
  gdbarch = get_class_arch (values_type);
  vtable_type = gdbarch_data (gdbarch, vtable_type_gdbarch_data);

  /* If we can't find the virtual table pointer for values_type, we
     can't find the RTTI.  */
  values_type_vptr_fieldno = get_vptr_fieldno (values_type,
					       &values_type_vptr_basetype);
  if (values_type_vptr_fieldno == -1)
    return NULL;

  if (using_enc_p)
    *using_enc_p = 0;

  /* Fetch VALUE's virtual table pointer, and tweak it to point at
     an instance of our imaginary gdb_gnu_v3_abi_vtable structure.  */
  base_type = check_typedef (values_type_vptr_basetype);
  if (values_type != base_type)
    {
      value = value_cast (base_type, value);
      if (using_enc_p)
	*using_enc_p = 1;
    }
  vtable_address
    = value_as_address (value_field (value, values_type_vptr_fieldno));
  vtable
    = value_at_lazy (vtable_type,
		     vtable_address - vtable_address_point_offset (gdbarch));
  
  /* Find the linker symbol for this vtable.  */
  vtable_symbol
    = lookup_minimal_symbol_by_pc (value_address (vtable)
                                   + value_embedded_offset (vtable));
  if (! vtable_symbol)
    return NULL;
  
  /* The symbol's demangled name should be something like "vtable for
     CLASS", where CLASS is the name of the run-time type of VALUE.
     If we didn't like this approach, we could instead look in the
     type_info object itself to get the class name.  But this way
     should work just as well, and doesn't read target memory.  */
  vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol);
  if (vtable_symbol_name == NULL
      || strncmp (vtable_symbol_name, "vtable for ", 11))
    {
      warning (_("can't find linker symbol for virtual table for `%s' value"),
	       TYPE_NAME (values_type));
      if (vtable_symbol_name)
	warning (_("  found `%s' instead"), vtable_symbol_name);
      return NULL;
    }
  class_name = vtable_symbol_name + 11;

  /* Try to look up the class name as a type name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465. */
  run_time_type = cp_lookup_rtti_type (class_name, NULL);
  if (run_time_type == NULL)
    return NULL;

  /* Get the offset from VALUE to the top of the complete object.
     NOTE: this is the reverse of the meaning of *TOP_P.  */
  offset_to_top
    = value_as_long (value_field (vtable, vtable_field_offset_to_top));

  if (full_p)
    *full_p = (- offset_to_top == value_embedded_offset (value)
               && (TYPE_LENGTH (value_enclosing_type (value))
                   >= TYPE_LENGTH (run_time_type)));
  if (top_p)
    *top_p = - offset_to_top;

  return run_time_type;
}
コード例 #27
0
ファイル: gnu-v2-abi.c プロジェクト: HoMeCracKeR/gdb-ng
static struct type *
gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
{
  struct type *known_type;
  struct type *rtti_type;
  CORE_ADDR vtbl;
  struct minimal_symbol *minsym;
  char *demangled_name;
  struct type *btype;

  if (full)
    *full = 0;
  if (top)
    *top = -1;
  if (using_enc)
    *using_enc = 0;

  /* Get declared type */
  known_type = value_type (v);
  CHECK_TYPEDEF (known_type);
  /* RTTI works only or class objects */
  if (TYPE_CODE (known_type) != TYPE_CODE_CLASS)
    return NULL;

  /* Plan on this changing in the future as i get around to setting
     the vtables properly for G++ compiled stuff.  Also, I'll be using
     the type info functions, which are always right.  Deal with it
     until then.
     JCI - This pretty much useless.  This gets the "true" type 
     correctly when there is single inheritance - but in all such  
     cases that I could find gdb already knows that.  In cases 
     where this points INTO the object (like non-virtual diamond 
     graphs) the demangled name is something like OUTER::INNER 
     and this is not a symbol gdb can resolve, so we fail & return 
     NULL anyway.  Seems like this really isn't going to work till 
     we actually call the RTTI function & parse it. 
*/

  /* If the type has no vptr fieldno, try to get it filled in */
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
    fill_in_vptr_fieldno(known_type);

  /* If we still can't find one, give up */
  if (TYPE_VPTR_FIELDNO(known_type) < 0)
    return NULL;

  /* Make sure our basetype and known type match, otherwise, cast
     so we can get at the vtable properly.
  */
  btype = TYPE_VPTR_BASETYPE (known_type);
  CHECK_TYPEDEF (btype);
  if (btype != known_type )
    {
      v = value_cast (btype, v);
      if (using_enc)
        *using_enc=1;
    }
  /*
    We can't use value_ind here, because it would want to use RTTI, and
    we'd waste a bunch of time figuring out we already know the type.
    Besides, we don't care about the type, just the actual pointer
  */
  if (VALUE_ADDRESS (value_field (v, TYPE_VPTR_FIELDNO (known_type))) == 0)
    return NULL;

  vtbl=value_as_address(value_field(v,TYPE_VPTR_FIELDNO(known_type)));

  /* Try to find a symbol that is the vtable */
  minsym=lookup_minimal_symbol_by_pc(vtbl);
  if (minsym==NULL
      || (demangled_name=DEPRECATED_SYMBOL_NAME (minsym))==NULL
      || !is_vtable_name (demangled_name))
    return NULL;

  /* If we just skip the prefix, we get screwed by namespaces */
  demangled_name=cplus_demangle(demangled_name,DMGL_PARAMS|DMGL_ANSI);
  *(strchr(demangled_name,' '))=0;

  /* Lookup the type for the name */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465. */
  rtti_type = cp_lookup_rtti_type (demangled_name, NULL);
  if (rtti_type == NULL)
    return NULL;

  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
    {
      if (top)
        *top=TYPE_BASECLASS_BITPOS(rtti_type,TYPE_VPTR_FIELDNO(rtti_type))/8;
      if (top && ((*top) >0))
        {
          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
            {
              if (full)
                *full=0;
            }
          else
            {
              if (full)
                *full=1;
            }
        }
    }
  else
    {
      if (full)
        *full=1;
    }

  return rtti_type;
}
コード例 #28
0
static struct type *
gnuv2_value_rtti_type (struct value *v, int *full, int *top, int *using_enc)
{
  struct type *known_type;
  struct type *rtti_type;
  CORE_ADDR vtbl;
  struct bound_minimal_symbol minsym;
  char *demangled_name, *p;
  const char *linkage_name;
  struct type *btype;
  struct type *known_type_vptr_basetype;
  int known_type_vptr_fieldno;

  if (full)
    *full = 0;
  if (top)
    *top = -1;
  if (using_enc)
    *using_enc = 0;

  /* Get declared type.  */
  known_type = value_type (v);
  CHECK_TYPEDEF (known_type);
  /* RTTI works only or class objects.  */
  if (TYPE_CODE (known_type) != TYPE_CODE_STRUCT)
    return NULL;

  /* Plan on this changing in the future as i get around to setting
     the vtables properly for G++ compiled stuff.  Also, I'll be using
     the type info functions, which are always right.  Deal with it
     until then.  */

  /* Try to get the vptr basetype, fieldno.  */
  known_type_vptr_fieldno = get_vptr_fieldno (known_type,
					      &known_type_vptr_basetype);

  /* If we can't find it, give up.  */
  if (known_type_vptr_fieldno < 0)
    return NULL;

  /* Make sure our basetype and known type match, otherwise, cast
     so we can get at the vtable properly.  */
  btype = known_type_vptr_basetype;
  CHECK_TYPEDEF (btype);
  if (btype != known_type )
    {
      v = value_cast (btype, v);
      if (using_enc)
        *using_enc=1;
    }
  /* We can't use value_ind here, because it would want to use RTTI, and
     we'd waste a bunch of time figuring out we already know the type.
     Besides, we don't care about the type, just the actual pointer.  */
  if (value_address (value_field (v, known_type_vptr_fieldno)) == 0)
    return NULL;

  vtbl = value_as_address (value_field (v, known_type_vptr_fieldno));

  /* Try to find a symbol that is the vtable.  */
  minsym=lookup_minimal_symbol_by_pc(vtbl);
  if (minsym.minsym==NULL
      || (linkage_name=MSYMBOL_LINKAGE_NAME (minsym.minsym))==NULL
      || !is_vtable_name (linkage_name))
    return NULL;

  /* If we just skip the prefix, we get screwed by namespaces.  */
  demangled_name=gdb_demangle(linkage_name,DMGL_PARAMS|DMGL_ANSI);
  p = strchr (demangled_name, ' ');
  if (p)
    *p = '\0';

  /* Lookup the type for the name.  */
  /* FIXME: chastain/2003-11-26: block=NULL is bogus.  See pr gdb/1465.  */
  rtti_type = cp_lookup_rtti_type (demangled_name, NULL);
  if (rtti_type == NULL)
    return NULL;

  if (TYPE_N_BASECLASSES(rtti_type) > 1 &&  full && (*full) != 1)
    {
      if (top)
        *top = TYPE_BASECLASS_BITPOS (rtti_type,
				      TYPE_VPTR_FIELDNO(rtti_type)) / 8;
      if (top && ((*top) >0))
        {
          if (TYPE_LENGTH(rtti_type) > TYPE_LENGTH(known_type))
            {
              if (full)
                *full=0;
            }
          else
            {
              if (full)
                *full=1;
            }
        }
    }
  else
    {
      if (full)
        *full=1;
    }

  return rtti_type;
}