+ case DW_OP_GNU_variable_value:
+ {
+ sect_offset sect_off
+ = (sect_offset) extract_unsigned_integer (op_ptr,
+ this->ref_addr_size,
+ byte_order);
+ op_ptr += this->ref_addr_size;
+ result_val = this->dwarf_variable_value (sect_off);
+ }
+ break;
+
+ case DW_OP_entry_value:
+ case DW_OP_GNU_entry_value:
+ {
+ uint64_t len;
+ CORE_ADDR deref_size;
+ union call_site_parameter_u kind_u;
+
+ op_ptr = safe_read_uleb128 (op_ptr, op_end, &len);
+ if (op_ptr + len > op_end)
+ error (_("DW_OP_entry_value: too few bytes available."));
+
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg (op_ptr, op_ptr + len);
+ if (kind_u.dwarf_reg != -1)
+ {
+ op_ptr += len;
+ this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG,
+ kind_u,
+ -1 /* deref_size */);
+ goto no_push;
+ }
+
+ kind_u.dwarf_reg = dwarf_block_to_dwarf_reg_deref (op_ptr,
+ op_ptr + len,
+ &deref_size);
+ if (kind_u.dwarf_reg != -1)
+ {
+ if (deref_size == -1)
+ deref_size = this->addr_size;
+ op_ptr += len;
+ this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG,
+ kind_u, deref_size);
+ goto no_push;
+ }
+
+ error (_("DWARF-2 expression error: DW_OP_entry_value is "
+ "supported only for single DW_OP_reg* "
+ "or for DW_OP_breg*(0)+DW_OP_deref*"));
+ }
+
+ case DW_OP_GNU_parameter_ref:
+ {
+ union call_site_parameter_u kind_u;
+
+ kind_u.param_cu_off
+ = (cu_offset) extract_unsigned_integer (op_ptr, 4, byte_order);
+ op_ptr += 4;
+ this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_PARAM_OFFSET,
+ kind_u,
+ -1 /* deref_size */);
+ }
+ goto no_push;
+
+ case DW_OP_const_type:
+ case DW_OP_GNU_const_type:
+ {
+ int n;
+ const gdb_byte *data;
+ struct type *type;
+
+ op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
+
+ n = *op_ptr++;
+ data = op_ptr;
+ op_ptr += n;
+
+ type = get_base_type (type_die_cu_off, n);
+ result_val = value_from_contents (type, data);
+ }
+ break;
+
+ case DW_OP_regval_type:
+ case DW_OP_GNU_regval_type:
+ {
+ struct type *type;
+
+ op_ptr = safe_read_uleb128 (op_ptr, op_end, ®);
+ op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
+
+ type = get_base_type (type_die_cu_off, 0);
+ result_val = this->get_reg_value (type, reg);
+ }
+ break;
+
+ case DW_OP_convert:
+ case DW_OP_GNU_convert:
+ case DW_OP_reinterpret:
+ case DW_OP_GNU_reinterpret:
+ {
+ struct type *type;
+
+ op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
+ cu_offset type_die_cu_off = (cu_offset) uoffset;
+
+ if (to_underlying (type_die_cu_off) == 0)
+ type = address_type;
+ else
+ type = get_base_type (type_die_cu_off, 0);
+
+ result_val = fetch (0);
+ pop ();
+
+ if (op == DW_OP_convert || op == DW_OP_GNU_convert)
+ result_val = value_cast (type, result_val);
+ else if (type == value_type (result_val))
+ {
+ /* Nothing. */
+ }
+ else if (TYPE_LENGTH (type)
+ != TYPE_LENGTH (value_type (result_val)))
+ error (_("DW_OP_reinterpret has wrong size"));
+ else
+ result_val
+ = value_from_contents (type,
+ value_contents_all (result_val));
+ }
+ break;
+
+ case DW_OP_push_object_address:
+ /* Return the address of the object we are currently observing. */
+ result = this->get_object_address ();
+ result_val = value_from_ulongest (address_type, result);
+ break;
+