示例#1
0
void CPActionReverse::Redo(CMainFrame &MainFrm)
{
	CSongView *pSongView = GET_SONG_VIEW();
	auto [b, e] = GetIterators(*pSongView);
	const CSelection &Sel = m_pUndoState->Selection;

	const column_t ColStart = GetSelectColumn(Sel.m_cpStart.Xpos.Column);
	const column_t ColEnd = GetSelectColumn(Sel.m_cpEnd.Xpos.Column);

	while (b < e) {
		for (int c = Sel.m_cpStart.Xpos.Track; c <= Sel.m_cpEnd.Xpos.Track; ++c) {
			auto NoteBegin = b.Get(c);
			auto NoteEnd = e.Get(c);
			if (c == Sel.m_cpStart.Xpos.Track && ColStart > column_t::Note) {		// // //
				auto Temp = NoteEnd;
				CopyNoteSection(NoteEnd, NoteBegin, column_t::Note, static_cast<column_t>(value_cast(ColStart) - 1));
				CopyNoteSection(NoteBegin, Temp, column_t::Note, static_cast<column_t>(value_cast(ColStart) - 1));
			}
			if (c == Sel.m_cpEnd.Xpos.Track && ColEnd < column_t::Effect4) {
				auto Temp = NoteEnd;
				CopyNoteSection(NoteEnd, NoteBegin, static_cast<column_t>(value_cast(ColEnd) + 1), column_t::Effect4);
				CopyNoteSection(NoteBegin, Temp, static_cast<column_t>(value_cast(ColEnd) + 1), column_t::Effect4);
			}
			b.Set(c, NoteEnd);
			e.Set(c, NoteBegin);
		}
		++b;
		--e;
	}
}
static struct value *
gnuv3_method_ptr_to_value (struct value **this_p, struct value *method_ptr)
{
  struct gdbarch *gdbarch;
  const gdb_byte *contents = value_contents (method_ptr);
  CORE_ADDR ptr_value;
  struct type *domain_type, *final_type, *method_type;
  LONGEST adjustment;
  struct value *adjval;
  int vbit;

  domain_type = TYPE_DOMAIN_TYPE (check_typedef (value_type (method_ptr)));
  final_type = lookup_pointer_type (domain_type);

  method_type = TYPE_TARGET_TYPE (check_typedef (value_type (method_ptr)));

  /* Extract the pointer to member.  */
  gdbarch = get_class_arch (domain_type);
  vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment);

  /* First convert THIS to match the containing type of the pointer to
     member.  This cast may adjust the value of THIS.  */
  *this_p = value_cast (final_type, *this_p);

  /* Then apply whatever adjustment is necessary.  This creates a somewhat
     strange pointer: it claims to have type FINAL_TYPE, but in fact it
     might not be a valid FINAL_TYPE.  For instance, it might be a
     base class of FINAL_TYPE.  And if it's not the primary base class,
     then printing it out as a FINAL_TYPE object would produce some pretty
     garbage.

     But we don't really know the type of the first argument in
     METHOD_TYPE either, which is why this happens.  We can't
     dereference this later as a FINAL_TYPE, but once we arrive in the
     called method we'll have debugging information for the type of
     "this" - and that'll match the value we produce here.

     You can provoke this case by casting a Base::* to a Derived::*, for
     instance.  */
  *this_p = value_cast (builtin_type (gdbarch)->builtin_data_ptr, *this_p);
  adjval = value_from_longest (builtin_type (gdbarch)->builtin_long,
			       adjustment);
  *this_p = value_ptradd (*this_p, adjval);
  *this_p = value_cast (final_type, *this_p);

  if (vbit)
    {
      LONGEST voffset;
      voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch));
      return gnuv3_get_virtual_fn (gdbarch, value_ind (*this_p),
				   method_type, voffset);
    }
  else
    return value_from_pointer (lookup_pointer_type (method_type), ptr_value);
}
示例#3
0
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;
}
示例#4
0
static int
wrap_value_cast (char *opaque_arg)
{
  struct gdb_wrapper_arguments **args = (struct gdb_wrapper_arguments **) opaque_arg;
  value_ptr val;
  struct type *type;

  type = (struct type *) (*args)->args[0].ptr;
  val = (value_ptr) (*args)->args[1].ptr;
  (*args)->result.ptr = value_cast (type, val);

  return 1;
}
BOOL CSplitKeyboardDlg::OnInitDialog()
{
	CComboBox *pCombo;
	const auto pDoc = CFamiTrackerDoc::GetDoc();

	pCombo = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_SPLIT_NOTE));
	for (auto n : KEY_NAME)
		pCombo->AddString(conv::to_wide(n).data());
	pCombo->SetCurSel(m_iSplitNote != -1 ? (value_cast(ft0cc::doc::pitch_from_midi(m_iSplitNote)) - 1) : 0);

	pCombo = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_SPLIT_OCTAVE));
	for (int i = 0; i < OCTAVE_RANGE; ++i)
		pCombo->AddString(conv::to_wide(conv::from_int(i)).data());
	pCombo->SetCurSel(m_iSplitNote != -1 ? ft0cc::doc::oct_from_midi(m_iSplitNote) : 3);

	pCombo = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_SPLIT_CHAN));
	pCombo->AddString(KEEP_INST_STRING);
	pCombo->SetCurSel(0);
	auto *pSCS = FTEnv.GetSoundChipService();
	int i = 0;
	pDoc->GetModule()->GetChannelOrder().ForeachChannel([&] (stChannelID ch) {
		pCombo->AddString(conv::to_wide(pSCS->GetChannelFullName(ch)).data());
		if (m_iSplitChannel == ch)
			pCombo->SetCurSel(i + 1);
		++i;
	});

	pCombo = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_SPLIT_INST));
	pCombo->AddString(KEEP_INST_STRING);
	pDoc->GetModule()->GetInstrumentManager()->VisitInstruments([&] (const CInstrument &, std::size_t i) {
		pCombo->AddString(conv::to_wide(conv::from_int_hex(i, 2)).data());
	});
	if (pCombo->SelectString(-1, FormattedW(L"%02X", m_iSplitInstrument)) == CB_ERR)
		pCombo->SelectString(-1, KEEP_INST_STRING);

	pCombo = static_cast<CComboBox*>(GetDlgItem(IDC_COMBO_SPLIT_TRSP));
	for (int j = -MAX_TRANSPOSE; j <= MAX_TRANSPOSE; ++j)
		pCombo->AddString(FormattedW(L"%+d", j));
	pCombo->SelectString(-1, FormattedW(L"%+d", m_iSplitTranspose));

	CheckDlgButton(IDC_CHECK_SPLIT_ENABLE, m_bSplitEnable ? BST_CHECKED : BST_UNCHECKED);
	OnBnClickedCheckSplitEnable();

	return CDialog::OnInitDialog();
}
示例#6
0
static struct value *
gnuv3_virtual_fn_field (struct value **value_p,
                        struct fn_field *f, int j,
			struct type *vfn_base, int offset)
{
  struct type *values_type = check_typedef (value_type (*value_p));
  struct gdbarch *gdbarch;

  /* Some simple sanity checks.  */
  if (TYPE_CODE (values_type) != TYPE_CODE_CLASS)
    error (_("Only classes can have virtual functions."));

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

  /* Cast our value to the base class which defines this virtual
     function.  This takes care of any necessary `this'
     adjustments.  */
  if (vfn_base != values_type)
    *value_p = value_cast (vfn_base, *value_p);

