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); ui_out_field_stream (uiout, "name", stb); if (what == all && SYMBOL_IS_ARGUMENT (arg->sym)) ui_out_field_int (uiout, "arg", 1); if (values == PRINT_SIMPLE_VALUES) { check_typedef (arg->sym->type); type_print (arg->sym->type, "", stb, -1); ui_out_field_stream (uiout, "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); ui_out_field_stream (uiout, "value", stb); } do_cleanups (old_chain); }
static CORE_ADDR mn10300_push_dummy_call (struct gdbarch *gdbarch, struct value *target_func, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { const int push_size = register_size (gdbarch, E_PC_REGNUM); int regs_used; int len, arg_len; int stack_offset = 0; int argnum; char *val, valbuf[MAX_REGISTER_SIZE]; /* This should be a nop, but align the stack just in case something went wrong. Stacks are four byte aligned on the mn10300. */ sp &= ~3; /* Now make space on the stack for the args. XXX This doesn't appear to handle pass-by-invisible reference arguments. */ regs_used = struct_return ? 1 : 0; for (len = 0, argnum = 0; argnum < nargs; argnum++) { arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; while (regs_used < 2 && arg_len > 0) { regs_used++; arg_len -= push_size; } len += arg_len; } /* Allocate stack space. */ sp -= len; if (struct_return) { regs_used = 1; write_register (E_D0_REGNUM, struct_addr); } else regs_used = 0; /* Push all arguments onto the stack. */ for (argnum = 0; argnum < nargs; argnum++) { /* FIXME what about structs? Unions? */ if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT && TYPE_LENGTH (value_type (*args)) > 8) { /* Change to pointer-to-type. */ arg_len = push_size; store_unsigned_integer (valbuf, push_size, VALUE_ADDRESS (*args)); val = &valbuf[0]; } else { arg_len = TYPE_LENGTH (value_type (*args)); val = (char *) value_contents (*args); } while (regs_used < 2 && arg_len > 0) { write_register (regs_used, extract_unsigned_integer (val, push_size)); val += push_size; arg_len -= push_size; regs_used++; } while (arg_len > 0) { write_memory (sp + stack_offset, val, push_size); arg_len -= push_size; val += push_size; stack_offset += push_size; } args++; } /* Make space for the flushback area. */ sp -= 8; /* Push the return address that contains the magic breakpoint. */ sp -= 4; write_memory_unsigned_integer (sp, push_size, bp_addr); /* Update $sp. */ regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp); return sp; }
int java_value_print (struct value *val, struct ui_file *stream, const struct value_print_options *options) { struct gdbarch *gdbarch = get_type_arch (value_type (val)); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct type *type; CORE_ADDR address; int i; char *name; struct value_print_options opts; type = value_type (val); address = value_address (val); if (is_object_type (type)) { CORE_ADDR obj_addr; /* Get the run-time type, and cast the object into that */ obj_addr = unpack_pointer (type, value_contents (val)); if (obj_addr != 0) { type = type_from_class (gdbarch, java_class_from_object (val)); type = lookup_pointer_type (type); val = value_at (type, address); } } if (TYPE_CODE (type) == TYPE_CODE_PTR && !value_logical_not (val)) type_print (TYPE_TARGET_TYPE (type), "", stream, -1); name = TYPE_TAG_NAME (type); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && name != NULL && (i = strlen (name), name[i - 1] == ']')) { gdb_byte buf4[4]; long length; unsigned int things_printed = 0; int reps; struct type *el_type = java_primitive_type_from_name (gdbarch, name, i - 2); i = 0; read_memory (address + get_java_object_header_size (gdbarch), buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); fprintf_filtered (stream, "{length: %ld", length); if (el_type == NULL) { CORE_ADDR element; CORE_ADDR next_element = -1; /* dummy initial value */ /* Skip object header and length. */ address += get_java_object_header_size (gdbarch) + 4; while (i < length && things_printed < options->print_max) { gdb_byte *buf; buf = alloca (gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT); fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) element = next_element; else { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ element = extract_unsigned_integer (buf, sizeof (buf), byte_order); } for (reps = 1; i + reps < length; reps++) { read_memory (address, buf, sizeof (buf)); address += gdbarch_ptr_bit (gdbarch) / HOST_CHAR_BIT; /* FIXME: cagney/2003-05-24: Bogus or what. It pulls a host sized pointer out of the target and then extracts that as an address (while assuming that the address is unsigned)! */ next_element = extract_unsigned_integer (buf, sizeof (buf), byte_order); if (next_element != element) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); if (element == 0) fprintf_filtered (stream, "null"); else fprintf_filtered (stream, "@%s", paddress (gdbarch, element)); things_printed++; i += reps; } } else { struct value *v = allocate_value (el_type); struct value *next_v = allocate_value (el_type); set_value_address (v, (address + get_java_object_header_size (gdbarch) + 4)); set_value_address (next_v, value_raw_address (v)); while (i < length && things_printed < options->print_max) { fputs_filtered (", ", stream); wrap_here (n_spaces (2)); if (i > 0) { struct value *tmp; tmp = next_v; next_v = v; v = tmp; } else { set_value_lazy (v, 1); set_value_offset (v, 0); } set_value_offset (next_v, value_offset (v)); for (reps = 1; i + reps < length; reps++) { set_value_lazy (next_v, 1); set_value_offset (next_v, value_offset (next_v) + TYPE_LENGTH (el_type)); if (memcmp (value_contents (v), value_contents (next_v), TYPE_LENGTH (el_type)) != 0) break; } if (reps == 1) fprintf_filtered (stream, "%d: ", i); else fprintf_filtered (stream, "%d..%d: ", i, i + reps - 1); opts = *options; opts.deref_ref = 1; common_val_print (v, stream, 1, &opts, current_language); things_printed++; i += reps; } } if (i < length) fprintf_filtered (stream, "..."); fprintf_filtered (stream, "}"); return 0; } /* If it's type String, print it */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_TARGET_TYPE (type) && TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)) && strcmp (TYPE_TAG_NAME (TYPE_TARGET_TYPE (type)), "java.lang.String") == 0 && (options->format == 0 || options->format == 's') && address != 0 && value_as_address (val) != 0) { struct type *char_type; struct value *data_val; CORE_ADDR data; struct value *boffset_val; unsigned long boffset; struct value *count_val; unsigned long count; struct value *mark; mark = value_mark (); /* Remember start of new values */ data_val = value_struct_elt (&val, NULL, "data", NULL, NULL); data = value_as_address (data_val); boffset_val = value_struct_elt (&val, NULL, "boffset", NULL, NULL); boffset = value_as_address (boffset_val); count_val = value_struct_elt (&val, NULL, "count", NULL, NULL); count = value_as_address (count_val); value_free_to_mark (mark); /* Release unnecessary values */ char_type = builtin_java_type (gdbarch)->builtin_char; val_print_string (char_type, data + boffset, count, stream, options); return 0; } opts = *options; opts.deref_ref = 1; return common_val_print (val, stream, 0, &opts, current_language); }
static void pascal_object_print_value (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, 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 = 0; struct type *baseclass = check_typedef (TYPE_BASECLASS (type, i)); const char *basename = type_name_no_tag (baseclass); const gdb_byte *base_valaddr = NULL; int thisoffset; int skip = 0; 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); } thisoffset = offset; TRY { boffset = baseclass_offset (type, i, valaddr, offset, address, val); } CATCH (ex, RETURN_MASK_ERROR) { if (ex.error == NOT_AVAILABLE_ERROR) skip = -1; else skip = 1; } END_CATCH if (skip == 0) { /* 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 < 0 || boffset >= TYPE_LENGTH (type)) { gdb_byte *buf; struct cleanup *back_to; buf = (gdb_byte *) xmalloc (TYPE_LENGTH (baseclass)); back_to = make_cleanup (xfree, buf); base_valaddr = buf; if (target_read_memory (address + boffset, buf, TYPE_LENGTH (baseclass)) != 0) skip = 1; address = address + boffset; thisoffset = 0; boffset = 0; do_cleanups (back_to); } else base_valaddr = valaddr; } if (options->prettyformat) { 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); if (skip < 0) val_print_unavailable (stream); else if (skip > 0) val_print_invalid_address (stream); else pascal_object_print_value_fields (baseclass, base_valaddr, thisoffset + boffset, address, stream, recurse, val, options, (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; } }
int c_textual_element_type (struct type *type, char format) { struct type *true_type, *iter_type; if (format != 0 && format != 's') return 0; /* We also rely on this for its side effect of setting up all the typedef pointers. */ true_type = check_typedef (type); /* TYPE_CODE_CHAR is always textual. */ if (TYPE_CODE (true_type) == TYPE_CODE_CHAR) return 1; /* Any other character-like types must be integral. */ if (TYPE_CODE (true_type) != TYPE_CODE_INT) return 0; /* We peel typedefs one by one, looking for a match. */ iter_type = type; while (iter_type) { /* Check the name of the type. */ if (TYPE_NAME (iter_type) && textual_name (TYPE_NAME (iter_type))) return 1; if (TYPE_CODE (iter_type) != TYPE_CODE_TYPEDEF) break; /* Peel a single typedef. If the typedef doesn't have a target type, we use check_typedef and hope the result is ok -- it might be for C++, where wchar_t is a built-in type. */ if (TYPE_TARGET_TYPE (iter_type)) iter_type = TYPE_TARGET_TYPE (iter_type); else iter_type = check_typedef (iter_type); } if (format == 's') { /* Print this as a string if we can manage it. For now, no wide character support. */ if (TYPE_CODE (true_type) == TYPE_CODE_INT && TYPE_LENGTH (true_type) == 1) return 1; } else { /* If a one-byte TYPE_CODE_INT is missing the not-a-character flag, then we treat it as text; otherwise, we assume it's being used as data. */ if (TYPE_CODE (true_type) == TYPE_CODE_INT && TYPE_LENGTH (true_type) == 1 && !TYPE_NOTTEXT (true_type)) return 1; } return 0; }
/* Return a GDB type representing `struct gdb_gnu_v3_abi_vtable', described above, laid out appropriately for ARCH. We use this function as the gdbarch per-architecture data initialization function. */ static void * build_gdb_vtable_type (struct gdbarch *arch) { struct type *t; struct field *field_list, *field; int offset; struct type *void_ptr_type = builtin_type (arch)->builtin_data_ptr; struct type *ptr_to_void_fn_type = builtin_type (arch)->builtin_func_ptr; /* ARCH can't give us the true ptrdiff_t type, so we guess. */ struct type *ptrdiff_type = arch_integer_type (arch, gdbarch_ptr_bit (arch), 0, "ptrdiff_t"); /* We assume no padding is necessary, since GDB doesn't know anything about alignment at the moment. If this assumption bites us, we should add a gdbarch method which, given a type, returns the alignment that type requires, and then use that here. */ /* Build the field list. */ field_list = xmalloc (sizeof (struct field [4])); memset (field_list, 0, sizeof (struct field [4])); field = &field_list[0]; offset = 0; /* ptrdiff_t vcall_and_vbase_offsets[0]; */ FIELD_NAME (*field) = "vcall_and_vbase_offsets"; FIELD_TYPE (*field) = lookup_array_range_type (ptrdiff_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* ptrdiff_t offset_to_top; */ FIELD_NAME (*field) = "offset_to_top"; FIELD_TYPE (*field) = ptrdiff_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void *type_info; */ FIELD_NAME (*field) = "type_info"; FIELD_TYPE (*field) = void_ptr_type; SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* void (*virtual_functions[0]) (); */ FIELD_NAME (*field) = "virtual_functions"; FIELD_TYPE (*field) = lookup_array_range_type (ptr_to_void_fn_type, 0, -1); SET_FIELD_BITPOS (*field, offset * TARGET_CHAR_BIT); offset += TYPE_LENGTH (FIELD_TYPE (*field)); field++; /* We assumed in the allocation above that there were four fields. */ gdb_assert (field == (field_list + 4)); t = arch_type (arch, TYPE_CODE_STRUCT, offset, NULL); TYPE_NFIELDS (t) = field - field_list; TYPE_FIELDS (t) = field_list; TYPE_TAG_NAME (t) = "gdb_gnu_v3_abi_vtable"; INIT_CPLUS_SPECIFIC (t); return t; }
static void gnuv3_print_method_ptr (const gdb_byte *contents, struct type *type, struct ui_file *stream) { struct type *domain = TYPE_DOMAIN_TYPE (type); struct gdbarch *gdbarch = get_type_arch (domain); CORE_ADDR ptr_value; LONGEST adjustment; int vbit; /* Extract the pointer to member. */ vbit = gnuv3_decode_method_ptr (gdbarch, contents, &ptr_value, &adjustment); /* Check for NULL. */ if (ptr_value == 0 && vbit == 0) { fprintf_filtered (stream, "NULL"); return; } /* Search for a virtual method. */ if (vbit) { CORE_ADDR voffset; const char *physname; /* It's a virtual table offset, maybe in this class. Search for a field with the correct vtable offset. First convert it to an index, as used in TYPE_FN_FIELD_VOFFSET. */ voffset = ptr_value / TYPE_LENGTH (vtable_ptrdiff_type (gdbarch)); physname = gnuv3_find_method_in (domain, voffset, adjustment); /* If we found a method, print that. We don't bother to disambiguate possible paths to the method based on the adjustment. */ if (physname) { char *demangled_name = gdb_demangle (physname, DMGL_ANSI | DMGL_PARAMS); fprintf_filtered (stream, "&virtual "); if (demangled_name == NULL) fputs_filtered (physname, stream); else { fputs_filtered (demangled_name, stream); xfree (demangled_name); } return; } } else if (ptr_value != 0) { /* Found a non-virtual function: print out the type. */ fputs_filtered ("(", stream); c_print_type (type, "", stream, -1, 0, &type_print_raw_options); fputs_filtered (") ", stream); } /* We didn't find it; print the raw data. */ if (vbit) { fprintf_filtered (stream, "&virtual table offset "); print_longest (stream, 'd', 1, ptr_value); } else { struct value_print_options opts; get_user_print_options (&opts); print_address_demangle (&opts, gdbarch, ptr_value, stream, demangle); } if (adjustment) { fprintf_filtered (stream, ", this adjustment "); print_longest (stream, 'd', 1, adjustment); } }
void c_type_print_base (struct type *type, struct ui_file *stream, int show, int level) { int i; int len, real_len; int lastval; char *mangled_name; char *demangled_name; char *demangled_no_static; enum { s_none, s_public, s_private, s_protected } section_type; int need_access_label = 0; int j, len2; 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 we have "typedef struct foo {. . .} bar;" do we want to print it as "struct foo" or as "bar"? Pick the latter, because C++ folk tend to expect things like "class5 *foo" rather than "struct class5 *foo". */ if (show <= 0 && TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); return; } CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_TYPEDEF: case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: case TYPE_CODE_MEMBER: case TYPE_CODE_REF: case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: c_type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; case TYPE_CODE_STRUCT: c_type_print_modifier (type, stream, 0, 1); /* Note TYPE_CODE_STRUCT and TYPE_CODE_CLASS have the same value, * so we use another means for distinguishing them. */ if (HAVE_CPLUS_STRUCT (type)) { switch (TYPE_DECLARED_TYPE (type)) { case DECLARED_TYPE_CLASS: fprintf_filtered (stream, "class "); break; case DECLARED_TYPE_UNION: fprintf_filtered (stream, "union "); break; case DECLARED_TYPE_STRUCT: fprintf_filtered (stream, "struct "); break; default: /* If there is a CPLUS_STRUCT, assume class if not * otherwise specified in the declared_type field. */ fprintf_filtered (stream, "class "); break; } /* switch */ } else { /* If not CPLUS_STRUCT, then assume it's a C struct */ fprintf_filtered (stream, "struct "); } goto struct_union; case TYPE_CODE_UNION: c_type_print_modifier (type, stream, 0, 1); fprintf_filtered (stream, "union "); struct_union: /* Print the tag if it exists. * The HP aCC compiler emits * a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" * tag for unnamed struct/union/enum's, which we don't * want to print. */ if (TYPE_TAG_NAME (type) != NULL && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8)) { 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) { cp_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")); } /* Start off with no specific section type, so we can print one for the first field we find, and use that section type thereafter until we find another type. */ section_type = s_none; /* For a class, if all members are private, there's no need for a "private:" label; similarly, for a struct or union masquerading as a class, if all members are public, there's no need for a "public:" label. */ if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_CLASS) || (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_TEMPLATE)) { QUIT; len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) if (!TYPE_FIELD_PRIVATE (type, i)) { need_access_label = 1; break; } QUIT; if (!need_access_label) { len2 = TYPE_NFN_FIELDS (type); for (j = 0; j < len2; j++) { len = TYPE_FN_FIELDLIST_LENGTH (type, j); for (i = 0; i < len; i++) if (!TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i)) { need_access_label = 1; break; } if (need_access_label) break; } } } else if ((TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_STRUCT) || (TYPE_DECLARED_TYPE (type) == DECLARED_TYPE_UNION)) { QUIT; len = TYPE_NFIELDS (type); for (i = TYPE_N_BASECLASSES (type); i < len; i++) if (TYPE_FIELD_PRIVATE (type, i) || TYPE_FIELD_PROTECTED (type, i)) { need_access_label = 1; break; } QUIT; if (!need_access_label) { len2 = TYPE_NFN_FIELDS (type); for (j = 0; j < len2; j++) { QUIT; len = TYPE_FN_FIELDLIST_LENGTH (type, j); for (i = 0; i < len; i++) if (TYPE_FN_FIELD_PRIVATE (TYPE_FN_FIELDLIST1 (type, j), i) || TYPE_FN_FIELD_PROTECTED (TYPE_FN_FIELDLIST1 (type, j), i)) { need_access_label = 1; break; } if (need_access_label) break; } } } /* 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. */ /* HP ANSI C++ case */ if (TYPE_HAS_VTABLE (type) && (strncmp (TYPE_FIELD_NAME (type, i), "__vfp", 5) == 0)) continue; /* Other compilers */ if (strncmp (TYPE_FIELD_NAME (type, i), "_vptr", 5) == 0 && is_cplus_marker ((TYPE_FIELD_NAME (type, i))[5])) continue; /* If this is a C++ class we can print the various C++ section labels. */ if (HAVE_CPLUS_STRUCT (type) && need_access_label) { if (TYPE_FIELD_PROTECTED (type, i)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FIELD_PRIVATE (type, i)) { if (section_type != s_private) { section_type = s_private; fprintfi_filtered (level + 2, stream, "private:\n"); } } else { if (section_type != s_public) { section_type = s_public; fprintfi_filtered (level + 2, stream, "public:\n"); } } } print_spaces_filtered (level + 4, stream); if (TYPE_FIELD_STATIC (type, i)) { fprintf_filtered (stream, "static "); } c_print_type (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4); if (!TYPE_FIELD_STATIC (type, i) && TYPE_FIELD_PACKED (type, i)) { /* It is a bitfield. This code does not attempt to look at the bitpos and reconstruct filler, unnamed fields. This would lead to misleading results if the compiler does not put out fields for such things (I don't know what it does). */ fprintf_filtered (stream, " : %d", TYPE_FIELD_BITSIZE (type, i)); } fprintf_filtered (stream, ";\n"); } /* If there are both fields and methods, put a blank line between them. Make sure to count only method that we will display; artificial methods will be hidden. */ len = TYPE_NFN_FIELDS (type); real_len = 0; for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); int j; for (j = 0; j < len2; j++) if (!TYPE_FN_FIELD_ARTIFICIAL (f, j)) real_len++; } if (real_len > 0 && section_type != s_none) fprintf_filtered (stream, "\n"); /* C++: print out the methods */ for (i = 0; i < len; i++) { struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); char *method_name = TYPE_FN_FIELDLIST_NAME (type, i); char *name = type_name_no_tag (type); int is_constructor = name && strcmp (method_name, name) == 0; for (j = 0; j < len2; j++) { char *physname = TYPE_FN_FIELD_PHYSNAME (f, j); int is_full_physname_constructor = is_constructor_name (physname) || is_destructor_name (physname) || method_name[0] == '~'; /* Do not print out artificial methods. */ if (TYPE_FN_FIELD_ARTIFICIAL (f, j)) continue; QUIT; if (TYPE_FN_FIELD_PROTECTED (f, j)) { if (section_type != s_protected) { section_type = s_protected; fprintfi_filtered (level + 2, stream, "protected:\n"); } } else if (TYPE_FN_FIELD_PRIVATE (f, j)) { if (section_type != s_private) { section_type = s_private; fprintfi_filtered (level + 2, stream, "private:\n"); } } else { if (section_type != s_public) { section_type = s_public; fprintfi_filtered (level + 2, stream, "public:\n"); } } print_spaces_filtered (level + 4, stream); if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) fprintf_filtered (stream, "virtual "); else if (TYPE_FN_FIELD_STATIC_P (f, j)) fprintf_filtered (stream, "static "); 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 && /* constructors don't have declared types */ !is_full_physname_constructor && /* " " */ !is_type_conversion_operator (type, i, j)) { 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 = TYPE_FN_FIELD_PHYSNAME (f, j); demangled_name = cplus_demangle (mangled_name, DMGL_ANSI | DMGL_PARAMS); if (demangled_name == NULL) { /* in some cases (for instance with the HP demangling), if a function has more than 10 arguments, the demangling will fail. Let's try to reconstruct the function signature from the symbol information */ if (!TYPE_FN_FIELD_STUB (f, j)) { int staticp = TYPE_FN_FIELD_STATIC_P (f, j); struct type *mtype = TYPE_FN_FIELD_TYPE (f, j); cp_type_print_method_args (mtype, "", method_name, staticp, stream); } else fprintf_filtered (stream, _("<badly mangled name '%s'>"), mangled_name); } else { char *p; char *demangled_no_class = remove_qualifiers (demangled_name); /* get rid of the `static' appended by the demangler */ p = strstr (demangled_no_class, " static"); if (p != NULL) { int length = p - demangled_no_class; demangled_no_static = (char *) xmalloc (length + 1); strncpy (demangled_no_static, demangled_no_class, length); *(demangled_no_static + length) = '\0'; fputs_filtered (demangled_no_static, stream); xfree (demangled_no_static); } else 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, "}"); if (TYPE_LOCALTYPE_PTR (type) && show >= 0) fprintfi_filtered (level, stream, _(" (Local at %s:%d)\n"), TYPE_LOCALTYPE_FILE (type), TYPE_LOCALTYPE_LINE (type)); } if (TYPE_CODE (type) == TYPE_CODE_TEMPLATE) goto go_back; break; case TYPE_CODE_ENUM: c_type_print_modifier (type, stream, 0, 1); /* HP C supports sized enums */ if (deprecated_hp_som_som_object_present) switch (TYPE_LENGTH (type)) { case 1: fputs_filtered ("char ", stream); break; case 2: fputs_filtered ("short ", stream); break; default: break; } fprintf_filtered (stream, "enum "); /* Print the tag name if it exists. The aCC compiler emits a spurious "{unnamed struct}"/"{unnamed union}"/"{unnamed enum}" tag for unnamed struct/union/enum's, which we don't want to print. */ if (TYPE_TAG_NAME (type) != NULL && strncmp (TYPE_TAG_NAME (type), "{unnamed", 8)) { 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) { fprintf_filtered (stream, "{"); len = TYPE_NFIELDS (type); lastval = 0; for (i = 0; i < len; i++) { QUIT; if (i) fprintf_filtered (stream, ", "); wrap_here (" "); fputs_filtered (TYPE_FIELD_NAME (type, i), stream); if (lastval != TYPE_FIELD_BITPOS (type, i)) { fprintf_filtered (stream, " = %d", TYPE_FIELD_BITPOS (type, i)); lastval = TYPE_FIELD_BITPOS (type, i); } lastval++; } fprintf_filtered (stream, "}"); } break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_UNDEF: fprintf_filtered (stream, _("struct <unknown>")); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<unknown type>")); break; case TYPE_CODE_RANGE: /* This should not occur */ fprintf_filtered (stream, _("<range type>")); break; case TYPE_CODE_TEMPLATE: /* Called on "ptype t" where "t" is a template. Prints the template header (with args), e.g.: template <class T1, class T2> class " and then merges with the struct/union/class code to print the rest of the definition. */ c_type_print_modifier (type, stream, 0, 1); fprintf_filtered (stream, "template <"); for (i = 0; i < TYPE_NTEMPLATE_ARGS (type); i++) { struct template_arg templ_arg; templ_arg = TYPE_TEMPLATE_ARG (type, i); fprintf_filtered (stream, "class %s", templ_arg.name); if (i < TYPE_NTEMPLATE_ARGS (type) - 1) fprintf_filtered (stream, ", "); } fprintf_filtered (stream, "> class "); /* Yuck, factor this out to a subroutine so we can call it and return to the point marked with the "goback:" label... - RT */ goto struct_union; go_back: if (TYPE_NINSTANTIATIONS (type) > 0) { fprintf_filtered (stream, _("\ntemplate instantiations:\n")); for (i = 0; i < TYPE_NINSTANTIATIONS (type); i++) { fprintf_filtered (stream, " "); c_type_print_base (TYPE_INSTANTIATION (type, i), stream, 0, level); if (i < TYPE_NINSTANTIATIONS (type) - 1) fprintf_filtered (stream, "\n"); } } break; case TYPE_CODE_NAMESPACE: fputs_filtered ("namespace ", stream); fputs_filtered (TYPE_TAG_NAME (type), stream); break; default: /* Handle types not explicitly handled by the other cases, such as fundamental types. For these, just print whatever the type name is, as recorded in the type itself. If there is no type name, then complain. */ if (TYPE_NAME (type) != NULL) { c_type_print_modifier (type, stream, 0, 1); fputs_filtered (TYPE_NAME (type), stream); } else { /* At least for dump_symtab, it is important that this not be an error (). */ fprintf_filtered (stream, _("<invalid type code %d>"), TYPE_CODE (type)); } break; } }
static int xstormy16_use_struct_convention (struct type *type) { return !xstormy16_type_is_scalar (type) || TYPE_LENGTH (type) > E_MAX_RETTYPE_SIZE_IN_REGS; }
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; } }
void c_type_print_varspec_suffix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr, int demangled_args) { if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (passed_a_ptr) fprintf_filtered (stream, ")"); fprintf_filtered (stream, "["); if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) fprintf_filtered (stream, "%d", (TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)))); fprintf_filtered (stream, "]"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); break; case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf_filtered (stream, ")"); c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 0, 0); if (passed_a_ptr) { c_type_print_args (type, stream); } break; case TYPE_CODE_PTR: case TYPE_CODE_REF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, 1, 0); break; case TYPE_CODE_FUNC: if (passed_a_ptr) fprintf_filtered (stream, ")"); if (!demangled_args) { int i, len = TYPE_NFIELDS (type); fprintf_filtered (stream, "("); if (len == 0 && (TYPE_PROTOTYPED (type) || current_language->la_language == language_cplus)) { fprintf_filtered (stream, "void"); } else for (i = 0; i < len; i++) { if (i > 0) { fputs_filtered (", ", stream); wrap_here (" "); } c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0); } fprintf_filtered (stream, ")"); } c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; case TYPE_CODE_TYPEDEF: c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show, passed_a_ptr, 0); break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_SET: case TYPE_CODE_RANGE: case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: case TYPE_CODE_TEMPLATE: case TYPE_CODE_NAMESPACE: /* These types do not need a suffix. They are listed so that gcc -Wall will report types that may not have been considered. */ break; default: error (_("type not handled in c_type_print_varspec_suffix()")); break; } }
static struct value * evaluate_subexp_java (struct type *expect_type, struct expression *exp, int *pos, enum noside noside) { int pc = *pos; int i; const char *name; enum exp_opcode op = exp->elts[*pos].opcode; struct value *arg1; struct value *arg2; struct type *type; switch (op) { case UNOP_IND: if (noside == EVAL_SKIP) goto standard; (*pos)++; arg1 = evaluate_subexp_java (NULL_TYPE, exp, pos, EVAL_NORMAL); if (is_object_type (value_type (arg1))) { struct type *type; type = type_from_class (exp->gdbarch, java_class_from_object (arg1)); arg1 = value_cast (lookup_pointer_type (type), arg1); } return value_ind (arg1); case BINOP_SUBSCRIPT: (*pos)++; arg1 = evaluate_subexp_with_coercion (exp, pos, noside); arg2 = evaluate_subexp_with_coercion (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; /* If the user attempts to subscript something that is not an array or pointer type (like a plain int variable for example), then report this as an error. */ arg1 = coerce_ref (arg1); type = check_typedef (value_type (arg1)); if (TYPE_CODE (type) == TYPE_CODE_PTR) type = check_typedef (TYPE_TARGET_TYPE (type)); name = TYPE_NAME (type); if (name == NULL) name = TYPE_TAG_NAME (type); i = name == NULL ? 0 : strlen (name); if (TYPE_CODE (type) == TYPE_CODE_STRUCT && i > 2 && name[i - 1] == ']') { enum bfd_endian byte_order = gdbarch_byte_order (exp->gdbarch); CORE_ADDR address; long length, index; struct type *el_type; gdb_byte buf4[4]; struct value *clas = java_class_from_object (arg1); struct value *temp = clas; /* Get CLASS_ELEMENT_TYPE of the array type. */ temp = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); deprecated_set_value_type (temp, value_type (clas)); el_type = type_from_class (exp->gdbarch, temp); if (TYPE_CODE (el_type) == TYPE_CODE_STRUCT) el_type = lookup_pointer_type (el_type); if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (el_type, VALUE_LVAL (arg1)); address = value_as_address (arg1); address += get_java_object_header_size (exp->gdbarch); read_memory (address, buf4, 4); length = (long) extract_signed_integer (buf4, 4, byte_order); index = (long) value_as_long (arg2); if (index >= length || index < 0) error (_("array index (%ld) out of bounds (length: %ld)"), index, length); address = (address + 4) + index * TYPE_LENGTH (el_type); return value_at (el_type, address); } else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { if (noside == EVAL_AVOID_SIDE_EFFECTS) return value_zero (TYPE_TARGET_TYPE (type), VALUE_LVAL (arg1)); else return value_subscript (arg1, value_as_long (arg2)); } if (name) error (_("cannot subscript something of type `%s'"), name); else error (_("cannot subscript requested type")); case OP_STRING: (*pos)++; i = longest_to_int (exp->elts[pc + 1].longconst); (*pos) += 3 + BYTES_TO_EXP_ELEM (i + 1); if (noside == EVAL_SKIP) goto nosideret; return java_value_string (&exp->elts[pc + 2].string, i); case STRUCTOP_PTR: arg1 = evaluate_subexp_standard (expect_type, exp, pos, noside); /* Convert object field (such as TYPE.class) to reference. */ if (TYPE_CODE (value_type (arg1)) == TYPE_CODE_STRUCT) arg1 = value_addr (arg1); return arg1; default: break; } standard: return evaluate_subexp_standard (expect_type, exp, pos, noside); nosideret: return value_from_longest (builtin_type (exp->gdbarch)->builtin_int, 1); }
static struct type * java_link_class_type (struct gdbarch *gdbarch, struct type *type, struct value *clas) { struct value *temp; const char *unqualified_name; const char *name = TYPE_TAG_NAME (type); int ninterfaces, nfields, nmethods; int type_is_object = 0; struct fn_field *fn_fields; struct fn_fieldlist *fn_fieldlists; struct value *fields; struct value *methods; struct value *method = NULL; struct value *field = NULL; int i, j; struct objfile *objfile = get_dynamics_objfile (gdbarch); struct type *tsuper; gdb_assert (name != NULL); unqualified_name = strrchr (name, '.'); if (unqualified_name == NULL) unqualified_name = name; temp = clas; temp = value_struct_elt (&temp, NULL, "superclass", NULL, "structure"); if (strcmp (name, "java.lang.Object") == 0) { tsuper = get_java_object_type (); if (tsuper && TYPE_CODE (tsuper) == TYPE_CODE_PTR) tsuper = TYPE_TARGET_TYPE (tsuper); type_is_object = 1; } else tsuper = type_from_class (gdbarch, temp); #if 1 ninterfaces = 0; #else temp = clas; ninterfaces = value_as_long (value_struct_elt (&temp, NULL, "interface_len", NULL, "structure")); #endif TYPE_N_BASECLASSES (type) = (tsuper == NULL ? 0 : 1) + ninterfaces; temp = clas; nfields = value_as_long (value_struct_elt (&temp, NULL, "field_count", NULL, "structure")); nfields += TYPE_N_BASECLASSES (type); nfields++; /* Add one for dummy "class" field. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) TYPE_ALLOC (type, sizeof (struct field) * nfields); memset (TYPE_FIELDS (type), 0, sizeof (struct field) * nfields); TYPE_FIELD_PRIVATE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); TYPE_FIELD_PROTECTED_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); TYPE_FIELD_IGNORE_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (nfields)); B_CLRALL (TYPE_FIELD_IGNORE_BITS (type), nfields); TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) TYPE_ALLOC (type, B_BYTES (TYPE_N_BASECLASSES (type))); B_CLRALL (TYPE_FIELD_VIRTUAL_BITS (type), TYPE_N_BASECLASSES (type)); if (tsuper != NULL) { TYPE_BASECLASS (type, 0) = tsuper; if (type_is_object) SET_TYPE_FIELD_PRIVATE (type, 0); } i = strlen (name); if (i > 2 && name[i - 1] == ']' && tsuper != NULL) { /* FIXME */ TYPE_LENGTH (type) = TYPE_LENGTH (tsuper) + 4; /* size with "length" */ } else { temp = clas; temp = value_struct_elt (&temp, NULL, "size_in_bytes", NULL, "structure"); TYPE_LENGTH (type) = value_as_long (temp); } fields = NULL; nfields--; /* First set up dummy "class" field. */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, nfields), value_address (clas)); TYPE_FIELD_NAME (type, nfields) = "class"; TYPE_FIELD_TYPE (type, nfields) = value_type (clas); SET_TYPE_FIELD_PRIVATE (type, nfields); for (i = TYPE_N_BASECLASSES (type); i < nfields; i++) { int accflags; int boffset; if (fields == NULL) { temp = clas; fields = value_struct_elt (&temp, NULL, "fields", NULL, "structure"); field = value_ind (fields); } else { /* Re-use field value for next field. */ CORE_ADDR addr = value_address (field) + TYPE_LENGTH (value_type (field)); set_value_address (field, addr); set_value_lazy (field, 1); } temp = field; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); TYPE_FIELD_NAME (type, i) = get_java_utf8_name (&objfile->objfile_obstack, temp); temp = field; accflags = value_as_long (value_struct_elt (&temp, NULL, "accflags", NULL, "structure")); temp = field; temp = value_struct_elt (&temp, NULL, "info", NULL, "structure"); boffset = value_as_long (value_struct_elt (&temp, NULL, "boffset", NULL, "structure")); if (accflags & 0x0001) /* public access */ { /* ??? */ } if (accflags & 0x0002) /* private access */ { SET_TYPE_FIELD_PRIVATE (type, i); } if (accflags & 0x0004) /* protected access */ { SET_TYPE_FIELD_PROTECTED (type, i); } if (accflags & 0x0008) /* ACC_STATIC */ SET_FIELD_PHYSADDR (TYPE_FIELD (type, i), boffset); else SET_FIELD_BITPOS (TYPE_FIELD (type, i), 8 * boffset); if (accflags & 0x8000) /* FIELD_UNRESOLVED_FLAG */ { TYPE_FIELD_TYPE (type, i) = get_java_object_type (); /* FIXME */ } else { struct type *ftype; temp = field; temp = value_struct_elt (&temp, NULL, "type", NULL, "structure"); ftype = type_from_class (gdbarch, temp); if (TYPE_CODE (ftype) == TYPE_CODE_STRUCT) ftype = lookup_pointer_type (ftype); TYPE_FIELD_TYPE (type, i) = ftype; } } temp = clas; nmethods = value_as_long (value_struct_elt (&temp, NULL, "method_count", NULL, "structure")); j = nmethods * sizeof (struct fn_field); fn_fields = (struct fn_field *) obstack_alloc (&objfile->objfile_obstack, j); memset (fn_fields, 0, j); fn_fieldlists = (struct fn_fieldlist *) alloca (nmethods * sizeof (struct fn_fieldlist)); methods = NULL; for (i = 0; i < nmethods; i++) { const char *mname; int k; if (methods == NULL) { temp = clas; methods = value_struct_elt (&temp, NULL, "methods", NULL, "structure"); method = value_ind (methods); } else { /* Re-use method value for next method. */ CORE_ADDR addr = value_address (method) + TYPE_LENGTH (value_type (method)); set_value_address (method, addr); set_value_lazy (method, 1); } /* Get method name. */ temp = method; temp = value_struct_elt (&temp, NULL, "name", NULL, "structure"); mname = get_java_utf8_name (&objfile->objfile_obstack, temp); if (strcmp (mname, "<init>") == 0) mname = unqualified_name; /* Check for an existing method with the same name. * This makes building the fn_fieldslists an O(nmethods**2) * operation. That could be using hashing, but I doubt it * is worth it. Note that we do maintain the order of methods * in the inferior's Method table (as long as that is grouped * by method name), which I think is desirable. --PB */ for (k = 0, j = TYPE_NFN_FIELDS (type);;) { if (--j < 0) { /* No match - new method name. */ j = TYPE_NFN_FIELDS (type)++; fn_fieldlists[j].name = mname; fn_fieldlists[j].length = 1; fn_fieldlists[j].fn_fields = &fn_fields[i]; k = i; break; } if (strcmp (mname, fn_fieldlists[j].name) == 0) { /* Found an existing method with the same name. */ int l; if (mname != unqualified_name) obstack_free (&objfile->objfile_obstack, mname); mname = fn_fieldlists[j].name; fn_fieldlists[j].length++; k = i - k; /* Index of new slot. */ /* Shift intervening fn_fields (between k and i) down. */ for (l = i; l > k; l--) fn_fields[l] = fn_fields[l - 1]; for (l = TYPE_NFN_FIELDS (type); --l > j;) fn_fieldlists[l].fn_fields++; break; } k += fn_fieldlists[j].length; } fn_fields[k].physname = ""; fn_fields[k].is_stub = 1; /* FIXME */ fn_fields[k].type = lookup_function_type (builtin_java_type (gdbarch)->builtin_void); TYPE_CODE (fn_fields[k].type) = TYPE_CODE_METHOD; } j = TYPE_NFN_FIELDS (type) * sizeof (struct fn_fieldlist); TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) obstack_alloc (&objfile->objfile_obstack, j); memcpy (TYPE_FN_FIELDLISTS (type), fn_fieldlists, j); return type; }
static void parse_find_args (char *args, ULONGEST *max_countp, char **pattern_bufp, ULONGEST *pattern_lenp, CORE_ADDR *start_addrp, ULONGEST *search_space_lenp, bfd_boolean big_p) { /* Default to using the specified type. */ char size = '\0'; ULONGEST max_count = ~(ULONGEST) 0; /* Buffer to hold the search pattern. */ char *pattern_buf; /* Current size of search pattern buffer. We realloc space as needed. */ #define INITIAL_PATTERN_BUF_SIZE 100 ULONGEST pattern_buf_size = INITIAL_PATTERN_BUF_SIZE; /* Pointer to one past the last in-use part of pattern_buf. */ char *pattern_buf_end; ULONGEST pattern_len; CORE_ADDR start_addr; ULONGEST search_space_len; char *s = args; struct cleanup *old_cleanups; struct value *v; if (args == NULL) error (_("Missing search parameters.")); pattern_buf = xmalloc (pattern_buf_size); pattern_buf_end = pattern_buf; old_cleanups = make_cleanup (free_current_contents, &pattern_buf); /* Get search granularity and/or max count if specified. They may be specified in either order, together or separately. */ while (*s == '/') { ++s; while (*s != '\0' && *s != '/' && !isspace (*s)) { if (isdigit (*s)) { max_count = atoi (s); while (isdigit (*s)) ++s; continue; } switch (*s) { case 'b': case 'h': case 'w': case 'g': size = *s++; break; default: error (_("Invalid size granularity.")); } } while (isspace (*s)) ++s; } /* Get the search range. */ v = parse_to_comma_and_eval (&s); start_addr = value_as_address (v); if (*s == ',') ++s; while (isspace (*s)) ++s; if (*s == '+') { LONGEST len; ++s; v = parse_to_comma_and_eval (&s); len = value_as_long (v); if (len == 0) { printf_filtered (_("Empty search range.\n")); return; } if (len < 0) error (_("Invalid length.")); /* Watch for overflows. */ if (len > CORE_ADDR_MAX || (start_addr + len - 1) < start_addr) error (_("Search space too large.")); search_space_len = len; } else { CORE_ADDR end_addr; v = parse_to_comma_and_eval (&s); end_addr = value_as_address (v); if (start_addr > end_addr) error (_("Invalid search space, end preceeds start.")); search_space_len = end_addr - start_addr + 1; /* We don't support searching all of memory (i.e. start=0, end = 0xff..ff). Bail to avoid overflows later on. */ if (search_space_len == 0) error (_("Overflow in address range computation, choose smaller range.")); } if (*s == ',') ++s; /* Fetch the search string. */ while (*s != '\0') { LONGEST x; int val_bytes; while (isspace (*s)) ++s; v = parse_to_comma_and_eval (&s); val_bytes = TYPE_LENGTH (value_type (v)); /* Keep it simple and assume size == 'g' when watching for when we need to grow the pattern buf. */ if ((pattern_buf_end - pattern_buf + max (val_bytes, sizeof (int64_t))) > pattern_buf_size) { size_t current_offset = pattern_buf_end - pattern_buf; pattern_buf_size *= 2; pattern_buf = xrealloc (pattern_buf, pattern_buf_size); pattern_buf_end = pattern_buf + current_offset; } if (size != '\0') { x = value_as_long (v); switch (size) { case 'b': *pattern_buf_end++ = x; break; case 'h': put_bits (x, pattern_buf_end, 16, big_p); pattern_buf_end += sizeof (int16_t); break; case 'w': put_bits (x, pattern_buf_end, 32, big_p); pattern_buf_end += sizeof (int32_t); break; case 'g': put_bits (x, pattern_buf_end, 64, big_p); pattern_buf_end += sizeof (int64_t); break; } } else { memcpy (pattern_buf_end, value_contents_raw (v), val_bytes); pattern_buf_end += val_bytes; } if (*s == ',') ++s; while (isspace (*s)) ++s; } if (pattern_buf_end == pattern_buf) error (_("Missing search pattern.")); pattern_len = pattern_buf_end - pattern_buf; if (search_space_len < pattern_len) error (_("Search space too small to contain pattern.")); *max_countp = max_count; *pattern_bufp = pattern_buf; *pattern_lenp = pattern_len; *start_addrp = start_addr; *search_space_lenp = search_space_len; /* We successfully parsed the arguments, leave the freeing of PATTERN_BUF to the caller now. */ discard_cleanups (old_cleanups); }
void pascal_type_print_varspec_prefix (struct type *type, struct ui_file *stream, int show, int passed_a_ptr) { char *name; if (type == 0) return; if (TYPE_NAME (type) && show <= 0) return; QUIT; switch (TYPE_CODE (type)) { case TYPE_CODE_PTR: fprintf_filtered (stream, "^"); pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); break; /* pointer should be handled normally in pascal */ case TYPE_CODE_MEMBER: if (passed_a_ptr) fprintf_filtered (stream, "("); pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); fprintf_filtered (stream, " "); name = type_name_no_tag (TYPE_DOMAIN_TYPE (type)); if (name) fputs_filtered (name, stream); else pascal_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); fprintf_filtered (stream, "::"); break; case TYPE_CODE_METHOD: if (passed_a_ptr) fprintf_filtered (stream, "("); if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) { fprintf_filtered (stream, "function "); } else { fprintf_filtered (stream, "procedure "); } if (passed_a_ptr) { fprintf_filtered (stream, " "); pascal_type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, passed_a_ptr); fprintf_filtered (stream, "::"); } break; case TYPE_CODE_REF: pascal_type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); fprintf_filtered (stream, "&"); break; case TYPE_CODE_FUNC: if (passed_a_ptr) fprintf_filtered (stream, "("); if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_VOID) { fprintf_filtered (stream, "function "); } else { fprintf_filtered (stream, "procedure "); } break; case TYPE_CODE_ARRAY: if (passed_a_ptr) fprintf_filtered (stream, "("); fprintf_filtered (stream, "array "); if (TYPE_LENGTH (type) >= 0 && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0 && TYPE_ARRAY_UPPER_BOUND_TYPE (type) != BOUND_CANNOT_BE_DETERMINED) fprintf_filtered (stream, "[%d..%d] ", TYPE_ARRAY_LOWER_BOUND_VALUE (type), TYPE_ARRAY_UPPER_BOUND_VALUE (type) ); fprintf_filtered (stream, "of "); break; case TYPE_CODE_UNDEF: case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: case TYPE_CODE_ENUM: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_CHAR: case TYPE_CODE_BOOL: case TYPE_CODE_SET: case TYPE_CODE_RANGE: case TYPE_CODE_STRING: case TYPE_CODE_BITSTRING: case TYPE_CODE_COMPLEX: case TYPE_CODE_TYPEDEF: case TYPE_CODE_TEMPLATE: /* These types need no prefix. They are listed here so that gcc -Wall will reveal any types that haven't been handled. */ break; default: error (_("type not handled in pascal_type_print_varspec_prefix()")); break; } }
static CORE_ADDR xstormy16_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); CORE_ADDR stack_dest = sp; int argreg = E_1ST_ARG_REGNUM; int i, j; int typelen, slacklen; const gdb_byte *val; gdb_byte buf[xstormy16_pc_size]; /* If struct_return is true, then the struct return address will consume one argument-passing register. */ if (struct_return) { regcache_cooked_write_unsigned (regcache, E_PTR_RET_REGNUM, struct_addr); argreg++; } /* Arguments are passed in R2-R7 as they fit. If an argument doesn't fit in the remaining registers we're switching over to the stack. No argument is put on stack partially and as soon as we switched over to stack no further argument is put in a register even if it would fit in the remaining unused registers. */ for (i = 0; i < nargs && argreg <= E_LST_ARG_REGNUM; i++) { typelen = TYPE_LENGTH (value_enclosing_type (args[i])); if (typelen > E_MAX_RETTYPE_SIZE (argreg)) break; /* Put argument into registers wordwise. */ val = value_contents (args[i]); for (j = 0; j < typelen; j += xstormy16_reg_size) { ULONGEST regval; int size = (typelen - j == 1) ? 1 : xstormy16_reg_size; regval = extract_unsigned_integer (val + j, size, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, regval); } } /* Align SP */ stack_dest = xstormy16_frame_align (gdbarch, stack_dest); /* Loop backwards through remaining arguments and push them on the stack, wordaligned. */ for (j = nargs - 1; j >= i; j--) { gdb_byte *val; struct cleanup *back_to; const gdb_byte *bytes = value_contents (args[j]); typelen = TYPE_LENGTH (value_enclosing_type (args[j])); slacklen = typelen & 1; val = xmalloc (typelen + slacklen); back_to = make_cleanup (xfree, val); memcpy (val, bytes, typelen); memset (val + typelen, 0, slacklen); /* Now write this data to the stack. The stack grows upwards. */ write_memory (stack_dest, val, typelen + slacklen); stack_dest += typelen + slacklen; do_cleanups (back_to); } store_unsigned_integer (buf, xstormy16_pc_size, byte_order, bp_addr); write_memory (stack_dest, buf, xstormy16_pc_size); stack_dest += xstormy16_pc_size; /* Update stack pointer. */ regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, stack_dest); /* Return the new stack pointer minus the return address slot since that's what DWARF2/GCC uses as the frame's CFA. */ return stack_dest - xstormy16_pc_size; }
static struct so_list * darwin_current_sos (void) { struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); int ptr_len = TYPE_LENGTH (ptr_type); unsigned int image_info_size; struct so_list *head = NULL; struct so_list *tail = NULL; int i; struct darwin_info *info = get_darwin_info (); /* Be sure image infos are loaded. */ darwin_load_image_infos (info); if (!darwin_dyld_version_ok (info)) return NULL; image_info_size = ptr_len * 3; /* Read infos for each solib. The first entry was rumored to be the executable itself, but this is not true when a large number of shared libraries are used (table expanded ?). We now check all entries, but discard executable images. */ for (i = 0; i < info->all_image.count; i++) { CORE_ADDR iinfo = info->all_image.info + i * image_info_size; gdb_byte buf[image_info_size]; CORE_ADDR load_addr; CORE_ADDR path_addr; struct mach_o_header_external hdr; unsigned long hdr_val; char *file_path; int errcode; struct darwin_so_list *dnew; struct so_list *newobj; struct cleanup *old_chain; /* Read image info from inferior. */ if (target_read_memory (iinfo, buf, image_info_size)) break; load_addr = extract_typed_address (buf, ptr_type); path_addr = extract_typed_address (buf + ptr_len, ptr_type); /* Read Mach-O header from memory. */ if (target_read_memory (load_addr, (gdb_byte *) &hdr, sizeof (hdr) - 4)) break; /* Discard wrong magic numbers. Shouldn't happen. */ hdr_val = extract_unsigned_integer (hdr.magic, sizeof (hdr.magic), byte_order); if (hdr_val != BFD_MACH_O_MH_MAGIC && hdr_val != BFD_MACH_O_MH_MAGIC_64) continue; /* Discard executable. Should happen only once. */ hdr_val = extract_unsigned_integer (hdr.filetype, sizeof (hdr.filetype), byte_order); if (hdr_val == BFD_MACH_O_MH_EXECUTE) continue; target_read_string (path_addr, &file_path, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (errcode) break; /* Create and fill the new so_list element. */ dnew = XCNEW (struct darwin_so_list); newobj = &dnew->sl; old_chain = make_cleanup (xfree, dnew); newobj->lm_info = &dnew->li; strncpy (newobj->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1); newobj->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; strcpy (newobj->so_original_name, newobj->so_name); xfree (file_path); newobj->lm_info->lm_addr = load_addr; if (head == NULL) head = newobj; else tail->next = newobj; tail = newobj; discard_cleanups (old_chain); } return head; }
static CORE_ADDR tilegx_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); CORE_ADDR stack_dest = sp; int argreg = TILEGX_R0_REGNUM; int i, j; int typelen, slacklen; static const gdb_byte four_zero_words[16] = { 0 }; /* If struct_return is 1, then the struct return address will consume one argument-passing register. */ if (struct_return) regcache_cooked_write_unsigned (regcache, argreg++, struct_addr); /* Arguments are passed in R0 - R9, and as soon as an argument will not fit completely in the remaining registers, then it, and all remaining arguments, are put on the stack. */ for (i = 0; i < nargs && argreg <= TILEGX_R9_REGNUM; i++) { const gdb_byte *val; typelen = TYPE_LENGTH (value_enclosing_type (args[i])); if (typelen > (TILEGX_R9_REGNUM - argreg + 1) * tilegx_reg_size) break; /* Put argument into registers wordwise. */ val = value_contents (args[i]); for (j = 0; j < typelen; j += tilegx_reg_size) { /* ISSUE: Why special handling for "typelen = 4x + 1"? I don't ever see "typelen" values except 4 and 8. */ int n = (typelen - j == 1) ? 1 : tilegx_reg_size; ULONGEST w = extract_unsigned_integer (val + j, n, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, w); } } /* Align SP. */ stack_dest = tilegx_frame_align (gdbarch, stack_dest); /* Loop backwards through remaining arguments and push them on the stack, word aligned. */ for (j = nargs - 1; j >= i; j--) { gdb_byte *val; struct cleanup *back_to; const gdb_byte *contents = value_contents (args[j]); typelen = TYPE_LENGTH (value_enclosing_type (args[j])); slacklen = align_up (typelen, 8) - typelen; val = (gdb_byte *) xmalloc (typelen + slacklen); back_to = make_cleanup (xfree, val); memcpy (val, contents, typelen); memset (val + typelen, 0, slacklen); /* Now write data to the stack. The stack grows downwards. */ stack_dest -= typelen + slacklen; write_memory (stack_dest, val, typelen + slacklen); do_cleanups (back_to); } /* Add 16 bytes for linkage space to the stack. */ stack_dest = stack_dest - 16; write_memory (stack_dest, four_zero_words, 16); /* Update stack pointer. */ regcache_cooked_write_unsigned (regcache, TILEGX_SP_REGNUM, stack_dest); /* Set the return address register to point to the entry point of the program, where a breakpoint lies in wait. */ regcache_cooked_write_unsigned (regcache, TILEGX_LR_REGNUM, bp_addr); return stack_dest; }
static struct type * gnuv3_rtti_type (struct value *value, int *full_p, int *top_p, int *using_enc_p) { struct gdbarch *gdbarch; struct type *values_type = check_typedef (value_type (value)); struct value *vtable; struct minimal_symbol *vtable_symbol; const char *vtable_symbol_name; const char *class_name; struct type *run_time_type; LONGEST offset_to_top; char *atsign; /* We only have RTTI for class objects. */ if (TYPE_CODE (values_type) != TYPE_CODE_CLASS) return NULL; /* Java doesn't have RTTI following the C++ ABI. */ if (TYPE_CPLUS_REALLY_JAVA (values_type)) return NULL; /* Determine architecture. */ gdbarch = get_type_arch (values_type); if (using_enc_p) *using_enc_p = 0; vtable = gnuv3_get_vtable (gdbarch, value_type (value), value_as_address (value_addr (value))); if (vtable == NULL) return NULL; /* Find the linker symbol for this vtable. */ vtable_symbol = lookup_minimal_symbol_by_pc (value_address (vtable) + value_embedded_offset (vtable)).minsym; if (! vtable_symbol) return NULL; /* The symbol's demangled name should be something like "vtable for CLASS", where CLASS is the name of the run-time type of VALUE. If we didn't like this approach, we could instead look in the type_info object itself to get the class name. But this way should work just as well, and doesn't read target memory. */ vtable_symbol_name = SYMBOL_DEMANGLED_NAME (vtable_symbol); if (vtable_symbol_name == NULL || strncmp (vtable_symbol_name, "vtable for ", 11)) { warning (_("can't find linker symbol for virtual table for `%s' value"), TYPE_SAFE_NAME (values_type)); if (vtable_symbol_name) warning (_(" found `%s' instead"), vtable_symbol_name); return NULL; } class_name = vtable_symbol_name + 11; /* Strip off @plt and version suffixes. */ atsign = strchr (class_name, '@'); if (atsign != NULL) { char *copy; copy = alloca (atsign - class_name + 1); memcpy (copy, class_name, atsign - class_name); copy[atsign - class_name] = '\0'; class_name = copy; } /* Try to look up the class name as a type name. */ /* FIXME: chastain/2003-11-26: block=NULL is bogus. See pr gdb/1465. */ run_time_type = cp_lookup_rtti_type (class_name, NULL); if (run_time_type == NULL) return NULL; /* Get the offset from VALUE to the top of the complete object. NOTE: this is the reverse of the meaning of *TOP_P. */ offset_to_top = value_as_long (value_field (vtable, vtable_field_offset_to_top)); if (full_p) *full_p = (- offset_to_top == value_embedded_offset (value) && (TYPE_LENGTH (value_enclosing_type (value)) >= TYPE_LENGTH (run_time_type))); if (top_p) *top_p = - offset_to_top; return run_time_type; }
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 pascal_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 */ unsigned len; LONGEST low_bound, high_bound; struct type *elttype; unsigned eltlen; int length_pos, length_size, string_pos; struct type *char_type; CORE_ADDR addr; int want_space = 0; type = check_typedef (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: if (get_array_bounds (type, &low_bound, &high_bound)) { len = high_bound - low_bound + 1; elttype = check_typedef (TYPE_TARGET_TYPE (type)); eltlen = TYPE_LENGTH (elttype); if (options->prettyformat_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* If 's' format is used, try to print out as string. If no format is given, print as string if element type is of TYPE_CODE_CHAR and element size is 1,2 or 4. */ if (options->format == 's' || ((eltlen == 1 || eltlen == 2 || eltlen == 4) && TYPE_CODE (elttype) == TYPE_CODE_CHAR && options->format == 0)) { /* If requested, look for the first null char and only print elements up to it. */ if (options->stop_print_at_null) { unsigned int temp_len; /* Look for a NULL char. */ for (temp_len = 0; extract_unsigned_integer (valaddr + embedded_offset + temp_len * eltlen, eltlen, byte_order) && temp_len < len && temp_len < options->print_max; temp_len++); len = temp_len; } LA_PRINT_STRING (stream, TYPE_TARGET_TYPE (type), valaddr + embedded_offset, len, NULL, 0, options); 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, recurse, original_value, options, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address + embedded_offset; goto print_unpacked_pointer; case TYPE_CODE_PTR: if (options->format && options->format != 's') { val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, options, 0, stream); break; } if (options->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. */ addr = extract_unsigned_integer (valaddr + embedded_offset, TYPE_LENGTH (type), byte_order); print_address_demangle (options, gdbarch, addr, stream, demangle); break; } 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 (options, gdbarch, addr, stream, demangle); return; } if (options->addressprint && options->format != 's') { fputs_filtered (paddress (gdbarch, addr), stream); want_space = 1; } /* 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)) || ((TYPE_LENGTH (elttype) == 2 || TYPE_LENGTH (elttype) == 4) && TYPE_CODE (elttype) == TYPE_CODE_CHAR)) && (options->format == 0 || options->format == 's') && addr != 0) { if (want_space) fputs_filtered (" ", stream); /* No wide string yet. */ i = val_print_string (elttype, NULL, addr, -1, stream, options); } /* 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_type, NULL) && addr != 0) { ULONGEST string_length; gdb_byte *buffer; if (want_space) fputs_filtered (" ", stream); buffer = (gdb_byte *) xmalloc (length_size); read_memory (addr + length_pos, buffer, length_size); string_length = extract_unsigned_integer (buffer, length_size, byte_order); xfree (buffer); i = val_print_string (char_type, NULL, addr + string_pos, string_length, stream, options); } else if (pascal_object_is_vtbl_member (type)) { /* Print vtbl's nicely. */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (vt_address); /* If 'symbol_print' is set, we did the work above. */ if (!options->symbol_print && (msymbol.minsym != NULL) && (vt_address == BMSYMBOL_VALUE_ADDRESS (msymbol))) { if (want_space) fputs_filtered (" ", stream); fputs_filtered ("<", stream); fputs_filtered (MSYMBOL_PRINT_NAME (msymbol.minsym), stream); fputs_filtered (">", stream); want_space = 1; } if (vt_address && options->vtblprint) { struct value *vt_val; struct symbol *wsym = NULL; struct type *wtype; struct block *block = NULL; struct field_of_this_result is_this_fld; if (want_space) fputs_filtered (" ", stream); if (msymbol.minsym != NULL) wsym = lookup_symbol (MSYMBOL_LINKAGE_NAME (msymbol.minsym), block, VAR_DOMAIN, &is_this_fld).symbol; 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, recurse + 1, options, current_language); if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } } } return; case TYPE_CODE_REF: case TYPE_CODE_ENUM: case TYPE_CODE_FLAGS: case TYPE_CODE_FUNC: case TYPE_CODE_RANGE: case TYPE_CODE_INT: case TYPE_CODE_FLT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_UNDEF: case TYPE_CODE_BOOL: case TYPE_CODE_CHAR: generic_val_print (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, &p_decorations); break; case TYPE_CODE_UNION: if (recurse && !options->unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: if (options->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 (options, gdbarch, extract_unsigned_integer (valaddr + embedded_offset + TYPE_FIELD_BITPOS (type, VTBL_FNADDR_OFFSET) / 8, TYPE_LENGTH (TYPE_FIELD_TYPE (type, VTBL_FNADDR_OFFSET)), byte_order), stream, demangle); } else { if (is_pascal_string_type (type, &length_pos, &length_size, &string_pos, &char_type, NULL)) { len = extract_unsigned_integer (valaddr + embedded_offset + length_pos, length_size, byte_order); LA_PRINT_STRING (stream, char_type, valaddr + embedded_offset + string_pos, len, NULL, 0, options); } else pascal_object_print_value_fields (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, NULL, 0); } break; case TYPE_CODE_SET: elttype = TYPE_INDEX_TYPE (type); elttype = check_typedef (elttype); if (TYPE_STUB (elttype)) { fprintf_filtered (stream, "<incomplete type>"); gdb_flush (stream); break; } else { struct type *range = elttype; LONGEST low_bound, high_bound; int i; int need_comma = 0; fputs_filtered ("[", stream); i = get_discrete_bounds (range, &low_bound, &high_bound); if (low_bound == 0 && high_bound == -1 && TYPE_LENGTH (type) > 0) { /* If we know the size of the set type, we can figure out the maximum value. */ i = 0; high_bound = TYPE_LENGTH (type) * TARGET_CHAR_BIT - 1; TYPE_HIGH_BOUND (range) = high_bound; } maybe_bad_bstring: if (i < 0) { fputs_filtered ("<error value>", stream); goto done; } for (i = low_bound; i <= high_bound; i++) { int element = value_bit_index (type, valaddr + embedded_offset, i); if (element < 0) { i = element; goto maybe_bad_bstring; } if (element) { if (need_comma) fputs_filtered (", ", stream); print_type_scalar (range, i, stream); need_comma = 1; if (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) { int j = i; fputs_filtered ("..", stream); while (i + 1 <= high_bound && value_bit_index (type, valaddr + embedded_offset, ++i)) j = i; print_type_scalar (range, j, stream); } } } done: fputs_filtered ("]", stream); } break; default: error (_("Invalid pascal type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); }
/* The 64 bit ABI retun value convention. Return non-zero if the return-value is stored in a register, return 0 if the return-value is instead stored on the stack (a.k.a., struct return convention). For a return-value stored in a register: when WRITEBUF is non-NULL, copy the buffer to the corresponding register return-value location location; when READBUF is non-NULL, fill the buffer from the corresponding register return-value location. */ enum return_value_convention ppc64_sysv_abi_return_value (struct gdbarch *gdbarch, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* This function exists to support a calling convention that requires floating-point registers. It shouldn't be used on processors that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* Floats and doubles in F1. */ if (TYPE_CODE (valtype) == TYPE_CODE_FLT && TYPE_LENGTH (valtype) <= 8) { gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); if (writebuf != NULL) { convert_typed_floating (writebuf, valtype, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval); } if (readbuf != NULL) { regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval); convert_typed_floating (regval, regtype, readbuf, valtype); } return RETURN_VALUE_REGISTER_CONVENTION; } if ((TYPE_CODE (valtype) == TYPE_CODE_INT || TYPE_CODE (valtype) == TYPE_CODE_ENUM) && TYPE_LENGTH (valtype) <= 8) { /* Integers in r3. */ if (writebuf != NULL) { /* Be careful to sign extend the value. */ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, unpack_long (valtype, writebuf)); } if (readbuf != NULL) { /* Extract the integer from r3. Since this is truncating the value, there isn't a sign extension problem. */ ULONGEST regval; regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, ®val); store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), regval); } return RETURN_VALUE_REGISTER_CONVENTION; } /* All pointers live in r3. */ if (TYPE_CODE (valtype) == TYPE_CODE_PTR) { /* All pointers live in r3. */ if (writebuf != NULL) regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf); if (readbuf != NULL) regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf); return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_LENGTH (valtype) <= 8 && TYPE_CODE (TYPE_TARGET_TYPE (valtype)) == TYPE_CODE_INT && TYPE_LENGTH (TYPE_TARGET_TYPE (valtype)) == 1) { /* Small character arrays are returned, right justified, in r3. */ int offset = (register_size (gdbarch, tdep->ppc_gp0_regnum + 3) - TYPE_LENGTH (valtype)); if (writebuf != NULL) regcache_cooked_write_part (regcache, tdep->ppc_gp0_regnum + 3, offset, TYPE_LENGTH (valtype), writebuf); if (readbuf != NULL) regcache_cooked_read_part (regcache, tdep->ppc_gp0_regnum + 3, offset, TYPE_LENGTH (valtype), readbuf); return RETURN_VALUE_REGISTER_CONVENTION; } /* Big floating point values get stored in adjacent floating point registers. */ if (TYPE_CODE (valtype) == TYPE_CODE_FLT && (TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 32)) { if (writebuf || readbuf != NULL) { int i; for (i = 0; i < TYPE_LENGTH (valtype) / 8; i++) { if (writebuf != NULL) regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + i, (const bfd_byte *) writebuf + i * 8); if (readbuf != NULL) regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1 + i, (bfd_byte *) readbuf + i * 8); } } return RETURN_VALUE_REGISTER_CONVENTION; } /* Complex values get returned in f1:f2, need to convert. */ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX && (TYPE_LENGTH (valtype) == 8 || TYPE_LENGTH (valtype) == 16)) { if (regcache != NULL) { int i; for (i = 0; i < 2; i++) { gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (current_gdbarch, tdep->ppc_fp0_regnum); if (writebuf != NULL) { convert_typed_floating ((const bfd_byte *) writebuf + i * (TYPE_LENGTH (valtype) / 2), valtype, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + i, regval); } if (readbuf != NULL) { regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1 + i, regval); convert_typed_floating (regval, regtype, (bfd_byte *) readbuf + i * (TYPE_LENGTH (valtype) / 2), valtype); } } } return RETURN_VALUE_REGISTER_CONVENTION; } /* Big complex values get stored in f1:f4. */ if (TYPE_CODE (valtype) == TYPE_CODE_COMPLEX && TYPE_LENGTH (valtype) == 32) { if (regcache != NULL) { int i; for (i = 0; i < 4; i++) { if (writebuf != NULL) regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + i, (const bfd_byte *) writebuf + i * 8); if (readbuf != NULL) regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1 + i, (bfd_byte *) readbuf + i * 8); } } return RETURN_VALUE_REGISTER_CONVENTION; } return RETURN_VALUE_STRUCT_CONVENTION; }
void c_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. */ unsigned len; struct type *elttype, *unresolved_elttype; struct type *unresolved_type = type; unsigned eltlen; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: unresolved_elttype = TYPE_TARGET_TYPE (type); elttype = check_typedef (unresolved_elttype); if (TYPE_LENGTH (type) > 0 && TYPE_LENGTH (unresolved_elttype) > 0) { LONGEST low_bound, high_bound; if (!get_array_bounds (type, &low_bound, &high_bound)) error (_("Could not determine the array high bound")); eltlen = TYPE_LENGTH (elttype); len = high_bound - low_bound + 1; if (options->prettyformat_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* Print arrays of textual chars with a string syntax, as long as the entire array is valid. */ if (c_textual_element_type (unresolved_elttype, options->format) && value_bytes_available (original_value, embedded_offset, TYPE_LENGTH (type)) && value_bits_valid (original_value, TARGET_CHAR_BIT * embedded_offset, TARGET_CHAR_BIT * TYPE_LENGTH (type))) { int force_ellipses = 0; /* If requested, look for the first null char and only print elements up to it. */ if (options->stop_print_at_null) { unsigned int temp_len; for (temp_len = 0; (temp_len < len && temp_len < options->print_max && extract_unsigned_integer (valaddr + embedded_offset + temp_len * eltlen, eltlen, byte_order) != 0); ++temp_len) ; /* Force LA_PRINT_STRING to print ellipses if we've printed the maximum characters and the next character is not \000. */ if (temp_len == options->print_max && temp_len < len) { ULONGEST val = extract_unsigned_integer (valaddr + embedded_offset + temp_len * eltlen, eltlen, byte_order); if (val != 0) force_ellipses = 1; } len = temp_len; } LA_PRINT_STRING (stream, unresolved_elttype, valaddr + embedded_offset, len, NULL, force_ellipses, options); 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, recurse, original_value, options, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address + embedded_offset; goto print_unpacked_pointer; case TYPE_CODE_METHODPTR: cplus_print_method_ptr (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, options, 0, stream); break; } if (options->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 (options, gdbarch, addr, stream); break; } unresolved_elttype = TYPE_TARGET_TYPE (type); elttype = check_typedef (unresolved_elttype); { int want_space; addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: want_space = 0; if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_function_pointer_address (options, gdbarch, addr, stream); return; } if (options->symbol_print) want_space = print_address_demangle (options, gdbarch, addr, stream, demangle); else if (options->addressprint) { fputs_filtered (paddress (gdbarch, addr), stream); want_space = 1; } /* For a pointer to a textual type, also print the string pointed to, unless pointer is null. */ if (c_textual_element_type (unresolved_elttype, options->format) && addr != 0) { if (want_space) fputs_filtered (" ", stream); i = val_print_string (unresolved_elttype, NULL, addr, -1, stream, options); } else if (cp_is_vtbl_member (type)) { /* Print vtbl's nicely. */ CORE_ADDR vt_address = unpack_pointer (type, valaddr + embedded_offset); struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (vt_address); /* If 'symbol_print' is set, we did the work above. */ if (!options->symbol_print && (msymbol.minsym != NULL) && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol.minsym))) { if (want_space) fputs_filtered (" ", stream); fputs_filtered (" <", stream); fputs_filtered (SYMBOL_PRINT_NAME (msymbol.minsym), stream); fputs_filtered (">", stream); want_space = 1; } if (vt_address && options->vtblprint) { struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; struct block *block = (struct block *) NULL; struct field_of_this_result is_this_fld; if (want_space) fputs_filtered (" ", stream); if (msymbol.minsym != NULL) wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol.minsym), block, VAR_DOMAIN, &is_this_fld); if (wsym) { wtype = SYMBOL_TYPE (wsym); } else { wtype = unresolved_elttype; } vt_val = value_at (wtype, vt_address); common_val_print (vt_val, stream, recurse + 1, options, current_language); if (options->prettyformat) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } } } return; } break; case TYPE_CODE_UNION: if (recurse && !options->unionprint) { fprintf_filtered (stream, "{...}"); break; } /* Fall through. */ case TYPE_CODE_STRUCT: /*FIXME: Abstract this away. */ if (options->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 (options, gdbarch, addr, stream); } else cp_print_value_fields_rtti (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, NULL, 0); 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); val_print_scalar_formatted (type, valaddr, embedded_offset, original_value, &opts, 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 (c_textual_element_type (unresolved_type, options->format)) { fputs_filtered (" ", stream); LA_PRINT_CHAR (unpack_long (type, valaddr + embedded_offset), unresolved_type, stream); } } break; case TYPE_CODE_MEMBERPTR: if (!options->format) { cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); break; } /* FALLTHROUGH */ case TYPE_CODE_REF: case TYPE_CODE_ENUM: case TYPE_CODE_FLAGS: case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: case TYPE_CODE_BOOL: case TYPE_CODE_RANGE: case TYPE_CODE_FLT: case TYPE_CODE_DECFLOAT: case TYPE_CODE_VOID: case TYPE_CODE_ERROR: case TYPE_CODE_UNDEF: case TYPE_CODE_COMPLEX: case TYPE_CODE_CHAR: default: generic_val_print (type, valaddr, embedded_offset, address, stream, recurse, original_value, options, &c_decorations); break; } gdb_flush (stream); }
static void ppc_push_argument (struct ppc_stack_abi *abi, struct ppc_stack_context *c, struct value *arg, int argno, int do_copy, int floatonly) { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); struct type *type = check_typedef (value_type (arg)); int len = TYPE_LENGTH (type); gdb_byte buf[16]; c->argoffset = ROUND_UP (c->argoffset, 4); switch (TYPE_CODE (type)) { case TYPE_CODE_FLT: { if (c->freg <= abi->last_freg) { struct value *rval; struct type *rtype; int rlen; /* APPLE LOCAL: If the thing is already a long double type, don't cast it to a builtin type double, since there are two long double types, and we will pass an 16 byte long double wrong if we assume it is an 8 byte double. */ if (strcmp (TYPE_NAME (type), "long double") != 0) { rval = value_cast (builtin_type_double, arg); rtype = check_typedef (value_type (rval)); rlen = TYPE_LENGTH (rtype); } else { rval = arg; rtype = type; rlen = len; } /* APPLE LOCAL: GCC 4.0 has 16 byte long doubles */ if ((len != 4) && (len != 8) && (len != 16)) error ("floating point parameter had unexpected size"); if (rlen != 8 && rlen != 16) error ("floating point parameter had unexpected size"); if (do_copy) regcache_raw_write (current_regcache, FP0_REGNUM + c->freg, value_contents (rval)); if (do_copy && ! floatonly && abi->fregs_shadow_gregs) ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, len, value_contents (arg)); if (do_copy && ! floatonly && abi->regs_shadow_stack) write_memory (c->sp + c->argoffset, value_contents (arg), len); c->freg++; /* APPLE LOCAL: We took up two registers... */ if (rlen == 16) c->freg++; if (! floatonly && (abi->fregs_shadow_gregs) && (c->greg <= abi->last_greg)) c->greg += len / 4; if (! floatonly && abi->regs_shadow_stack) c->argoffset += len; } else if (! floatonly) { if ((len != 4) && (len != 8) && (len != 16)) error ("floating point parameter had unexpected size"); c->argoffset = ROUND_UP (c->argoffset, len); if (do_copy) write_memory (c->sp + c->argoffset, value_contents (arg), len); c->argoffset += len; } break; } case TYPE_CODE_INT: case TYPE_CODE_ENUM: case TYPE_CODE_PTR: case TYPE_CODE_REF: { int nregs; gdb_byte *val_contents; if (floatonly) break; /* APPLE LOCAL: Huge Hack... The problem is that if we are a 32 bit app on Mac OS X, the registers are really 64 bits, but we don't want to pass all 64 bits. So if we get passed a value that came from a register, and it's length is > the wordsize, cast it to the wordsize first before passing it in. */ if (VALUE_REGNUM (arg) != -1 && len == 8 && tdep->wordsize == 4) { len = 4; val_contents = value_contents (arg) + 4; } else val_contents = value_contents (arg); /* END APPLE LOCAL */ nregs = (len <= 4) ? 1 : 2; if ((len != 1) && (len != 2) && (len != 4) && (len != 8)) error ("integer parameter had unexpected size"); if (c->greg <= abi->last_greg) { /* If the parameter fits in the remaining argument registers, write it to the registers, and to the stack if the abi requires it. */ if (do_copy) { /* Split the argument between registers & the stack if it doesn't fit in the remaining registers. */ int regs_avaliable = abi->last_greg - c->greg + 1; if (regs_avaliable >= nregs) regs_avaliable = nregs; ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, regs_avaliable * 4, val_contents); } if (do_copy && abi->regs_shadow_stack) write_memory (c->sp + c->argoffset, val_contents, len); c->greg += nregs; if (abi->regs_shadow_stack) c->argoffset += (nregs * 4); } else { /* If we've filled up the registers, then just write it on the stack. */ if (do_copy) write_memory (c->sp + c->argoffset, val_contents, len); c->argoffset += (nregs * 4); } break; } case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: { if (! abi->structs_with_args) { if (floatonly) break; if (len > 4) { /* Rounding to the nearest multiple of 8 may not be necessary, but it is safe. Particularly since we don't know the field types of the structure */ c->structoffset = ROUND_UP (c->structoffset, 8); if (do_copy) { write_memory (c->sp + c->structoffset, value_contents (arg), len); store_unsigned_integer (buf, 4, c->sp + c->structoffset); } c->structoffset += ROUND_UP (len, 8); } else if (do_copy) { memset (buf, 0, 4); memcpy (buf, value_contents (arg), len); } if (c->greg <= abi->last_greg) { if (do_copy) ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, 4, buf); c->greg++; } else { if (do_copy) write_memory (c->sp + c->argoffset, buf, 4); c->argoffset += 4; } break; } else { int i; int regspace = (abi->last_greg - c->greg + 1) * 4; int stackspace = (len <= regspace) ? 0 : (len - regspace); int writereg = (regspace > len) ? len : regspace; int writestack = abi->regs_shadow_stack ? len : stackspace; for (i = 0; i < TYPE_NFIELDS (type); i++) { struct value *subarg = value_field (arg, i); ppc_push_argument (abi, c, subarg, argno, do_copy, 1); } if (floatonly) break; if (do_copy) { gdb_byte *ptr = value_contents (arg); if (len < 4) { memset (buf, 0, 4); if ((len == 1) || (len == 2)) memcpy (buf + 4 - len, ptr, len); else memcpy (buf, ptr, len); ptr = buf; } ppc_copy_into_greg (current_regcache, c->greg, tdep->wordsize, (writereg < 4) ? 4 : writereg, ptr); write_memory (c->sp + c->argoffset, ptr, (writestack < 4) ? 4 : writestack); } c->greg += ROUND_UP (writereg, 4) / 4; c->argoffset += writestack; } break; } case TYPE_CODE_ARRAY: { if (floatonly) break; if (! TYPE_VECTOR (type)) error ("non-vector array type"); if (len != 16) error ("unexpected vector length"); if (c->vreg <= abi->last_vreg) { if (do_copy) regcache_raw_write (current_regcache, tdep->ppc_vr0_regnum + c->vreg, value_contents (arg)); c->vreg++; } else { /* Vector arguments must be aligned to 16 bytes on the stack. */ c->argoffset = ROUND_UP (c->argoffset, 16); if (do_copy) write_memory (c->sp + c->argoffset, value_contents (arg), len); c->argoffset += len; } break; } default: error ("argument %d has unknown type code 0x%x (%s)", argno, TYPE_CODE (type), type_code_name (TYPE_CODE (type))); } return; }
int f_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) { unsigned int i = 0; /* Number of characters printed */ struct type *elttype; LONGEST val; CORE_ADDR addr; CHECK_TYPEDEF (type); switch (TYPE_CODE (type)) { case TYPE_CODE_STRING: f77_get_dynamic_length_of_aggregate (type); LA_PRINT_STRING (stream, valaddr, TYPE_LENGTH (type), 1, 0); break; case TYPE_CODE_ARRAY: fprintf_filtered (stream, "("); f77_print_array (type, valaddr, address, stream, format, deref_ref, recurse, pretty); fprintf_filtered (stream, ")"); break; case TYPE_CODE_PTR: if (format && format != 's') { print_scalar_formatted (valaddr, type, format, 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 (addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return 0; } if (addressprint && format != 's') print_address_numeric (addr, 1, 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 && (format == 0 || format == 's') && addr != 0) i = val_print_string (addr, -1, TYPE_LENGTH (elttype), 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) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); 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), NULL); val_print (VALUE_TYPE (deref_val), VALUE_CONTENTS (deref_val), 0, VALUE_ADDRESS (deref_val), stream, format, deref_ref, recurse, pretty); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_FUNC: if (format) { print_scalar_formatted (valaddr, 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_INT: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr, type, format, 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), stream); } } break; case TYPE_CODE_FLT: if (format) print_scalar_formatted (valaddr, type, format, 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, "<error 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: format = format ? format : output_format; if (format) print_scalar_formatted (valaddr, type, format, 0, stream); else { val = 0; switch (TYPE_LENGTH (type)) { case 1: val = unpack_long (builtin_type_f_logical_s1, valaddr); break; case 2: val = unpack_long (builtin_type_f_logical_s2, valaddr); break; case 4: val = unpack_long (builtin_type_f_logical, valaddr); break; default: error ("Logicals of length %d bytes not supported", TYPE_LENGTH (type)); } 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; f_val_print (type, valaddr, 0, address, stream, format, deref_ref, recurse, pretty); /* Restore the type code so later uses work as intended. */ TYPE_CODE (type) = TYPE_CODE_BOOL; } } break; case TYPE_CODE_COMPLEX: switch (TYPE_LENGTH (type)) { case 8: type = builtin_type_f_real; break; case 16: type = builtin_type_f_real_s8; break; case 32: type = builtin_type_f_real_s16; break; default: error ("Cannot print out complex*%d variables", TYPE_LENGTH (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; default: error ("Invalid F77 type code %d in symbol table.", TYPE_CODE (type)); } gdb_flush (stream); return 0; }
static enum return_value_convention do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, /* APPLE LOCAL gdb_byte */ struct regcache *regcache, gdb_byte *readbuf, /* APPLE LOCAL gdb_byte */ const gdb_byte *writebuf, int broken_gcc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); gdb_assert (tdep->wordsize == 4); if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8 && ppc_floating_point_unit_p (gdbarch)) { if (readbuf) { /* Floats and doubles stored in "f1". Convert the value to the required type. */ gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum + 1); regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval); convert_typed_floating (regval, regtype, readbuf, type); } if (writebuf) { /* Floats and doubles stored in "f1". Convert the value to the register's "double" type. */ gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); convert_typed_floating (writebuf, type, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval); } return RETURN_VALUE_REGISTER_CONVENTION; } /* APPLE LOCAL: gcc 3.3 had 8 byte long doubles, but gcc 4.0 uses 16 byte long doubles even for 32 bit ppc. They are stored across f1 & f2. */ /* Big floating point values get stored in adjacent floating point registers. */ if (TYPE_CODE (type) == TYPE_CODE_FLT && (TYPE_LENGTH (type) == 16 || TYPE_LENGTH (type) == 32)) { if (writebuf || readbuf != NULL) { int i; for (i = 0; i < TYPE_LENGTH (type) / 8; i++) { if (writebuf != NULL) regcache_cooked_write (regcache, FP0_REGNUM + 1 + i, (const bfd_byte *) writebuf + i * 8); if (readbuf != NULL) regcache_cooked_read (regcache, FP0_REGNUM + 1 + i, (bfd_byte *) readbuf + i * 8); } } return RETURN_VALUE_REGISTER_CONVENTION; } /* END APPLE LOCAL */ if ((TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 8) || (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)) { if (readbuf) { /* A long long, or a double stored in the 32 bit r3/r4. */ ppc_copy_from_greg (regcache, tdep->ppc_gp0_regnum + 3, tdep->wordsize, 8, (bfd_byte *) readbuf); } if (writebuf) { /* A long long, or a double stored in the 32 bit r3/r4. */ ppc_copy_into_greg (regcache, tdep->ppc_gp0_regnum + 3, tdep->wordsize, 8, writebuf); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) <= tdep->wordsize) { if (readbuf) { /* Some sort of integer stored in r3. Since TYPE isn't bigger than the register, sign extension isn't a problem - just do everything unsigned. */ ULONGEST regval; regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, ®val); store_unsigned_integer (readbuf, TYPE_LENGTH (type), regval); } if (writebuf) { /* Some sort of integer stored in r3. Use unpack_long since that should handle any required sign extension. */ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, unpack_long (type, writebuf)); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) == 16 && TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && tdep->ppc_vr0_regnum >= 0) { if (readbuf) { /* Altivec places the return value in "v2". */ regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf); } if (writebuf) { /* Altivec places the return value in "v2". */ regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + 2, writebuf); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) == 8 && TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && tdep->ppc_ev0_regnum >= 0) { /* The e500 ABI places return values for the 64-bit DSP types (__ev64_opaque__) in r3. However, in GDB-speak, ev3 corresponds to the entire r3 value for e500, whereas GDB's r3 only corresponds to the least significant 32-bits. So place the 64-bit DSP type's value in ev3. */ if (readbuf) regcache_cooked_read (regcache, tdep->ppc_ev0_regnum + 3, readbuf); if (writebuf) regcache_cooked_write (regcache, tdep->ppc_ev0_regnum + 3, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } if (broken_gcc && TYPE_LENGTH (type) <= 8) { if (readbuf) { /* GCC screwed up. The last register isn't "left" aligned. Need to extract the least significant part of each register and then store that. */ /* Transfer any full words. */ int word = 0; while (1) { ULONGEST reg; int len = TYPE_LENGTH (type) - word * tdep->wordsize; if (len <= 0) break; if (len > tdep->wordsize) len = tdep->wordsize; regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3 + word, ®); store_unsigned_integer (((bfd_byte *) readbuf + word * tdep->wordsize), len, reg); word++; } } if (writebuf) { /* GCC screwed up. The last register isn't "left" aligned. Need to extract the least significant part of each register and then store that. */ /* Transfer any full words. */ int word = 0; while (1) { ULONGEST reg; int len = TYPE_LENGTH (type) - word * tdep->wordsize; if (len <= 0) break; if (len > tdep->wordsize) len = tdep->wordsize; reg = extract_unsigned_integer (((const bfd_byte *) writebuf + word * tdep->wordsize), len); regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3 + word, reg); word++; } } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) <= 8) { if (readbuf) { /* This matches SVr4 PPC, it does not match GCC. */ /* The value is right-padded to 8 bytes and then loaded, as two "words", into r3/r4. */ ppc_copy_from_greg (regcache, tdep->ppc_gp0_regnum + 3, tdep->wordsize, TYPE_LENGTH (type), readbuf); } if (writebuf) { /* This matches SVr4 PPC, it does not match GCC. */ /* The value is padded out to 8 bytes and then loaded, as two "words" into r3/r4. */ gdb_byte regvals[MAX_REGISTER_SIZE * 2]; memset (regvals, 0, sizeof regvals); memcpy (regvals, writebuf, TYPE_LENGTH (type)); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (TYPE_LENGTH (type) > tdep->wordsize) regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, regvals + 1 * tdep->wordsize); } return RETURN_VALUE_REGISTER_CONVENTION; } return RETURN_VALUE_STRUCT_CONVENTION; }
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 * REGISTER_SIZE; /* Some arguments go into A1-A4. */ if (struct_return) /* The struct address goes in A1. */ nstack_size += 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) && 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 && REGISTER_SIZE == len) { DOUBLEST dblval; dblval = extract_floating (val, len); len = TARGET_DOUBLE_BIT / TARGET_CHAR_BIT; val = alloca (len); 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_address (val, len); if (arm_pc_is_thumb (regval)) store_address (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 < REGISTER_SIZE ? len : REGISTER_SIZE; if (argreg <= ARM_LAST_ARG_REGNUM) { /* It's an argument being passed in a general register. */ regval = extract_address (val, partial_len); write_register (argreg++, regval); } else { /* Push the arguments onto the stack. */ write_memory ((CORE_ADDR) fp, val, REGISTER_SIZE); fp += REGISTER_SIZE; } len -= partial_len; val += partial_len; } } /* Return adjusted stack pointer. */ return sp; }
CORE_ADDR ppc64_sysv_abi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { CORE_ADDR func_addr = find_function_addr (function, NULL); struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); /* By this stage in the proceedings, SP has been decremented by "red zone size" + "struct return size". Fetch the stack-pointer from before this and use that as the BACK_CHAIN. */ const CORE_ADDR back_chain = read_sp (); /* See for-loop comment below. */ int write_pass; /* Size of the Altivec's vector parameter region, the final value is computed in the for-loop below. */ LONGEST vparam_size = 0; /* Size of the general parameter region, the final value is computed in the for-loop below. */ LONGEST gparam_size = 0; /* Kevin writes ... I don't mind seeing tdep->wordsize used in the calls to align_up(), align_down(), etc. because this makes it easier to reuse this code (in a copy/paste sense) in the future, but it is a 64-bit ABI and asserting that the wordsize is 8 bytes at some point makes it easier to verify that this function is correct without having to do a non-local analysis to figure out the possible values of tdep->wordsize. */ gdb_assert (tdep->wordsize == 8); /* Go through the argument list twice. Pass 1: Compute the function call's stack space and register requirements. Pass 2: Replay the same computation but this time also write the values out to the target. */ for (write_pass = 0; write_pass < 2; write_pass++) { int argno; /* Next available floating point register for float and double arguments. */ int freg = 1; /* Next available general register for non-vector (but possibly float) arguments. */ int greg = 3; /* Next available vector register for vector arguments. */ int vreg = 2; /* The address, at which the next general purpose parameter (integer, struct, float, ...) should be saved. */ CORE_ADDR gparam; /* Address, at which the next Altivec vector parameter should be saved. */ CORE_ADDR vparam; if (!write_pass) { /* During the first pass, GPARAM and VPARAM are more like offsets (start address zero) than addresses. That way the accumulate the total stack space each region requires. */ gparam = 0; vparam = 0; } else { /* Decrement the stack pointer making space for the Altivec and general on-stack parameters. Set vparam and gparam to their corresponding regions. */ vparam = align_down (sp - vparam_size, 16); gparam = align_down (vparam - gparam_size, 16); /* Add in space for the TOC, link editor double word, compiler double word, LR save area, CR save area. */ sp = align_down (gparam - 48, 16); } /* If the function is returning a `struct', then there is an extra hidden parameter (which will be passed in r3) containing the address of that struct.. In that case we should advance one word and start from r4 register to copy parameters. This also consumes one on-stack parameter slot. */ if (struct_return) { if (write_pass) regcache_cooked_write_signed (regcache, tdep->ppc_gp0_regnum + greg, struct_addr); greg++; gparam = align_up (gparam + tdep->wordsize, tdep->wordsize); } for (argno = 0; argno < nargs; argno++) { struct value *arg = args[argno]; struct type *type = check_typedef (value_type (arg)); const bfd_byte *val = value_contents (arg); if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8) { /* Floats and Doubles go in f1 .. f13. They also consume a left aligned GREG,, and can end up in memory. */ if (write_pass) { if (ppc_floating_point_unit_p (current_gdbarch) && freg <= 13) { gdb_byte regval[MAX_REGISTER_SIZE]; struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); convert_typed_floating (val, type, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, regval); } if (greg <= 10) { /* The ABI states "Single precision floating point values are mapped to the first word in a single doubleword" and "... floating point values mapped to the first eight doublewords of the parameter save area are also passed in general registers"). This code interprets that to mean: store it, left aligned, in the general register. */ gdb_byte regval[MAX_REGISTER_SIZE]; memset (regval, 0, sizeof regval); memcpy (regval, val, TYPE_LENGTH (type)); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); } write_memory (gparam, val, TYPE_LENGTH (type)); } /* Always consume parameter stack space. */ freg++; greg++; gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } else if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type) && TYPE_CODE (type) == TYPE_CODE_ARRAY && tdep->ppc_vr0_regnum >= 0) { /* In the Altivec ABI, vectors go in the vector registers v2 .. v13, or when that runs out, a vector annex which goes above all the normal parameters. NOTE: cagney/2003-09-21: This is a guess based on the PowerOpen Altivec ABI. */ if (vreg <= 13) { if (write_pass) regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + vreg, val); vreg++; } else { if (write_pass) write_memory (vparam, val, TYPE_LENGTH (type)); vparam = align_up (vparam + TYPE_LENGTH (type), 16); } } else if ((TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_ENUM || TYPE_CODE (type) == TYPE_CODE_PTR) && TYPE_LENGTH (type) <= 8) { /* Scalars and Pointers get sign[un]extended and go in gpr3 .. gpr10. They can also end up in memory. */ if (write_pass) { /* Sign extend the value, then store it unsigned. */ ULONGEST word = unpack_long (type, val); /* Convert any function code addresses into descriptors. */ if (TYPE_CODE (type) == TYPE_CODE_PTR && TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC) { CORE_ADDR desc = word; convert_code_addr_to_desc_addr (word, &desc); word = desc; } if (greg <= 10) regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + greg, word); write_memory_unsigned_integer (gparam, tdep->wordsize, word); } greg++; gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } else { int byte; for (byte = 0; byte < TYPE_LENGTH (type); byte += tdep->wordsize) { if (write_pass && greg <= 10) { gdb_byte regval[MAX_REGISTER_SIZE]; int len = TYPE_LENGTH (type) - byte; if (len > tdep->wordsize) len = tdep->wordsize; memset (regval, 0, sizeof regval); /* WARNING: cagney/2003-09-21: As best I can tell, the ABI specifies that the value should be left aligned. Unfortunately, GCC doesn't do this - it instead right aligns even sized values and puts odd sized values on the stack. Work around that by putting both a left and right aligned value into the register (hopefully no one notices :-^). Arrrgh! */ /* Left aligned (8 byte values such as pointers fill the buffer). */ memcpy (regval, val + byte, len); /* Right aligned (but only if even). */ if (len == 1 || len == 2 || len == 4) memcpy (regval + tdep->wordsize - len, val + byte, len); regcache_cooked_write (regcache, greg, regval); } greg++; } if (write_pass) /* WARNING: cagney/2003-09-21: Strictly speaking, this isn't necessary, unfortunately, GCC appears to get "struct convention" parameter passing wrong putting odd sized structures in memory instead of in a register. Work around this by always writing the value to memory. Fortunately, doing this simplifies the code. */ write_memory (gparam, val, TYPE_LENGTH (type)); if (write_pass) /* WARNING: cagney/2004-06-20: It appears that GCC likes to put structures containing a single floating-point member in an FP register instead of general general purpose. */ /* Always consume parameter stack space. */ gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } } if (!write_pass) { /* Save the true region sizes ready for the second pass. */ vparam_size = vparam; /* Make certain that the general parameter save area is at least the minimum 8 registers (or doublewords) in size. */ if (greg < 8) gparam_size = 8 * tdep->wordsize; else gparam_size = gparam; } } /* Update %sp. */ regcache_cooked_write_signed (regcache, SP_REGNUM, sp); /* Write the backchain (it occupies WORDSIZED bytes). */ write_memory_signed_integer (sp, tdep->wordsize, back_chain); /* Point the inferior function call's return address at the dummy's breakpoint. */ regcache_cooked_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); /* Use the func_addr to find the descriptor, and use that to find the TOC. */ { CORE_ADDR desc_addr; if (convert_code_addr_to_desc_addr (func_addr, &desc_addr)) { /* The TOC is the second double word in the descriptor. */ CORE_ADDR toc = read_memory_unsigned_integer (desc_addr + tdep->wordsize, tdep->wordsize); regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 2, toc); } } return sp; }
int 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_print_options *options) { struct gdbarch *gdbarch = get_type_arch (type); 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 (options->format && options->format != 's') { print_scalar_formatted (valaddr, type, options, 0, stream); break; } #if 0 if (options->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.) */ /* Extract an address, assume that it is unsigned. */ print_address_demangle (gdbarch, extract_unsigned_integer (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 (gdbarch, addr, stream, demangle); /* Return value is irrelevant except for string pointers. */ return (0); } if (options->addressprint && options->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. */ 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 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), type, stream); else val_print_type_code_int (type, valaddr, stream); break; case TYPE_CODE_STRUCT: java_print_value_fields (type, valaddr, address, stream, recurse, options); break; default: return c_val_print (type, valaddr, embedded_offset, address, stream, recurse, options); } return 0; }
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); }