static void m2_print_unbounded_array (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value_print_options *options) { CORE_ADDR addr; LONGEST len; struct value *val; type = check_typedef (type); addr = unpack_pointer (TYPE_FIELD_TYPE (type, 0), (TYPE_FIELD_BITPOS (type, 0) / 8) + valaddr + embedded_offset); val = value_at_lazy (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0)), addr); len = unpack_field_as_long (type, valaddr + embedded_offset, 1); fprintf_filtered (stream, "{"); m2_print_array_contents (value_type (val), value_contents_for_printing (val), value_embedded_offset (val), addr, stream, recurse, val, options, len); fprintf_filtered (stream, ", HIGH = %d}", (int) len); }
static void ada_val_print_gnat_array (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *original_value, const struct value_print_options *options, const struct language_defn *language) { struct value *mark = value_mark (); struct value *val; val = value_from_contents_and_address (type, valaddr + offset, address); /* If this is a reference, coerce it now. This helps taking care of the case where ADDRESS is meaningless because original_value was not an lval. */ val = coerce_ref (val); if (TYPE_CODE (type) == TYPE_CODE_TYPEDEF) /* array access type. */ val = ada_coerce_to_simple_array_ptr (val); else val = ada_coerce_to_simple_array (val); if (val == NULL) { gdb_assert (TYPE_CODE (type) == TYPE_CODE_TYPEDEF); fprintf_filtered (stream, "0x0"); } else val_print (value_type (val), value_contents_for_printing (val), value_embedded_offset (val), value_address (val), stream, recurse, val, options, language); value_free_to_mark (mark); }
static void ada_val_print_ref (struct type *type, const gdb_byte *valaddr, int offset, int offset_aligned, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *original_value, const struct value_print_options *options, const struct language_defn *language) { /* For references, the debugger is expected to print the value as an address if DEREF_REF is null. But printing an address in place of the object value would be confusing to an Ada programmer. So, for Ada values, we print the actual dereferenced value regardless. */ struct type *elttype = check_typedef (TYPE_TARGET_TYPE (type)); struct value *deref_val; CORE_ADDR deref_val_int; if (TYPE_CODE (elttype) == TYPE_CODE_UNDEF) { fputs_filtered ("<ref to undefined type>", stream); return; } deref_val = coerce_ref_if_computed (original_value); if (deref_val) { if (ada_is_tagged_type (value_type (deref_val), 1)) deref_val = ada_tag_value_at_base_address (deref_val); common_val_print (deref_val, stream, recurse + 1, options, language); return; } deref_val_int = unpack_pointer (type, valaddr + offset_aligned); if (deref_val_int == 0) { fputs_filtered ("(null)", stream); return; } deref_val = ada_value_ind (value_from_pointer (lookup_pointer_type (elttype), deref_val_int)); if (ada_is_tagged_type (value_type (deref_val), 1)) deref_val = ada_tag_value_at_base_address (deref_val); /* Make sure that the object does not have an unreasonable size before trying to print it. This can happen for instance with references to dynamic objects whose contents is uninitialized (Eg: an array whose bounds are not set yet). */ ada_ensure_varsize_limit (value_type (deref_val)); val_print (value_type (deref_val), value_contents_for_printing (deref_val), value_embedded_offset (deref_val), value_address (deref_val), stream, recurse + 1, deref_val, options, language); }
enum ext_lang_rc gdbpy_apply_val_pretty_printer (const struct extension_language_defn *extlang, struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options, const struct language_defn *language) { struct gdbarch *gdbarch = get_type_arch (type); struct value *value; enum string_repr_result print_result; const gdb_byte *valaddr = value_contents_for_printing (val); /* No pretty-printer support for unavailable values. */ if (!value_bytes_available (val, embedded_offset, TYPE_LENGTH (type))) return EXT_LANG_RC_NOP; if (!gdb_python_initialized) return EXT_LANG_RC_NOP; gdbpy_enter enter_py (gdbarch, language); /* Instantiate the printer. */ value = value_from_component (val, type, embedded_offset); gdbpy_ref<> val_obj (value_to_value_object (value)); if (val_obj == NULL) { print_stack_unless_memory_error (stream); return EXT_LANG_RC_ERROR; } /* Find the constructor. */ gdbpy_ref<> printer (find_pretty_printer (val_obj.get ())); if (printer == NULL) { print_stack_unless_memory_error (stream); return EXT_LANG_RC_ERROR; } if (printer == Py_None) return EXT_LANG_RC_NOP; /* If we are printing a map, we want some special formatting. */ gdb::unique_xmalloc_ptr<char> hint (gdbpy_get_display_hint (printer.get ())); /* Print the section */ print_result = print_string_repr (printer.get (), hint.get (), stream, recurse, options, language, gdbarch); if (print_result != string_repr_error) print_children (printer.get (), hint.get (), stream, recurse, options, language, print_result == string_repr_none); if (PyErr_Occurred ()) print_stack_unless_memory_error (stream); return EXT_LANG_RC_OK; }
static void print_go_string (struct type *type, LONGEST embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *val, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); struct type *elt_ptr_type = TYPE_FIELD_TYPE (type, 0); struct type *elt_type = TYPE_TARGET_TYPE (elt_ptr_type); LONGEST length; /* TODO(dje): The encapsulation of what a pointer is belongs in value.c. I.e. If there's going to be unpack_pointer, there should be unpack_value_field_as_pointer. Do this until we can get unpack_value_field_as_pointer. */ LONGEST addr; const gdb_byte *valaddr = value_contents_for_printing (val); if (! unpack_value_field_as_long (type, valaddr, embedded_offset, 0, val, &addr)) error (_("Unable to read string address")); if (! unpack_value_field_as_long (type, valaddr, embedded_offset, 1, val, &length)) error (_("Unable to read string length")); /* TODO(dje): Print address of struct or actual string? */ if (options->addressprint) { fputs_filtered (paddress (gdbarch, addr), stream); fputs_filtered (" ", stream); } if (length < 0) { fputs_filtered (_("<invalid length: "), stream); fputs_filtered (plongest (addr), stream); fputs_filtered (">", stream); return; } /* TODO(dje): Perhaps we should pass "UTF8" for ENCODING. The target encoding is a global switch. Either choice is problematic. */ val_print_string (elt_type, NULL, addr, length, stream, options); }
static int dynamic_array_type (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) { if (TYPE_NFIELDS (type) == 2 && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_INT && strcmp (TYPE_FIELD_NAME (type, 0), "length") == 0 && strcmp (TYPE_FIELD_NAME (type, 1), "ptr") == 0 && !value_bits_any_optimized_out (val, TARGET_CHAR_BIT * embedded_offset, TARGET_CHAR_BIT * TYPE_LENGTH (type))) { CORE_ADDR addr; struct type *elttype; struct type *true_type; struct type *ptr_type; struct value *ival; int length; length = unpack_field_as_long (type, valaddr + embedded_offset, 0); ptr_type = TYPE_FIELD_TYPE (type, 1); elttype = check_typedef (TYPE_TARGET_TYPE (ptr_type)); addr = unpack_pointer (ptr_type, valaddr + TYPE_FIELD_BITPOS (type, 1) / 8 + embedded_offset); true_type = check_typedef (elttype); true_type = lookup_array_range_type (true_type, 0, length - 1); ival = value_at (true_type, addr); true_type = value_type (ival); d_val_print (true_type, value_contents_for_printing (ival), value_embedded_offset (ival), addr, stream, recurse + 1, ival, options); return 0; } return 1; }
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); }
if (value_address (val) == first_dont_print[i]) { fputs_filtered ("\ <same as static member of an already seen type>", stream); return; } } addr = value_address (val); obstack_grow (&dont_print_statmem_obstack, (char *) &addr, sizeof (CORE_ADDR)); type = check_typedef (type); pascal_object_print_value_fields (type, value_contents_for_printing (val), value_embedded_offset (val), addr, stream, recurse, val, options, NULL, 1); return; } opts = *options; opts.deref_ref = 0; common_val_print (val, stream, recurse, &opts, current_language); } /* -Wmissing-prototypes */ extern initialize_file_ftype _initialize_pascal_valprint;
static void ada_val_print_1 (struct type *type, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options, const struct language_defn *language) { int offset_aligned; const gdb_byte *valaddr = value_contents_for_printing (original_value); type = ada_check_typedef (type); if (ada_is_array_descriptor_type (type) || (ada_is_constrained_packed_array_type (type) && TYPE_CODE (type) != TYPE_CODE_PTR)) { ada_val_print_gnat_array (type, valaddr, offset, address, stream, recurse, original_value, options, language); return; } offset_aligned = offset + ada_aligned_value_addr (type, valaddr) - valaddr; type = printable_val_type (type, valaddr + offset_aligned); type = resolve_dynamic_type (type, valaddr + offset_aligned, address + offset_aligned); switch (TYPE_CODE (type)) { default: val_print (type, offset, address, stream, recurse, original_value, options, language_def (language_c)); break; case TYPE_CODE_PTR: ada_val_print_ptr (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; case TYPE_CODE_INT: case TYPE_CODE_RANGE: ada_val_print_num (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; case TYPE_CODE_ENUM: ada_val_print_enum (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; case TYPE_CODE_FLT: ada_val_print_flt (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; case TYPE_CODE_UNION: case TYPE_CODE_STRUCT: ada_val_print_struct_union (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; case TYPE_CODE_ARRAY: ada_val_print_array (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options); return; case TYPE_CODE_REF: ada_val_print_ref (type, valaddr, offset, offset_aligned, address, stream, recurse, original_value, options, language); break; } }
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, const 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_contents_for_printing (v), value_embedded_offset (v), 0, stream, recurse + 1, v, options, language); } else val_print (TYPE_TARGET_TYPE (type), valaddr, 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, valaddr, 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; } }
static int print_field_values (struct type *type, const gdb_byte *valaddr, int offset, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options, int comma_needed, struct type *outer_type, int outer_offset, const struct language_defn *language) { int i, len; len = TYPE_NFIELDS (type); for (i = 0; i < len; i += 1) { if (ada_is_ignored_field (type, i)) continue; if (ada_is_wrapper_field (type, i)) { comma_needed = print_field_values (TYPE_FIELD_TYPE (type, i), valaddr, (offset + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), stream, recurse, val, options, comma_needed, type, offset, language); continue; } else if (ada_is_variant_part (type, i)) { comma_needed = print_variant_part (type, i, valaddr, offset, stream, recurse, val, options, comma_needed, outer_type, outer_offset, language); continue; } if (comma_needed) fprintf_filtered (stream, ", "); comma_needed = 1; if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } annotate_field_begin (TYPE_FIELD_TYPE (type, i)); fprintf_filtered (stream, "%.*s", ada_name_prefix_len (TYPE_FIELD_NAME (type, i)), TYPE_FIELD_NAME (type, i)); annotate_field_name_end (); fputs_filtered (" => ", stream); annotate_field_value (); if (TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (HAVE_CPLUS_STRUCT (type) && TYPE_FIELD_IGNORE (type, i)) { fputs_filtered (_("<optimized out or zero length>"), stream); } else { int bit_pos = TYPE_FIELD_BITPOS (type, i); int bit_size = TYPE_FIELD_BITSIZE (type, i); struct value_print_options opts; adjust_type_signedness (TYPE_FIELD_TYPE (type, i)); v = ada_value_primitive_packed_val (NULL, valaddr, offset + bit_pos / HOST_CHAR_BIT, bit_pos % HOST_CHAR_BIT, bit_size, TYPE_FIELD_TYPE (type, i)); opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), value_contents_for_printing (v), value_embedded_offset (v), 0, stream, recurse + 1, v, &opts, language); } } else { struct value_print_options opts = *options; opts.deref_ref = 0; val_print (TYPE_FIELD_TYPE (type, i), valaddr, (offset + TYPE_FIELD_BITPOS (type, i) / HOST_CHAR_BIT), 0, stream, recurse + 1, val, &opts, language); } annotate_field_end (); } return comma_needed; }
static void val_print_packed_array_elements (struct type *type, const gdb_byte *valaddr, int offset, int bitoffset, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) { unsigned int i; unsigned int things_printed = 0; unsigned len; struct type *elttype, *index_type; unsigned eltlen; unsigned long bitsize = TYPE_FIELD_BITSIZE (type, 0); struct value *mark = value_mark (); LONGEST low = 0; elttype = TYPE_TARGET_TYPE (type); eltlen = TYPE_LENGTH (check_typedef (elttype)); index_type = TYPE_INDEX_TYPE (type); { LONGEST high; if (get_discrete_bounds (index_type, &low, &high) < 0) len = 1; else len = high - low + 1; } i = 0; annotate_array_section_begin (i, elttype); while (i < len && things_printed < options->print_max) { struct value *v0, *v1; int i0; if (i != 0) { if (options->prettyformat_arrays) { fprintf_filtered (stream, ",\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { fprintf_filtered (stream, ", "); } } wrap_here (n_spaces (2 + 2 * recurse)); maybe_print_array_index (index_type, i + low, stream, options); i0 = i; v0 = ada_value_primitive_packed_val (NULL, valaddr + offset, (i0 * bitsize) / HOST_CHAR_BIT, (i0 * bitsize) % HOST_CHAR_BIT, bitsize, elttype); while (1) { i += 1; if (i >= len) break; v1 = ada_value_primitive_packed_val (NULL, valaddr + offset, (i * bitsize) / HOST_CHAR_BIT, (i * bitsize) % HOST_CHAR_BIT, bitsize, elttype); if (!value_contents_eq (v0, value_embedded_offset (v0), v1, value_embedded_offset (v1), eltlen)) break; } if (i - i0 > options->repeat_count_threshold) { struct value_print_options opts = *options; opts.deref_ref = 0; val_print (elttype, value_contents_for_printing (v0), value_embedded_offset (v0), 0, stream, recurse + 1, v0, &opts, current_language); annotate_elt_rep (i - i0); fprintf_filtered (stream, _(" <repeats %u times>"), i - i0); annotate_elt_rep_end (); } else { int j; struct value_print_options opts = *options; opts.deref_ref = 0; for (j = i0; j < i; j += 1) { if (j > i0) { if (options->prettyformat_arrays) { fprintf_filtered (stream, ",\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { fprintf_filtered (stream, ", "); } wrap_here (n_spaces (2 + 2 * recurse)); maybe_print_array_index (index_type, j + low, stream, options); } val_print (elttype, value_contents_for_printing (v0), value_embedded_offset (v0), 0, stream, recurse + 1, v0, &opts, current_language); annotate_elt (); } } things_printed += i - i0; } annotate_array_section_end (); if (i < len) { fprintf_filtered (stream, "..."); } value_free_to_mark (mark); }
void m2_val_print (struct type *type, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); unsigned len; struct type *elttype; CORE_ADDR addr; const gdb_byte *valaddr = value_contents_for_printing (original_value); type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { elttype = check_typedef (TYPE_TARGET_TYPE (type)); len = TYPE_LENGTH (type) / TYPE_LENGTH (elttype); if (options->prettyformat_arrays) print_spaces_filtered (2 + 2 * recurse, stream); /* For an array of chars, print with string syntax. */ if (TYPE_LENGTH (elttype) == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_m2) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (options->format == 0 || options->format == 's')) { /* If requested, look for the first null char and only print elements up to it. */ if (options->stop_print_at_null) { unsigned int temp_len; /* Look for a NULL char. */ for (temp_len = 0; (valaddr + embedded_offset)[temp_len] && temp_len < len && temp_len < options->print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type), valaddr + embedded_offset, len, NULL, 0, options); } else { fprintf_filtered (stream, "{"); val_print_array_elements (type, embedded_offset, address, stream, recurse, original_value, options, 0); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ print_unpacked_pointer (type, address, address, options, stream); break; case TYPE_CODE_PTR: if (TYPE_CONST (type)) print_variable_at_address (type, valaddr + embedded_offset, stream, recurse, options); else if (options->format && options->format != 's') val_print_scalar_formatted (type, embedded_offset, original_value, options, 0, stream); else { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer (type, addr, address, options, stream); } break; case TYPE_CODE_UNION: if (recurse && !options->unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: if (m2_is_long_set (type)) m2_print_long_set (type, valaddr, embedded_offset, address, stream); else if (m2_is_unbounded_array (type)) m2_print_unbounded_array (type, valaddr, embedded_offset, address, stream, recurse, options); else cp_print_value_fields (type, type, embedded_offset, address, stream, recurse, original_value, options, NULL, 0); break; case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); elttype = check_typedef (elttype); if (TYPE_STUB (elttype)) { fprintf_filtered (stream, _("<incomplete type>")); gdb_flush (stream); break; } else { struct type *range = elttype; LONGEST low_bound, high_bound; int i; int need_comma = 0; fputs_filtered ("{", stream); i = get_discrete_bounds (range, &low_bound, &high_bound); maybe_bad_bstring: if (i < 0) { fputs_filtered (_("<error value>"), stream); goto done; } for (i = low_bound; i <= high_bound; i++) { int element = value_bit_index (type, valaddr + embedded_offset, i); if (element < 0) { i = element; goto maybe_bad_bstring; } if (element) { if (need_comma) fputs_filtered (", ", stream); print_type_scalar (range, i, stream); need_comma = 1; if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) { int j = i; fputs_filtered ("..", stream); while (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) j = i; print_type_scalar (range, j, stream); } } } done: fputs_filtered ("}", stream); } break; case TYPE_CODE_RANGE: if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) { m2_val_print (TYPE_TARGET_TYPE (type), embedded_offset, address, stream, recurse, original_value, options); break; } /* FIXME: create_static_range_type does not set the unsigned bit in a range type (I think it probably should copy it from the target type), so we won't print values which are too large to fit in a signed integer correctly. */ /* FIXME: Doesn't handle ranges of enums correctly. (Can't just print with the target type, though, because the size of our type and the target type might differ). */ /* FALLTHROUGH */ case TYPE_CODE_REF: case TYPE_CODE_ENUM: case TYPE_CODE_FUNC: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_METHOD: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_UNDEF: case TYPE_CODE_BOOL: case TYPE_CODE_CHAR: default: generic_val_print (type, embedded_offset, address, stream, recurse, original_value, options, &m2_decorations); break; } gdb_flush (stream); }
extern "C" void monda_val_print (struct type* type, struct frame_info* frame, int embedded_offset, CORE_ADDR address, struct ui_file* stream, int recurse, struct value* val, const struct value_print_options* options, int depth, int max_string_length, int only_print_short_type, int only_print_short_value) { CAMLparam0(); CAMLlocal4(v_type, v_stream, v_value, v_search_path); CAMLlocal2(v_val, v_frame); CAMLlocalN(args, 12); static caml_value* callback = NULL; int is_synthetic_pointer; const gdb_byte* valaddr; /* The try/catch is required so we don't leave local roots incorrectly registered in the case of an exception. We also ensure that any GDB function we call from the OCaml code invoked below (via [caml_callbackN]) never throws any exceptions across the OCaml -> C boundary. If it were to, then we would fail to run the second part of the [caml_start_program] code, causing global variables (e.g. [caml_last_return_address]) to be set incorrectly. */ TRY { if (callback == NULL) { callback = caml_named_value("From_gdb_ocaml.print_value"); assert (callback != NULL); } valaddr = value_contents_for_printing(val); v_value = (valaddr == NULL) ? caml_copy_nativeint(0) : caml_copy_nativeint(*(intnat*) valaddr); /* Determine whether the value is actually a construction made up in the debugger's address space by virtue of interpreting DW_OP_implicit_pointer. The second part of this conditional is really just a sanity check. */ is_synthetic_pointer = (value_lval_const(val) == lval_computed && value_bits_synthetic_pointer(val, 0, sizeof(CORE_ADDR) * 8)); /* fprintf(stderr, "monda_val_print. SP %d *valaddr=%p v_value=%p value_lval_const=%d lval_funcs=%p lazy=%d\n", is_synthetic_pointer, (void*) *(intnat*) valaddr, (void*) v_value, (int) (value_lval_const(val)), value_lval_const(val) == lval_computed ? value_computed_funcs(val) : NULL, value_lazy(val)); */ /* CR mshinwell: improve this test */ #if 0 if ((TYPE_NAME(type) == NULL && !is_synthetic_pointer) || (is_synthetic_pointer && TYPE_CODE(type) != TYPE_CODE_PTR)) { /* fprintf(stderr, "monda_val_print -> c_val_print (1)\n"); fflush(stderr); */ c_val_print(type, frame, valaddr, embedded_offset, address, stream, recurse, val, options, depth); } else #endif { v_type = caml_copy_string(TYPE_NAME(type) == NULL ? "" : TYPE_NAME(type)); v_stream = caml_copy_int64((uint64_t) stream); v_search_path = caml_copy_string(""); /* CR mshinwell: remove */ v_val = caml_copy_nativeint((intnat) val); v_frame = caml_copy_nativeint((intnat) frame); /* N.B. [Store_field] must not be used on [args]! */ args[0] = Val_bool(is_synthetic_pointer); args[1] = v_value; args[2] = v_val; args[3] = v_stream; args[4] = v_type; args[5] = Val_bool(options->summary); args[6] = Val_long(depth); args[7] = Val_long(max_string_length); args[8] = v_search_path; args[9] = Val_bool(only_print_short_type); args[10] = Val_bool(only_print_short_value); args[11] = v_frame; /* fprintf(stderr, "monda_val_print -> OCaml printer. Type '%s'\n", TYPE_NAME(type)); fflush(stderr); */ /* CR mshinwell: This should catch any OCaml exceptions. */ if (caml_callbackN(*callback, 12, args) == Val_false) { /* fprintf(stderr, "monda_val_print -> c_val_print (2)\n"); fflush(stderr); */ c_val_print (type, frame, embedded_offset, address, stream, recurse, val, options); } } } CATCH (exn, RETURN_MASK_ALL) { fprintf(stderr, "monda_val_print: exception: %s\n", exn.message ? exn.message : "<no message>"); CAMLdrop; throw_exception(exn); }