  return gnuv3_get_virtual_fn (gdbarch, *value_p, TYPE_FN_FIELD_TYPE (f, j),
			       TYPE_FN_FIELD_VOFFSET (f, j));
}
示例#7
0
static struct value *
evaluate_subexp_modula2 (struct type *expect_type, struct expression *exp,
			 int *pos, enum noside noside)
{
  enum exp_opcode op = exp->elts[*pos].opcode;
  struct value *arg1;
  struct value *arg2;
  struct type *type;

  switch (op)
    {
    case UNOP_HIGH:
      (*pos)++;
      arg1 = evaluate_subexp_with_coercion (exp, pos, noside);

      if (noside == EVAL_SKIP || noside == EVAL_AVOID_SIDE_EFFECTS)
	return arg1;
      else
	{
	  arg1 = coerce_ref (arg1);
	  type = check_typedef (value_type (arg1));

	  if (m2_is_unbounded_array (type))
	    {
	      struct value *temp = arg1;

	      type = TYPE_FIELD_TYPE (type, 1);
	      /* i18n: Do not translate the "_m2_high" part!  */
	      arg1 = value_struct_elt (&temp, NULL, "_m2_high", NULL,
				       _("unbounded structure "
					 "missing _m2_high field"));
	  
	      if (value_type (arg1) != type)
		arg1 = value_cast (type, arg1);
	    }
	}
      return 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 (m2_is_unbounded_array (type))
	{
	  struct value *temp = arg1;
	  type = TYPE_FIELD_TYPE (type, 0);
	  if (type == NULL || (TYPE_CODE (type) != TYPE_CODE_PTR))
	    {
	      warning (_("internal error: unbounded "
			 "array structure is unknown"));
	      return evaluate_subexp_standard (expect_type, exp, pos, noside);
	    }
	  /* i18n: Do not translate the "_m2_contents" part!  */
	  arg1 = value_struct_elt (&temp, NULL, "_m2_contents", NULL,
				   _("unbounded structure "
				     "missing _m2_contents field"));
	  
	  if (value_type (arg1) != type)
	    arg1 = value_cast (type, arg1);

	  check_typedef (value_type (arg1));
	  return value_ind (value_ptradd (arg1, value_as_long (arg2)));
	}
      else
	if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
	  {
	    if (TYPE_NAME (type))
	      error (_("cannot subscript something of type `%s'"),
		     TYPE_NAME (type));
	    else
	      error (_("cannot subscript requested type"));
	  }

      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));

    default:
      return evaluate_subexp_standard (expect_type, exp, pos, noside);
    }

 nosideret:
  return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1);
}
示例#8
0
文件: m88k-tdep.c 项目: 5kg/gdb
static CORE_ADDR
m88k_store_arguments (struct regcache *regcache, int nargs,
		      struct value **args, CORE_ADDR sp)
{
  struct gdbarch *gdbarch = get_regcache_arch (regcache);
  int num_register_words = 0;
  int num_stack_words = 0;
  int i;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);

      if (m88k_integral_or_pointer_p (type) && len < 4)
	{
	  args[i] = value_cast (builtin_type (gdbarch)->builtin_int32,
				args[i]);
	  type = value_type (args[i]);
	  len = TYPE_LENGTH (type);
	}

      if (m88k_in_register_p (type))
	{
	  int num_words = 0;

	  if (num_register_words % 2 == 1 && m88k_8_byte_align_p (type))
	    num_words++;

	  num_words += ((len + 3) / 4);
	  if (num_register_words + num_words <= 8)
	    {
	      num_register_words += num_words;
	      continue;
	    }

	  /* We've run out of available registers.  Pass the argument
             on the stack.  */
	}

      if (num_stack_words % 2 == 1 && m88k_8_byte_align_p (type))
	num_stack_words++;

      num_stack_words += ((len + 3) / 4);
    }

  /* Allocate stack space.  */
  sp = align_down (sp - 32 - num_stack_words * 4, 16);
  num_stack_words = num_register_words = 0;

  for (i = 0; i < nargs; i++)
    {
      const bfd_byte *valbuf = value_contents (args[i]);
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);
      int stack_word = num_stack_words;

      if (m88k_in_register_p (type))
	{
	  int register_word = num_register_words;

	  if (register_word % 2 == 1 && m88k_8_byte_align_p (type))
	    register_word++;

	  gdb_assert (len == 4 || len == 8);

	  if (register_word + len / 8 < 8)
	    {
	      int regnum = M88K_R2_REGNUM + register_word;

	      regcache_raw_write (regcache, regnum, valbuf);
	      if (len > 4)
		regcache_raw_write (regcache, regnum + 1, valbuf + 4);

	      num_register_words = (register_word + len / 4);
	      continue;
	    }
	}

      if (stack_word % 2 == -1 && m88k_8_byte_align_p (type))
	stack_word++;

      write_memory (sp + stack_word * 4, valbuf, len);
      num_stack_words = (stack_word + (len + 3) / 4);
    }

  return sp;
}
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;
}
示例#10
0
void CPActionScrollValues::Redo(CMainFrame &MainFrm)
{
	CPatternEditor *pPatternEditor = GET_PATTERN_EDITOR();
	CSongView *pSongView = GET_SONG_VIEW();
	auto [b, e] = GetIterators(*pSongView);
	int ChanStart     = (m_pUndoState->IsSelecting ? m_pUndoState->Selection.m_cpStart : m_pUndoState->Cursor).Xpos.Track;
	int ChanEnd       = (m_pUndoState->IsSelecting ? m_pUndoState->Selection.m_cpEnd : m_pUndoState->Cursor).Xpos.Track;
	column_t ColStart = GetSelectColumn(
		(m_pUndoState->IsSelecting ? m_pUndoState->Selection.m_cpStart : m_pUndoState->Cursor).Xpos.Column);
	column_t ColEnd   = GetSelectColumn(
		(m_pUndoState->IsSelecting ? m_pUndoState->Selection.m_cpEnd : m_pUndoState->Cursor).Xpos.Column);

	const bool bSingular = b == e && !m_pUndoState->IsSelecting;
	const unsigned Length = pSongView->GetSong().GetPatternLength();

	const auto WarpFunc = [this] (unsigned char &x, int Lim) {
		int Val = x + m_iAmount;
		if (FTEnv.GetSettings()->General.bWrapPatternValue) {
			Val %= Lim;
			if (Val < 0) Val += Lim;
		}
		else {
			if (Val >= Lim) Val = Lim - 1;
			if (Val < 0) Val = 0;
		}
		x = static_cast<unsigned char>(Val);
	};

	int Row = 0;
	int oldRow = -1;
	do {
		if (b.m_iRow <= oldRow)
			Row += Length + b.m_iRow - oldRow - 1;
		for (int i = ChanStart; i <= ChanEnd; ++i) {
			auto Note = *(m_UndoClipData.GetPattern(i - ChanStart, Row));		// // //
			for (column_t k = column_t::Instrument; k <= column_t::Effect4; k = static_cast<column_t>(value_cast(k) + 1)) {
				if (i == ChanStart && k < ColStart)
					continue;
				if (i == ChanEnd && k > ColEnd)
					continue;
				switch (k) {
				case column_t::Instrument:
					if (Note.Instrument == MAX_INSTRUMENTS || Note.Instrument == HOLD_INSTRUMENT) break;		// // // 050B
					WarpFunc(Note.Instrument, MAX_INSTRUMENTS);
					break;
				case column_t::Volume:
					if (Note.Vol == MAX_VOLUME) break;
					WarpFunc(Note.Vol, MAX_VOLUME);
					break;
				case column_t::Effect1: case column_t::Effect2: case column_t::Effect3: case column_t::Effect4:
				{
					unsigned fx = value_cast(k) - value_cast(column_t::Effect1);
					if (Note.Effects[fx].fx == effect_t::none)
						break;
					if (bSingular) switch (Note.Effects[fx].fx) {
					case effect_t::SWEEPUP: case effect_t::SWEEPDOWN: case effect_t::ARPEGGIO: case effect_t::VIBRATO: case effect_t::TREMOLO:
					case effect_t::SLIDE_UP: case effect_t::SLIDE_DOWN: case effect_t::VOLUME_SLIDE: case effect_t::DELAYED_VOLUME: case effect_t::TRANSPOSE:
						unsigned char Hi = Note.Effects[fx].param >> 4;
						unsigned char Lo = Note.Effects[fx].param & 0x0F;
						WarpFunc(value_cast(pPatternEditor->GetColumn()) % 3 == 2 ? Hi : Lo, 0x10);
						Note.Effects[fx].param = (Hi << 4) | Lo;
						continue;
					}
					WarpFunc(Note.Effects[fx].param, 0x100);
					break;
				}
				}
			}
			b.Set(i, Note);
		}
		++Row;
		oldRow = b.m_iRow;
	} while (++b <= e);
}
示例#11
0
static CORE_ADDR
lm32_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)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int first_arg_reg = SIM_LM32_R1_REGNUM;
  int num_arg_regs = 8;
  int i;

  /* Set the return address.  */
  regcache_cooked_write_signed (regcache, SIM_LM32_RA_REGNUM, bp_addr);

  /* If we're returning a large struct, a pointer to the address to
     store it at is passed as a first hidden parameter.  */
  if (struct_return)
    {
      regcache_cooked_write_unsigned (regcache, first_arg_reg, struct_addr);
      first_arg_reg++;
      num_arg_regs--;
      sp -= 4;
    }

  /* Setup parameters.  */
  for (i = 0; i < nargs; i++)
    {
      struct value *arg = args[i];
      struct type *arg_type = check_typedef (value_type (arg));
      gdb_byte *contents;
      int len;
      int j;
      int reg;
      ULONGEST val;

      /* Promote small integer types to int.  */
      switch (TYPE_CODE (arg_type))
	{
	case TYPE_CODE_INT:
	case TYPE_CODE_BOOL:
	case TYPE_CODE_CHAR:
	case TYPE_CODE_RANGE:
	case TYPE_CODE_ENUM:
	  if (TYPE_LENGTH (arg_type) < 4)
	    {
	      arg_type = builtin_type (gdbarch)->builtin_int32;
	      arg = value_cast (arg_type, arg);
	    }
	  break;
	}

      /* FIXME: Handle structures.  */

      contents = (gdb_byte *) value_contents (arg);
      len = TYPE_LENGTH (arg_type);
      val = extract_unsigned_integer (contents, len, byte_order);

      /* First num_arg_regs parameters are passed by registers, 
         and the rest are passed on the stack.  */
      if (i < num_arg_regs)
	regcache_cooked_write_unsigned (regcache, first_arg_reg + i, val);
      else
	{
	  write_memory (sp, (void *) &val, len);
	  sp -= 4;
	}
    }

  /* Update stack pointer.  */
  regcache_cooked_write_signed (regcache, SIM_LM32_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}
