static void java_print_value_fields (struct type *type, char *valaddr, CORE_ADDR address, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty) { int i, len, n_baseclasses; CHECK_TYPEDEF (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); if (n_baseclasses > 0) { int i, n_baseclasses = TYPE_N_BASECLASSES (type); for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = TYPE_NAME (baseclass); char *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) continue; if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) continue; boffset = 0; if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * (recurse + 1), stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); base_valaddr = valaddr; java_print_value_fields (baseclass, base_valaddr, address + boffset, stream, format, recurse + 1, pretty); fputs_filtered (", ", stream); flush_it: ; } } if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { extern int inspect_it; int fields_seen = 0; for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (TYPE_FIELD_STATIC (type, i)) { char *name = TYPE_FIELD_NAME (type, i); if (!static_field_print) continue; if (name != NULL && strcmp (name, "class") == 0) continue; } if (fields_seen) fprintf_filtered (stream, ", "); else if (n_baseclasses > 0) { if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); fputs_filtered ("members of ", stream); fputs_filtered (type_name_no_tag (type), stream); fputs_filtered (": ", stream); } } fields_seen = 1; if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } else { wrap_here (n_spaces (2 + 2 * recurse)); } if (inspect_it) { if (TYPE_CODE (TYPE_FIELD_TYPE (type, i)) == TYPE_CODE_PTR) fputs_filtered ("\"( ptr \"", stream); else fputs_filtered ("\"( nodef \"", stream); if (TYPE_FIELD_STATIC (type, i)) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\" \"", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); fputs_filtered ("\") \"", stream); } else { annotate_field_begin (TYPE_FIELD_TYPE (type, i)); if (TYPE_FIELD_STATIC (type, i)) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (": ", stream); annotate_field_value (); } if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else { v = value_from_longest (TYPE_FIELD_TYPE (type, i), unpack_field_as_long (type, valaddr, i)); val_print (TYPE_FIELD_TYPE (type, i), VALUE_CONTENTS (v), 0, 0, stream, format, 0, recurse + 1, pretty); } } else { if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (TYPE_FIELD_STATIC (type, i)) { struct value *v = value_static_field (type, i); if (v == NULL) fputs_filtered ("<optimized out>", stream); else { struct type *t = check_typedef (VALUE_TYPE (v)); if (TYPE_CODE (t) == TYPE_CODE_STRUCT) v = value_addr (v); val_print (VALUE_TYPE (v), VALUE_CONTENTS (v), 0, VALUE_ADDRESS (v), stream, format, 0, recurse + 1, pretty); } } else if (TYPE_FIELD_TYPE (type, i) == NULL) fputs_filtered ("<unknown type>", stream); else { val_print (TYPE_FIELD_TYPE (type, i), valaddr + TYPE_FIELD_BITPOS (type, i) / 8, 0, address + TYPE_FIELD_BITPOS (type, i) / 8, stream, format, 0, recurse + 1, pretty); } } annotate_field_end (); } if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
static struct block_symbol d_lookup_symbol (const struct language_defn *langdef, const char *name, const struct block *block, const domain_enum domain, int search) { struct block_symbol sym; sym = lookup_symbol_in_static_block (name, block, domain); if (sym.symbol != NULL) return sym; /* If we didn't find a definition for a builtin type in the static block, such as "ucent" which is a specialist type, search for it now. */ if (langdef != NULL && domain == VAR_DOMAIN) { struct gdbarch *gdbarch; if (block == NULL) gdbarch = target_gdbarch (); else gdbarch = block_gdbarch (block); sym.symbol = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name); sym.block = NULL; if (sym.symbol != NULL) return sym; } sym = lookup_global_symbol (name, block, domain); if (sym.symbol != NULL) return sym; if (search) { char *classname, *nested; unsigned int prefix_len; struct cleanup *cleanup; struct block_symbol class_sym; /* A simple lookup failed. Check if the symbol was defined in a base class. */ cleanup = make_cleanup (null_cleanup, NULL); /* Find the name of the class and the name of the method, variable, etc. */ prefix_len = d_entire_prefix_len (name); /* If no prefix was found, search "this". */ if (prefix_len == 0) { struct type *type; struct block_symbol lang_this; lang_this = lookup_language_this (language_def (language_d), block); if (lang_this.symbol == NULL) { do_cleanups (cleanup); return null_block_symbol; } type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (lang_this.symbol))); classname = xstrdup (TYPE_NAME (type)); nested = xstrdup (name); } else { /* The class name is everything up to and including PREFIX_LEN. */ classname = savestring (name, prefix_len); /* The rest of the name is everything else past the initial scope operator. */ nested = xstrdup (name + prefix_len + 1); } /* Add cleanups to free memory for these strings. */ make_cleanup (xfree, classname); make_cleanup (xfree, nested); /* Lookup a class named CLASSNAME. If none is found, there is nothing more that can be done. */ class_sym = lookup_global_symbol (classname, block, domain); if (class_sym.symbol == NULL) { do_cleanups (cleanup); return null_block_symbol; } /* Look for a symbol named NESTED in this class. */ sym = d_lookup_nested_symbol (SYMBOL_TYPE (class_sym.symbol), nested, block); do_cleanups (cleanup); } return sym; }
int pascal_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; int length_pos, length_size, string_pos; int char_size; LONGEST val; CORE_ADDR addr; 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)); eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* For an array of chars, print with string syntax. */ if (eltlen == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_pascal) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (format == 0 || format == 's')) { /* If requested, look for the first null char and only print elements up to it. */ if (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 < print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0); i = len; } else { fprintf_filtered (stream, "{"); /* If this is a virtual function table, print the 0th entry specially, and the rest of the members normally. */ if (pascal_object_is_vtbl_ptr_type (elttype)) { i = 1; fprintf_filtered (stream, "%d vtable entries", len - 1); } else { i = 0; } val_print_array_elements (type, valaddr + embedded_offset, address, stream, format, deref_ref, recurse, pretty, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address; goto print_unpacked_pointer; case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } if (vtblprint && pascal_object_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ /* Extract the address, assume that it is unsigned. */ print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type)), stream, demangle); break; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return (0); } if (addressprint && format != 's') { fputs_filtered (paddress (addr), stream); } /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ if (TYPE_LENGTH (elttype) == 1 && (TYPE_CODE (elttype) == TYPE_CODE_INT || TYPE_CODE(elttype) == TYPE_CODE_CHAR) && (format == 0 || format == 's') && addr != 0) { /* no wide string yet */ i = val_print_string (addr, -1, 1, stream); } /* also for pointers to pascal strings */ /* Note: this is Free Pascal specific: as GDB does not recognize stabs pascal strings Pascal strings are mapped to records with lowercase names PM */ if (is_pascal_string_type (elttype, &length_pos, &length_size, &string_pos, &char_size, NULL) && addr != 0) { ULONGEST string_length; void *buffer; buffer = xmalloc (length_size); read_memory (addr + length_pos, buffer, length_size); string_length = extract_unsigned_integer (buffer, length_size); xfree (buffer); i = val_print_string (addr + string_pos, string_length, char_size, stream); } else if (pascal_object_is_vtbl_member (type)) { /* print vtbl's nicely */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (vt_address); if ((msymbol != NULL) && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && vtblprint) { struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block, VAR_DOMAIN, &is_this_fld, NULL); if (wsym) { wtype = SYMBOL_TYPE (wsym); } else { wtype = TYPE_TARGET_TYPE (type); } vt_val = value_at (wtype, vt_address); common_val_print (vt_val, stream, format, deref_ref, recurse + 1, pretty); if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } } } /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (addressprint) { fprintf_filtered (stream, "@"); /* Extract the address, assume that it is unsigned. */ fputs_filtered (paddress ( extract_unsigned_integer (valaddr + embedded_offset, gdbarch_ptr_bit (current_gdbarch) / HOST_CHAR_BIT)), stream); if (deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr + embedded_offset)); common_val_print (deref_val, stream, format, deref_ref, recurse + 1, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: if (vtblprint && pascal_object_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if NOT using -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ /* Extract the address, assume that it is unsigned. */ print_address_demangle (extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET))), stream, demangle); } else { if (is_pascal_string_type (type, &length_pos, &length_size, &string_pos, &char_size, NULL)) { len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size); LA_PRINT_STRING (stream, valaddr + embedded_offset + string_pos, len, char_size, 0); } else pascal_object_print_value_fields (type, valaddr + embedded_offset, address, stream, format, recurse, pretty, NULL, 0); } break; case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr + embedded_offset); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FLAGS: if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else val_print_type_code_flags (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (address, stream, demangle); break; case TYPE_CODE_BOOL: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { val = unpack_long (type, valaddr + embedded_offset); if (val == 0) fputs_filtered ("false", stream); else if (val == 1) fputs_filtered ("true", stream); else { fputs_filtered ("true (", stream); fprintf_filtered (stream, "%ld)", (long int) val); } } break; case TYPE_CODE_RANGE: /* FIXME: create_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_INT: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val_print_type_code_int (type, valaddr + embedded_offset, stream); } break; case TYPE_CODE_CHAR: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val = unpack_long (type, valaddr + embedded_offset); if (TYPE_UNSIGNED (type)) fprintf_filtered (stream, "%u", (unsigned int) val); else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) val, stream); } break; case TYPE_CODE_FLT: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { print_floating (valaddr + embedded_offset, type, stream); } break; case TYPE_CODE_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); 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 is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; int need_comma = 0; if (is_bitstring) fputs_filtered ("B'", stream); else 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 (is_bitstring) fprintf_filtered (stream, "%d", element); else 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: if (is_bitstring) fputs_filtered ("'", stream); else fputs_filtered ("]", stream); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "<error type>"); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, "<incomplete type>"); break; default: error (_("Invalid pascal type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
int c_value_print (struct value *val, struct ui_file *stream, int format, enum val_prettyprint pretty) { struct type *type, *real_type; int full, top, using_enc; /* 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. */ type = check_typedef (value_type (val)); 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. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_NAME (type) == NULL && TYPE_NAME (TYPE_TARGET_TYPE (type)) != NULL && strcmp (TYPE_NAME (TYPE_TARGET_TYPE (type)), "char") == 0) { /* Print nothing */ } else if (objectprint && (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_CLASS)) { if (TYPE_CODE(type) == TYPE_CODE_REF) { /* Copy value, change to pointer, so we don't get an * error about a non-pointer type in value_rtti_target_type */ struct value *temparg; temparg=value_copy(val); deprecated_set_value_type (temparg, lookup_pointer_type (TYPE_TARGET_TYPE(type))); val=temparg; } /* Pointer to class, check real type of object */ fprintf_filtered (stream, "("); real_type = value_rtti_target_type (val, &full, &top, &using_enc); if (real_type) { /* RTTI entry found */ if (TYPE_CODE (type) == TYPE_CODE_PTR) { /* create a pointer type pointing to the real type */ type = lookup_pointer_type (real_type); } else { /* create a reference type referencing the real type */ type = lookup_reference_type (real_type); } /* JYG: Need to adjust pointer value. */ /* NOTE: cagney/2005-01-02: THIS IS BOGUS. */ value_contents_writeable (val)[0] -= top; /* 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, ") "); } else { /* normal case */ fprintf_filtered (stream, "("); type_print (value_type (val), "", stream, -1); fprintf_filtered (stream, ") "); } } if (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 */ return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); /* 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))); return val_print (value_enclosing_type (val), value_contents_all (val), 0, VALUE_ADDRESS (val), stream, format, 1, 0, pretty); } /* Otherwise, we end up at the return outside this "if" */ } return val_print (type, value_contents_all (val), value_embedded_offset (val), VALUE_ADDRESS (val) + value_offset (val), stream, format, 1, 0, pretty); }
void pascal_printstr (struct ui_file *stream, struct type *type, const gdb_byte *string, unsigned int length, const char *encoding, int force_ellipses, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; int width; /* Preserve TYPE's original type, just set its LENGTH. */ check_typedef (type); width = TYPE_LENGTH (type); /* If the string was not truncated due to `set print elements', and the last byte of it is a null, we don't print that, in traditional C style. */ if ((!force_ellipses) && length > 0 && extract_unsigned_integer (string + (length - 1) * width, width, byte_order) == 0) length--; if (length == 0) { fputs_filtered ("''", stream); return; } for (i = 0; i < length && things_printed < options->print_max; ++i) { /* Position of the character we are examining to see whether it is repeated. */ unsigned int rep1; /* Number of repetitions we have detected so far. */ unsigned int reps; unsigned long int current_char; QUIT; if (need_comma) { fputs_filtered (", ", stream); need_comma = 0; } current_char = extract_unsigned_integer (string + i * width, width, byte_order); rep1 = i + 1; reps = 1; while (rep1 < length && extract_unsigned_integer (string + rep1 * width, width, byte_order) == current_char) { ++rep1; ++reps; } if (reps > options->repeat_count_threshold) { if (in_quotes) { fputs_filtered ("', ", stream); in_quotes = 0; } pascal_printchar (current_char, type, stream); fprintf_filtered (stream, " <repeats %u times>", reps); i = rep1 - 1; things_printed += options->repeat_count_threshold; need_comma = 1; } else { if ((!in_quotes) && (PRINT_LITERAL_FORM (current_char))) { fputs_filtered ("'", stream); in_quotes = 1; } pascal_one_char (current_char, stream, &in_quotes); ++things_printed; } } /* Terminate the quotes if necessary. */ if (in_quotes) fputs_filtered ("'", stream); if (force_ellipses || i < length) fputs_filtered ("...", stream); }
void c_get_string (struct value *value, gdb_byte **buffer, int *length, struct type **char_type, const char **charset) { int err, width; unsigned int fetchlimit; struct type *type = check_typedef (value_type (value)); struct type *element_type = TYPE_TARGET_TYPE (type); int req_length = *length; enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); if (element_type == NULL) goto error; if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { /* If we know the size of the array, we can use it as a limit on the number of characters to be fetched. */ if (TYPE_NFIELDS (type) == 1 && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE) { LONGEST low_bound, high_bound; get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low_bound, &high_bound); fetchlimit = high_bound - low_bound + 1; } else fetchlimit = UINT_MAX; } else if (TYPE_CODE (type) == TYPE_CODE_PTR) fetchlimit = UINT_MAX; else /* We work only with arrays and pointers. */ goto error; if (! c_textual_element_type (element_type, 0)) goto error; classify_type (element_type, get_type_arch (element_type), charset); width = TYPE_LENGTH (element_type); /* If the string lives in GDB's memory instead of the inferior's, then we just need to copy it to BUFFER. Also, since such strings are arrays with known size, FETCHLIMIT will hold the size of the array. */ if ((VALUE_LVAL (value) == not_lval || VALUE_LVAL (value) == lval_internalvar) && fetchlimit != UINT_MAX) { int i; const gdb_byte *contents = value_contents (value); /* If a length is specified, use that. */ if (*length >= 0) i = *length; else /* Otherwise, look for a null character. */ for (i = 0; i < fetchlimit; i++) if (extract_unsigned_integer (contents + i * width, width, byte_order) == 0) break; /* I is now either a user-defined length, the number of non-null characters, or FETCHLIMIT. */ *length = i * width; *buffer = xmalloc (*length); memcpy (*buffer, contents, *length); err = 0; } else { CORE_ADDR addr = value_as_address (value); /* Prior to the fix for PR 16196 read_string would ignore fetchlimit if length > 0. The old "broken" behaviour is the behaviour we want: The caller may want to fetch 100 bytes from a variable length array implemented using the common idiom of having an array of length 1 at the end of a struct. In this case we want to ignore the declared size of the array. However, it's counterintuitive to implement that behaviour in read_string: what does fetchlimit otherwise mean if length > 0. Therefore we implement the behaviour we want here: If *length > 0, don't specify a fetchlimit. This preserves the previous behaviour. We could move this check above where we know whether the array is declared with a fixed size, but we only want to apply this behaviour when calling read_string. PR 16286. */ if (*length > 0) fetchlimit = UINT_MAX; err = read_string (addr, *length, width, fetchlimit, byte_order, buffer, length); if (err) { xfree (*buffer); memory_error (err, addr); } } /* If the LENGTH is specified at -1, we want to return the string length up to the terminating null character. If an actual length was specified, we want to return the length of exactly what was read. */ if (req_length == -1) /* If the last character is null, subtract it from LENGTH. */ if (*length > 0 && extract_unsigned_integer (*buffer + *length - width, width, byte_order) == 0) *length -= width; /* The read_string function will return the number of bytes read. If length returned from read_string was > 0, return the number of characters read by dividing the number of bytes by width. */ if (*length != 0) *length = *length / width; *char_type = element_type; return; error: { char *type_str; type_str = type_to_string (type); if (type_str) { make_cleanup (xfree, type_str); error (_("Trying to read string with inappropriate type `%s'."), type_str); } else error (_("Trying to read string with inappropriate type.")); } }
static enum c_string_type classify_type (struct type *elttype, struct gdbarch *gdbarch, const char **encoding) { enum c_string_type result; /* We loop because ELTTYPE may be a typedef, and we want to successively peel each typedef until we reach a type we understand. We don't use CHECK_TYPEDEF because that will strip all typedefs at once -- but in C, wchar_t is itself a typedef, so that would do the wrong thing. */ while (elttype) { const char *name = TYPE_NAME (elttype); if (TYPE_CODE (elttype) == TYPE_CODE_CHAR || !name) { result = C_CHAR; goto done; } if (!strcmp (name, "wchar_t")) { result = C_WIDE_CHAR; goto done; } if (!strcmp (name, "char16_t")) { result = C_CHAR_16; goto done; } if (!strcmp (name, "char32_t")) { result = C_CHAR_32; goto done; } if (TYPE_CODE (elttype) != TYPE_CODE_TYPEDEF) break; /* Call for side effects. */ check_typedef (elttype); if (TYPE_TARGET_TYPE (elttype)) elttype = TYPE_TARGET_TYPE (elttype); else { /* Perhaps check_typedef did not update the target type. In this case, force the lookup again and hope it works out. It never will for C, but it might for C++. */ CHECK_TYPEDEF (elttype); } } /* Punt. */ result = C_CHAR; done: if (encoding) *encoding = charset_for_string_type (result, gdbarch); return result; }
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; 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; }
static void list_arg_or_local (const struct frame_arg *arg, enum what_to_list what, enum print_values values, int skip_unavailable) { struct cleanup *old_chain; struct ui_out *uiout = current_uiout; struct ui_file *stb; gdb_assert (!arg->val || !arg->error); gdb_assert ((values == PRINT_NO_VALUES && arg->val == NULL && arg->error == NULL) || values == PRINT_SIMPLE_VALUES || (values == PRINT_ALL_VALUES && (arg->val != NULL || arg->error != NULL))); gdb_assert (arg->entry_kind == print_entry_values_no || (arg->entry_kind == print_entry_values_only && (arg->val || arg->error))); if (skip_unavailable && arg->val != NULL && (value_entirely_unavailable (arg->val) /* A scalar object that does not have all bits available is also considered unavailable, because all bits contribute to its representation. */ || (val_print_scalar_type_p (value_type (arg->val)) && !value_bytes_available (arg->val, value_embedded_offset (arg->val), TYPE_LENGTH (value_type (arg->val)))))) return; stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); if (values != PRINT_NO_VALUES || what == all) make_cleanup_ui_out_tuple_begin_end (uiout, NULL); fputs_filtered (SYMBOL_PRINT_NAME (arg->sym), stb); if (arg->entry_kind == print_entry_values_only) fputs_filtered ("@entry", stb); uiout->field_stream ("name", stb); if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) uiout->field_int ("arg", 1); if (values == PRINT_SIMPLE_VALUES) { check_typedef (arg->sym->type); type_print (arg->sym->type, "", stb, -1); uiout->field_stream ("type", stb); } if (arg->val || arg->error) { const char *error_message = NULL; if (arg->error) error_message = arg->error; else { TRY { struct value_print_options opts; get_no_prettyformat_print_options (&opts); opts.deref_ref = 1; common_val_print (arg->val, stb, 0, &opts, language_def (SYMBOL_LANGUAGE (arg->sym))); } CATCH (except, RETURN_MASK_ERROR) { error_message = except.message; } END_CATCH } if (error_message != NULL) fprintf_filtered (stb, _("<error reading variable: %s>"), error_message); uiout->field_stream ("value", stb); } do_cleanups (old_chain); }
static struct type * get_out_value_type (struct symbol *func_sym, struct objfile *objfile, enum compile_i_scope_types scope) { struct symbol *gdb_ptr_type_sym; /* Initialize it just to avoid a GCC false warning. */ struct symbol *gdb_val_sym = NULL; struct type *gdb_ptr_type, *gdb_type_from_ptr, *gdb_type, *retval; /* Initialize it just to avoid a GCC false warning. */ const struct block *block = NULL; const struct blockvector *bv; int nblocks = 0; int block_loop = 0; bv = SYMTAB_BLOCKVECTOR (func_sym->owner.symtab); nblocks = BLOCKVECTOR_NBLOCKS (bv); gdb_ptr_type_sym = NULL; for (block_loop = 0; block_loop < nblocks; block_loop++) { struct symbol *function = NULL; const struct block *function_block; block = BLOCKVECTOR_BLOCK (bv, block_loop); if (BLOCK_FUNCTION (block) != NULL) continue; gdb_val_sym = block_lookup_symbol (block, COMPILE_I_EXPR_VAL, VAR_DOMAIN); if (gdb_val_sym == NULL) continue; function_block = block; while (function_block != BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) && function_block != BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK)) { function_block = BLOCK_SUPERBLOCK (function_block); function = BLOCK_FUNCTION (function_block); if (function != NULL) break; } if (function != NULL && (BLOCK_SUPERBLOCK (function_block) == BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK)) && (strcmp (SYMBOL_LINKAGE_NAME (function), GCC_FE_WRAPPER_FUNCTION) == 0)) break; } if (block_loop == nblocks) error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE); gdb_type = SYMBOL_TYPE (gdb_val_sym); gdb_type = check_typedef (gdb_type); gdb_ptr_type_sym = block_lookup_symbol (block, COMPILE_I_EXPR_PTR_TYPE, VAR_DOMAIN); if (gdb_ptr_type_sym == NULL) error (_("No \"%s\" symbol found"), COMPILE_I_EXPR_PTR_TYPE); gdb_ptr_type = SYMBOL_TYPE (gdb_ptr_type_sym); gdb_ptr_type = check_typedef (gdb_ptr_type); if (TYPE_CODE (gdb_ptr_type) != TYPE_CODE_PTR) error (_("Type of \"%s\" is not a pointer"), COMPILE_I_EXPR_PTR_TYPE); gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_ptr_type); if (types_deeply_equal (gdb_type, gdb_type_from_ptr)) { if (scope != COMPILE_I_PRINT_ADDRESS_SCOPE) error (_("Expected address scope in compiled module \"%s\"."), objfile_name (objfile)); return gdb_type; } if (TYPE_CODE (gdb_type) != TYPE_CODE_PTR) error (_("Invalid type code %d of symbol \"%s\" " "in compiled module \"%s\"."), TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_VAL, objfile_name (objfile)); retval = gdb_type_from_ptr; switch (TYPE_CODE (gdb_type_from_ptr)) { case TYPE_CODE_ARRAY: gdb_type_from_ptr = TYPE_TARGET_TYPE (gdb_type_from_ptr); break; case TYPE_CODE_FUNC: break; default: error (_("Invalid type code %d of symbol \"%s\" " "in compiled module \"%s\"."), TYPE_CODE (gdb_type_from_ptr), COMPILE_I_EXPR_PTR_TYPE, objfile_name (objfile)); } if (!types_deeply_equal (gdb_type_from_ptr, TYPE_TARGET_TYPE (gdb_type))) error (_("Referenced types do not match for symbols \"%s\" and \"%s\" " "in compiled module \"%s\"."), COMPILE_I_EXPR_PTR_TYPE, COMPILE_I_EXPR_VAL, objfile_name (objfile)); if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE) return NULL; return retval; }
struct compile_module * compile_object_load (const char *object_file, const char *source_file, enum compile_i_scope_types scope, void *scope_data) { struct cleanup *cleanups, *cleanups_free_objfile; bfd *abfd; struct setup_sections_data setup_sections_data; CORE_ADDR addr, regs_addr, out_value_addr = 0; struct symbol *func_sym; struct type *func_type; struct bound_minimal_symbol bmsym; long storage_needed; asymbol **symbol_table, **symp; long number_of_symbols, missing_symbols; struct type *dptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; unsigned dptr_type_len = TYPE_LENGTH (dptr_type); struct compile_module *retval; struct type *regs_type, *out_value_type = NULL; char *filename, **matching; struct objfile *objfile; int expect_parameters; struct type *expect_return_type; struct munmap_list *munmap_list_head = NULL; filename = tilde_expand (object_file); cleanups = make_cleanup (xfree, filename); abfd = gdb_bfd_open (filename, gnutarget, -1); if (abfd == NULL) error (_("\"%s\": could not open as compiled module: %s"), filename, bfd_errmsg (bfd_get_error ())); make_cleanup_bfd_unref (abfd); if (!bfd_check_format_matches (abfd, bfd_object, &matching)) error (_("\"%s\": not in loadable format: %s"), filename, gdb_bfd_errmsg (bfd_get_error (), matching)); if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) != 0) error (_("\"%s\": not in object format."), filename); setup_sections_data.last_size = 0; setup_sections_data.last_section_first = abfd->sections; setup_sections_data.last_prot = -1; setup_sections_data.last_max_alignment = 1; setup_sections_data.munmap_list_headp = &munmap_list_head; make_cleanup (munmap_listp_free_cleanup, &munmap_list_head); bfd_map_over_sections (abfd, setup_sections, &setup_sections_data); setup_sections (abfd, NULL, &setup_sections_data); storage_needed = bfd_get_symtab_upper_bound (abfd); if (storage_needed < 0) error (_("Cannot read symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); /* SYMFILE_VERBOSE is not passed even if FROM_TTY, user is not interested in "Reading symbols from ..." message for automatically generated file. */ objfile = symbol_file_add_from_bfd (abfd, filename, 0, NULL, 0, NULL); cleanups_free_objfile = make_cleanup_free_objfile (objfile); func_sym = lookup_global_symbol_from_objfile (objfile, GCC_FE_WRAPPER_FUNCTION, VAR_DOMAIN).symbol; if (func_sym == NULL) error (_("Cannot find function \"%s\" in compiled module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); func_type = SYMBOL_TYPE (func_sym); if (TYPE_CODE (func_type) != TYPE_CODE_FUNC) error (_("Invalid type code %d of function \"%s\" in compiled " "module \"%s\"."), TYPE_CODE (func_type), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); switch (scope) { case COMPILE_I_SIMPLE_SCOPE: expect_parameters = 1; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; case COMPILE_I_RAW_SCOPE: expect_parameters = 0; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; case COMPILE_I_PRINT_ADDRESS_SCOPE: case COMPILE_I_PRINT_VALUE_SCOPE: expect_parameters = 2; expect_return_type = builtin_type (target_gdbarch ())->builtin_void; break; default: internal_error (__FILE__, __LINE__, _("invalid scope %d"), scope); } if (TYPE_NFIELDS (func_type) != expect_parameters) error (_("Invalid %d parameters of function \"%s\" in compiled " "module \"%s\"."), TYPE_NFIELDS (func_type), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); if (!types_deeply_equal (expect_return_type, TYPE_TARGET_TYPE (func_type))) error (_("Invalid return type of function \"%s\" in compiled " "module \"%s\"."), GCC_FE_WRAPPER_FUNCTION, objfile_name (objfile)); /* The memory may be later needed by bfd_generic_get_relocated_section_contents called from default_symfile_relocate. */ symbol_table = obstack_alloc (&objfile->objfile_obstack, storage_needed); number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table); if (number_of_symbols < 0) error (_("Cannot parse symbols of compiled module \"%s\": %s"), filename, bfd_errmsg (bfd_get_error ())); missing_symbols = 0; for (symp = symbol_table; symp < symbol_table + number_of_symbols; symp++) { asymbol *sym = *symp; if (sym->flags != 0) continue; sym->flags = BSF_GLOBAL; sym->section = bfd_abs_section_ptr; if (strcmp (sym->name, "_GLOBAL_OFFSET_TABLE_") == 0) { if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF symbol \"%s\" relocated to zero\n", sym->name); /* It seems to be a GCC bug, with -mcmodel=large there should be no need for _GLOBAL_OFFSET_TABLE_. Together with -fPIE the data remain PC-relative even with _GLOBAL_OFFSET_TABLE_ as zero. */ sym->value = 0; continue; } bmsym = lookup_minimal_symbol (sym->name, NULL, NULL); switch (bmsym.minsym == NULL ? mst_unknown : MSYMBOL_TYPE (bmsym.minsym)) { case mst_text: sym->value = BMSYMBOL_VALUE_ADDRESS (bmsym); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF mst_text symbol \"%s\" relocated to %s\n", sym->name, paddress (target_gdbarch (), sym->value)); break; case mst_text_gnu_ifunc: sym->value = gnu_ifunc_resolve_addr (target_gdbarch (), BMSYMBOL_VALUE_ADDRESS (bmsym)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "ELF mst_text_gnu_ifunc symbol \"%s\" " "relocated to %s\n", sym->name, paddress (target_gdbarch (), sym->value)); break; default: warning (_("Could not find symbol \"%s\" " "for compiled module \"%s\"."), sym->name, filename); missing_symbols++; } } if (missing_symbols) error (_("%ld symbols were missing, cannot continue."), missing_symbols); bfd_map_over_sections (abfd, copy_sections, symbol_table); regs_type = get_regs_type (func_sym, objfile); if (regs_type == NULL) regs_addr = 0; else { /* Use read-only non-executable memory protection. */ regs_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (regs_type), GDB_MMAP_PROT_READ); gdb_assert (regs_addr != 0); munmap_list_add (&munmap_list_head, regs_addr, TYPE_LENGTH (regs_type)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "allocated %s bytes at %s for registers\n", paddress (target_gdbarch (), TYPE_LENGTH (regs_type)), paddress (target_gdbarch (), regs_addr)); store_regs (regs_type, regs_addr); } if (scope == COMPILE_I_PRINT_ADDRESS_SCOPE || scope == COMPILE_I_PRINT_VALUE_SCOPE) { out_value_type = get_out_value_type (func_sym, objfile, scope); if (out_value_type == NULL) { do_cleanups (cleanups); return NULL; } check_typedef (out_value_type); out_value_addr = gdbarch_infcall_mmap (target_gdbarch (), TYPE_LENGTH (out_value_type), (GDB_MMAP_PROT_READ | GDB_MMAP_PROT_WRITE)); gdb_assert (out_value_addr != 0); munmap_list_add (&munmap_list_head, out_value_addr, TYPE_LENGTH (out_value_type)); if (compile_debug) fprintf_unfiltered (gdb_stdlog, "allocated %s bytes at %s for printed value\n", paddress (target_gdbarch (), TYPE_LENGTH (out_value_type)), paddress (target_gdbarch (), out_value_addr)); } discard_cleanups (cleanups_free_objfile); retval = xmalloc (sizeof (*retval)); retval->objfile = objfile; retval->source_file = xstrdup (source_file); retval->func_sym = func_sym; retval->regs_addr = regs_addr; retval->scope = scope; retval->scope_data = scope_data; retval->out_value_type = out_value_type; retval->out_value_addr = out_value_addr; /* CLEANUPS will free MUNMAP_LIST_HEAD. */ retval->munmap_list_head = munmap_list_head; munmap_list_head = NULL; do_cleanups (cleanups); return retval; }
void c_get_string (struct value *value, gdb_byte **buffer, int *length, struct type **char_type, const char **charset) { int err, width; unsigned int fetchlimit; struct type *type = check_typedef (value_type (value)); struct type *element_type = TYPE_TARGET_TYPE (type); int req_length = *length; enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); enum c_string_type kind; if (element_type == NULL) goto error; if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { /* If we know the size of the array, we can use it as a limit on the number of characters to be fetched. */ if (TYPE_NFIELDS (type) == 1 && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE) { LONGEST low_bound, high_bound; get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low_bound, &high_bound); fetchlimit = high_bound - low_bound + 1; } else fetchlimit = UINT_MAX; } else if (TYPE_CODE (type) == TYPE_CODE_PTR) fetchlimit = UINT_MAX; else /* We work only with arrays and pointers. */ goto error; if (! c_textual_element_type (element_type, 0)) goto error; kind = classify_type (element_type, get_type_arch (element_type), charset); width = TYPE_LENGTH (element_type); /* If the string lives in GDB's memory instead of the inferior's, then we just need to copy it to BUFFER. Also, since such strings are arrays with known size, FETCHLIMIT will hold the size of the array. */ if ((VALUE_LVAL (value) == not_lval || VALUE_LVAL (value) == lval_internalvar) && fetchlimit != UINT_MAX) { int i; const gdb_byte *contents = value_contents (value); /* If a length is specified, use that. */ if (*length >= 0) i = *length; else /* Otherwise, look for a null character. */ for (i = 0; i < fetchlimit; i++) if (extract_unsigned_integer (contents + i * width, width, byte_order) == 0) break; /* I is now either a user-defined length, the number of non-null characters, or FETCHLIMIT. */ *length = i * width; *buffer = xmalloc (*length); memcpy (*buffer, contents, *length); err = 0; } else { CORE_ADDR addr = value_as_address (value); err = read_string (addr, *length, width, fetchlimit, byte_order, buffer, length); if (err) { xfree (*buffer); if (err == EIO) throw_error (MEMORY_ERROR, "Address %s out of bounds", paddress (get_type_arch (type), addr)); else error (_("Error reading string from inferior: %s"), safe_strerror (err)); } } /* If the LENGTH is specified at -1, we want to return the string length up to the terminating null character. If an actual length was specified, we want to return the length of exactly what was read. */ if (req_length == -1) /* If the last character is null, subtract it from LENGTH. */ if (*length > 0 && extract_unsigned_integer (*buffer + *length - width, width, byte_order) == 0) *length -= width; /* The read_string function will return the number of bytes read. If length returned from read_string was > 0, return the number of characters read by dividing the number of bytes by width. */ if (*length != 0) *length = *length / width; *char_type = element_type; return; error: { char *type_str; type_str = type_to_string (type); if (type_str) { make_cleanup (xfree, type_str); error (_("Trying to read string with inappropriate type `%s'."), type_str); } else error (_("Trying to read string with inappropriate type.")); } }
static void java_type_print_base (struct type *type, struct ui_file *stream, int show, int level, const struct type_print_options *flags) { int i; int len; char *mangled_name; char *demangled_name; QUIT; wrap_here (" "); if (type == NULL) { fputs_filtered ("<type unknown>", stream); return; } /* When SHOW is zero or less, and there is a valid type name, then always just print the type name directly from the type. */ if (show <= 0 && TYPE_NAME (type) != NULL) { fputs_filtered (TYPE_NAME (type), stream); return; } type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: java_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level, flags); break; case TYPE_CODE_STRUCT: if (TYPE_TAG_NAME (type) != NULL && TYPE_TAG_NAME (type)[0] == '[') { /* array type */ char *name = java_demangle_type_signature (TYPE_TAG_NAME (type)); fputs_filtered (name, stream); xfree (name); break; } if (show >= 0) fprintf_filtered (stream, "class "); if (TYPE_TAG_NAME (type) != NULL) { fputs_filtered (TYPE_TAG_NAME (type), stream); if (show > 0) fputs_filtered (" ", stream); } wrap_here (" "); if (show < 0) { /* If we just printed a tag name, no need to print anything else. */ if (TYPE_TAG_NAME (type) == NULL) fprintf_filtered (stream, "{...}"); } else if (show > 0 || TYPE_TAG_NAME (type) == NULL) { java_type_print_derivation_info (stream, type); fprintf_filtered (stream, "{\n"); if ((TYPE_NFIELDS (type) == 0) && (TYPE_NFN_FIELDS (type) == 0)) { if (TYPE_STUB (type)) fprintfi_filtered (level + 4, stream, "<incomplete type>\n"); else fprintfi_filtered (level + 4, stream, "<no data fields>\n"); } /* If there is a base class for this type, do not print the field that it occupies. */ len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) { QUIT; /* Don't print out virtual function table. */ if (startswith (TYPE_FIELD_NAME (type, i), "_vptr") && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* Don't print the dummy field "class". */ if (startswith (TYPE_FIELD_NAME (type, i), "class")) continue; print_spaces_filtered (level + 4, stream); if (HAVE_CPLUS_STRUCT (type)) { if (TYPE_FIELD_PROTECTED (type, i)) fprintf_filtered (stream, "protected "); else if (TYPE_FIELD_PRIVATE (type, i)) fprintf_filtered (stream, "private "); else fprintf_filtered (stream, "public "); } if (field_is_static (&TYPE_FIELD (type, i))) fprintf_filtered (stream, "static "); java_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4, flags); fprintf_filtered (stream, ";\n"); } /* If there are both fields and methods, put a space between. */ len = TYPE_NFN_FIELDS (type); if (len) fprintf_filtered (stream, "\n"); /* Print out the methods. */ for (i = 0; i < len; i++) { struct fn_field *f; int j; const char *method_name; const char *name; int is_constructor; int n_overloads; f = TYPE_FN_FIELDLIST1 (type, i); n_overloads = TYPE_FN_FIELDLIST_LENGTH (type, i); method_name = TYPE_FN_FIELDLIST_NAME (type, i); name = type_name_no_tag (type); is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < n_overloads; j++) { const char *real_physname; char *physname, *p; int is_full_physname_constructor; real_physname = TYPE_FN_FIELD_PHYSNAME (f, j); /* The physname will contain the return type after the final closing parenthesis. Strip it off. */ p = strrchr (real_physname, ')'); gdb_assert (p != NULL); ++p; /* Keep the trailing ')'. */ physname = (char *) alloca (p - real_physname + 1); memcpy (physname, real_physname, p - real_physname); physname[p - real_physname] = '\0'; is_full_physname_constructor = (TYPE_FN_FIELD_CONSTRUCTOR (f, j) || is_constructor_name (physname) || is_destructor_name (physname)); QUIT; print_spaces_filtered (level + 4, stream); if (TYPE_FN_FIELD_PROTECTED (f, j)) fprintf_filtered (stream, "protected "); else if (TYPE_FN_FIELD_PRIVATE (f, j)) fprintf_filtered (stream, "private "); else if (TYPE_FN_FIELD_PUBLIC (f, j)) fprintf_filtered (stream, "public "); if (TYPE_FN_FIELD_ABSTRACT (f, j)) fprintf_filtered (stream, "abstract "); if (TYPE_FN_FIELD_STATIC (f, j)) fprintf_filtered (stream, "static "); if (TYPE_FN_FIELD_FINAL (f, j)) fprintf_filtered (stream, "final "); if (TYPE_FN_FIELD_SYNCHRONIZED (f, j)) fprintf_filtered (stream, "synchronized "); if (TYPE_FN_FIELD_NATIVE (f, j)) fprintf_filtered (stream, "native "); if (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)) == 0) { /* Keep GDB from crashing here. */ fprintf_filtered (stream, "<undefined type> %s;\n", TYPE_FN_FIELD_PHYSNAME (f, j)); break; } else if (!is_constructor && !is_full_physname_constructor) { type_print (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j)), "", stream, -1); fputs_filtered (" ", stream); } if (TYPE_FN_FIELD_STUB (f, j)) /* Build something we can demangle. */ mangled_name = gdb_mangle_name (type, i, j); else mangled_name = physname; demangled_name = gdb_demangle (mangled_name, DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA); if (demangled_name == NULL) demangled_name = xstrdup (mangled_name); { char *demangled_no_class; char *ptr; ptr = demangled_no_class = demangled_name; while (1) { char c; c = *ptr++; if (c == 0 || c == '(') break; if (c == '.') demangled_no_class = ptr; } fputs_filtered (demangled_no_class, stream); xfree (demangled_name); } if (TYPE_FN_FIELD_STUB (f, j)) xfree (mangled_name); fprintf_filtered (stream, ";\n"); } } fprintfi_filtered (level, stream, "}"); } break; default: c_type_print_base (type, stream, show, level, flags); } }
int java_val_print (struct type *type, char *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { register unsigned int i = 0; /* Number of characters printed */ struct type *target_type; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr, type, format, 0, stream); break; } #if 0 if (vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ print_address_demangle (extract_address (valaddr, TYPE_LENGTH (type)), stream, demangle); break; } #endif addr = unpack_pointer (type, valaddr); if (addr == 0) { fputs_filtered ("null", stream); return i; } target_type = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (target_type) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return (0); } if (addressprint && format != 's') { fputs_filtered ("@", stream); print_longest (stream, 'x', 0, (ULONGEST) addr); } return i; case TYPE_CODE_CHAR: case TYPE_CODE_INT: /* Can't just call c_val_print because that prints bytes as C chars. */ format = format ? format : output_format; if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else if (TYPE_CODE (type) == TYPE_CODE_CHAR || (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 2 && strcmp (TYPE_NAME (type), "char") == 0)) LA_PRINT_CHAR ((int) unpack_long (type, valaddr), stream); else val_print_type_code_int (type, valaddr, stream); break; case TYPE_CODE_STRUCT: java_print_value_fields (type, valaddr, address, stream, format, recurse, pretty); break; default: return c_val_print (type, valaddr, embedded_offset, address, stream, format, deref_ref, recurse, pretty); } return 0; }
static void java_print_value_fields (struct type *type, const gdb_byte *valaddr, int offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *val, const struct value_print_options *options) { int i, len, n_baseclasses; CHECK_TYPEDEF (type); fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); n_baseclasses = TYPE_N_BASECLASSES (type); if (n_baseclasses > 0) { int i, n_baseclasses = TYPE_N_BASECLASSES (type); for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); const char *basename = TYPE_NAME (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) continue; if (basename != NULL && strcmp (basename, "java.lang.Object") == 0) continue; boffset = 0; if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * (recurse + 1), stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); base_valaddr = valaddr; java_print_value_fields (baseclass, base_valaddr, offset + boffset, address, stream, recurse + 1, val, options); fputs_filtered (", ", stream); } } if (!len && n_baseclasses == 1) fprintf_filtered (stream, "<No data fields>"); else { int fields_seen = 0; for (i = n_baseclasses; i < len; i++) { /* If requested, skip printing of static fields. */ if (field_is_static (&TYPE_FIELD (type, i))) { const char *name = TYPE_FIELD_NAME (type, i); if (!options->static_field_print) continue; if (name != NULL && strcmp (name, "class") == 0) continue; } if (fields_seen) fprintf_filtered (stream, ", "); else if (n_baseclasses > 0) { if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); fputs_filtered ("members of ", stream); fputs_filtered (type_name_no_tag (type), stream); fputs_filtered (": ", stream); } } fields_seen = 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)); if (field_is_static (&TYPE_FIELD (type, i))) fputs_filtered ("static ", stream); fprintf_symbol_filtered (stream, TYPE_FIELD_NAME (type, i), language_cplus, DMGL_PARAMS | DMGL_ANSI); annotate_field_name_end (); fputs_filtered (": ", stream); annotate_field_value (); if (!field_is_static (&TYPE_FIELD (type, i)) && TYPE_FIELD_PACKED (type, i)) { struct value *v; /* Bitfields require special handling, especially due to byte order problems. */ if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (value_bits_synthetic_pointer (val, TYPE_FIELD_BITPOS (type, i), TYPE_FIELD_BITSIZE (type, i))) { fputs_filtered (_("<synthetic pointer>"), stream); } else if (!value_bits_valid (val, TYPE_FIELD_BITPOS (type, i), TYPE_FIELD_BITSIZE (type, i))) { val_print_optimized_out (val, stream); } else { struct value_print_options opts; v = value_field_bitfield (type, i, valaddr, offset, val); opts = *options; opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } } else { if (TYPE_FIELD_IGNORE (type, i)) { fputs_filtered ("<optimized out or zero length>", stream); } else if (field_is_static (&TYPE_FIELD (type, i))) { struct value *v = value_static_field (type, i); if (v == NULL) val_print_optimized_out (NULL, stream); else { struct value_print_options opts; struct type *t = check_typedef (value_type (v)); if (TYPE_CODE (t) == TYPE_CODE_STRUCT) v = value_addr (v); opts = *options; opts.deref_ref = 0; common_val_print (v, stream, recurse + 1, &opts, current_language); } } else if (TYPE_FIELD_TYPE (type, i) == NULL) fputs_filtered ("<unknown type>", stream); 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) / 8, address, stream, recurse + 1, val, &opts, current_language); } } annotate_field_end (); } if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } } fprintf_filtered (stream, "}"); }
static void list_args_or_locals (enum what_to_list what, enum print_values values, struct frame_info *fi, int skip_unavailable) { const struct block *block; struct symbol *sym; struct block_iterator iter; struct cleanup *cleanup_list; struct type *type; char *name_of_result; struct ui_out *uiout = current_uiout; block = get_frame_block (fi, 0); switch (what) { case locals: name_of_result = "locals"; break; case arguments: name_of_result = "args"; break; case all: name_of_result = "variables"; break; default: internal_error (__FILE__, __LINE__, "unexpected what_to_list: %d", (int) what); } cleanup_list = make_cleanup_ui_out_list_begin_end (uiout, name_of_result); while (block != 0) { ALL_BLOCK_SYMBOLS (block, iter, sym) { int print_me = 0; switch (SYMBOL_CLASS (sym)) { default: case LOC_UNDEF: /* catches errors */ case LOC_CONST: /* constant */ case LOC_TYPEDEF: /* local typedef */ case LOC_LABEL: /* local label */ case LOC_BLOCK: /* local function */ case LOC_CONST_BYTES: /* loc. byte seq. */ case LOC_UNRESOLVED: /* unresolved static */ case LOC_OPTIMIZED_OUT: /* optimized out */ print_me = 0; break; case LOC_ARG: /* argument */ case LOC_REF_ARG: /* reference arg */ case LOC_REGPARM_ADDR: /* indirect register arg */ case LOC_LOCAL: /* stack local */ case LOC_STATIC: /* static */ case LOC_REGISTER: /* register */ case LOC_COMPUTED: /* computed location */ if (what == all) print_me = 1; else if (what == locals) print_me = !SYMBOL_IS_ARGUMENT (sym); else print_me = SYMBOL_IS_ARGUMENT (sym); break; } if (print_me) { struct symbol *sym2; struct frame_arg arg, entryarg; if (SYMBOL_IS_ARGUMENT (sym)) sym2 = lookup_symbol (SYMBOL_LINKAGE_NAME (sym), block, VAR_DOMAIN, NULL).symbol; else sym2 = sym; gdb_assert (sym2 != NULL); memset (&arg, 0, sizeof (arg)); arg.sym = sym2; arg.entry_kind = print_entry_values_no; memset (&entryarg, 0, sizeof (entryarg)); entryarg.sym = sym2; entryarg.entry_kind = print_entry_values_no; switch (values) { case PRINT_SIMPLE_VALUES: type = check_typedef (sym2->type); if (TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_UNION) { case PRINT_ALL_VALUES: if (SYMBOL_IS_ARGUMENT (sym)) read_frame_arg (sym2, fi, &arg, &entryarg); else read_frame_local (sym2, fi, &arg); } break; } if (arg.entry_kind != print_entry_values_only) list_arg_or_local (&arg, what, values, skip_unavailable); if (entryarg.entry_kind != print_entry_values_no) list_arg_or_local (&entryarg, what, values, skip_unavailable); xfree (arg.error); xfree (entryarg.error); } } if (BLOCK_FUNCTION (block)) break; else block = BLOCK_SUPERBLOCK (block); }
void java_val_print (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) { struct gdbarch *gdbarch = get_type_arch (type); struct type *target_type; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: if (options->format && options->format != 's') { val_print_scalar_formatted (type, valaddr, embedded_offset, val, options, 0, stream); break; } addr = unpack_pointer (type, valaddr + embedded_offset); if (addr == 0) { fputs_filtered ("null", stream); return; } target_type = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (target_type) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (options, gdbarch, addr, stream, demangle); return; } if (options->addressprint && options->format != 's') { fputs_filtered ("@", stream); print_longest (stream, 'x', 0, (ULONGEST) addr); } return; case TYPE_CODE_CHAR: case TYPE_CODE_INT: /* Can't just call c_val_print because that prints bytes as C chars. */ if (options->format || options->output_format) { struct value_print_options opts = *options; opts.format = (options->format ? options->format : options->output_format); val_print_scalar_formatted (type, valaddr, embedded_offset, val, &opts, 0, stream); } else if (TYPE_CODE (type) == TYPE_CODE_CHAR || (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 2 && strcmp (TYPE_NAME (type), "char") == 0)) LA_PRINT_CHAR ((int) unpack_long (type, valaddr + embedded_offset), type, stream); else val_print_type_code_int (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_STRUCT: java_print_value_fields (type, valaddr, embedded_offset, address, stream, recurse, val, options); break; default: c_val_print (type, valaddr, embedded_offset, address, stream, recurse, val, options); break; } }
static CORE_ADDR arm_linux_push_arguments (int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { char *fp; int argnum, argreg, nstack_size; /* Walk through the list of args and determine how large a temporary stack is required. Need to take care here as structs may be passed on the stack, and we have to to push them. */ nstack_size = -4 * DEPRECATED_REGISTER_SIZE; /* Some arguments go into A1-A4. */ if (struct_return) /* The struct address goes in A1. */ nstack_size += DEPRECATED_REGISTER_SIZE; /* Walk through the arguments and add their size to nstack_size. */ for (argnum = 0; argnum < nargs; argnum++) { int len; struct type *arg_type; arg_type = check_typedef (VALUE_TYPE (args[argnum])); len = TYPE_LENGTH (arg_type); /* ANSI C code passes float arguments as integers, K&R code passes float arguments as doubles. Correct for this here. */ if (TYPE_CODE_FLT == TYPE_CODE (arg_type) && DEPRECATED_REGISTER_SIZE == len) nstack_size += FP_REGISTER_VIRTUAL_SIZE; else nstack_size += len; } /* Allocate room on the stack, and initialize our stack frame pointer. */ fp = NULL; if (nstack_size > 0) { sp -= nstack_size; fp = (char *) sp; } /* Initialize the integer argument register pointer. */ argreg = ARM_A1_REGNUM; /* The struct_return pointer occupies the first parameter passing register. */ if (struct_return) write_register (argreg++, struct_addr); /* Process arguments from left to right. Store as many as allowed in the parameter passing registers (A1-A4), and save the rest on the temporary stack. */ for (argnum = 0; argnum < nargs; argnum++) { int len; char *val; CORE_ADDR regval; enum type_code typecode; struct type *arg_type, *target_type; arg_type = check_typedef (VALUE_TYPE (args[argnum])); target_type = TYPE_TARGET_TYPE (arg_type); len = TYPE_LENGTH (arg_type); typecode = TYPE_CODE (arg_type); val = (char *) VALUE_CONTENTS (args[argnum]); /* ANSI C code passes float arguments as integers, K&R code passes float arguments as doubles. The .stabs record for for ANSI prototype floating point arguments records the type as FP_INTEGER, while a K&R style (no prototype) .stabs records the type as FP_FLOAT. In this latter case the compiler converts the float arguments to double before calling the function. */ if (TYPE_CODE_FLT == typecode && DEPRECATED_REGISTER_SIZE == len) { DOUBLEST dblval; dblval = deprecated_extract_floating (val, len); len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT; val = alloca (len); deprecated_store_floating (val, len, dblval); } /* If the argument is a pointer to a function, and it is a Thumb function, set the low bit of the pointer. */ if (TYPE_CODE_PTR == typecode && NULL != target_type && TYPE_CODE_FUNC == TYPE_CODE (target_type)) { CORE_ADDR regval = extract_unsigned_integer (val, len); if (arm_pc_is_thumb (regval)) store_unsigned_integer (val, len, MAKE_THUMB_ADDR (regval)); } /* Copy the argument to general registers or the stack in register-sized pieces. Large arguments are split between registers and stack. */ while (len > 0) { int partial_len = len < DEPRECATED_REGISTER_SIZE ? len : DEPRECATED_REGISTER_SIZE; if (argreg <= ARM_LAST_ARG_REGNUM) { /* It's an argument being passed in a general register. */ regval = extract_unsigned_integer (val, partial_len); write_register (argreg++, regval); } else { /* Push the arguments onto the stack. */ write_memory ((CORE_ADDR) fp, val, DEPRECATED_REGISTER_SIZE); fp += DEPRECATED_REGISTER_SIZE; } len -= partial_len; val += partial_len; } } /* Return adjusted stack pointer. */ return sp; }
struct value * evaluate_subexp_c (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { enum exp_opcode op = exp->elts[*pos].opcode; switch (op) { case OP_STRING: { int oplen, limit; struct type *type; struct obstack output; struct cleanup *cleanup; struct value *result; enum c_string_type dest_type; const char *dest_charset; int satisfy_expected = 0; obstack_init (&output); cleanup = make_cleanup_obstack_free (&output); ++*pos; oplen = longest_to_int (exp->elts[*pos].longconst); ++*pos; limit = *pos + BYTES_TO_EXP_ELEM (oplen + 1); dest_type = (enum c_string_type) longest_to_int (exp->elts[*pos].longconst); switch (dest_type & ~C_CHAR) { case C_STRING: type = language_string_char_type (exp->language_defn, exp->gdbarch); break; case C_WIDE_STRING: type = lookup_typename (exp->language_defn, exp->gdbarch, "wchar_t", NULL, 0); break; case C_STRING_16: type = lookup_typename (exp->language_defn, exp->gdbarch, "char16_t", NULL, 0); break; case C_STRING_32: type = lookup_typename (exp->language_defn, exp->gdbarch, "char32_t", NULL, 0); break; default: internal_error (__FILE__, __LINE__, _("unhandled c_string_type")); } /* Ensure TYPE_LENGTH is valid for TYPE. */ check_typedef (type); /* If the caller expects an array of some integral type, satisfy them. If something odder is expected, rely on the caller to cast. */ if (expect_type && TYPE_CODE (expect_type) == TYPE_CODE_ARRAY) { struct type *element_type = check_typedef (TYPE_TARGET_TYPE (expect_type)); if (TYPE_CODE (element_type) == TYPE_CODE_INT || TYPE_CODE (element_type) == TYPE_CODE_CHAR) { type = element_type; satisfy_expected = 1; } } dest_charset = charset_for_string_type (dest_type, exp->gdbarch); ++*pos; while (*pos < limit) { int len; len = longest_to_int (exp->elts[*pos].longconst); ++*pos; if (noside != EVAL_SKIP) parse_one_string (&output, &exp->elts[*pos].string, len, dest_charset, type); *pos += BYTES_TO_EXP_ELEM (len); } /* Skip the trailing length and opcode. */ *pos += 2; if (noside == EVAL_SKIP) { /* Return a dummy value of the appropriate type. */ if (expect_type != NULL) result = allocate_value (expect_type); else if ((dest_type & C_CHAR) != 0) result = allocate_value (type); else result = value_cstring ("", 0, type); do_cleanups (cleanup); return result; } if ((dest_type & C_CHAR) != 0) { LONGEST value; if (obstack_object_size (&output) != TYPE_LENGTH (type)) error (_("Could not convert character " "constant to target character set")); value = unpack_long (type, (gdb_byte *) obstack_base (&output)); result = value_from_longest (type, value); } else { int i; /* Write the terminating character. */ for (i = 0; i < TYPE_LENGTH (type); ++i) obstack_1grow (&output, 0); if (satisfy_expected) { LONGEST low_bound, high_bound; int element_size = TYPE_LENGTH (type); if (get_discrete_bounds (TYPE_INDEX_TYPE (expect_type), &low_bound, &high_bound) < 0) { low_bound = 0; high_bound = (TYPE_LENGTH (expect_type) / element_size) - 1; } if (obstack_object_size (&output) / element_size > (high_bound - low_bound + 1)) error (_("Too many array elements")); result = allocate_value (expect_type); memcpy (value_contents_raw (result), obstack_base (&output), obstack_object_size (&output)); } else result = value_cstring (obstack_base (&output), obstack_object_size (&output), type); } do_cleanups (cleanup); return result; } break; default: break; } return evaluate_subexp_standard (expect_type, exp, pos, noside); }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *values_type = check_typedef (value_type (value)); struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; LONGEST offset_to_top; /* We only have RTTI for class objects. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; /* Determine architecture. */ gdbarch = get_type_arch (values_type); if (using_enc_p) *using_enc_p = 0; vtable = gnuv3_get_vtable (gdbarch, value_type (value), value_as_address (value_addr (value))); if (vtable == NULL) return NULL; /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)); 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; }
/* 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; LONGEST vi = (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j); struct type *fcontext = TYPE_FN_FIELD_FCONTEXT (f, j); struct type *context; struct type *context_vptr_basetype; int context_vptr_fieldno; 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. */ context_vptr_fieldno = get_vptr_fieldno (context, &context_vptr_basetype); /* FIXME: What to do if vptr_fieldno is still -1? */ /* 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, context_vptr_fieldno, context_vptr_basetype); /* 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_ptradd (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; }
/* Return nonzero if a type should be passed by reference. The rule in the v3 ABI document comes from section 3.1.1. If the type has a non-trivial copy constructor or destructor, then the caller must make a copy (by calling the copy constructor if there is one or perform the copy itself otherwise), pass the address of the copy, and then destroy the temporary (if necessary). For return values with non-trivial copy constructors or destructors, space will be allocated in the caller, and a pointer will be passed as the first argument (preceding "this"). We don't have a bulletproof mechanism for determining whether a constructor or destructor is trivial. For GCC and DWARF2 debug information, we can check the artificial flag. We don't do anything with the constructors or destructors, but we have to get the argument passing right anyway. */ static int gnuv3_pass_by_reference (struct type *type) { int fieldnum, fieldelem; CHECK_TYPEDEF (type); /* We're only interested in things that can have methods. */ if (TYPE_CODE (type) != TYPE_CODE_STRUCT && TYPE_CODE (type) != TYPE_CODE_CLASS && TYPE_CODE (type) != TYPE_CODE_UNION) return 0; for (fieldnum = 0; fieldnum < TYPE_NFN_FIELDS (type); fieldnum++) for (fieldelem = 0; fieldelem < TYPE_FN_FIELDLIST_LENGTH (type, fieldnum); fieldelem++) { struct fn_field *fn = TYPE_FN_FIELDLIST1 (type, fieldnum); char *name = TYPE_FN_FIELDLIST_NAME (type, fieldnum); struct type *fieldtype = TYPE_FN_FIELD_TYPE (fn, fieldelem); /* If this function is marked as artificial, it is compiler-generated, and we assume it is trivial. */ if (TYPE_FN_FIELD_ARTIFICIAL (fn, fieldelem)) continue; /* If we've found a destructor, we must pass this by reference. */ if (name[0] == '~') return 1; /* If the mangled name of this method doesn't indicate that it is a constructor, we're not interested. FIXME drow/2007-09-23: We could do this using the name of the method and the name of the class instead of dealing with the mangled name. We don't have a convenient function to strip off both leading scope qualifiers and trailing template arguments yet. */ if (!is_constructor_name (TYPE_FN_FIELD_PHYSNAME (fn, fieldelem))) continue; /* If this method takes two arguments, and the second argument is a reference to this class, then it is a copy constructor. */ if (TYPE_NFIELDS (fieldtype) == 2 && TYPE_CODE (TYPE_FIELD_TYPE (fieldtype, 1)) == TYPE_CODE_REF && check_typedef (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (fieldtype, 1))) == type) return 1; } /* Even if all the constructors and destructors were artificial, one of them may have invoked a non-artificial constructor or destructor in a base class. If any base class needs to be passed by reference, so does this class. Similarly for members, which are constructed whenever this class is. We do not need to worry about recursive loops here, since we are only looking at members of complete class type. */ for (fieldnum = 0; fieldnum < TYPE_NFIELDS (type); fieldnum++) if (gnuv3_pass_by_reference (TYPE_FIELD_TYPE (type, fieldnum))) return 1; return 0; }
int c_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0) { eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* For an array of chars, print with string syntax. */ if (eltlen == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_m2) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (format == 0 || format == 's')) { /* If requested, look for the first null char and only print elements up to it. */ if (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 < print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, valaddr + embedded_offset, len, eltlen, 0); i = len; } else { fprintf_filtered (stream, "{"); /* If this is a virtual function table, print the 0th entry specially, and the rest of the members normally. */ if (cp_is_vtbl_ptr_type (elttype)) { i = 1; fprintf_filtered (stream, _("%d vtable entries"), len - 1); } else { i = 0; } val_print_array_elements (type, valaddr + embedded_offset, address, stream, format, deref_ref, recurse, pretty, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address; goto print_unpacked_pointer; case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } if (vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if we ARE using -fvtable_thunks. (Otherwise, look under TYPE_CODE_STRUCT.) */ CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); print_function_pointer_address (addr, stream); break; } elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_METHOD) { cp_print_class_method (valaddr + embedded_offset, type, stream); } else if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER) { cp_print_class_member (valaddr + embedded_offset, TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type)), stream, "&"); } else { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_function_pointer_address (addr, stream); /* Return value is irrelevant except for string pointers. */ return (0); } if (addressprint && format != 's') { deprecated_print_address_numeric (addr, 1, stream); } /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ /* FIXME: need to handle wchar_t here... */ if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT && (format == 0 || format == 's') && addr != 0) { i = val_print_string (addr, -1, TYPE_LENGTH (elttype), stream); } else if (cp_is_vtbl_member (type)) { /* print vtbl's nicely */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (vt_address); if ((msymbol != NULL) && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && vtblprint) { struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) wsym = lookup_symbol (DEPRECATED_SYMBOL_NAME (msymbol), block, VAR_DOMAIN, &is_this_fld, NULL); if (wsym) { wtype = SYMBOL_TYPE (wsym); } else { wtype = TYPE_TARGET_TYPE (type); } vt_val = value_at (wtype, vt_address); common_val_print (vt_val, stream, format, deref_ref, recurse + 1, pretty); if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } } } /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_MEMBER: error (_("not implemented: member type in c_val_print")); break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_MEMBER) { cp_print_class_member (valaddr + embedded_offset, TYPE_DOMAIN_TYPE (elttype), stream, ""); break; } if (addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); deprecated_print_address_numeric (addr, 1, stream); if (deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr + embedded_offset)); common_val_print (deref_val, stream, format, deref_ref, recurse, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: /*FIXME: Abstract this away */ if (vtblprint && cp_is_vtbl_ptr_type (type)) { /* Print the unmangled name if desired. */ /* Print vtable entry - we only get here if NOT using -fvtable_thunks. (Otherwise, look under TYPE_CODE_PTR.) */ int offset = (embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8); struct type *field_type = TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET); CORE_ADDR addr = extract_typed_address (valaddr + offset, field_type); print_function_pointer_address (addr, stream); } else cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format, recurse, pretty, NULL, 0); break; case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr + embedded_offset); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (address, stream, demangle); break; case TYPE_CODE_BOOL: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { val = unpack_long (type, valaddr + embedded_offset); if (val == 0) fputs_filtered ("false", stream); else if (val == 1) fputs_filtered ("true", stream); else print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_RANGE: /* FIXME: create_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_INT: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val_print_type_code_int (type, valaddr + embedded_offset, stream); /* C and C++ has no single byte int type, char is used instead. Since we don't know whether the value is really intended to be used as an integer or a character, print the character equivalent as well. */ if (TYPE_LENGTH (type) == 1) { fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr + embedded_offset), stream); } } break; case TYPE_CODE_CHAR: format = format ? format : output_format; if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { val = unpack_long (type, valaddr + embedded_offset); if (TYPE_UNSIGNED (type)) fprintf_filtered (stream, "%u", (unsigned int) val); else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) val, stream); } break; case TYPE_CODE_FLT: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); } else { print_floating (valaddr + embedded_offset, type, stream); } break; case TYPE_CODE_METHOD: { struct value *v = value_at (type, address); cp_print_class_method (value_contents (value_addr (v)), lookup_pointer_type (type), stream); break; } case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<error type>")); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, _("<incomplete type>")); break; case TYPE_CODE_COMPLEX: if (format) print_scalar_formatted (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), format, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " + "); if (format) print_scalar_formatted (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), format, 0, stream); else print_floating (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " * I"); break; default: error (_("Invalid C/C++ type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
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); }
int f_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int recurse, const struct value *original_value, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned int i = 0; /* Number of characters printed */ struct type *elttype; LONGEST val; CORE_ADDR addr; int index; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_STRING: f77_get_dynamic_length_of_aggregate (type); LA_PRINT_STRING (stream, builtin_type (gdbarch)->builtin_char, valaddr, TYPE_LENGTH (type), NULL, 0, options); break; case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); f77_print_array (type, valaddr, address, stream, recurse, original_value, options); fprintf_filtered (stream, ")"); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { print_scalar_formatted (valaddr, type, options, 0, stream); break; } else { addr = unpack_pointer (type, valaddr); elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_address_demangle (gdbarch, addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return 0; } if (options->addressprint && options->format != 's') fputs_filtered (paddress (gdbarch, addr), stream); /* For a pointer to char or unsigned char, also print the string pointed to, unless pointer is null. */ if (TYPE_LENGTH (elttype) == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT && (options->format == 0 || options->format == 's') && addr != 0) i = val_print_string (TYPE_TARGET_TYPE (type), addr, -1, stream, options); /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (options->addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (options->deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (type, valaddr + embedded_offset)); common_val_print (deref_val, stream, recurse, options, current_language); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_FUNC: if (options->format) { print_scalar_formatted (valaddr, type, options, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (gdbarch, address, stream, demangle); break; case TYPE_CODE_INT: if (options->format || options->output_format) { struct value_print_options opts = *options; opts.format = (options->format ? options->format : options->output_format); print_scalar_formatted (valaddr, type, &opts, 0, stream); } else { val_print_type_code_int (type, valaddr, stream); /* C and C++ has no single byte int type, char is used instead. Since we don't know whether the value is really intended to be used as an integer or a character, print the character equivalent as well. */ if (TYPE_LENGTH (type) == 1) { fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) unpack_long (type, valaddr), type, stream); } } break; case TYPE_CODE_FLAGS: if (options->format) print_scalar_formatted (valaddr, type, options, 0, stream); else val_print_type_code_flags (type, valaddr, stream); break; case TYPE_CODE_FLT: if (options->format) print_scalar_formatted (valaddr, type, options, 0, stream); else print_floating (valaddr, type, stream); break; case TYPE_CODE_VOID: fprintf_filtered (stream, "VOID"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, "%s", TYPE_ERROR_NAME (type)); break; case TYPE_CODE_RANGE: /* FIXME, we should not ever have to print one of these yet. */ fprintf_filtered (stream, "<range type>"); break; case TYPE_CODE_BOOL: if (options->format || options->output_format) { struct value_print_options opts = *options; opts.format = (options->format ? options->format : options->output_format); print_scalar_formatted (valaddr, type, &opts, 0, stream); } else { val = extract_unsigned_integer (valaddr, TYPE_LENGTH (type), byte_order); if (val == 0) fprintf_filtered (stream, ".FALSE."); else if (val == 1) fprintf_filtered (stream, ".TRUE."); else /* Not a legitimate logical type, print as an integer. */ { /* Bash the type code temporarily. */ TYPE_CODE (type) = TYPE_CODE_INT; val_print (type, valaddr, 0, address, stream, recurse, original_value, options, current_language); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; } } break; case TYPE_CODE_COMPLEX: type = TYPE_TARGET_TYPE (type); fputs_filtered ("(", stream); print_floating (valaddr, type, stream); fputs_filtered (",", stream); print_floating (valaddr + TYPE_LENGTH (type), type, stream); fputs_filtered (")", stream); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, "<incomplete type>"); break; case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: /* Starting from the Fortran 90 standard, Fortran supports derived types. */ fprintf_filtered (stream, "( "); for (index = 0; index < TYPE_NFIELDS (type); index++) { int offset = TYPE_FIELD_BITPOS (type, index) / 8; val_print (TYPE_FIELD_TYPE (type, index), valaddr + offset, embedded_offset, address, stream, recurse + 1, original_value, options, current_language); if (index != TYPE_NFIELDS (type) - 1) fputs_filtered (", ", stream); } fprintf_filtered (stream, " )"); break; default: error (_("Invalid F77 type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return 0; }
CORE_ADDR find_function_addr (struct value *function, struct type **retval_type) { struct type *ftype = check_typedef (value_type (function)); struct gdbarch *gdbarch = get_type_arch (ftype); struct type *value_type = NULL; /* Initialize it just to avoid a GCC false warning. */ CORE_ADDR funaddr = 0; /* If it's a member function, just look at the function part of it. */ /* Determine address to call. */ if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) funaddr = value_address (function); else if (TYPE_CODE (ftype) == TYPE_CODE_PTR) { funaddr = value_as_address (function); ftype = check_typedef (TYPE_TARGET_TYPE (ftype)); if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr, ¤t_target); } if (TYPE_CODE (ftype) == TYPE_CODE_FUNC || TYPE_CODE (ftype) == TYPE_CODE_METHOD) { value_type = TYPE_TARGET_TYPE (ftype); if (TYPE_GNU_IFUNC (ftype)) { funaddr = gnu_ifunc_resolve_addr (gdbarch, funaddr); /* Skip querying the function symbol if no RETVAL_TYPE has been asked for. */ if (retval_type) value_type = find_function_return_type (funaddr); } } else if (TYPE_CODE (ftype) == TYPE_CODE_INT) { /* Handle the case of functions lacking debugging info. Their values are characters since their addresses are char. */ if (TYPE_LENGTH (ftype) == 1) funaddr = value_as_address (value_addr (function)); else { /* Handle function descriptors lacking debug info. */ int found_descriptor = 0; funaddr = 0; /* pacify "gcc -Werror" */ if (VALUE_LVAL (function) == lval_memory) { CORE_ADDR nfunaddr; funaddr = value_as_address (value_addr (function)); nfunaddr = funaddr; funaddr = gdbarch_convert_from_func_ptr_addr (gdbarch, funaddr, ¤t_target); if (funaddr != nfunaddr) found_descriptor = 1; } if (!found_descriptor) /* Handle integer used as address of a function. */ funaddr = (CORE_ADDR) value_as_long (function); } } else error (_("Invalid data type for function to be called.")); if (retval_type != NULL) *retval_type = value_type; return funaddr + gdbarch_deprecated_function_start_offset (gdbarch); }
int m2_val_print (struct type *type, const gdb_byte *valaddr, int embedded_offset, CORE_ADDR address, struct ui_file *stream, int format, int deref_ref, int recurse, enum val_prettyprint pretty) { unsigned int i = 0; /* Number of characters printed */ unsigned len; struct type *elttype; unsigned eltlen; int length_pos, length_size, string_pos; int char_size; LONGEST val; CORE_ADDR addr; 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)); eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (prettyprint_arrays) print_spaces_filtered (2 + 2 * recurse, stream); /* For an array of chars, print with string syntax. */ if (eltlen == 1 && ((TYPE_CODE (elttype) == TYPE_CODE_INT) || ((current_language->la_language == language_m2) && (TYPE_CODE (elttype) == TYPE_CODE_CHAR))) && (format == 0 || format == 's')) { /* If requested, look for the first null char and only print elements up to it. */ if (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 < print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, valaddr + embedded_offset, len, 1, 0); i = len; } else { fprintf_filtered (stream, "{"); val_print_array_elements (type, valaddr + embedded_offset, address, stream, format, deref_ref, recurse, pretty, 0); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ print_unpacked_pointer (type, address, address, format, stream); break; case TYPE_CODE_PTR: if (TYPE_CONST (type)) print_variable_at_address (type, valaddr + embedded_offset, stream, format, deref_ref, recurse, pretty); else if (format && format != 's') print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer (type, addr, address, format, stream); } break; case TYPE_CODE_MEMBER: error (_("not implemented: member type in m2_val_print")); break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); fputs_filtered (paddress (addr), stream); if (deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (lookup_pointer_type (builtin_type_void), valaddr + embedded_offset)); common_val_print (deref_val, stream, format, deref_ref, recurse, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_UNION: if (recurse && !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, format, pretty); else cp_print_value_fields (type, type, valaddr, embedded_offset, address, stream, format, recurse, pretty, NULL, 0); break; case TYPE_CODE_ENUM: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr + embedded_offset); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (address, stream, demangle); break; case TYPE_CODE_BOOL: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { val = unpack_long (type, valaddr + embedded_offset); if (val == 0) fputs_filtered ("FALSE", stream); else if (val == 1) fputs_filtered ("TRUE", stream); else fprintf_filtered (stream, "%ld)", (long int) val); } break; case TYPE_CODE_RANGE: if (TYPE_LENGTH (type) == TYPE_LENGTH (TYPE_TARGET_TYPE (type))) { m2_val_print (TYPE_TARGET_TYPE (type), valaddr, embedded_offset, address, stream, format, deref_ref, recurse, pretty); break; } /* FIXME: create_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_INT: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else val_print_type_code_int (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_CHAR: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else { val = unpack_long (type, valaddr + embedded_offset); if (TYPE_UNSIGNED (type)) fprintf_filtered (stream, "%u", (unsigned int) val); else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) val, stream); } break; case TYPE_CODE_FLT: if (format) print_scalar_formatted (valaddr + embedded_offset, type, format, 0, stream); else print_floating (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_METHOD: break; case TYPE_CODE_BITSTRING: case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); 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 is_bitstring = TYPE_CODE (type) == TYPE_CODE_BITSTRING; int need_comma = 0; if (is_bitstring) fputs_filtered ("B'", stream); else 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 (is_bitstring) fprintf_filtered (stream, "%d", element); else 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: if (is_bitstring) fputs_filtered ("'", stream); else fputs_filtered ("}", stream); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<error type>")); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, _("<incomplete type>")); break; default: error (_("Invalid m2 type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
static CORE_ADDR rs6000_lynx178_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) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int ii; int len = 0; int argno; /* current argument number */ int argbytes; /* current argument byte */ gdb_byte tmp_buffer[50]; int f_argno = 0; /* current floating point argno */ int wordsize = gdbarch_tdep (gdbarch)->wordsize; CORE_ADDR func_addr = find_function_addr (function, NULL); struct value *arg = 0; struct type *type; ULONGEST saved_sp; /* The calling convention this function implements assumes the processor has floating-point registers. We shouldn't be using it on PPC variants that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* The first eight words of ther arguments are passed in registers. Copy them appropriately. */ ii = 0; /* If the function is returning a `struct', then the first word (which will be passed in r3) is used for struct return address. In that case we should advance one word and start from r4 register to copy parameters. */ if (struct_return) { regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, struct_addr); ii++; } /* Effectively indirect call... gcc does... return_val example( float, int); eabi: float in fp0, int in r3 offset of stack on overflow 8/16 for varargs, must go by type. power open: float in r3&r4, int in r5 offset of stack on overflow different both: return in r3 or f0. If no float, must study how gcc emulates floats; pay attention to arg promotion. User may have to cast\args to handle promotion correctly since gdb won't know if prototype supplied or not. */ for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) { int reg_size = register_size (gdbarch, ii + 3); arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); if (TYPE_CODE (type) == TYPE_CODE_FLT) { /* Floating point arguments are passed in fpr's, as well as gpr's. There are 13 fpr's reserved for passing parameters. At this point there is no way we would run out of them. Always store the floating point value using the register's floating-point format. */ const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno; gdb_byte reg_val[MAX_REGISTER_SIZE]; struct type *reg_type = register_type (gdbarch, fp_regnum); gdb_assert (len <= 8); convert_typed_floating (value_contents (arg), type, reg_val, reg_type); regcache_cooked_write (regcache, fp_regnum, reg_val); ++f_argno; } if (len > reg_size) { /* Argument takes more than one register. */ while (argbytes < len) { gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, ((char *) value_contents (arg)) + argbytes, (len - argbytes) > reg_size ? reg_size : len - argbytes); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 + ii, word); ++ii, argbytes += reg_size; if (ii >= 8) goto ran_out_of_registers_for_arguments; } argbytes = 0; --ii; } else { /* Argument can fit in one register. No problem. */ int adj = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? reg_size - len : 0; gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, value_contents (arg), len); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word); } ++argno; } ran_out_of_registers_for_arguments: regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &saved_sp); /* Location for 8 parameters are always reserved. */ sp -= wordsize * 8; /* Another six words for back chain, TOC register, link register, etc. */ sp -= wordsize * 6; /* Stack pointer must be quadword aligned. */ sp = align_down (sp, 16); /* If there are more arguments, allocate space for them in the stack, then push them starting from the ninth one. */ if ((argno < nargs) || argbytes) { int space = 0, jj; if (argbytes) { space += align_up (len - argbytes, 4); jj = argno + 1; } else jj = argno; for (; jj < nargs; ++jj) { struct value *val = args[jj]; space += align_up (TYPE_LENGTH (value_type (val)), 4); } /* Add location required for the rest of the parameters. */ space = align_up (space, 16); sp -= space; /* This is another instance we need to be concerned about securing our stack space. If we write anything underneath %sp (r1), we might conflict with the kernel who thinks he is free to use this area. So, update %sp first before doing anything else. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* If the last argument copied into the registers didn't fit there completely, push the rest of it into stack. */ if (argbytes) { write_memory (sp + 24 + (ii * 4), value_contents (arg) + argbytes, len - argbytes); ++argno; ii += align_up (len - argbytes, 4) / 4; } /* Push the rest of the arguments into stack. */ for (; argno < nargs; ++argno) { arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); /* Float types should be passed in fpr's, as well as in the stack. */ if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13) { gdb_assert (len <= 8); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + f_argno, value_contents (arg)); ++f_argno; } write_memory (sp + 24 + (ii * 4), value_contents (arg), len); ii += align_up (len, 4) / 4; } } /* Set the stack pointer. According to the ABI, the SP is meant to be set _before_ the corresponding stack space is used. On AIX, this even applies when the target has been completely stopped! Not doing this can lead to conflicts with the kernel which thinks that it still has control over this not-yet-allocated stack region. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* Set back chain properly. */ store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp); write_memory (sp, tmp_buffer, wordsize); /* Point the inferior function call's return address at the dummy's breakpoint. */ regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); target_store_registers (regcache, -1); return sp; }
static void pascal_object_print_value (struct type *type, const gdb_byte *valaddr, CORE_ADDR address, struct ui_file *stream, int format, int recurse, enum val_prettyprint pretty, struct type **dont_print_vb) { struct type **last_dont_print = (struct type **) obstack_next_free (&dont_print_vb_obstack); struct obstack tmp_obstack = dont_print_vb_obstack; int i, n_baseclasses = TYPE_N_BASECLASSES (type); if (dont_print_vb == 0) { /* If we're at top level, carve out a completely fresh chunk of the obstack and use that until this particular invocation returns. */ /* Bump up the high-water mark. Now alpha is omega. */ obstack_finish (&dont_print_vb_obstack); } for (i = 0; i < n_baseclasses; i++) { int boffset; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr; if (BASETYPE_VIA_VIRTUAL (type, i)) { struct type **first_dont_print = (struct type **) obstack_base (&dont_print_vb_obstack); int j = (struct type **) obstack_next_free (&dont_print_vb_obstack) - first_dont_print; while (--j >= 0) if (baseclass == first_dont_print[j]) goto flush_it; obstack_ptr_grow (&dont_print_vb_obstack, baseclass); } boffset = baseclass_offset (type, i, valaddr, address); if (pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 * recurse, stream); } fputs_filtered ("<", stream); /* Not sure what the best notation is in the case where there is no baseclass name. */ fputs_filtered (basename ? basename : "", stream); fputs_filtered ("> = ", stream); /* The virtual base class pointer might have been clobbered by the user program. Make sure that it still points to a valid memory location. */ if (boffset != -1 && (boffset < 0 || boffset >= TYPE_LENGTH (type))) { /* FIXME (alloc): not safe is baseclass is really really big. */ gdb_byte *buf = alloca (TYPE_LENGTH (baseclass)); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) boffset = -1; } else base_valaddr = valaddr + boffset; if (boffset == -1) fprintf_filtered (stream, "<invalid address>"); else pascal_object_print_value_fields (baseclass, base_valaddr, address + boffset, stream, format, recurse, pretty, (struct type **) obstack_base (&dont_print_vb_obstack), 0); fputs_filtered (", ", stream); flush_it: ; } if (dont_print_vb == 0) { /* Free the space used to deal with the printing of this type from top level. */ obstack_free (&dont_print_vb_obstack, last_dont_print); /* Reset watermark so that we can continue protecting ourselves from whatever we were protecting ourselves. */ dont_print_vb_obstack = tmp_obstack; } }
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); }