示例#12
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 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;
}
示例#13
0
/* 
 * For 32,000 elements
 * NIL: 0.01 sec
 * all: 0.17 sec
 * MPZ: 0.21 sec
 * MPF: 0.19 sec
 * STR: 0.24 sec
 * ID : 0.18 sec
 * LST: 0.04 sec
 * 
 * 
 */ 
int test_hash()
{
#define NUMBER ((1 << 15) + 1)
#define REPEATS 20
	
	value x = value_init_nil();
	
	value val = value_set_str("result");
	size_t i, j, k, start, finish;
	
	value keys[NUMBER];
	char *skeys[NUMBER];
	for (i = 0; i < NUMBER; ++i) {
		skeys[i] = value_malloc(NULL, 30);
		sprintf(skeys[i], "%ld", (long) i);
		
		value num = value_set_long(i);
		
		switch (i % 4) {
			case 0:
				keys[i] = value_set(num);
				break;
			case 1:
				keys[i] = value_set_double(i);
				break;
			case 2:
				keys[i] = value_cast(num, VALUE_STR);
				break;
			case 3:
				keys[i] = value_cast(num, VALUE_STR);
				keys[i].type = VALUE_ID;
				break;
			case 4:
				keys[i] = value_init(VALUE_LST);
				value_cons_now2(&num, &keys[i]);
				break;
			default:
				keys[i] = value_init_nil();
				break;
		}
		
		value_clear(&num);
		
		// This overrides the setting done above.
//		keys[i] = value_cast(value_set_long(i), VALUE_STR);
	}
	
	for (i = 1 << 4; i < NUMBER; i <<= 1) {
		long average = 0;
		long difference = 0;
		
		for (j = 0; j < REPEATS; ++j) {
			x = value_init(VALUE_HSH);
//			StrMap *map = strmap_new(HASH_DEFAULT_CAPACITY);
			
			start = usec();
			
			for (k = 0; k < i; ++k)
				value_hash_put(&x, keys[k], val);
//				strmap_put(map, skeys[k], sval);
			
			finish = usec();
			average += finish - start;
			if (labs((long) (average / (j+1)) - (finish - start)) > difference)
				difference = labs((long) (average / (j+1)) - (finish - start));

			value_clear(&x);
//			strmap_delete(map);
		}
		
		printf("time for %ld elements: %ld usec +/= %ld\n", (long) i, average / j, difference);
	}

#undef NUMBER
#undef REPEATS

	return 0;
}
示例#14
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;
}
示例#15
0
/* 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.  */
static struct value *
hpacc_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
			struct type * type, int offset)
{
  struct value *arg1 = *arg1p;
  struct type *type1 = check_typedef (value_type (arg1));

  /* Deal with HP/Taligent runtime model for virtual functions */
  struct value *vp;
  struct value *argp;		/* arg1 cast to base */
  CORE_ADDR coreptr;		/* pointer to target address */
  int class_index;		/* which class segment pointer to use */
  struct type *ftype = TYPE_FN_FIELD_TYPE (f, j);	/* method type */

  argp = value_cast (type, *arg1p);

  if (VALUE_ADDRESS (argp) == 0)
    error (_("Address of object is null; object may not have been created."));

  /* pai: FIXME -- 32x64 possible problem? */
  /* First word (4 bytes) in object layout is the vtable pointer */
  coreptr = *(CORE_ADDR *) (value_contents (argp));	/* pai: (temp)  */
  /* + offset + value_embedded_offset (argp)); */

  if (!coreptr)
    error
      ("Virtual table pointer is null for object; object may not have been created.");

  /* pai/1997-05-09
   * FIXME: The code here currently handles only
   * the non-RRBC case of the Taligent/HP runtime spec; when RRBC
   * is introduced, the condition for the "if" below will have to
   * be changed to be a test for the RRBC case.  */

  if (1)
    {
      /* Non-RRBC case; the virtual function pointers are stored at fixed
       * offsets in the virtual table. */

      /* Retrieve the offset in the virtual table from the debug
       * info.  The offset of the vfunc's entry is in words from
       * the beginning of the vtable; but first we have to adjust
       * by HP_ACC_VFUNC_START to account for other entries */

      /* pai: FIXME: 32x64 problem here, a word may be 8 bytes in
       * which case the multiplier should be 8 and values should be long */
      vp = value_at (builtin_type_int,
		     coreptr + 4 * (TYPE_FN_FIELD_VOFFSET (f, j) +
				    HP_ACC_VFUNC_START));

      coreptr = *(CORE_ADDR *) (value_contents (vp));
      /* coreptr now contains the address of the virtual function */
      /* (Actually, it contains the pointer to the plabel for the function. */
    }
  else
    {
      /* RRBC case; the virtual function pointers are found by double
       * indirection through the class segment tables. */

      /* Choose class segment depending on type we were passed */
      class_index = class_index_in_primary_list (type);

      /* Find class segment pointer.  These are in the vtable slots after
       * some other entries, so adjust by HP_ACC_VFUNC_START for that. */
      /* pai: FIXME 32x64 problem here, if words are 8 bytes long
       * the multiplier below has to be 8 and value should be long. */
      vp = value_at (builtin_type_int,
		     coreptr + 4 * (HP_ACC_VFUNC_START + class_index));
      /* Indirect once more, offset by function index */
      /* pai: FIXME 32x64 problem here, again multiplier could be 8 and value long */
      coreptr =
	*(CORE_ADDR *) (value_contents (vp) +
			4 * TYPE_FN_FIELD_VOFFSET (f, j));
      vp = value_at (builtin_type_int, coreptr);
      coreptr = *(CORE_ADDR *) (value_contents (vp));

      /* coreptr now contains the address of the virtual function */
      /* (Actually, it contains the pointer to the plabel for the function.) */

    }

  if (!coreptr)
    error (_("Address of virtual function is null; error in virtual table?"));

  /* Wrap this addr in a value and return pointer */
  vp = allocate_value (ftype);
  deprecated_set_value_type (vp, ftype);
  VALUE_ADDRESS (vp) = coreptr;

  /* pai: (temp) do we need the value_ind stuff in value_fn_field? */
  return vp;
}
示例#16
0
static void
ppc_push_argument (struct ppc_stack_abi *abi, 
		   struct ppc_stack_context *c, struct value *arg,
		   int argno, int do_copy, int floatonly)
{
  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);

  struct type *type = check_typedef (value_type (arg));
  int len = TYPE_LENGTH (type);

  gdb_byte buf[16];

  c->argoffset = ROUND_UP (c->argoffset, 4);

  switch (TYPE_CODE (type)) {
      
  case TYPE_CODE_FLT:
    {
      if (c->freg <= abi->last_freg)
	{
	  struct value *rval;
	  struct type *rtype;
	  int rlen;
	  /* APPLE LOCAL: If the thing is already a long double type,
	     don't cast it to a builtin type double, since there are two
	     long double types, and we will pass an 16 byte long double
	     wrong if we assume it is an 8 byte double.  */
	  if (strcmp (TYPE_NAME (type), "long double") != 0)
	    {
	      rval  = value_cast (builtin_type_double, arg);
	      rtype = check_typedef (value_type (rval));
	      rlen = TYPE_LENGTH (rtype);
	    }
	  else
	    {
	      rval = arg;
	      rtype = type;
	      rlen = len;
	    }

	  /* APPLE LOCAL: GCC 4.0 has 16 byte long doubles */
	  if ((len != 4) && (len != 8) && (len != 16))
	    error ("floating point parameter had unexpected size");

	  if (rlen != 8 && rlen != 16)
	    error ("floating point parameter had unexpected size");

	  if (do_copy)
	    regcache_raw_write (current_regcache, FP0_REGNUM + c->freg, 
				value_contents (rval));
	  if (do_copy && ! floatonly && abi->fregs_shadow_gregs)
	    ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, len, value_contents (arg));
	  if (do_copy && ! floatonly && abi->regs_shadow_stack)
	    write_memory (c->sp + c->argoffset, value_contents (arg), len);

	  c->freg++;
	  /* APPLE LOCAL: We took up two registers...  */
	  if (rlen == 16)
	    c->freg++;

	  if (! floatonly && (abi->fregs_shadow_gregs) && (c->greg <= abi->last_greg))
	    c->greg += len / 4;
	  if (! floatonly && abi->regs_shadow_stack)
	    c->argoffset += len;
	}
      else if (! floatonly)
	{
	  if ((len != 4) && (len != 8) && (len != 16))
	    error ("floating point parameter had unexpected size");

	  c->argoffset = ROUND_UP (c->argoffset, len);
	  if (do_copy)
	    write_memory (c->sp + c->argoffset, value_contents (arg), len);
	  c->argoffset += len;
	}
      break;
    }

  case TYPE_CODE_INT:
  case TYPE_CODE_ENUM:
  case TYPE_CODE_PTR:
  case TYPE_CODE_REF:
    {
      int nregs;
      gdb_byte *val_contents;

      if (floatonly)
	break;

      /* APPLE LOCAL: Huge Hack...  The problem is that if we are a 32
	 bit app on Mac OS X, the registers are really 64 bits, but we
	 don't want to pass all 64 bits.  So if we get passed a value
	 that came from a register, and it's length is > the wordsize,
	 cast it to the wordsize first before passing it in.  */
      if (VALUE_REGNUM (arg) != -1 && len == 8 && tdep->wordsize == 4)
	{
	  len = 4;
	  val_contents = value_contents (arg) + 4;
	}
      else
	val_contents = value_contents (arg);
      /* END APPLE LOCAL  */

      nregs = (len <= 4) ? 1 : 2;
      if ((len != 1) && (len != 2) && (len != 4) && (len != 8))
	error ("integer parameter had unexpected size");

      if (c->greg <= abi->last_greg)
	{
	  /* If the parameter fits in the remaining argument registers, write it to
	     the registers, and to the stack if the abi requires it. */

	  if (do_copy)
	    {
	      /* Split the argument between registers & the stack if it
		 doesn't fit in the remaining registers.  */
	      int regs_avaliable = abi->last_greg - c->greg + 1;
	      if (regs_avaliable >= nregs)
		regs_avaliable = nregs;

	      ppc_copy_into_greg (current_regcache, c->greg, 
				  tdep->wordsize, regs_avaliable * 4, val_contents);
	    }
	  if (do_copy && abi->regs_shadow_stack)
	    write_memory (c->sp + c->argoffset, val_contents, len);

	  c->greg += nregs;
	  if (abi->regs_shadow_stack)
	    c->argoffset += (nregs * 4);
	}
      else 
	{
	  /* If we've filled up the registers, then just write it on the stack. */

	  if (do_copy)
	    write_memory (c->sp + c->argoffset, val_contents, len);
	  c->argoffset += (nregs * 4);
	}
      break;
    }

  case TYPE_CODE_STRUCT:
  case TYPE_CODE_UNION:
    {
      if (! abi->structs_with_args)
	{
	  if (floatonly)
	    break;

	  if (len > 4)
	    {
	      /* Rounding to the nearest multiple of 8 may not be necessary,
		 but it is safe.  Particularly since we don't know the
		 field types of the structure */
	      c->structoffset = ROUND_UP (c->structoffset, 8);
	      if (do_copy)
		{
		  write_memory (c->sp + c->structoffset, value_contents (arg), len);
		  store_unsigned_integer (buf, 4, c->sp + c->structoffset);
		}
	      c->structoffset += ROUND_UP (len, 8);
	    }
	  else
	    if (do_copy)
	      {
		memset (buf, 0, 4);
		memcpy (buf, value_contents (arg), len);
	      }

	  if (c->greg <= abi->last_greg)
	    {
	      if (do_copy)
		ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, 4, buf);
	      c->greg++;
	    }
	  else
	    {
	      if (do_copy)
		write_memory (c->sp + c->argoffset, buf, 4);
	      c->argoffset += 4;
	    }
	  break;
	}
      else
	{
	  int i;
	  int regspace = (abi->last_greg - c->greg + 1) * 4;
	  int stackspace = (len <= regspace) ? 0 : (len - regspace);
	  int writereg = (regspace > len) ? len : regspace;
	  int writestack = abi->regs_shadow_stack ? len : stackspace;

	  for (i = 0; i < TYPE_NFIELDS (type); i++)
	    {
	      struct value *subarg = value_field (arg, i);

	      ppc_push_argument (abi, c, subarg, argno, do_copy, 1);
	    }

	  if (floatonly)
	    break;

	  if (do_copy)
	    {
	      gdb_byte *ptr = value_contents (arg);
	      if (len < 4)
		{
		  memset (buf, 0, 4);
		  if ((len == 1) || (len == 2))
		    memcpy (buf + 4 - len, ptr, len);
		  else
		    memcpy (buf, ptr, len);
		  ptr = buf;
		}
	      ppc_copy_into_greg (current_regcache, c->greg, 
				  tdep->wordsize, (writereg < 4) ? 4 : writereg, ptr);
	      write_memory (c->sp + c->argoffset, ptr,
			    (writestack < 4) ? 4 : writestack);
	    }

	  c->greg += ROUND_UP (writereg, 4) / 4;
	  c->argoffset += writestack;
	}
      break;
    }

  case TYPE_CODE_ARRAY:
    {
      if (floatonly)
	break;

      if (! TYPE_VECTOR (type))
	error ("non-vector array type");
      if (len != 16)
	error ("unexpected vector length");

      if (c->vreg <= abi->last_vreg)
	{
	  if (do_copy)
	    regcache_raw_write (current_regcache, tdep->ppc_vr0_regnum + c->vreg,
				value_contents (arg));
	  c->vreg++;
	}
      else
	{
	  /* Vector arguments must be aligned to 16 bytes on
	     the stack. */
	  c->argoffset = ROUND_UP (c->argoffset, 16);
	  if (do_copy)
	    write_memory (c->sp + c->argoffset, value_contents (arg), len);
	  c->argoffset += len;
	}
      break;
    }

  default:
    error ("argument %d has unknown type code 0x%x (%s)",
	   argno, TYPE_CODE (type),
	   type_code_name (TYPE_CODE (type)));
  }

  return;
}
示例#17
0
std::optional<int> CSeqConversionDefault::GetNextInteger(std::string_view &sv, bool Signed) const
{
	re::svmatch m;

	if (m_bHex) {
		static const std::regex HEX_RE {R"(^([\+-]?)[0-9A-Fa-f]+)", std::regex_constants::optimize};
		if (std::regex_search(sv.begin(), sv.end(), m, HEX_RE))
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[0]), 16)) {
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
	}
	else {
		static const std::regex NUMBER_RE {R"(^([\+-]?)[0-9]+)", std::regex_constants::optimize};
		static const std::regex HEX_PREFIX_RE {R"(^([\+-]?)[\$x]([0-9A-Fa-f]+))", std::regex_constants::optimize}; // do not allow 0x prefix
		if (std::regex_search(sv.begin(), sv.end(), m, HEX_PREFIX_RE)) {
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[2]), 16)) {
					if (m[1] == "-")
						*val = -*val;
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
		}
		else if (std::regex_search(sv.begin(), sv.end(), m, NUMBER_RE)) {
			if (!(Signed && !m[1].length()))
				if (auto val = conv::to_int(re::sv_from_submatch(m[0]))) {
					sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
					return val;
				}
		}
	}

	return std::nullopt;
}

std::optional<int> CSeqConversionDefault::GetNextTerm(std::string_view &sv)
{
	return GetNextInteger(sv);
}



std::string CSeqConversion5B::ToString(char Value) const
{
	std::string Str = std::to_string(Value & 0x1F);
	uint8_t m = (uint8_t)Value & 0xE0;
	if ((m & value_cast(s5b_mode_t::Square)) == value_cast(s5b_mode_t::Square))
		Str.push_back('t');
	if ((m & value_cast(s5b_mode_t::Noise)) == value_cast(s5b_mode_t::Noise))
		Str.push_back('n');
	if ((m & value_cast(s5b_mode_t::Envelope)) == value_cast(s5b_mode_t::Envelope))
		Str.push_back('e');
//	auto m = enum_cast<s5b_mode_t>((unsigned char)Value);
//	if ((m & s5b_mode_t::Square) == s5b_mode_t::Square)
//		Str.push_back('t');
//	if ((m & s5b_mode_t::Noise) == s5b_mode_t::Noise)
//		Str.push_back('n');
//	if ((m & s5b_mode_t::Envelope) == s5b_mode_t::Envelope)
//		Str.push_back('e');
	return Str;
}

bool CSeqConversion5B::ToValue(std::string_view sv)
{
	m_iEnableFlags = -1;
	return CSeqConversionDefault::ToValue(sv);
}

char CSeqConversion5B::GetValue()
{
	return CSeqConversionDefault::GetValue() | m_iEnableFlags;
}

std::optional<int> CSeqConversion5B::GetNextTerm(std::string_view &sv)
{
	if (auto o = GetNextInteger(sv)) {
		static const std::regex S5B_FLAGS_RE {R"(^[TtNnEe]*)", std::regex_constants::optimize};
		if (re::svmatch m; std::regex_search(sv.begin(), sv.end(), m, S5B_FLAGS_RE)) {
			if (m_iEnableFlags == -1) {
				m_iEnableFlags = 0;
				auto flags = re::sv_from_submatch(m[0]);
				if (flags.find_first_of("Tt") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Square);
				if (flags.find_first_of("Nn") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Noise);
				if (flags.find_first_of("Ee") != std::string::npos)
					m_iEnableFlags |= value_cast(s5b_mode_t::Envelope);
			}
			sv.remove_prefix(std::distance(sv.begin(), m.suffix().first));
		}
static int
ada_val_print_1 (struct type *type, char *valaddr0, int embedded_offset,
		 CORE_ADDR address, struct ui_file *stream, int format,
		 int deref_ref, int recurse, enum val_prettyprint pretty)
{
  unsigned int len;
  int i;
  struct type *elttype;
  unsigned int eltlen;
  LONGEST val;
  char *valaddr = valaddr0 + embedded_offset;

  CHECK_TYPEDEF (type);

  if (ada_is_array_descriptor_type (type) || ada_is_packed_array_type (type))
    {
      int retn;
      struct value *mark = value_mark ();
      struct value *val;
      val = value_from_contents_and_address (type, valaddr, address);
      val = ada_coerce_to_simple_array_ptr (val);
      if (val == NULL)
	{
	  fprintf_filtered (stream, "(null)");
	  retn = 0;
	}
      else
	retn = ada_val_print_1 (VALUE_TYPE (val), VALUE_CONTENTS (val), 0,
				VALUE_ADDRESS (val), stream, format,
				deref_ref, recurse, pretty);
      value_free_to_mark (mark);
      return retn;
    }

  valaddr = ada_aligned_value_addr (type, valaddr);
  embedded_offset -= valaddr - valaddr0 - embedded_offset;
  type = printable_val_type (type, valaddr);

  switch (TYPE_CODE (type))
    {
    default:
      return c_val_print (type, valaddr0, embedded_offset, address, stream,
			  format, deref_ref, recurse, pretty);

    case TYPE_CODE_PTR:
      {
	int ret = c_val_print (type, valaddr0, embedded_offset, address, 
			       stream, format, deref_ref, recurse, pretty);
	if (ada_is_tag_type (type))
	  {
	    struct value *val = 
	      value_from_contents_and_address (type, valaddr, address);
	    const char *name = ada_tag_name (val);
	    if (name != NULL) 
	      fprintf_filtered (stream, " (%s)", name);
	    return 0;
	}
	return ret;
      }

    case TYPE_CODE_INT:
    case TYPE_CODE_RANGE:
      if (ada_is_fixed_point_type (type))
	{
	  LONGEST v = unpack_long (type, valaddr);
	  int len = TYPE_LENGTH (type);

	  fprintf_filtered (stream, len < 4 ? "%.11g" : "%.17g",
			    (double) ada_fixed_to_float (type, v));
	  return 0;
	}
      else if (ada_is_vax_floating_type (type))
	{
	  struct value *val =
	    value_from_contents_and_address (type, valaddr, address);
	  struct value *func = ada_vax_float_print_function (type);
	  if (func != 0)
	    {
	      static struct type *parray_of_char = NULL;
	      struct value *printable_val;

	      if (parray_of_char == NULL)
		parray_of_char =
		  make_pointer_type
		  (create_array_type
		   (NULL, builtin_type_char,
		    create_range_type (NULL, builtin_type_int, 0, 32)), NULL);

	      printable_val =
		value_ind (value_cast (parray_of_char,
				       call_function_by_hand (func, 1,
							      &val)));

	      fprintf_filtered (stream, "%s", VALUE_CONTENTS (printable_val));
	      return 0;
	    }
	  /* No special printing function.  Do as best we can.  */
	}
      else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
	{
	  struct type *target_type = TYPE_TARGET_TYPE (type);
	  if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type))
	    {
	      /* Obscure case of range type that has different length from
	         its base type.  Perform a conversion, or we will get a
	         nonsense value.  Actually, we could use the same
	         code regardless of lengths; I'm just avoiding a cast.  */
	      struct value *v = value_cast (target_type,
					    value_from_contents_and_address
					    (type, valaddr, 0));
	      return ada_val_print_1 (target_type, VALUE_CONTENTS (v), 0, 0,
				      stream, format, 0, recurse + 1, pretty);
	    }
	  else
	    return ada_val_print_1 (TYPE_TARGET_TYPE (type),
				    valaddr0, embedded_offset,
				    address, stream, format, deref_ref,
				    recurse, pretty);
	}
      else
	{
	  format = format ? format : output_format;
	  if (format)
	    {
	      print_scalar_formatted (valaddr, type, format, 0, stream);
	    }
          else if (ada_is_system_address_type (type))
            {
              /* FIXME: We want to print System.Address variables using
                 the same format as for any access type.  But for some
                 reason GNAT encodes the System.Address type as an int,
                 so we have to work-around this deficiency by handling
                 System.Address values as a special case.  */
              fprintf_filtered (stream, "(");
              type_print (type, "", stream, -1);
              fprintf_filtered (stream, ") ");
              print_address_numeric 
		(extract_typed_address (valaddr, builtin_type_void_data_ptr),
                 1, stream);
            }
	  else
	    {
	      val_print_type_code_int (type, valaddr, stream);
	      if (ada_is_character_type (type))
		{
		  fputs_filtered (" ", stream);
		  ada_printchar ((unsigned char) unpack_long (type, valaddr),
				 stream);
		}
	    }
	  return 0;
	}

    case TYPE_CODE_ENUM:
      if (format)
	{
	  print_scalar_formatted (valaddr, type, format, 0, stream);
	  break;
	}
      len = TYPE_NFIELDS (type);
      val = unpack_long (type, valaddr);
      for (i = 0; i < len; i++)
	{
	  QUIT;
	  if (val == TYPE_FIELD_BITPOS (type, i))
	    {
	      break;
	    }
	}
      if (i < len)
	{
	  const char *name = ada_enum_name (TYPE_FIELD_NAME (type, i));
	  if (name[0] == '\'')
	    fprintf_filtered (stream, "%ld %s", (long) val, name);
	  else
	    fputs_filtered (name, stream);
	}
      else
	{
	  print_longest (stream, 'd', 0, val);
	}
      break;

    case TYPE_CODE_FLT:
      if (format)
	return c_val_print (type, valaddr0, embedded_offset, address, stream,
			    format, deref_ref, recurse, pretty);
      else
	ada_print_floating (valaddr0 + embedded_offset, type, stream);
      break;

    case TYPE_CODE_UNION:
    case TYPE_CODE_STRUCT:
      if (ada_is_bogus_array_descriptor (type))
	{
	  fprintf_filtered (stream, "(...?)");
	  return 0;
	}
      else
	{
	  print_record (type, valaddr, stream, format, recurse, pretty);
	  return 0;
	}

    case TYPE_CODE_ARRAY:
      elttype = TYPE_TARGET_TYPE (type);
      if (elttype == NULL)
	eltlen = 0;
      else
	eltlen = TYPE_LENGTH (elttype);
      /* FIXME: This doesn't deal with non-empty arrays of
	 0-length items (not a typical case!) */
      if (eltlen == 0)
	len = 0;
      else
	len = TYPE_LENGTH (type) / eltlen;

	  /* For an array of chars, print with string syntax.  */
      if (ada_is_string_type (type) && (format == 0 || format == 's'))
	{
	  if (prettyprint_arrays)
	    {
	      print_spaces_filtered (2 + 2 * recurse, stream);
	    }
	  /* If requested, look for the first null char and only print
	     elements up to it.  */
	  if (stop_print_at_null)
	    {
	      int temp_len;

	      /* Look for a NULL char.  */
	      for (temp_len = 0;
		   temp_len < len && temp_len < print_max
		     && char_at (valaddr, temp_len, eltlen) != 0;
		   temp_len += 1);
	      len = temp_len;
	    }

	  printstr (stream, valaddr, len, 0, eltlen);
	}
      else
	{
	  len = 0;
	  fprintf_filtered (stream, "(");
	  print_optional_low_bound (stream, type);
	  if (TYPE_FIELD_BITSIZE (type, 0) > 0)
	    val_print_packed_array_elements (type, valaddr, 0, stream,
					     format, recurse, pretty);
	  else
	    val_print_array_elements (type, valaddr, address, stream,
				      format, deref_ref, recurse,
				      pretty, 0);
	  fprintf_filtered (stream, ")");
	}
      gdb_flush (stream);
      return len;

    case TYPE_CODE_REF:
      elttype = check_typedef (TYPE_TARGET_TYPE (type));
      /* De-reference the reference */
      if (deref_ref)
	{
	  if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF)
	    {
	      LONGEST deref_val_int = (LONGEST)
		unpack_pointer (lookup_pointer_type (builtin_type_void),
				valaddr);
	      if (deref_val_int != 0)
		{
		  struct value *deref_val =
		    ada_value_ind (value_from_longest
				   (lookup_pointer_type (elttype),
				    deref_val_int));
		  val_print (VALUE_TYPE (deref_val),
			     VALUE_CONTENTS (deref_val), 0,
			     VALUE_ADDRESS (deref_val), stream, format,
			     deref_ref, recurse + 1, pretty);
		}
	      else
		fputs_filtered ("(null)", stream);
	    }
	  else
	    fputs_filtered ("???", stream);
	}
      break;
    }
  gdb_flush (stream);
  return 0;
}
示例#19
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);
}
示例#20
0
static void
ada_val_print_num (struct type *type, const gdb_byte *valaddr,
		   int offset, int offset_aligned, CORE_ADDR address,
		   struct ui_file *stream, int recurse,
		   struct value *original_value,
		   const struct value_print_options *options,
		   const struct language_defn *language)
{
  if (ada_is_fixed_point_type (type))
    {
      LONGEST v = unpack_long (type, valaddr + offset_aligned);

      fprintf_filtered (stream, TYPE_LENGTH (type) < 4 ? "%.11g" : "%.17g",
			(double) ada_fixed_to_float (type, v));
      return;
    }
  else if (TYPE_CODE (type) == TYPE_CODE_RANGE)
    {
      struct type *target_type = TYPE_TARGET_TYPE (type);

      if (TYPE_LENGTH (type) != TYPE_LENGTH (target_type))
	{
	  /* Obscure case of range type that has different length from
	     its base type.  Perform a conversion, or we will get a
	     nonsense value.  Actually, we could use the same
	     code regardless of lengths; I'm just avoiding a cast.  */
	  struct value *v1
	    = value_from_contents_and_address (type, valaddr + offset, 0);
	  struct value *v = value_cast (target_type, v1);

	  val_print (target_type,
		     value_embedded_offset (v), 0, stream,
		     recurse + 1, v, options, language);
	}
      else
	val_print (TYPE_TARGET_TYPE (type), offset,
		   address, stream, recurse, original_value,
		   options, language);
      return;
    }
  else
    {
      int format = (options->format ? options->format
		    : options->output_format);

      if (format)
	{
	  struct value_print_options opts = *options;

	  opts.format = format;
	  val_print_scalar_formatted (type, offset_aligned,
				      original_value, &opts, 0, stream);
	}
      else if (ada_is_system_address_type (type))
	{
	  /* FIXME: We want to print System.Address variables using
	     the same format as for any access type.  But for some
	     reason GNAT encodes the System.Address type as an int,
	     so we have to work-around this deficiency by handling
	     System.Address values as a special case.  */

	  struct gdbarch *gdbarch = get_type_arch (type);
	  struct type *ptr_type = builtin_type (gdbarch)->builtin_data_ptr;
	  CORE_ADDR addr = extract_typed_address (valaddr + offset_aligned,
						  ptr_type);

	  fprintf_filtered (stream, "(");
	  type_print (type, "", stream, -1);
	  fprintf_filtered (stream, ") ");
	  fputs_filtered (paddress (gdbarch, addr), stream);
	}
      else
	{
	  val_print_type_code_int (type, valaddr + offset_aligned, stream);
	  if (ada_is_character_type (type))
	    {
	      LONGEST c;

	      fputs_filtered (" ", stream);
	      c = unpack_long (type, valaddr + offset_aligned);
	      ada_printchar (c, type, stream);
	    }
	}
      return;
    }
}
示例#21
0
/* 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.  */
static struct value *
gnuv2_virtual_fn_field (struct value **arg1p, struct fn_field * f, int j,
			struct type * type, int offset)
{
  struct value *arg1 = *arg1p;
  struct type *type1 = check_typedef (value_type (arg1));


  struct type *entry_type;
  /* 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.  */
  struct value *entry;
  struct value *vfn;
  struct value *vtbl;
  struct 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) != type1)
    {
      struct value *tmp = value_cast (context, value_addr (arg1));
      arg1 = value_ind (tmp);
      type1 = check_typedef (value_type (arg1));
    }

  context = type1;
  /* 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_primitive_field (arg1, 0, TYPE_VPTR_FIELDNO (context),
				TYPE_VPTR_BASETYPE (context));

  /* With older versions of g++, the vtbl field pointed to an array
     of structures.  Nowadays it points directly to the structure. */
  if (TYPE_CODE (value_type (vtbl)) == TYPE_CODE_PTR
      && TYPE_CODE (TYPE_TARGET_TYPE (value_type (vtbl))) == TYPE_CODE_ARRAY)
    {
      /* Handle the case where the vtbl field points to an
         array of structures. */
      vtbl = value_ind (vtbl);

      /* 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);
    }
  else
    {
      /* Handle the case where the vtbl field points directly to a structure. */
      vtbl = value_add (vtbl, vi);
      entry = value_ind (vtbl);
    }

  entry_type = check_typedef (value_type (entry));

  if (TYPE_CODE (entry_type) == TYPE_CODE_STRUCT)
    {
      /* Move the `this' pointer according to the virtual function table. */
      set_value_offset (arg1, value_offset (arg1) + value_as_long (value_field (entry, 0)));

      if (!value_lazy (arg1))
	{
	  set_value_lazy (arg1, 1);
	  value_fetch_lazy (arg1);
	}

      vfn = value_field (entry, 2);
    }
  else if (TYPE_CODE (entry_type) == TYPE_CODE_PTR)
    vfn = entry;
  else
    error (_("I'm confused:  virtual function table has bad type"));
  /* Reinstantiate the function pointer with the correct type.  */
  deprecated_set_value_type (vfn, lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)));

  *arg1p = arg1;
  return vfn;
}
示例#22
0
文件: infcall.c 项目: ChrisG0x20/gdb
static struct value *
value_arg_coerce (struct gdbarch *gdbarch, struct value *arg,
		  struct type *param_type, int is_prototyped, CORE_ADDR *sp)
{
  const struct builtin_type *builtin = builtin_type (gdbarch);
  struct type *arg_type = check_typedef (value_type (arg));
  struct type *type
    = param_type ? check_typedef (param_type) : arg_type;

  /* Perform any Ada-specific coercion first.  */
  if (current_language->la_language == language_ada)
    arg = ada_convert_actual (arg, type);

  /* Force the value to the target if we will need its address.  At
     this point, we could allocate arguments on the stack instead of
     calling malloc if we knew that their addresses would not be
     saved by the called function.  */
  arg = value_coerce_to_target (arg);

  switch (TYPE_CODE (type))
    {
    case TYPE_CODE_REF:
      {
	struct value *new_value;

	if (TYPE_CODE (arg_type) == TYPE_CODE_REF)
	  return value_cast_pointers (type, arg, 0);

	/* Cast the value to the reference's target type, and then
	   convert it back to a reference.  This will issue an error
	   if the value was not previously in memory - in some cases
	   we should clearly be allowing this, but how?  */
	new_value = value_cast (TYPE_TARGET_TYPE (type), arg);
	new_value = value_ref (new_value);
	return new_value;
      }
    case TYPE_CODE_INT:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_ENUM:
      /* If we don't have a prototype, coerce to integer type if necessary.  */
      if (!is_prototyped)
	{
	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
	    type = builtin->builtin_int;
	}
      /* Currently all target ABIs require at least the width of an integer
         type for an argument.  We may have to conditionalize the following
         type coercion for future targets.  */
      if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_int))
	type = builtin->builtin_int;
      break;
    case TYPE_CODE_FLT:
      if (!is_prototyped && coerce_float_to_double_p)
	{
	  if (TYPE_LENGTH (type) < TYPE_LENGTH (builtin->builtin_double))
	    type = builtin->builtin_double;
	  else if (TYPE_LENGTH (type) > TYPE_LENGTH (builtin->builtin_double))
	    type = builtin->builtin_long_double;
	}
      break;
    case TYPE_CODE_FUNC:
      type = lookup_pointer_type (type);
      break;
    case TYPE_CODE_ARRAY:
      /* Arrays are coerced to pointers to their first element, unless
         they are vectors, in which case we want to leave them alone,
         because they are passed by value.  */
      if (current_language->c_style_arrays)
	if (!TYPE_VECTOR (type))
	  type = lookup_pointer_type (TYPE_TARGET_TYPE (type));
      break;
    case TYPE_CODE_UNDEF:
    case TYPE_CODE_PTR:
    case TYPE_CODE_STRUCT:
    case TYPE_CODE_UNION:
    case TYPE_CODE_VOID:
    case TYPE_CODE_SET:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_STRING:
    case TYPE_CODE_ERROR:
    case TYPE_CODE_MEMBERPTR:
    case TYPE_CODE_METHODPTR:
    case TYPE_CODE_METHOD:
    case TYPE_CODE_COMPLEX:
    default:
      break;
    }

  return value_cast (type, arg);
}
示例#23
0
static CORE_ADDR
sparc32_store_arguments (struct regcache *regcache, int nargs,
			 struct value **args, CORE_ADDR sp,
			 int struct_return, CORE_ADDR struct_addr)
{
  /* Number of words in the "parameter array".  */
  int num_elements = 0;
  int element = 0;
  int i;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);

      if (sparc_structure_or_union_p (type)
	  || (sparc_floating_p (type) && len == 16))
	{
	  /* Structure, Union and Quad-Precision Arguments.  */
	  sp -= len;

	  /* Use doubleword alignment for these values.  That's always
             correct, and wasting a few bytes shouldn't be a problem.  */
	  sp &= ~0x7;

	  write_memory (sp, value_contents (args[i]), len);
	  args[i] = value_from_pointer (lookup_pointer_type (type), sp);
	  num_elements++;
	}
      else if (sparc_floating_p (type))
	{
	  /* Floating arguments.  */
	  gdb_assert (len == 4 || len == 8);
	  num_elements += (len / 4);
	}
      else
	{
	  /* Integral and pointer arguments.  */
	  gdb_assert (sparc_integral_or_pointer_p (type));

	  if (len < 4)
	    args[i] = value_cast (builtin_type_int32, args[i]);
	  num_elements += ((len + 3) / 4);
	}
    }

  /* Always allocate at least six words.  */
  sp -= max (6, num_elements) * 4;

  /* The psABI says that "Software convention requires space for the
     struct/union return value pointer, even if the word is unused."  */
  sp -= 4;

  /* The psABI says that "Although software convention and the
     operating system require every stack frame to be doubleword
     aligned."  */
  sp &= ~0x7;

  for (i = 0; i < nargs; i++)
    {
      const bfd_byte *valbuf = value_contents (args[i]);
      struct type *type = value_type (args[i]);
      int len = TYPE_LENGTH (type);

      gdb_assert (len == 4 || len == 8);

      if (element < 6)
	{
	  int regnum = SPARC_O0_REGNUM + element;

	  regcache_cooked_write (regcache, regnum, valbuf);
	  if (len > 4 && element < 5)
	    regcache_cooked_write (regcache, regnum + 1, valbuf + 4);
	}

      /* Always store the argument in memory.  */
      write_memory (sp + 4 + element * 4, valbuf, len);
      element += len / 4;
    }

  gdb_assert (element == num_elements);

  if (struct_return)
    {
      gdb_byte buf[4];

      store_unsigned_integer (buf, 4, struct_addr);
      write_memory (sp, buf, 4);
    }

  return sp;
}
示例#24
0
bool CPatternAction::SetTargetSelection(const CMainFrame &MainFrm, CSelection &Sel)		// // //
{
	CPatternEditor *pPatternEditor = GET_PATTERN_EDITOR();
	CCursorPos Start;

	if ((m_iPastePos == paste_pos_t::SELECTION || m_iPastePos == paste_pos_t::FILL) && !m_bSelecting)
		m_iPastePos = paste_pos_t::CURSOR;

	switch (m_iPastePos) { // Xpos.Column will be written later
	case paste_pos_t::CURSOR:
		Start = m_pUndoState->Cursor;
		break;
	case paste_pos_t::DRAG:
		Start.Ypos.Frame = m_dragTarget.GetFrameStart();
		Start.Ypos.Row = m_dragTarget.GetRowStart();
		Start.Xpos.Track = m_dragTarget.GetChanStart();
		break;
	case paste_pos_t::SELECTION:
	case paste_pos_t::FILL:
		Start.Ypos.Frame = m_selection.GetFrameStart();
		Start.Ypos.Row = m_selection.GetRowStart();
		Start.Xpos.Track = m_selection.GetChanStart();
		break;
	}

	auto pSongView = GET_SONG_VIEW();

	CPatternIterator End(*pSongView, Start);

	if (m_iPasteMode == paste_mode_t::INSERT) {
		End.m_iFrame = Start.Ypos.Frame;
		End.m_iRow = pPatternEditor->GetCurrentPatternLength(End.m_iFrame) - 1;
	}
	else
		End += m_ClipData.ClipInfo.Rows - 1;

	switch (m_iPastePos) {
	case paste_pos_t::FILL:
		End.m_iFrame = m_selection.GetFrameEnd();
		End.m_iRow = m_selection.GetRowEnd();
		End.m_iChannel = m_selection.GetChanEnd();
		Start.Xpos.Column = GetCursorStartColumn(m_ClipData.ClipInfo.StartColumn);
		End.m_iColumn = GetCursorEndColumn(
			!((End.m_iChannel - Start.Xpos.Track + 1) % m_ClipData.ClipInfo.Channels) ?
			m_ClipData.ClipInfo.EndColumn :
			static_cast<column_t>(value_cast(column_t::Effect1) + pSongView->GetEffectColumnCount(End.m_iChannel)));
		break;
	case paste_pos_t::DRAG:
		End.m_iChannel += m_ClipData.ClipInfo.Channels - 1;
		Start.Xpos.Column = m_dragTarget.GetColStart();
		End.m_iColumn = m_dragTarget.GetColEnd();
		break;
	default:
		End.m_iChannel += m_ClipData.ClipInfo.Channels - 1;
		Start.Xpos.Column = GetCursorStartColumn(m_ClipData.ClipInfo.StartColumn);
		End.m_iColumn = GetCursorEndColumn(m_ClipData.ClipInfo.EndColumn);
	}

	const bool bOverflow = FTEnv.GetSettings()->General.bOverflowPaste;
	if (!bOverflow && End.m_iFrame > Start.Ypos.Frame) {
		End.m_iFrame = Start.Ypos.Frame;
		End.m_iRow = pPatternEditor->GetCurrentPatternLength(End.m_iFrame) - 1;
	}

	const cursor_column_t EFBEGIN = GetCursorStartColumn(column_t::Effect1);
	int OFFS = 3 * (value_cast(GetSelectColumn(m_pUndoState->Cursor.Xpos.Column)) - value_cast(m_ClipData.ClipInfo.StartColumn));
	if (OFFS < static_cast<int>(value_cast(EFBEGIN) - value_cast(Start.Xpos.Column)))
		OFFS = value_cast(EFBEGIN) - value_cast(Start.Xpos.Column);
	if (Start.Xpos.Track == End.m_iChannel && Start.Xpos.Column >= EFBEGIN && End.m_iColumn >= EFBEGIN) {
		if (m_iPastePos != paste_pos_t::DRAG) {
			End.m_iColumn = static_cast<cursor_column_t>(value_cast(End.m_iColumn) + OFFS);
			Start.Xpos.Column = static_cast<cursor_column_t>(value_cast(Start.Xpos.Column) + OFFS);
			if (End.m_iColumn > cursor_column_t::EFF4_PARAM2)
				End.m_iColumn = cursor_column_t::EFF4_PARAM2;
		}
	}

	CSelection New;
	New.m_cpStart = Start;
	New.m_cpEnd = End.GetCursor();
	pPatternEditor->SetSelection(New);

	sel_condition_t Cond = pPatternEditor->GetSelectionCondition();
	if (Cond == sel_condition_t::CLEAN) {
		Sel = New;
		return true;
	}
	else {
		pPatternEditor->SetSelection(m_selection);
		if (!m_bSelecting) pPatternEditor->CancelSelection();
		int Confirm = IDYES;
		switch (Cond) {
		case sel_condition_t::REPEATED_ROW:
			Confirm = AfxMessageBox(IDS_PASTE_REPEATED_ROW, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2);
			break;
		case sel_condition_t::NONTERMINAL_SKIP: case sel_condition_t::TERMINAL_SKIP:
			if (!bOverflow) break;
			Confirm = AfxMessageBox(IDS_PASTE_NONTERMINAL, MB_YESNO | MB_ICONEXCLAMATION | MB_DEFBUTTON2);
			break;
		}
		if (Confirm == IDYES) {
			pPatternEditor->SetSelection(Sel = New);
			return true;
		}
		else {
			return false;
		}
	}
}