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 (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST back_chain; /* 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); /* 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)); /* 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. */ regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &back_chain); /* 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 they 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) { gdb_byte regval[MAX_REGISTER_SIZE]; const gdb_byte *p; /* Version 1.7 of the 64-bit PowerPC ELF ABI says: "Single precision floating point values are mapped to the first word in a single doubleword." And version 1.9 says: "Single precision floating point values are mapped to the second word in a single doubleword." GDB then writes single precision floating point values at both words in a doubleword, to support both ABIs. */ if (TYPE_LENGTH (type) == 4) { memcpy (regval, val, 4); memcpy (regval + 4, val, 4); p = regval; } else p = val; /* Write value in the stack's parameter save area. */ write_memory (gparam, p, 8); if (freg <= 13) { 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) regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, regval); } freg++; greg++; /* Always consume parameter stack space. */ gparam = align_up (gparam + 8, tdep->wordsize); } else if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 16 && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { /* IBM long double stored in two doublewords of the parameter save area and corresponding registers. */ if (write_pass) { if (!tdep->soft_float && freg <= 13) { regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val); if (freg <= 12) regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1, val + 8); } if (greg <= 10) { regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg, val); if (greg <= 9) regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + greg + 1, val + 8); } write_memory (gparam, val, TYPE_LENGTH (type)); } freg += 2; greg += 2; gparam = align_up (gparam + TYPE_LENGTH (type), tdep->wordsize); } else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) <= 8) { /* 32-bit and 64-bit decimal floats go in f1 .. f13. They can end up in memory. */ if (write_pass) { gdb_byte regval[MAX_REGISTER_SIZE]; const gdb_byte *p; /* 32-bit decimal floats are right aligned in the doubleword. */ if (TYPE_LENGTH (type) == 4) { memcpy (regval + 4, val, 4); p = regval; } else p = val; /* Write value in the stack's parameter save area. */ write_memory (gparam, p, 8); if (freg <= 13) regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, p); } freg++; greg++; /* Always consume parameter stack space. */ gparam = align_up (gparam + 8, tdep->wordsize); } else if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) == 16) { /* 128-bit decimal floats go in f2 .. f12, always in even/odd pairs. They can end up in memory, using two doublewords. */ if (write_pass) { if (freg <= 12) { /* Make sure freg is even. */ freg += freg & 1; regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg, val); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + freg + 1, val + 8); } write_memory (gparam, val, TYPE_LENGTH (type)); } freg += 2; greg += 2; 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_BOOL || TYPE_CODE (type) == TYPE_CODE_CHAR || TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF) && 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) == TYPE_CODE_REF) { struct type *target_type; target_type = check_typedef (TYPE_TARGET_TYPE (type)); if (TYPE_CODE (target_type) == TYPE_CODE_FUNC || TYPE_CODE (target_type) == TYPE_CODE_METHOD) { 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, byte_order, 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); /* The ABI (version 1.9) specifies that values smaller than one doubleword are right-aligned and those larger are left-aligned. GCC versions before 3.4 implemented this incorrectly; see <http://gcc.gnu.org/gcc-3.4/powerpc-abi.html>. */ if (byte == 0) memcpy (regval + tdep->wordsize - len, val + byte, len); else memcpy (regval, 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. */ int len = TYPE_LENGTH (type); if (len < tdep->wordsize) write_memory (gparam + tdep->wordsize - len, val, len); else write_memory (gparam, val, len); } if (freg <= 13 && TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1 && TYPE_LENGTH (type) <= 16) { /* The ABI (version 1.9) specifies that structs containing a single floating-point value, at any level of nesting of single-member structs, are passed in floating-point registers. */ while (TYPE_CODE (type) == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) type = check_typedef (TYPE_FIELD_TYPE (type, 0)); if (TYPE_CODE (type) == TYPE_CODE_FLT) { if (TYPE_LENGTH (type) <= 8) { if (write_pass) { 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); } freg++; } else if (TYPE_LENGTH (type) == 16 && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { if (write_pass) { regcache_cooked_write (regcache, (tdep->ppc_fp0_regnum + freg), val); if (freg <= 12) regcache_cooked_write (regcache, (tdep->ppc_fp0_regnum + freg + 1), val + 8); } freg += 2; } } } /* 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, gdbarch_sp_regnum (gdbarch), sp); /* Write the backchain (it occupies WORDSIZED bytes). */ write_memory_signed_integer (sp, tdep->wordsize, byte_order, 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. If we're calling via a function pointer, the pointer itself identifies the descriptor. */ { struct type *ftype = check_typedef (value_type (function)); CORE_ADDR desc_addr = value_as_address (function); if (TYPE_CODE (ftype) == TYPE_CODE_PTR || 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, byte_order); regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 2, toc); } } return sp; }
static struct so_list * dsbt_current_sos (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); CORE_ADDR lm_addr; struct so_list *sos_head = NULL; struct so_list **sos_next_ptr = &sos_head; struct dsbt_info *info = get_dsbt_info (); /* Make sure that the main executable has been relocated. This is required in order to find the address of the global offset table, which in turn is used to find the link map info. (See lm_base for details.) Note that the relocation of the main executable is also performed by solib_create_inferior_hook, however, in the case of core files, this hook is called too late in order to be of benefit to solib_add. solib_add eventually calls this function, dsbt_current_sos, and also precedes the call to solib_create_inferior_hook. (See post_create_inferior in infcmd.c.) */ if (info->main_executable_lm_info == 0 && core_bfd != NULL) dsbt_relocate_main_executable (); /* Locate the address of the first link map struct. */ lm_addr = lm_base (); /* We have at least one link map entry. Fetch the the lot of them, building the solist chain. */ while (lm_addr) { struct ext_link_map lm_buf; ext_Elf32_Word indexword; CORE_ADDR map_addr; int dsbt_index; int ret; if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "current_sos: reading link_map entry at %s\n", hex_string_custom (lm_addr, 8)); ret = target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf)); if (ret) { warning (_("dsbt_current_sos: Unable to read link map entry." " Shared object chain may be incomplete.")); break; } /* Fetch the load map address. */ map_addr = extract_unsigned_integer (lm_buf.l_addr.map, sizeof lm_buf.l_addr.map, byte_order); ret = target_read_memory (map_addr + 12, (gdb_byte *) &indexword, sizeof indexword); if (ret) { warning (_("dsbt_current_sos: Unable to read dsbt index." " Shared object chain may be incomplete.")); break; } dsbt_index = extract_unsigned_integer (indexword, sizeof indexword, byte_order); /* If the DSBT index is zero, then we're looking at the entry for the main executable. By convention, we don't include this in the list of shared objects. */ if (dsbt_index != 0) { int errcode; char *name_buf; struct int_elf32_dsbt_loadmap *loadmap; struct so_list *sop; CORE_ADDR addr; loadmap = fetch_loadmap (map_addr); if (loadmap == NULL) { warning (_("dsbt_current_sos: Unable to fetch load map." " Shared object chain may be incomplete.")); break; } sop = xcalloc (1, sizeof (struct so_list)); sop->lm_info = xcalloc (1, sizeof (struct lm_info)); sop->lm_info->map = loadmap; /* Fetch the name. */ addr = extract_unsigned_integer (lm_buf.l_name, sizeof (lm_buf.l_name), byte_order); target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1, &errcode); if (errcode != 0) warning (_("Can't read pathname for link map entry: %s."), safe_strerror (errcode)); else { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n", name_buf); strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1); sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0'; xfree (name_buf); strcpy (sop->so_original_name, sop->so_name); } *sos_next_ptr = sop; sos_next_ptr = &sop->next; } else { info->main_lm_addr = lm_addr; } lm_addr = extract_unsigned_integer (lm_buf.l_next, sizeof (lm_buf.l_next), byte_order); } return sos_head; }
static void printstr (struct ui_file *stream, struct type *elttype, const gdb_byte *string, unsigned int length, int force_ellipses, int type_len, const struct value_print_options *options) { enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (elttype)); unsigned int i; unsigned int things_printed = 0; int in_quotes = 0; int need_comma = 0; if (length == 0) { fputs_filtered ("\"\"", stream); return; } for (i = 0; i < length && things_printed < options->print_max; i += 1) { /* 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; QUIT; if (need_comma) { fputs_filtered (", ", stream); need_comma = 0; } rep1 = i + 1; reps = 1; while (rep1 < length && char_at (string, rep1, type_len, byte_order) == char_at (string, i, type_len, byte_order)) { rep1 += 1; reps += 1; } if (reps > options->repeat_count_threshold) { if (in_quotes) { fputs_filtered ("\", ", stream); in_quotes = 0; } fputs_filtered ("'", stream); ada_emit_char (char_at (string, i, type_len, byte_order), elttype, stream, '\'', type_len); fputs_filtered ("'", stream); fprintf_filtered (stream, _(" <repeats %u times>"), reps); i = rep1 - 1; things_printed += options->repeat_count_threshold; need_comma = 1; } else { if (!in_quotes) { fputs_filtered ("\"", stream); in_quotes = 1; } ada_emit_char (char_at (string, i, type_len, byte_order), elttype, stream, '"', type_len); things_printed += 1; } } /* Terminate the quotes if necessary. */ if (in_quotes) fputs_filtered ("\"", stream); if (force_ellipses || i < length) fputs_filtered ("...", stream); }
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 int_elf32_dsbt_loadmap * fetch_loadmap (CORE_ADDR ldmaddr) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); struct ext_elf32_dsbt_loadmap ext_ldmbuf_partial; struct ext_elf32_dsbt_loadmap *ext_ldmbuf; struct int_elf32_dsbt_loadmap *int_ldmbuf; int ext_ldmbuf_size, int_ldmbuf_size; int version, seg, nsegs; /* Fetch initial portion of the loadmap. */ if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial)) { /* Problem reading the target's memory. */ return NULL; } /* Extract the version. */ version = extract_unsigned_integer (ext_ldmbuf_partial.version, sizeof ext_ldmbuf_partial.version, byte_order); if (version != 0) { /* We only handle version 0. */ return NULL; } /* Extract the number of segments. */ nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs, sizeof ext_ldmbuf_partial.nsegs, byte_order); if (nsegs <= 0) return NULL; /* Allocate space for the complete (external) loadmap. */ ext_ldmbuf_size = sizeof (struct ext_elf32_dsbt_loadmap) + (nsegs - 1) * sizeof (struct ext_elf32_dsbt_loadseg); ext_ldmbuf = xmalloc (ext_ldmbuf_size); /* Copy over the portion of the loadmap that's already been read. */ memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial); /* Read the rest of the loadmap from the target. */ if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial, (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial, ext_ldmbuf_size - sizeof ext_ldmbuf_partial)) { /* Couldn't read rest of the loadmap. */ xfree (ext_ldmbuf); return NULL; } /* Allocate space into which to put information extract from the external loadsegs. I.e, allocate the internal loadsegs. */ int_ldmbuf_size = sizeof (struct int_elf32_dsbt_loadmap) + (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg); int_ldmbuf = xmalloc (int_ldmbuf_size); /* Place extracted information in internal structs. */ int_ldmbuf->version = version; int_ldmbuf->nsegs = nsegs; for (seg = 0; seg < nsegs; seg++) { int_ldmbuf->segs[seg].addr = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr, sizeof (ext_ldmbuf->segs[seg].addr), byte_order); int_ldmbuf->segs[seg].p_vaddr = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr, sizeof (ext_ldmbuf->segs[seg].p_vaddr), byte_order); int_ldmbuf->segs[seg].p_memsz = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz, sizeof (ext_ldmbuf->segs[seg].p_memsz), byte_order); } xfree (ext_ldmbuf); return int_ldmbuf; }
static enum return_value_convention rs6000_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* The calling convention this function implements assumes the processor has floating-point registers. We shouldn't be using it on PowerPC variants that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* AltiVec extension: Functions that declare a vector data type as a return value place that return value in VR2. */ if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY && TYPE_VECTOR (valtype) && TYPE_LENGTH (valtype) == 16) { if (readbuf) regcache_cooked_read (regcache, tdep->ppc_vr0_regnum + 2, readbuf); if (writebuf) regcache_cooked_write (regcache, tdep->ppc_vr0_regnum + 2, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } /* If the called subprogram returns an aggregate, there exists an implicit first argument, whose value is the address of a caller- allocated buffer into which the callee is assumed to store its return value. All explicit parameters are appropriately relabeled. */ if (TYPE_CODE (valtype) == TYPE_CODE_STRUCT || TYPE_CODE (valtype) == TYPE_CODE_UNION || TYPE_CODE (valtype) == TYPE_CODE_ARRAY) return RETURN_VALUE_STRUCT_CONVENTION; /* Scalar floating-point values are returned in FPR1 for float or double, and in FPR1:FPR2 for quadword precision. Fortran complex*8 and complex*16 are returned in FPR1:FPR2, and complex*32 is returned in FPR1:FPR4. */ if (TYPE_CODE (valtype) == TYPE_CODE_FLT && (TYPE_LENGTH (valtype) == 4 || TYPE_LENGTH (valtype) == 8)) { struct type *regtype = register_type (gdbarch, tdep->ppc_fp0_regnum); gdb_byte regval[8]; /* FIXME: kettenis/2007-01-01: Add support for quadword precision and complex. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, regval); convert_typed_floating (regval, regtype, readbuf, valtype); } if (writebuf) { convert_typed_floating (writebuf, valtype, regval, regtype); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, regval); } return RETURN_VALUE_REGISTER_CONVENTION; } /* Values of the types int, long, short, pointer, and char (length is less than or equal to four bytes), as well as bit values of lengths less than or equal to 32 bits, must be returned right justified in GPR3 with signed values sign extended and unsigned values zero extended, as necessary. */ if (TYPE_LENGTH (valtype) <= tdep->wordsize) { if (readbuf) { ULONGEST regval; /* For reading we don't have to worry about sign extension. */ regcache_cooked_read_unsigned (regcache, tdep->ppc_gp0_regnum + 3, ®val); store_unsigned_integer (readbuf, TYPE_LENGTH (valtype), byte_order, regval); } if (writebuf) { /* For writing, use unpack_long since that should handle any required sign extension. */ regcache_cooked_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, unpack_long (valtype, writebuf)); } return RETURN_VALUE_REGISTER_CONVENTION; } /* Eight-byte non-floating-point scalar values must be returned in GPR3:GPR4. */ if (TYPE_LENGTH (valtype) == 8) { gdb_assert (TYPE_CODE (valtype) != TYPE_CODE_FLT); gdb_assert (tdep->wordsize == 4); if (readbuf) { gdb_byte regval[8]; regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regval); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, regval + 4); memcpy (readbuf, regval, 8); } if (writebuf) { regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, writebuf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; } return RETURN_VALUE_STRUCT_CONVENTION; }
/* Scan an FR-V prologue, starting at PC, until frame->PC. If FRAME is non-zero, fill in its saved_regs with appropriate addresses. We assume FRAME's saved_regs array has already been allocated and cleared. Return the first PC value after the prologue. Note that, for unoptimized code, we almost don't need this function at all; all arguments and locals live on the stack, so we just need the FP to find everything. The catch: structures passed by value have their addresses living in registers; they're never spilled to the stack. So if you ever want to be able to get to these arguments in any frame but the top, you'll need to do this serious prologue analysis. */ static CORE_ADDR frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, struct frame_info *this_frame, struct frv_unwind_cache *info) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); /* When writing out instruction bitpatterns, we use the following letters to label instruction fields: P - The parallel bit. We don't use this. J - The register number of GRj in the instruction description. K - The register number of GRk in the instruction description. I - The register number of GRi. S - a signed imediate offset. U - an unsigned immediate offset. The dots below the numbers indicate where hex digit boundaries fall, to make it easier to check the numbers. */ /* Non-zero iff we've seen the instruction that initializes the frame pointer for this function's frame. */ int fp_set = 0; /* If fp_set is non_zero, then this is the distance from the stack pointer to frame pointer: fp = sp + fp_offset. */ int fp_offset = 0; /* Total size of frame prior to any alloca operations. */ int framesize = 0; /* Flag indicating if lr has been saved on the stack. */ int lr_saved_on_stack = 0; /* The number of the general-purpose register we saved the return address ("link register") in, or -1 if we haven't moved it yet. */ int lr_save_reg = -1; /* Offset (from sp) at which lr has been saved on the stack. */ int lr_sp_offset = 0; /* If gr_saved[i] is non-zero, then we've noticed that general register i has been saved at gr_sp_offset[i] from the stack pointer. */ char gr_saved[64]; int gr_sp_offset[64]; /* The address of the most recently scanned prologue instruction. */ CORE_ADDR last_prologue_pc; /* The address of the next instruction. */ CORE_ADDR next_pc; /* The upper bound to of the pc values to scan. */ CORE_ADDR lim_pc; memset (gr_saved, 0, sizeof (gr_saved)); last_prologue_pc = pc; /* Try to compute an upper limit (on how far to scan) based on the line number info. */ lim_pc = skip_prologue_using_sal (gdbarch, pc); /* If there's no line number info, lim_pc will be 0. In that case, set the limit to be 100 instructions away from pc. Hopefully, this will be far enough away to account for the entire prologue. Don't worry about overshooting the end of the function. The scan loop below contains some checks to avoid scanning unreasonably far. */ if (lim_pc == 0) lim_pc = pc + 400; /* If we have a frame, we don't want to scan past the frame's pc. This will catch those cases where the pc is in the prologue. */ if (this_frame) { CORE_ADDR frame_pc = get_frame_pc (this_frame); if (frame_pc < lim_pc) lim_pc = frame_pc; } /* Scan the prologue. */ while (pc < lim_pc) { char buf[frv_instr_size]; LONGEST op; if (target_read_memory (pc, buf, sizeof buf) != 0) break; op = extract_signed_integer (buf, sizeof buf, byte_order); next_pc = pc + 4; /* The tests in this chain of ifs should be in order of decreasing selectivity, so that more particular patterns get to fire before less particular patterns. */ /* Some sort of control transfer instruction: stop scanning prologue. Integer Conditional Branch: X XXXX XX 0000110 XX XXXXXXXXXXXXXXXX Floating-point / media Conditional Branch: X XXXX XX 0000111 XX XXXXXXXXXXXXXXXX LCR Conditional Branch to LR X XXXX XX 0001110 XX XX 001 X XXXXXXXXXX Integer conditional Branches to LR X XXXX XX 0001110 XX XX 010 X XXXXXXXXXX X XXXX XX 0001110 XX XX 011 X XXXXXXXXXX Floating-point/Media Branches to LR X XXXX XX 0001110 XX XX 110 X XXXXXXXXXX X XXXX XX 0001110 XX XX 111 X XXXXXXXXXX Jump and Link X XXXXX X 0001100 XXXXXX XXXXXX XXXXXX X XXXXX X 0001101 XXXXXX XXXXXX XXXXXX Call X XXXXXX 0001111 XXXXXXXXXXXXXXXXXX Return from Trap X XXXXX X 0000101 XXXXXX XXXXXX XXXXXX Integer Conditional Trap X XXXX XX 0000100 XXXXXX XXXX 00 XXXXXX X XXXX XX 0011100 XXXXXX XXXXXXXXXXXX Floating-point /media Conditional Trap X XXXX XX 0000100 XXXXXX XXXX 01 XXXXXX X XXXX XX 0011101 XXXXXX XXXXXXXXXXXX Break X XXXX XX 0000100 XXXXXX XXXX 11 XXXXXX Media Trap X XXXX XX 0000100 XXXXXX XXXX 10 XXXXXX */ if ((op & 0x01d80000) == 0x00180000 /* Conditional branches and Call */ || (op & 0x01f80000) == 0x00300000 /* Jump and Link */ || (op & 0x01f80000) == 0x00100000 /* Return from Trap, Trap */ || (op & 0x01f80000) == 0x00700000) /* Trap immediate */ { /* Stop scanning; not in prologue any longer. */ break; } /* Loading something from memory into fp probably means that we're in the epilogue. Stop scanning the prologue. ld @(GRi, GRk), fp X 000010 0000010 XXXXXX 000100 XXXXXX ldi @(GRi, d12), fp X 000010 0110010 XXXXXX XXXXXXXXXXXX */ else if ((op & 0x7ffc0fc0) == 0x04080100 || (op & 0x7ffc0000) == 0x04c80000) { break; } /* Setting the FP from the SP: ori sp, 0, fp P 000010 0100010 000001 000000000000 = 0x04881000 0 111111 1111111 111111 111111111111 = 0x7fffffff . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7fffffff) == 0x04881000) { fp_set = 1; fp_offset = 0; last_prologue_pc = next_pc; } /* Move the link register to the scratch register grJ, before saving: movsg lr, grJ P 000100 0000011 010000 000111 JJJJJJ = 0x080d01c0 0 111111 1111111 111111 111111 000000 = 0x7fffffc0 . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7fffffc0) == 0x080d01c0) { int gr_j = op & 0x3f; /* If we're moving it to a scratch register, that's fine. */ if (is_caller_saves_reg (gr_j)) { lr_save_reg = gr_j; last_prologue_pc = next_pc; } } /* To save multiple callee-saves registers on the stack, at offset zero: std grK,@(sp,gr0) P KKKKKK 0000011 000001 000011 000000 = 0x000c10c0 0 000000 1111111 111111 111111 111111 = 0x01ffffff stq grK,@(sp,gr0) P KKKKKK 0000011 000001 000100 000000 = 0x000c1100 0 000000 1111111 111111 111111 111111 = 0x01ffffff . . . . . . . . We treat this as part of the prologue, and record the register's saved address in the frame structure. */ else if ((op & 0x01ffffff) == 0x000c10c0 || (op & 0x01ffffff) == 0x000c1100) { int gr_k = ((op >> 25) & 0x3f); int ope = ((op >> 6) & 0x3f); int count; int i; /* Is it an std or an stq? */ if (ope == 0x03) count = 2; else count = 4; /* Is it really a callee-saves register? */ if (is_callee_saves_reg (gr_k)) { for (i = 0; i < count; i++) { gr_saved[gr_k + i] = 1; gr_sp_offset[gr_k + i] = 4 * i; } last_prologue_pc = next_pc; } } /* Adjusting the stack pointer. (The stack pointer is GR1.) addi sp, S, sp P 000001 0010000 000001 SSSSSSSSSSSS = 0x02401000 0 111111 1111111 111111 000000000000 = 0x7ffff000 . . . . . . . . We treat this as part of the prologue. */ else if ((op & 0x7ffff000) == 0x02401000)
static struct trad_frame_cache * i386nbsd_trapframe_cache(struct frame_info *this_frame, void **this_cache) { struct trad_frame_cache *cache; CORE_ADDR func, sp, addr, tmp; ULONGEST cs; const char *name; int i; struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); if (*this_cache) return (struct trad_frame_cache *)*this_cache; cache = trad_frame_cache_zalloc (this_frame); *this_cache = cache; func = get_frame_func (this_frame); sp = get_frame_register_unsigned (this_frame, I386_ESP_REGNUM); find_pc_partial_function (func, &name, NULL, NULL); if (name && strncmp (name, "Xintr", 5) == 0) { /* It's an interrupt frame. */ tmp = read_memory_unsigned_integer (sp + 4, 4, byte_order); if (tmp < 15) { /* Reasonable value for 'ppl': already on interrupt stack. */ addr = sp + 8; } else { /* Switch to previous stack. */ addr = tmp + 4; } } else { /* It's a trap frame. */ addr = sp + 4; } for (i = 0; i < ARRAY_SIZE (i386nbsd_tf_reg_offset); i++) if (i386nbsd_tf_reg_offset[i] != -1) trad_frame_set_reg_addr (cache, i, addr + i386nbsd_tf_reg_offset[i]); /* Read %cs from trap frame. */ addr += i386nbsd_tf_reg_offset[I386_CS_REGNUM]; cs = read_memory_unsigned_integer (addr, 4, byte_order); if ((cs & I386_SEL_RPL) == I386_SEL_UPL) { /* Trap from user space; terminate backtrace. */ trad_frame_set_id (cache, outer_frame_id); } else { /* Construct the frame ID using the function start. */ trad_frame_set_id (cache, frame_id_build (sp + 8, func)); } return cache; }
void mips64_fill_fpregset (const struct regcache *regcache, mips64_elf_fpregset_t *fpregsetp, int regno) { gdb_byte *to; if ((regno >= gdbarch_fp0_regnum (current_gdbarch)) && (regno < gdbarch_fp0_regnum (current_gdbarch) + 32)) { /* See mips_linux_o32_sigframe_init for a description of the peculiar FP register layout. */ if (register_size (current_gdbarch, regno) == 4) { int regi = regno - gdbarch_fp0_regnum (current_gdbarch); to = (gdb_byte *) (*fpregsetp + (regi & ~1)); if ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) != (regi & 1)) to += 4; regcache_raw_collect (regcache, regno, to); } else { to = (gdb_byte *) (*fpregsetp + regno - gdbarch_fp0_regnum (current_gdbarch)); regcache_raw_collect (regcache, regno, to); } } else if (regno == mips_regnum (current_gdbarch)->fp_control_status) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (current_gdbarch, regno)); to = (gdb_byte *) (*fpregsetp + 32); store_signed_integer (to, 4, val); } else if (regno == mips_regnum (current_gdbarch)->fp_implementation_revision) { gdb_byte buf[MAX_REGISTER_SIZE]; LONGEST val; regcache_raw_collect (regcache, regno, buf); val = extract_signed_integer (buf, register_size (current_gdbarch, regno)); to = (gdb_byte *) (*fpregsetp + 32) + 4; store_signed_integer (to, 4, val); } else if (regno == -1) { int regi; for (regi = 0; regi < 32; regi++) mips64_fill_fpregset (regcache, fpregsetp, gdbarch_fp0_regnum (current_gdbarch) + regi); mips64_fill_fpregset (regcache, fpregsetp, mips_regnum (current_gdbarch)->fp_control_status); mips64_fill_fpregset (regcache, fpregsetp, (mips_regnum (current_gdbarch) ->fp_implementation_revision)); } }
static void get_register (int regnum, map_arg arg) { int realnum; CORE_ADDR addr; enum lval_type lval; struct type *reg_vtype; gdb_byte buffer[MAX_REGISTER_SIZE]; int optim, format; struct cleanup *old_chain = NULL; struct ui_file *stb; long dummy; char *res; format = regformat[regnum]; if (format == 0) format = 'x'; reg_vtype = regtype[regnum]; if (reg_vtype == NULL) reg_vtype = register_type (get_current_arch (), regnum); if (!target_has_registers) { if (result_ptr->flags & GDBTK_MAKES_LIST) Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj ("", -1)); else Tcl_SetStringObj (result_ptr->obj_ptr, "", -1); return; } frame_register (get_selected_frame (NULL), regnum, &optim, &lval, &addr, &realnum, buffer); if (optim) { Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj ("Optimized out", -1)); return; } stb = mem_fileopen (); old_chain = make_cleanup_ui_file_delete (stb); if (format == 'r') { /* shouldn't happen. raw format is deprecated */ int j; char *ptr, buf[1024]; strcpy (buf, "0x"); ptr = buf + 2; for (j = 0; j < register_size (get_current_arch (), regnum); j++) { int idx = ((gdbarch_byte_order (get_current_arch ()) == BFD_ENDIAN_BIG) ? j : register_size (get_current_arch (), regnum) - 1 - j); sprintf (ptr, "%02x", (unsigned char) buffer[idx]); ptr += 2; } fputs_unfiltered (buf, stb); } else { struct value_print_options opts; get_formatted_print_options (&opts, format); opts.deref_ref = 1; opts.pretty = Val_pretty_default; if ((TYPE_CODE (reg_vtype) == TYPE_CODE_UNION) && (strcmp (FIELD_NAME (TYPE_FIELD (reg_vtype, 0)), gdbarch_register_name (get_current_arch (), regnum)) == 0)) { val_print (FIELD_TYPE (TYPE_FIELD (reg_vtype, 0)), buffer, 0, 0, stb, 0, NULL, &opts, current_language); } else val_print (reg_vtype, buffer, 0, 0, stb, 0, NULL, &opts, current_language); } res = ui_file_xstrdup (stb, &dummy); if (result_ptr->flags & GDBTK_MAKES_LIST) Tcl_ListObjAppendElement (NULL, result_ptr->obj_ptr, Tcl_NewStringObj (res, -1)); else Tcl_SetStringObj (result_ptr->obj_ptr, res, -1); xfree (res); do_cleanups (old_chain); }
static CORE_ADDR iq2000_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR scan_start, CORE_ADDR scan_end, struct frame_info *fi, struct iq2000_frame_cache *cache) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct symtab_and_line sal; CORE_ADDR pc; CORE_ADDR loop_end; int srcreg; int tgtreg; signed short offset; if (scan_end == (CORE_ADDR) 0) { loop_end = scan_start + 100; sal.end = sal.pc = 0; } else { loop_end = scan_end; if (fi) sal = find_last_line_symbol (scan_start, scan_end, 0); else sal.end = 0; /* Avoid GCC false warning. */ } /* Saved registers: We first have to save the saved register's offset, and only later do we compute its actual address. Since the offset can be zero, we must first initialize all the saved regs to minus one (so we can later distinguish between one that's not saved, and one that's saved at zero). */ for (srcreg = 0; srcreg < E_NUM_REGS; srcreg ++) cache->saved_regs[srcreg] = -1; cache->using_fp = 0; cache->framesize = 0; for (pc = scan_start; pc < loop_end; pc += 4) { LONGEST insn = read_memory_unsigned_integer (pc, 4, byte_order); /* Skip any instructions writing to (sp) or decrementing the SP. */ if ((insn & 0xffe00000) == 0xac200000) { /* sw using SP/%1 as base. */ /* LEGACY -- from assembly-only port. */ tgtreg = ((insn >> 16) & 0x1f); if (tgtreg >= 0 && tgtreg < E_NUM_REGS) cache->saved_regs[tgtreg] = -((signed short) (insn & 0xffff)); continue; } if ((insn & 0xffff8000) == 0x20218000) { /* addi %1, %1, -N == addi %sp, %sp, -N */ /* LEGACY -- from assembly-only port. */ cache->framesize = -((signed short) (insn & 0xffff)); continue; } if (INSN_IS_ADDIU (insn)) { srcreg = ADDIU_REG_SRC (insn); tgtreg = ADDIU_REG_TGT (insn); offset = ADDIU_IMMEDIATE (insn); if (srcreg == E_SP_REGNUM && tgtreg == E_SP_REGNUM) cache->framesize = -offset; continue; } if (INSN_IS_STORE_WORD (insn)) { srcreg = SW_REG_SRC (insn); tgtreg = SW_REG_INDEX (insn); offset = SW_OFFSET (insn); if (tgtreg == E_SP_REGNUM || tgtreg == E_FP_REGNUM) { /* "push" to stack (via SP or FP reg). */ if (cache->saved_regs[srcreg] == -1) /* Don't save twice. */ cache->saved_regs[srcreg] = offset; continue; } } if (INSN_IS_MOVE (insn)) { srcreg = MOVE_REG_SRC (insn); tgtreg = MOVE_REG_TGT (insn); if (srcreg == E_SP_REGNUM && tgtreg == E_FP_REGNUM) { /* Copy sp to fp. */ cache->using_fp = 1; continue; } } /* Unknown instruction encountered in frame. Bail out? 1) If we have a subsequent line symbol, we can keep going. 2) If not, we need to bail out and quit scanning instructions. */ if (fi && sal.end && (pc < sal.end)) /* Keep scanning. */ continue; else /* bail */ break; }
static CORE_ADDR tic6x_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc, const CORE_ADDR current_pc, struct tic6x_unwind_cache *cache, struct frame_info *this_frame) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); unsigned long inst; unsigned int src_reg, base_reg, dst_reg; int i; CORE_ADDR pc = start_pc; CORE_ADDR return_pc = start_pc; int frame_base_offset_to_sp = 0; /* Counter of non-stw instructions after first insn ` sub sp, xxx, sp'. */ int non_stw_insn_counter = 0; if (start_pc >= current_pc) return_pc = current_pc; cache->base = 0; /* The landmarks in prologue is one or two SUB instructions to SP. Instructions on setting up dsbt are in the last part of prologue, if needed. In maxim, prologue can be divided to three parts by two `sub sp, xx, sp' insns. */ /* Step 1: Look for the 1st and 2nd insn `sub sp, xx, sp', in which, the 2nd one is optional. */ while (pc < current_pc) { int offset = 0; unsigned long inst = tic6x_fetch_instruction (gdbarch, pc); if ((inst & 0x1ffc) == 0x1dc0 || (inst & 0x1ffc) == 0x1bc0 || (inst & 0x0ffc) == 0x9c0) { /* SUBAW/SUBAH/SUB, and src1 is ucst 5. */ unsigned int src2 = tic6x_register_number ((inst >> 18) & 0x1f, INST_S_BIT (inst), 0); unsigned int dst = tic6x_register_number ((inst >> 23) & 0x1f, INST_S_BIT (inst), 0); if (src2 == TIC6X_SP_REGNUM && dst == TIC6X_SP_REGNUM) { /* Extract const from insn SUBAW/SUBAH/SUB, and translate it to offset. The constant offset is decoded in bit 13-17 in all these three kinds of instructions. */ unsigned int ucst5 = (inst >> 13) & 0x1f; if ((inst & 0x1ffc) == 0x1dc0) /* SUBAW */ frame_base_offset_to_sp += ucst5 << 2; else if ((inst & 0x1ffc) == 0x1bc0) /* SUBAH */ frame_base_offset_to_sp += ucst5 << 1; else if ((inst & 0x0ffc) == 0x9c0) /* SUB */ frame_base_offset_to_sp += ucst5; else gdb_assert_not_reached ("unexpected instruction"); return_pc = pc + 4; } }
static enum target_xfer_status ctf_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, ULONGEST offset, ULONGEST len, ULONGEST *xfered_len) { /* We're only doing regular memory for now. */ if (object != TARGET_OBJECT_MEMORY) return -1; if (readbuf == NULL) error (_("ctf_xfer_partial: trace file is read-only")); if (get_traceframe_number () != -1) { struct bt_iter_pos *pos; int i = 0; enum target_xfer_status res; /* Records the lowest available address of all blocks that intersects the requested range. */ ULONGEST low_addr_available = 0; gdb_assert (ctf_iter != NULL); /* Save the current position. */ pos = bt_iter_get_pos (bt_ctf_get_iter (ctf_iter)); gdb_assert (pos->type == BT_SEEK_RESTORE); /* Iterate through the traceframe's blocks, looking for memory. */ while (1) { ULONGEST amt; uint64_t maddr; uint16_t mlen; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); const struct bt_definition *scope; const struct bt_definition *def; struct bt_ctf_event *event = bt_ctf_iter_read_event (ctf_iter); const char *name = bt_ctf_event_name (event); if (name == NULL || strcmp (name, "frame") == 0) break; else if (strcmp (name, "memory") != 0) { if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) break; continue; } scope = bt_ctf_get_top_level_scope (event, BT_EVENT_FIELDS); def = bt_ctf_get_field (event, scope, "address"); maddr = bt_ctf_get_uint64 (def); def = bt_ctf_get_field (event, scope, "length"); mlen = (uint16_t) bt_ctf_get_uint64 (def); /* If the block includes the first part of the desired range, return as much it has; GDB will re-request the remainder, which might be in a different block of this trace frame. */ if (maddr <= offset && offset < (maddr + mlen)) { const struct bt_definition *array = bt_ctf_get_field (event, scope, "contents"); const struct bt_declaration *decl = bt_ctf_get_decl_from_def (array); gdb_byte *contents; int k; contents = xmalloc (mlen); for (k = 0; k < mlen; k++) { const struct bt_definition *element = bt_ctf_get_index (event, array, k); contents[k] = (gdb_byte) bt_ctf_get_uint64 (element); } amt = (maddr + mlen) - offset; if (amt > len) amt = len; memcpy (readbuf, &contents[offset - maddr], amt); xfree (contents); /* Restore the position. */ bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); if (amt == 0) return TARGET_XFER_EOF; else { *xfered_len = amt; return TARGET_XFER_OK; } } if (offset < maddr && maddr < (offset + len)) if (low_addr_available == 0 || low_addr_available > maddr) low_addr_available = maddr; if (bt_iter_next (bt_ctf_get_iter (ctf_iter)) < 0) break; } /* Restore the position. */ bt_iter_set_pos (bt_ctf_get_iter (ctf_iter), pos); /* Requested memory is unavailable in the context of traceframes, and this address falls within a read-only section, fallback to reading from executable, up to LOW_ADDR_AVAILABLE */ if (offset < low_addr_available) len = min (len, low_addr_available - offset); res = exec_read_partial_read_only (readbuf, offset, len, xfered_len); if (res == TARGET_XFER_OK) return TARGET_XFER_OK; else { /* No use trying further, we know some memory starting at MEMADDR isn't available. */ *xfered_len = len; return TARGET_XFER_UNAVAILABLE; } } else { /* Fallback to reading from read-only sections. */ return section_table_read_available_memory (readbuf, offset, len, xfered_len); } }
void fetch_inferior_registers (int regno) { int current_pid; thread_t current_thread; int fetched = 0; current_pid = ptid_get_pid (inferior_ptid); current_thread = ptid_get_tid (inferior_ptid); /* ifdef the following code so that gdb doesn't send the new GDB_x86_THREAD_STATE constant when built on an older x86 MacOS X 10.4 system that won't recognize it. In Leopard this is unnecessary. */ if (TARGET_OSABI == GDB_OSABI_UNKNOWN) { /* Attaching to a process. Let's figure out what kind it is. */ gdb_x86_thread_state_t gp_regs; struct gdbarch_info info; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } gdbarch_info_init (&info); gdbarch_info_fill (current_gdbarch, &info); info.byte_order = gdbarch_byte_order (current_gdbarch); if (gp_regs.tsh.flavor == GDB_x86_THREAD_STATE64) { info.osabi = GDB_OSABI_DARWIN64; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_x86_64); } else { info.osabi = GDB_OSABI_DARWIN; info.bfd_arch_info = bfd_lookup_arch (bfd_arch_i386, bfd_mach_i386_i386); } gdbarch_update_p (info); } if (TARGET_OSABI == GDB_OSABI_DARWIN64) { if ((regno == -1) || IS_GP_REGNUM_64 (regno)) { gdb_x86_thread_state_t gp_regs; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } x86_64_macosx_fetch_gp_registers (&gp_regs.uts.ts64); fetched++; } if ((regno == -1) || IS_FP_REGNUM_64 (regno) || IS_VP_REGNUM_64 (regno) || regno == REGS_64_MXCSR) { gdb_x86_float_state_t fp_regs; unsigned int fp_count = GDB_x86_FLOAT_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for float registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } x86_64_macosx_fetch_fp_registers (&fp_regs.ufs.fs64); fetched++; } } else { if ((regno == -1) || IS_GP_REGNUM (regno)) { gdb_x86_thread_state_t gp_regs; unsigned int gp_count = GDB_x86_THREAD_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_x86_THREAD_STATE, (thread_state_t) & gp_regs, &gp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for GP registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } i386_macosx_fetch_gp_registers (&(gp_regs.uts.ts32)); fetched++; } if ((regno == -1) || IS_FP_REGNUM (regno) || i386_sse_regnum_p (current_gdbarch, regno) || i386_mxcsr_regnum_p (current_gdbarch, regno)) { gdb_i386_float_state_t fp_regs; unsigned int fp_count = GDB_i386_FLOAT_STATE_COUNT; kern_return_t ret = thread_get_state (current_thread, GDB_i386_FLOAT_STATE, (thread_state_t) & fp_regs, &fp_count); if (ret != KERN_SUCCESS) { printf_unfiltered ("Error calling thread_get_state for float registers for thread 0x%x\n", (int) current_thread); MACH_CHECK_ERROR (ret); } i386_macosx_fetch_fp_registers (&fp_regs); fetched++; } } if (! fetched) { warning ("unknown register %d", regno); regcache_raw_supply (current_regcache, regno, NULL); } }
void c_get_string (struct value *value, gdb_byte **buffer, int *length, struct type **char_type, const char **charset) { int err, width; unsigned int fetchlimit; struct type *type = check_typedef (value_type (value)); struct type *element_type = TYPE_TARGET_TYPE (type); int req_length = *length; enum bfd_endian byte_order = gdbarch_byte_order (get_type_arch (type)); if (element_type == NULL) goto error; if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { /* If we know the size of the array, we can use it as a limit on the number of characters to be fetched. */ if (TYPE_NFIELDS (type) == 1 && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_RANGE) { LONGEST low_bound, high_bound; get_discrete_bounds (TYPE_FIELD_TYPE (type, 0), &low_bound, &high_bound); fetchlimit = high_bound - low_bound + 1; } else fetchlimit = UINT_MAX; } else if (TYPE_CODE (type) == TYPE_CODE_PTR) fetchlimit = UINT_MAX; else /* We work only with arrays and pointers. */ goto error; if (! c_textual_element_type (element_type, 0)) goto error; classify_type (element_type, get_type_arch (element_type), charset); width = TYPE_LENGTH (element_type); /* If the string lives in GDB's memory instead of the inferior's, then we just need to copy it to BUFFER. Also, since such strings are arrays with known size, FETCHLIMIT will hold the size of the array. */ if ((VALUE_LVAL (value) == not_lval || VALUE_LVAL (value) == lval_internalvar) && fetchlimit != UINT_MAX) { int i; const gdb_byte *contents = value_contents (value); /* If a length is specified, use that. */ if (*length >= 0) i = *length; else /* Otherwise, look for a null character. */ for (i = 0; i < fetchlimit; i++) if (extract_unsigned_integer (contents + i * width, width, byte_order) == 0) break; /* I is now either a user-defined length, the number of non-null characters, or FETCHLIMIT. */ *length = i * width; *buffer = xmalloc (*length); memcpy (*buffer, contents, *length); err = 0; } else { CORE_ADDR addr = value_as_address (value); /* Prior to the fix for PR 16196 read_string would ignore fetchlimit if length > 0. The old "broken" behaviour is the behaviour we want: The caller may want to fetch 100 bytes from a variable length array implemented using the common idiom of having an array of length 1 at the end of a struct. In this case we want to ignore the declared size of the array. However, it's counterintuitive to implement that behaviour in read_string: what does fetchlimit otherwise mean if length > 0. Therefore we implement the behaviour we want here: If *length > 0, don't specify a fetchlimit. This preserves the previous behaviour. We could move this check above where we know whether the array is declared with a fixed size, but we only want to apply this behaviour when calling read_string. PR 16286. */ if (*length > 0) fetchlimit = UINT_MAX; err = read_string (addr, *length, width, fetchlimit, byte_order, buffer, length); if (err) { xfree (*buffer); memory_error (err, addr); } } /* If the LENGTH is specified at -1, we want to return the string length up to the terminating null character. If an actual length was specified, we want to return the length of exactly what was read. */ if (req_length == -1) /* If the last character is null, subtract it from LENGTH. */ if (*length > 0 && extract_unsigned_integer (*buffer + *length - width, width, byte_order) == 0) *length -= width; /* The read_string function will return the number of bytes read. If length returned from read_string was > 0, return the number of characters read by dividing the number of bytes by width. */ if (*length != 0) *length = *length / width; *char_type = element_type; return; error: { char *type_str; type_str = type_to_string (type); if (type_str) { make_cleanup (xfree, type_str); error (_("Trying to read string with inappropriate type `%s'."), type_str); } else error (_("Trying to read string with inappropriate type.")); } }
static void mips_linux_o32_sigframe_init (const struct tramp_frame *self, struct frame_info *next_frame, struct trad_frame_cache *this_cache, CORE_ADDR func) { int ireg, reg_position; CORE_ADDR sigcontext_base = func - SIGFRAME_CODE_OFFSET; const struct mips_regnum *regs = mips_regnum (current_gdbarch); CORE_ADDR regs_base; if (self == &mips_linux_o32_sigframe) sigcontext_base += SIGFRAME_SIGCONTEXT_OFFSET; else sigcontext_base += RTSIGFRAME_SIGCONTEXT_OFFSET; /* I'm not proud of this hack. Eventually we will have the infrastructure to indicate the size of saved registers on a per-frame basis, but right now we don't; the kernel saves eight bytes but we only want four. Use regs_base to access any 64-bit fields. */ if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) regs_base = sigcontext_base + 4; else regs_base = sigcontext_base; if (mips_linux_restart_reg_p (current_gdbarch)) trad_frame_set_reg_addr (this_cache, (MIPS_RESTART_REGNUM + gdbarch_num_regs (current_gdbarch)), regs_base + SIGCONTEXT_REGS); for (ireg = 1; ireg < 32; ireg++) trad_frame_set_reg_addr (this_cache, ireg + MIPS_ZERO_REGNUM + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_REGS + ireg * SIGCONTEXT_REG_SIZE); /* The way that floating point registers are saved, unfortunately, depends on the architecture the kernel is built for. For the r3000 and tx39, four bytes of each register are at the beginning of each of the 32 eight byte slots. For everything else, the registers are saved using double precision; only the even-numbered slots are initialized, and the high bits are the odd-numbered register. Assume the latter layout, since we can't tell, and it's much more common. Which bits are the "high" bits depends on endianness. */ for (ireg = 0; ireg < 32; ireg++) if ((gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG) != (ireg & 1)) trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_FPREGS + 4 + (ireg & ~1) * SIGCONTEXT_REG_SIZE); else trad_frame_set_reg_addr (this_cache, ireg + regs->fp0 + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_FPREGS + (ireg & ~1) * SIGCONTEXT_REG_SIZE); trad_frame_set_reg_addr (this_cache, regs->pc + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_PC); trad_frame_set_reg_addr (this_cache, regs->fp_control_status + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_FPCSR); trad_frame_set_reg_addr (this_cache, regs->hi + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_HI); trad_frame_set_reg_addr (this_cache, regs->lo + gdbarch_num_regs (current_gdbarch), regs_base + SIGCONTEXT_LO); trad_frame_set_reg_addr (this_cache, regs->cause + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_CAUSE); trad_frame_set_reg_addr (this_cache, regs->badvaddr + gdbarch_num_regs (current_gdbarch), sigcontext_base + SIGCONTEXT_BADVADDR); /* Choice of the bottom of the sigframe is somewhat arbitrary. */ trad_frame_set_id (this_cache, frame_id_build (func - SIGFRAME_CODE_OFFSET, func)); }
static CORE_ADDR rs6000_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int ii; int len = 0; int argno; /* current argument number */ int argbytes; /* current argument byte */ gdb_byte tmp_buffer[50]; int f_argno = 0; /* current floating point argno */ int wordsize = gdbarch_tdep (gdbarch)->wordsize; CORE_ADDR func_addr = find_function_addr (function, NULL); struct value *arg = 0; struct type *type; ULONGEST saved_sp; /* The calling convention this function implements assumes the processor has floating-point registers. We shouldn't be using it on PPC variants that lack them. */ gdb_assert (ppc_floating_point_unit_p (gdbarch)); /* The first eight words of ther arguments are passed in registers. Copy them appropriately. */ ii = 0; /* If the function is returning a `struct', then the first word (which will be passed in r3) is used for struct return address. In that case we should advance one word and start from r4 register to copy parameters. */ if (struct_return) { regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, struct_addr); ii++; } /* effectively indirect call... gcc does... return_val example( float, int); eabi: float in fp0, int in r3 offset of stack on overflow 8/16 for varargs, must go by type. power open: float in r3&r4, int in r5 offset of stack on overflow different both: return in r3 or f0. If no float, must study how gcc emulates floats; pay attention to arg promotion. User may have to cast\args to handle promotion correctly since gdb won't know if prototype supplied or not. */ for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) { int reg_size = register_size (gdbarch, ii + 3); arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); if (TYPE_CODE (type) == TYPE_CODE_FLT) { /* Floating point arguments are passed in fpr's, as well as gpr's. There are 13 fpr's reserved for passing parameters. At this point there is no way we would run out of them. Always store the floating point value using the register's floating-point format. */ const int fp_regnum = tdep->ppc_fp0_regnum + 1 + f_argno; gdb_byte reg_val[MAX_REGISTER_SIZE]; struct type *reg_type = register_type (gdbarch, fp_regnum); gdb_assert (len <= 8); convert_typed_floating (value_contents (arg), type, reg_val, reg_type); regcache_cooked_write (regcache, fp_regnum, reg_val); ++f_argno; } if (len > reg_size) { /* Argument takes more than one register. */ while (argbytes < len) { gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, ((char *) value_contents (arg)) + argbytes, (len - argbytes) > reg_size ? reg_size : len - argbytes); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 + ii, word); ++ii, argbytes += reg_size; if (ii >= 8) goto ran_out_of_registers_for_arguments; } argbytes = 0; --ii; } else { /* Argument can fit in one register. No problem. */ int adj = gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? reg_size - len : 0; gdb_byte word[MAX_REGISTER_SIZE]; memset (word, 0, reg_size); memcpy (word, value_contents (arg), len); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3 +ii, word); } ++argno; } ran_out_of_registers_for_arguments: regcache_cooked_read_unsigned (regcache, gdbarch_sp_regnum (gdbarch), &saved_sp); /* Location for 8 parameters are always reserved. */ sp -= wordsize * 8; /* Another six words for back chain, TOC register, link register, etc. */ sp -= wordsize * 6; /* Stack pointer must be quadword aligned. */ sp &= -16; /* If there are more arguments, allocate space for them in the stack, then push them starting from the ninth one. */ if ((argno < nargs) || argbytes) { int space = 0, jj; if (argbytes) { space += ((len - argbytes + 3) & -4); jj = argno + 1; } else jj = argno; for (; jj < nargs; ++jj) { struct value *val = args[jj]; space += ((TYPE_LENGTH (value_type (val))) + 3) & -4; } /* Add location required for the rest of the parameters. */ space = (space + 15) & -16; sp -= space; /* This is another instance we need to be concerned about securing our stack space. If we write anything underneath %sp (r1), we might conflict with the kernel who thinks he is free to use this area. So, update %sp first before doing anything else. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* If the last argument copied into the registers didn't fit there completely, push the rest of it into stack. */ if (argbytes) { write_memory (sp + 24 + (ii * 4), value_contents (arg) + argbytes, len - argbytes); ++argno; ii += ((len - argbytes + 3) & -4) / 4; } /* Push the rest of the arguments into stack. */ for (; argno < nargs; ++argno) { arg = args[argno]; type = check_typedef (value_type (arg)); len = TYPE_LENGTH (type); /* Float types should be passed in fpr's, as well as in the stack. */ if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13) { gdb_assert (len <= 8); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1 + f_argno, value_contents (arg)); ++f_argno; } write_memory (sp + 24 + (ii * 4), value_contents (arg), len); ii += ((len + 3) & -4) / 4; } } /* Set the stack pointer. According to the ABI, the SP is meant to be set _before_ the corresponding stack space is used. On AIX, this even applies when the target has been completely stopped! Not doing this can lead to conflicts with the kernel which thinks that it still has control over this not-yet-allocated stack region. */ regcache_raw_write_signed (regcache, gdbarch_sp_regnum (gdbarch), sp); /* Set back chain properly. */ store_unsigned_integer (tmp_buffer, wordsize, byte_order, saved_sp); write_memory (sp, tmp_buffer, wordsize); /* Point the inferior function call's return address at the dummy's breakpoint. */ regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); /* Set the TOC register value. */ regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, solib_aix_get_toc_value (func_addr)); target_store_registers (regcache, -1); return sp; }
static CORE_ADDR lm32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int first_arg_reg = SIM_LM32_R1_REGNUM; int num_arg_regs = 8; int i; /* Set the return address. */ regcache_cooked_write_signed (regcache, SIM_LM32_RA_REGNUM, bp_addr); /* If we're returning a large struct, a pointer to the address to store it at is passed as a first hidden parameter. */ if (struct_return) { regcache_cooked_write_unsigned (regcache, first_arg_reg, struct_addr); first_arg_reg++; num_arg_regs--; sp -= 4; } /* Setup parameters. */ for (i = 0; i < nargs; i++) { struct value *arg = args[i]; struct type *arg_type = check_typedef (value_type (arg)); gdb_byte *contents; ULONGEST val; /* Promote small integer types to int. */ switch (TYPE_CODE (arg_type)) { case TYPE_CODE_INT: case TYPE_CODE_BOOL: case TYPE_CODE_CHAR: case TYPE_CODE_RANGE: case TYPE_CODE_ENUM: if (TYPE_LENGTH (arg_type) < 4) { arg_type = get_builtin_type(gdbarch)->builtin_int32; arg = value_cast (arg_type, arg); } break; } /* FIXME: Handle structures. */ contents = (gdb_byte *) value_contents (arg); val = extract_unsigned_integer (contents, TYPE_LENGTH (arg_type), byte_order); /* First num_arg_regs parameters are passed by registers, and the rest are passed on the stack. */ if (i < num_arg_regs) regcache_cooked_write_unsigned (regcache, first_arg_reg + i, val); else { write_memory (sp, (void *) &val, TYPE_LENGTH (arg_type)); sp -= 4; } } /* Update stack pointer. */ regcache_cooked_write_signed (regcache, SIM_LM32_SP_REGNUM, sp); /* Return adjusted stack pointer. */ return sp; }
/* Build a list of `struct so_list' objects describing the shared objects currently loaded in the inferior. */ static struct so_list * spu_current_sos (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); struct so_list *head; struct so_list **link_ptr; gdb_byte buf[MAX_SPE_FD * 4]; int i, size; /* First, retrieve the SVR4 shared library list. */ head = svr4_so_ops.current_sos (); /* Append our libraries to the end of the list. */ for (link_ptr = &head; *link_ptr; link_ptr = &(*link_ptr)->next) ; /* Determine list of SPU ids. */ size = target_read (¤t_target, TARGET_OBJECT_SPU, NULL, buf, 0, sizeof buf); /* Do not add stand-alone SPE executable context as shared library, but relocate main SPE executable objfile. */ if (spu_standalone_p ()) { if (size == 4) { int fd = extract_unsigned_integer (buf, 4, byte_order); spu_relocate_main_executable (fd); /* Re-enable breakpoints after main SPU context was established; see also comments in spu_solib_create_inferior_hook. */ enable_breakpoints_after_startup (); } return head; } /* Create an so_list entry for each SPU id. */ for (i = 0; i < size; i += 4) { int fd = extract_unsigned_integer (buf + i, 4, byte_order); struct so_list *newobj; unsigned long long addr; char annex[32], id[100]; int len; /* Read object ID. There's a race window where the inferior may have already created the SPE context, but not installed the object-id yet. Skip such entries; we'll be back for them later. */ xsnprintf (annex, sizeof annex, "%d/object-id", fd); len = target_read (¤t_target, TARGET_OBJECT_SPU, annex, (gdb_byte *) id, 0, sizeof id); if (len <= 0 || len >= sizeof id) continue; id[len] = 0; if (sscanf (id, "0x%llx", &addr) != 1 || !addr) continue; /* Allocate so_list structure. */ newobj = XCNEW (struct so_list); /* Encode FD and object ID in path name. Choose the name so as not to conflict with any (normal) SVR4 library path name. */ xsnprintf (newobj->so_name, sizeof newobj->so_name, "@%s <%d>", hex_string (addr), fd); strcpy (newobj->so_original_name, newobj->so_name); *link_ptr = newobj; link_ptr = &newobj->next; } /* Append OpenCL sos. */ append_ocl_sos (link_ptr); 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, alignlen; 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 = 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 LONGEST frv_linux_sigcontext_reg_addr (struct frame_info *this_frame, int regno, CORE_ADDR *sc_addr_cache_ptr) { struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR sc_addr; if (sc_addr_cache_ptr && *sc_addr_cache_ptr) { sc_addr = *sc_addr_cache_ptr; } else { CORE_ADDR pc, sp; char buf[4]; int tramp_type; pc = get_frame_pc (this_frame); tramp_type = frv_linux_pc_in_sigtramp (gdbarch, pc, 0); get_frame_register (this_frame, sp_regnum, buf); sp = extract_unsigned_integer (buf, sizeof buf, byte_order); if (tramp_type == NORMAL_SIGTRAMP) { /* For a normal sigtramp frame, the sigcontext struct starts at SP + 8. */ sc_addr = sp + 8; } else if (tramp_type == RT_SIGTRAMP) { /* For a realtime sigtramp frame, SP + 12 contains a pointer to a ucontext struct. The ucontext struct contains a sigcontext struct starting 24 bytes in. (The offset of uc_mcontext within struct ucontext is derived as follows: stack_t is a 12-byte struct and struct sigcontext is 8-byte aligned. This gives an offset of 8 + 12 + 4 (for padding) = 24.) */ if (target_read_memory (sp + 12, buf, sizeof buf) != 0) { warning (_("Can't read realtime sigtramp frame.")); return 0; } sc_addr = extract_unsigned_integer (buf, sizeof buf, byte_order); sc_addr += 24; } else internal_error (__FILE__, __LINE__, _("not a signal trampoline")); if (sc_addr_cache_ptr) *sc_addr_cache_ptr = sc_addr; } switch (regno) { case psr_regnum : return sc_addr + 0; /* sc_addr + 4 has "isr", the Integer Status Register. */ case ccr_regnum : return sc_addr + 8; case cccr_regnum : return sc_addr + 12; case lr_regnum : return sc_addr + 16; case lcr_regnum : return sc_addr + 20; case pc_regnum : return sc_addr + 24; /* sc_addr + 28 is __status, the exception status. sc_addr + 32 is syscallno, the syscall number or -1. sc_addr + 36 is orig_gr8, the original syscall arg #1. sc_addr + 40 is gner[0]. sc_addr + 44 is gner[1]. */ case iacc0h_regnum : return sc_addr + 48; case iacc0l_regnum : return sc_addr + 52; default : if (first_gpr_regnum <= regno && regno <= last_gpr_regnum) return sc_addr + 56 + 4 * (regno - first_gpr_regnum); else if (first_fpr_regnum <= regno && regno <= last_fpr_regnum) return sc_addr + 312 + 4 * (regno - first_fpr_regnum); else return -1; /* not saved. */ } }
static CORE_ADDR tilegx_analyze_prologue (struct gdbarch* gdbarch, CORE_ADDR start_addr, CORE_ADDR end_addr, struct tilegx_frame_cache *cache, struct frame_info *next_frame) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR next_addr; CORE_ADDR prolog_end = end_addr; ULONGEST inst, inst2; LONGEST offset; int regnum; gdb_byte instbuf[32 * TILEGX_BUNDLE_SIZE_IN_BYTES]; CORE_ADDR instbuf_start; unsigned int instbuf_size; int status; bfd_uint64_t bundle; struct tilegx_decoded_instruction decoded[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; int num_insns; struct tilegx_reverse_regs reverse_frame[TILEGX_NUM_PHYS_REGS]; struct tilegx_reverse_regs new_reverse_frame[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; int dest_regs[TILEGX_MAX_INSTRUCTIONS_PER_BUNDLE]; int reverse_frame_valid, prolog_done, branch_seen, lr_saved_on_stack_p; LONGEST prev_sp_value; int i, j; if (start_addr >= end_addr || (start_addr % TILEGX_BUNDLE_ALIGNMENT_IN_BYTES) != 0) return end_addr; /* Initialize the reverse frame. This maps the CURRENT frame's registers to the outer frame's registers (the frame on the stack goes the other way). */ memcpy (&reverse_frame, &template_reverse_regs, sizeof (reverse_frame)); prolog_done = 0; branch_seen = 0; prev_sp_value = 0; lr_saved_on_stack_p = 0; /* To cut down on round-trip overhead, we fetch multiple bundles at once. These variables describe the range of memory we have prefetched. */ instbuf_start = 0; instbuf_size = 0; for (next_addr = start_addr; next_addr < end_addr; next_addr += TILEGX_BUNDLE_SIZE_IN_BYTES) { /* Retrieve the next instruction. */ if (next_addr - instbuf_start >= instbuf_size) { /* Figure out how many bytes to fetch. Don't span a page boundary since that might cause an unnecessary memory error. */ unsigned int size_on_same_page = 4096 - (next_addr & 4095); instbuf_size = sizeof instbuf; if (instbuf_size > size_on_same_page) instbuf_size = size_on_same_page; instbuf_size = min (instbuf_size, (end_addr - next_addr)); instbuf_start = next_addr; status = safe_frame_unwind_memory (next_frame, instbuf_start, instbuf, instbuf_size); if (status == 0) memory_error (status, next_addr); } reverse_frame_valid = 0; bundle = extract_unsigned_integer (&instbuf[next_addr - instbuf_start], 8, byte_order); num_insns = parse_insn_tilegx (bundle, next_addr, decoded); for (i = 0; i < num_insns; i++) { struct tilegx_decoded_instruction *this_insn = &decoded[i]; int64_t *operands = (int64_t *) this_insn->operand_values; const struct tilegx_opcode *opcode = this_insn->opcode; switch (opcode->mnemonic) { case TILEGX_OPC_ST: if (cache && reverse_frame[operands[0]].state == REVERSE_STATE_VALUE && reverse_frame[operands[1]].state == REVERSE_STATE_REGISTER) { LONGEST saved_address = reverse_frame[operands[0]].value; unsigned saved_register = (unsigned) reverse_frame[operands[1]].value; /* realreg >= 0 and addr != -1 indicates that the value of saved_register is in memory location saved_address. The value of realreg is not meaningful in this case but it must be >= 0. See trad-frame.h. */ cache->saved_regs[saved_register].realreg = saved_register; cache->saved_regs[saved_register].addr = saved_address; } else if (cache && (operands[0] == TILEGX_SP_REGNUM) && (operands[1] == TILEGX_LR_REGNUM)) lr_saved_on_stack_p = 1; break; case TILEGX_OPC_ADDI: case TILEGX_OPC_ADDLI: if (cache && operands[0] == TILEGX_SP_REGNUM && operands[1] == TILEGX_SP_REGNUM && reverse_frame[operands[1]].state == REVERSE_STATE_REGISTER) { /* Special case. We're fixing up the stack frame. */ uint64_t hopefully_sp = (unsigned) reverse_frame[operands[1]].value; short op2_as_short = (short) operands[2]; signed char op2_as_char = (signed char) operands[2]; /* Fix up the sign-extension. */ if (opcode->mnemonic == TILEGX_OPC_ADDI) op2_as_short = op2_as_char; prev_sp_value = (cache->saved_regs[hopefully_sp].addr - op2_as_short); new_reverse_frame[i].state = REVERSE_STATE_VALUE; new_reverse_frame[i].value = cache->saved_regs[hopefully_sp].addr; trad_frame_set_value (cache->saved_regs, hopefully_sp, prev_sp_value); } else { short op2_as_short = (short) operands[2]; signed char op2_as_char = (signed char) operands[2]; /* Fix up the sign-extension. */ if (opcode->mnemonic == TILEGX_OPC_ADDI) op2_as_short = op2_as_char; new_reverse_frame[i] = reverse_frame[operands[1]]; if (new_reverse_frame[i].state == REVERSE_STATE_VALUE) new_reverse_frame[i].value += op2_as_short; else new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; } reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_ADD: if (reverse_frame[operands[1]].state == REVERSE_STATE_VALUE && reverse_frame[operands[2]].state == REVERSE_STATE_VALUE) { /* We have values -- we can do this. */ new_reverse_frame[i] = reverse_frame[operands[2]]; new_reverse_frame[i].value += reverse_frame[operands[i]].value; } else { /* We don't know anything about the values. Punt. */ new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; } reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_MOVE: new_reverse_frame[i] = reverse_frame[operands[1]]; reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_MOVEI: case TILEGX_OPC_MOVELI: new_reverse_frame[i].state = REVERSE_STATE_VALUE; new_reverse_frame[i].value = operands[1]; reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_ORI: if (reverse_frame[operands[1]].state == REVERSE_STATE_VALUE) { /* We have a value in A -- we can do this. */ new_reverse_frame[i] = reverse_frame[operands[1]]; new_reverse_frame[i].value = reverse_frame[operands[1]].value | operands[2]; } else if (operands[2] == 0) { /* This is a move. */ new_reverse_frame[i] = reverse_frame[operands[1]]; } else { /* We don't know anything about the values. Punt. */ new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; } reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_OR: if (reverse_frame[operands[1]].state == REVERSE_STATE_VALUE && reverse_frame[operands[1]].value == 0) { /* This is a move. */ new_reverse_frame[i] = reverse_frame[operands[2]]; } else if (reverse_frame[operands[2]].state == REVERSE_STATE_VALUE && reverse_frame[operands[2]].value == 0) { /* This is a move. */ new_reverse_frame[i] = reverse_frame[operands[1]]; } else { /* We don't know anything about the values. Punt. */ new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; } reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_SUB: if (reverse_frame[operands[1]].state == REVERSE_STATE_VALUE && reverse_frame[operands[2]].state == REVERSE_STATE_VALUE) { /* We have values -- we can do this. */ new_reverse_frame[i] = reverse_frame[operands[1]]; new_reverse_frame[i].value -= reverse_frame[operands[2]].value; } else { /* We don't know anything about the values. Punt. */ new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; } reverse_frame_valid |= 1 << i; dest_regs[i] = operands[0]; break; case TILEGX_OPC_FNOP: case TILEGX_OPC_INFO: case TILEGX_OPC_INFOL: /* Nothing to see here, move on. Note that real NOP is treated as a 'real' instruction because someone must have intended that it be there. It therefore terminates the prolog. */ break; case TILEGX_OPC_J: case TILEGX_OPC_JAL: case TILEGX_OPC_BEQZ: case TILEGX_OPC_BEQZT: case TILEGX_OPC_BGEZ: case TILEGX_OPC_BGEZT: case TILEGX_OPC_BGTZ: case TILEGX_OPC_BGTZT: case TILEGX_OPC_BLBC: case TILEGX_OPC_BLBCT: case TILEGX_OPC_BLBS: case TILEGX_OPC_BLBST: case TILEGX_OPC_BLEZ: case TILEGX_OPC_BLEZT: case TILEGX_OPC_BLTZ: case TILEGX_OPC_BLTZT: case TILEGX_OPC_BNEZ: case TILEGX_OPC_BNEZT: case TILEGX_OPC_IRET: case TILEGX_OPC_JALR: case TILEGX_OPC_JALRP: case TILEGX_OPC_JR: case TILEGX_OPC_JRP: case TILEGX_OPC_SWINT0: case TILEGX_OPC_SWINT1: case TILEGX_OPC_SWINT2: case TILEGX_OPC_SWINT3: /* We're really done -- this is a branch. */ branch_seen = 1; prolog_done = 1; break; default: /* We don't know or care what this instruction is. All we know is that it isn't part of a prolog, and if there's a destination register, we're trashing it. */ prolog_done = 1; for (j = 0; j < opcode->num_operands; j++) { if (this_insn->operands[j]->is_dest_reg) { dest_regs[i] = operands[j]; new_reverse_frame[i].state = REVERSE_STATE_UNKNOWN; reverse_frame_valid |= 1 << i; break; } } break; } } /* Now update the reverse frames. */ for (i = 0; i < num_insns; i++) { /* ISSUE: Does this properly handle "network" registers? */ if ((reverse_frame_valid & (1 << i)) && dest_regs[i] != TILEGX_ZERO_REGNUM) reverse_frame[dest_regs[i]] = new_reverse_frame[i]; } if (prev_sp_value != 0) { /* GCC uses R52 as a frame pointer. Have we seen "move r52, sp"? */ if (reverse_frame[TILEGX_R52_REGNUM].state == REVERSE_STATE_REGISTER && reverse_frame[TILEGX_R52_REGNUM].value == TILEGX_SP_REGNUM) { reverse_frame[TILEGX_R52_REGNUM].state = REVERSE_STATE_VALUE; reverse_frame[TILEGX_R52_REGNUM].value = prev_sp_value; } prev_sp_value = 0; } if (prolog_done && prolog_end == end_addr) { /* We found non-prolog code. As such, _this_ instruction is the one after the prolog. We keep processing, because there may be more prolog code in there, but this is what we'll return. */ /* ISSUE: There may not have actually been a prologue, and we may have simply skipped some random instructions. */ prolog_end = next_addr; } if (branch_seen) { /* We saw a branch. The prolog absolutely must be over. */ break; } } if (prolog_end == end_addr && cache) { /* We may have terminated the prolog early, and we're certainly at THIS point right now. It's possible that the values of registers we need are currently actually in other registers (and haven't been written to memory yet). Go find them. */ for (i = 0; i < TILEGX_NUM_PHYS_REGS; i++) { if (reverse_frame[i].state == REVERSE_STATE_REGISTER && reverse_frame[i].value != i) { unsigned saved_register = (unsigned) reverse_frame[i].value; cache->saved_regs[saved_register].realreg = i; cache->saved_regs[saved_register].addr = (LONGEST) -1; } } } if (lr_saved_on_stack_p) { cache->saved_regs[TILEGX_LR_REGNUM].realreg = TILEGX_LR_REGNUM; cache->saved_regs[TILEGX_LR_REGNUM].addr = cache->saved_regs[TILEGX_SP_REGNUM].addr; } return prolog_end; }
static void trace_save (const char *filename, struct trace_file_writer *writer, int target_does_save) { struct trace_status *ts = current_trace_status (); struct uploaded_tp *uploaded_tps = NULL, *utp; struct uploaded_tsv *uploaded_tsvs = NULL, *utsv; ULONGEST offset = 0; #define MAX_TRACE_UPLOAD 2000 gdb_byte buf[MAX_TRACE_UPLOAD]; enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); /* If the target is to save the data to a file on its own, then just send the command and be done with it. */ if (target_does_save) { if (!writer->ops->target_save (writer, filename)) error (_("Target failed to save trace data to '%s'."), filename); return; } /* Get the trace status first before opening the file, so if the target is losing, we can get out without touching files. Since we're just calling this for side effects, we ignore the result. */ target_get_trace_status (ts); writer->ops->start (writer, filename); writer->ops->write_header (writer); /* Write descriptive info. */ /* Write out the size of a register block. */ writer->ops->write_regblock_type (writer, trace_regblock_size); /* Write out the target description info. */ writer->ops->write_tdesc (writer); /* Write out status of the tracing run (aka "tstatus" info). */ writer->ops->write_status (writer, ts); /* Note that we want to upload tracepoints and save those, rather than simply writing out the local ones, because the user may have changed tracepoints in GDB in preparation for a future tracing run, or maybe just mass-deleted all types of breakpoints as part of cleaning up. So as not to contaminate the session, leave the data in its uploaded form, don't make into real tracepoints. */ /* Get trace state variables first, they may be checked when parsing uploaded commands. */ target_upload_trace_state_variables (&uploaded_tsvs); for (utsv = uploaded_tsvs; utsv; utsv = utsv->next) writer->ops->write_uploaded_tsv (writer, utsv); free_uploaded_tsvs (&uploaded_tsvs); target_upload_tracepoints (&uploaded_tps); for (utp = uploaded_tps; utp; utp = utp->next) target_get_tracepoint_status (NULL, utp); for (utp = uploaded_tps; utp; utp = utp->next) writer->ops->write_uploaded_tp (writer, utp); free_uploaded_tps (&uploaded_tps); /* Mark the end of the definition section. */ writer->ops->write_definition_end (writer); /* Get and write the trace data proper. */ while (1) { LONGEST gotten = 0; /* The writer supports writing the contents of trace buffer directly to trace file. Don't parse the contents of trace buffer. */ if (writer->ops->write_trace_buffer != NULL) { /* We ask for big blocks, in the hopes of efficiency, but will take less if the target has packet size limitations or some such. */ gotten = target_get_raw_trace_data (buf, offset, MAX_TRACE_UPLOAD); if (gotten < 0) error (_("Failure to get requested trace buffer data")); /* No more data is forthcoming, we're done. */ if (gotten == 0) break; writer->ops->write_trace_buffer (writer, buf, gotten); offset += gotten; } else { uint16_t tp_num; uint32_t tf_size; /* Parse the trace buffers according to how data are stored in trace buffer in GDBserver. */ gotten = target_get_raw_trace_data (buf, offset, 6); if (gotten == 0) break; /* Read the first six bytes in, which is the tracepoint number and trace frame size. */ tp_num = (uint16_t) extract_unsigned_integer (&buf[0], 2, byte_order); tf_size = (uint32_t) extract_unsigned_integer (&buf[2], 4, byte_order); writer->ops->frame_ops->start (writer, tp_num); gotten = 6; if (tf_size > 0) { unsigned int block; offset += 6; for (block = 0; block < tf_size; ) { gdb_byte block_type; /* We'll fetch one block each time, in order to handle the extremely large 'M' block. We first fetch one byte to get the type of the block. */ gotten = target_get_raw_trace_data (buf, offset, 1); if (gotten < 1) error (_("Failure to get requested trace buffer data")); gotten = 1; block += 1; offset += 1; block_type = buf[0]; switch (block_type) { case 'R': gotten = target_get_raw_trace_data (buf, offset, trace_regblock_size); if (gotten < trace_regblock_size) error (_("Failure to get requested trace" " buffer data")); TRACE_WRITE_R_BLOCK (writer, buf, trace_regblock_size); break; case 'M': { unsigned short mlen; ULONGEST addr; LONGEST t; int j; t = target_get_raw_trace_data (buf,offset, 10); if (t < 10) error (_("Failure to get requested trace" " buffer data")); offset += 10; block += 10; gotten = 0; addr = (ULONGEST) extract_unsigned_integer (buf, 8, byte_order); mlen = (unsigned short) extract_unsigned_integer (&buf[8], 2, byte_order); TRACE_WRITE_M_BLOCK_HEADER (writer, addr, mlen); /* The memory contents in 'M' block may be very large. Fetch the data from the target and write them into file one by one. */ for (j = 0; j < mlen; ) { unsigned int read_length; if (mlen - j > MAX_TRACE_UPLOAD) read_length = MAX_TRACE_UPLOAD; else read_length = mlen - j; t = target_get_raw_trace_data (buf, offset + j, read_length); if (t < read_length) error (_("Failure to get requested" " trace buffer data")); TRACE_WRITE_M_BLOCK_MEMORY (writer, buf, read_length); j += read_length; gotten += read_length; } break; } case 'V': { int vnum; LONGEST val; gotten = target_get_raw_trace_data (buf, offset, 12); if (gotten < 12) error (_("Failure to get requested" " trace buffer data")); vnum = (int) extract_signed_integer (buf, 4, byte_order); val = extract_signed_integer (&buf[4], 8, byte_order); TRACE_WRITE_V_BLOCK (writer, vnum, val); } break; default: error (_("Unknown block type '%c' (0x%x) in" " trace frame"), block_type, block_type); } block += gotten; offset += gotten; } } else offset += gotten; writer->ops->frame_ops->end (writer); } } writer->ops->end (writer); }
int 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_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; LONGEST val; 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) { eltlen = TYPE_LENGTH (elttype); len = TYPE_LENGTH (type) / eltlen; if (options->prettyprint_arrays) { print_spaces_filtered (2 + 2 * recurse, stream); } /* Print arrays of textual chars with a string syntax. */ if (c_textual_element_type (unresolved_elttype, options->format)) { /* 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) ; len = temp_len; } LA_PRINT_STRING (stream, unresolved_elttype, 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 (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, options, i); fprintf_filtered (stream, "}"); } break; } /* Array of unspecified length: treat like pointer to first elt. */ addr = address; goto print_unpacked_pointer; case TYPE_CODE_MEMBERPTR: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); break; } cp_print_class_member (valaddr + embedded_offset, type, stream, "&"); break; case TYPE_CODE_METHODPTR: cplus_print_method_ptr (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_PTR: if (options->format && options->format != 's') { print_scalar_formatted (valaddr + embedded_offset, type, 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 (gdbarch, addr, stream, options->addressprint); break; } unresolved_elttype = TYPE_TARGET_TYPE (type); elttype = check_typedef (unresolved_elttype); { addr = unpack_pointer (type, valaddr + embedded_offset); print_unpacked_pointer: if (TYPE_CODE (elttype) == TYPE_CODE_FUNC) { /* Try to print what function it points to. */ print_function_pointer_address (gdbarch, addr, stream, options->addressprint); /* Return value is irrelevant except for string pointers. */ return (0); } if (options->addressprint) fputs_filtered (paddress (gdbarch, addr), stream); /* 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) { i = val_print_string (unresolved_elttype, 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 minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (vt_address); if ((msymbol != NULL) && (vt_address == SYMBOL_VALUE_ADDRESS (msymbol))) { fputs_filtered (" <", stream); fputs_filtered (SYMBOL_PRINT_NAME (msymbol), stream); fputs_filtered (">", stream); } if (vt_address && options->vtblprint) { struct value *vt_val; struct symbol *wsym = (struct symbol *) NULL; struct type *wtype; struct block *block = (struct block *) NULL; int is_this_fld; if (msymbol != NULL) wsym = lookup_symbol (SYMBOL_LINKAGE_NAME (msymbol), block, VAR_DOMAIN, &is_this_fld); 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->pretty) { fprintf_filtered (stream, "\n"); print_spaces_filtered (2 + 2 * recurse, stream); } } } /* Return number of characters printed, including the terminating '\0' if we reached the end. val_print_string takes care including the terminating '\0' if necessary. */ return i; } break; case TYPE_CODE_REF: elttype = check_typedef (TYPE_TARGET_TYPE (type)); if (options->addressprint) { CORE_ADDR addr = extract_typed_address (valaddr + embedded_offset, type); fprintf_filtered (stream, "@"); fputs_filtered (paddress (gdbarch, addr), stream); if (options->deref_ref) fputs_filtered (": ", stream); } /* De-reference the reference. */ if (options->deref_ref) { if (TYPE_CODE (elttype) != TYPE_CODE_UNDEF) { struct value *deref_val = value_at (TYPE_TARGET_TYPE (type), unpack_pointer (type, valaddr + embedded_offset)); common_val_print (deref_val, stream, recurse, options, current_language); } else fputs_filtered ("???", stream); } break; case TYPE_CODE_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 (gdbarch, addr, stream, options->addressprint); } else cp_print_value_fields_rtti (type, valaddr, embedded_offset, address, stream, recurse, options, NULL, 0); break; case TYPE_CODE_ENUM: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); break; } len = TYPE_NFIELDS (type); val = unpack_long (type, valaddr + embedded_offset); for (i = 0; i < len; i++) { QUIT; if (val == TYPE_FIELD_BITPOS (type, i)) { break; } } if (i < len) { fputs_filtered (TYPE_FIELD_NAME (type, i), stream); } else { print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_FLAGS: if (options->format) print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); else val_print_type_code_flags (type, valaddr + embedded_offset, stream); break; case TYPE_CODE_FUNC: case TYPE_CODE_METHOD: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); break; } /* FIXME, we should consider, at least for ANSI C language, eliminating the distinction made between FUNCs and POINTERs to FUNCs. */ fprintf_filtered (stream, "{"); type_print (type, "", stream, -1); fprintf_filtered (stream, "} "); /* Try to print what function it points to, and its address. */ print_address_demangle (gdbarch, address, stream, demangle); break; case TYPE_CODE_BOOL: if (options->format || options->output_format) { struct value_print_options opts = *options; opts.format = (options->format ? options->format : options->output_format); print_scalar_formatted (valaddr + embedded_offset, type, &opts, 0, stream); } else { val = unpack_long (type, valaddr + embedded_offset); if (val == 0) fputs_filtered ("false", stream); else if (val == 1) fputs_filtered ("true", stream); else print_longest (stream, 'd', 0, val); } break; case TYPE_CODE_RANGE: /* FIXME: create_range_type does not set the unsigned bit in a range type (I think it probably should copy it from the target type), so we won't print values which are too large to fit in a signed integer correctly. */ /* FIXME: Doesn't handle ranges of enums correctly. (Can't just print with the target type, though, because the size of our type and the target type might differ). */ /* FALLTHROUGH */ case TYPE_CODE_INT: 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 + embedded_offset, type, &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 ((unsigned char) unpack_long (type, valaddr + embedded_offset), unresolved_type, stream); } } break; case TYPE_CODE_CHAR: 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 + embedded_offset, type, &opts, 0, stream); } else { val = unpack_long (type, valaddr + embedded_offset); if (TYPE_UNSIGNED (type)) fprintf_filtered (stream, "%u", (unsigned int) val); else fprintf_filtered (stream, "%d", (int) val); fputs_filtered (" ", stream); LA_PRINT_CHAR ((unsigned char) val, unresolved_type, stream); } break; case TYPE_CODE_FLT: if (options->format) { print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); } else { print_floating (valaddr + embedded_offset, type, stream); } break; case TYPE_CODE_DECFLOAT: if (options->format) print_scalar_formatted (valaddr + embedded_offset, type, options, 0, stream); else print_decimal_floating (valaddr + embedded_offset, type, stream); break; case TYPE_CODE_VOID: fprintf_filtered (stream, "void"); break; case TYPE_CODE_ERROR: fprintf_filtered (stream, _("<error type>")); break; case TYPE_CODE_UNDEF: /* This happens (without TYPE_FLAG_STUB set) on systems which don't use dbx xrefs (NO_DBX_XREFS in gcc) if a file has a "struct foo *bar" and no complete type for struct foo in that file. */ fprintf_filtered (stream, _("<incomplete type>")); break; case TYPE_CODE_COMPLEX: if (options->format) print_scalar_formatted (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), options, 0, stream); else print_floating (valaddr + embedded_offset, TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " + "); if (options->format) print_scalar_formatted (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), options, 0, stream); else print_floating (valaddr + embedded_offset + TYPE_LENGTH (TYPE_TARGET_TYPE (type)), TYPE_TARGET_TYPE (type), stream); fprintf_filtered (stream, " * I"); break; default: error (_("Invalid C/C++ type code %d in symbol table."), TYPE_CODE (type)); } gdb_flush (stream); return (0); }
static CORE_ADDR lm_base (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); struct minimal_symbol *got_sym; CORE_ADDR addr; gdb_byte buf[TIC6X_PTR_SIZE]; struct dsbt_info *info = get_dsbt_info (); /* One of our assumptions is that the main executable has been relocated. Bail out if this has not happened. (Note that post_create_inferior in infcmd.c will call solib_add prior to solib_create_inferior_hook. If we allow this to happen, lm_base_cache will be initialized with a bogus value. */ if (info->main_executable_lm_info == 0) return 0; /* If we already have a cached value, return it. */ if (info->lm_base_cache) return info->lm_base_cache; got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL, symfile_objfile); if (got_sym != 0) { addr = SYMBOL_VALUE_ADDRESS (got_sym); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n", (unsigned int) addr); } else if (scan_dyntag (DT_PLTGOT, exec_bfd, &addr)) { struct int_elf32_dsbt_loadmap *ldm; dsbt_get_initial_loadmaps (); ldm = info->exec_loadmap; addr += displacement_from_map (ldm, addr); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "lm_base: get addr %x by DT_PLTGOT.\n", (unsigned int) addr); } else { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n"); return 0; } addr += GOT_MODULE_OFFSET; if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "lm_base: _GLOBAL_OFFSET_TABLE_ + %d = %s\n", GOT_MODULE_OFFSET, hex_string_custom (addr, 8)); if (target_read_memory (addr, buf, sizeof buf) != 0) return 0; info->lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "lm_base: lm_base_cache = %s\n", hex_string_custom (info->lm_base_cache, 8)); return info->lm_base_cache; }
static struct libunwind_frame_cache * libunwind_frame_cache (struct frame_info *this_frame, void **this_cache) { unw_accessors_t *acc; unw_addr_space_t as; unw_word_t fp; unw_regnum_t uw_sp_regnum; struct libunwind_frame_cache *cache; struct libunwind_descr *descr; struct gdbarch *gdbarch = get_frame_arch (this_frame); int i, ret; if (*this_cache) return (struct libunwind_frame_cache *) *this_cache; /* Allocate a new cache. */ cache = FRAME_OBSTACK_ZALLOC (struct libunwind_frame_cache); cache->func_addr = get_frame_func (this_frame); if (cache->func_addr == 0) /* This can happen when the frame corresponds to a function for which there is no debugging information nor any entry in the symbol table. This is probably a static function for which an entry in the symbol table was not created when the objfile got linked (observed in libpthread.so on ia64-hpux). The best we can do, in that case, is use the frame PC as the function address. We don't need to give up since we still have the unwind record to help us perform the unwinding. There is also another compelling to continue, because abandonning now means stopping the backtrace, which can never be helpful for the user. */ cache->func_addr = get_frame_pc (this_frame); /* Get a libunwind cursor to the previous frame. We do this by initializing a cursor. Libunwind treats a new cursor as the top of stack and will get the current register set via the libunwind register accessor. Now, we provide the platform-specific accessors and we set up the register accessor to use the frame register unwinding interfaces so that we properly get the registers for the current frame rather than the top. We then use the unw_step function to move the libunwind cursor back one frame. We can later use this cursor to find previous registers via the unw_get_reg interface which will invoke libunwind's special logic. */ descr = libunwind_descr (gdbarch); acc = (unw_accessors_t *) descr->accessors; as = unw_create_addr_space_p (acc, gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG ? __BIG_ENDIAN : __LITTLE_ENDIAN); unw_init_remote_p (&cache->cursor, as, this_frame); if (unw_step_p (&cache->cursor) < 0) { unw_destroy_addr_space_p (as); return NULL; } /* To get base address, get sp from previous frame. */ uw_sp_regnum = descr->gdb2uw (gdbarch_sp_regnum (gdbarch)); ret = unw_get_reg_p (&cache->cursor, uw_sp_regnum, &fp); if (ret < 0) { unw_destroy_addr_space_p (as); error (_("Can't get libunwind sp register.")); } cache->base = (CORE_ADDR)fp; cache->as = as; *this_cache = cache; return cache; }
static int enable_break (void) { enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); asection *interp_sect; struct dsbt_info *info; if (exec_bfd == NULL) return 0; if (!target_has_execution) return 0; info = get_dsbt_info (); info->interp_text_sect_low = 0; info->interp_text_sect_high = 0; info->interp_plt_sect_low = 0; info->interp_plt_sect_high = 0; /* Find the .interp section; if not found, warn the user and drop into the old breakpoint at symbol code. */ interp_sect = bfd_get_section_by_name (exec_bfd, ".interp"); if (interp_sect) { unsigned int interp_sect_size; char *buf; bfd *tmp_bfd = NULL; CORE_ADDR addr; gdb_byte addr_buf[TIC6X_PTR_SIZE]; struct int_elf32_dsbt_loadmap *ldm; volatile struct gdb_exception ex; int ret; /* Read the contents of the .interp section into a local buffer; the contents specify the dynamic linker this program uses. */ interp_sect_size = bfd_section_size (exec_bfd, interp_sect); buf = alloca (interp_sect_size); bfd_get_section_contents (exec_bfd, interp_sect, buf, 0, interp_sect_size); /* Now we need to figure out where the dynamic linker was loaded so that we can load its symbols and place a breakpoint in the dynamic linker itself. */ TRY_CATCH (ex, RETURN_MASK_ALL) { tmp_bfd = solib_bfd_open (buf); } if (tmp_bfd == NULL) { enable_break_failure_warning (); return 0; } dsbt_get_initial_loadmaps (); ldm = info->interp_loadmap; /* Record the relocated start and end address of the dynamic linker text and plt section for dsbt_in_dynsym_resolve_code. */ interp_sect = bfd_get_section_by_name (tmp_bfd, ".text"); if (interp_sect) { info->interp_text_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_text_sect_low += displacement_from_map (ldm, info->interp_text_sect_low); info->interp_text_sect_high = info->interp_text_sect_low + bfd_section_size (tmp_bfd, interp_sect); } interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt"); if (interp_sect) { info->interp_plt_sect_low = bfd_section_vma (tmp_bfd, interp_sect); info->interp_plt_sect_low += displacement_from_map (ldm, info->interp_plt_sect_low); info->interp_plt_sect_high = info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect); } addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state"); if (addr != 0) { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state (prior to relocation) = %s\n", hex_string_custom (addr, 8)); addr += displacement_from_map (ldm, addr); if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state (after relocation) = %s\n", hex_string_custom (addr, 8)); /* Now (finally!) create the solib breakpoint. */ create_solib_event_breakpoint (target_gdbarch (), addr); ret = 1; } else { if (solib_dsbt_debug) fprintf_unfiltered (gdb_stdlog, "enable_break: _dl_debug_state is not found\n"); ret = 0; } /* We're done with the temporary bfd. */ gdb_bfd_unref (tmp_bfd); /* We're also done with the loadmap. */ xfree (ldm); return ret; }
static void i386_linux_resume (struct target_ops *ops, ptid_t ptid, int step, enum gdb_signal signal) { int pid = ptid_get_pid (ptid); int request; if (catch_syscall_enabled () > 0) request = PTRACE_SYSCALL; else request = PTRACE_CONT; if (step) { struct regcache *regcache = get_thread_regcache (pid_to_ptid (pid)); struct gdbarch *gdbarch = get_regcache_arch (regcache); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST pc; gdb_byte buf[LINUX_SYSCALL_LEN]; request = PTRACE_SINGLESTEP; regcache_cooked_read_unsigned (regcache, gdbarch_pc_regnum (gdbarch), &pc); /* Returning from a signal trampoline is done by calling a special system call (sigreturn or rt_sigreturn, see i386-linux-tdep.c for more information). This system call restores the registers that were saved when the signal was raised, including %eflags. That means that single-stepping won't work. Instead, we'll have to modify the signal context that's about to be restored, and set the trace flag there. */ /* First check if PC is at a system call. */ if (target_read_memory (pc, buf, LINUX_SYSCALL_LEN) == 0 && memcmp (buf, linux_syscall, LINUX_SYSCALL_LEN) == 0) { ULONGEST syscall; regcache_cooked_read_unsigned (regcache, LINUX_SYSCALL_REGNUM, &syscall); /* Then check the system call number. */ if (syscall == SYS_sigreturn || syscall == SYS_rt_sigreturn) { ULONGEST sp, addr; unsigned long int eflags; regcache_cooked_read_unsigned (regcache, I386_ESP_REGNUM, &sp); if (syscall == SYS_rt_sigreturn) addr = read_memory_unsigned_integer (sp + 8, 4, byte_order) + 20; else addr = sp; /* Set the trace flag in the context that's about to be restored. */ addr += LINUX_SIGCONTEXT_EFLAGS_OFFSET; read_memory (addr, (gdb_byte *) &eflags, 4); eflags |= 0x0100; write_memory (addr, (gdb_byte *) &eflags, 4); } } } if (ptrace (request, pid, 0, gdb_signal_to_host (signal)) == -1) perror_with_name (("ptrace")); }
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; 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->prettyprint_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; void *buffer; if (want_space) fputs_filtered (" ", stream); buffer = 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 == 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 = TYPE_TARGET_TYPE (type); } vt_val = value_at (wtype, vt_address); common_val_print (vt_val, stream, recurse + 1, options, current_language); if (options->pretty) { 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); 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); }
static enum return_value_convention do_ppc_sysv_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf, int broken_gcc) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_assert (tdep->wordsize == 4); if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) <= 8 && !tdep->soft_float) { 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; } if (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 16 && !tdep->soft_float && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) { /* IBM long double stored in f1 and f2. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 1, readbuf); regcache_cooked_read (regcache, tdep->ppc_fp0_regnum + 2, readbuf + 8); } if (writebuf) { regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 1, writebuf); regcache_cooked_write (regcache, tdep->ppc_fp0_regnum + 2, writebuf + 8); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) == 16 && ((TYPE_CODE (type) == TYPE_CODE_FLT && (gdbarch_long_double_format (gdbarch) == floatformats_ibm_long_double)) || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && tdep->soft_float))) { /* Soft-float IBM long double or _Decimal128 stored in r3, r4, r5, r6. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, readbuf + 4); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5, readbuf + 8); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6, readbuf + 12); } if (writebuf) { regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, writebuf + 4); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5, writebuf + 8); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6, writebuf + 12); } return RETURN_VALUE_REGISTER_CONVENTION; } if ((TYPE_CODE (type) == TYPE_CODE_INT && TYPE_LENGTH (type) == 8) || (TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8) || (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && TYPE_LENGTH (type) == 8 && tdep->soft_float)) { if (readbuf) { /* A long long, double or _Decimal64 stored in the 32 bit r3/r4. */ regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf + 0); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, readbuf + 4); } if (writebuf) { /* A long long, double or _Decimal64 stored in the 32 bit r3/r4. */ regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf + 0); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, writebuf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_CODE (type) == TYPE_CODE_DECFLOAT && !tdep->soft_float) return get_decimal_float_return_value (gdbarch, type, regcache, readbuf, writebuf); else if ((TYPE_CODE (type) == TYPE_CODE_INT || TYPE_CODE (type) == TYPE_CODE_CHAR || TYPE_CODE (type) == TYPE_CODE_BOOL || TYPE_CODE (type) == TYPE_CODE_PTR || TYPE_CODE (type) == TYPE_CODE_REF || TYPE_CODE (type) == TYPE_CODE_ENUM) && 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), byte_order, 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->vector_abi == POWERPC_VEC_ALTIVEC) { 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) == 16 && TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && tdep->vector_abi == POWERPC_VEC_GENERIC) { /* GCC -maltivec -mabi=no-altivec returns vectors in r3/r4/r5/r6. GCC without AltiVec returns them in memory, but it warns about ABI risks in that case; we don't try to support it. */ if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, readbuf + 0); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, readbuf + 4); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 5, readbuf + 8); regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 6, readbuf + 12); } if (writebuf) { regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, writebuf + 0); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, writebuf + 4); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 5, writebuf + 8); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 6, writebuf + 12); } return RETURN_VALUE_REGISTER_CONVENTION; } if (TYPE_LENGTH (type) == 8 && TYPE_CODE (type) == TYPE_CODE_ARRAY && TYPE_VECTOR (type) && tdep->vector_abi == POWERPC_VEC_SPE) { /* 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) { /* GCC screwed up for structures or unions whose size is less than or equal to 8 bytes.. Instead of left-aligning, it right-aligns the data into the buffer formed by r3, r4. */ gdb_byte regvals[MAX_REGISTER_SIZE * 2]; int len = TYPE_LENGTH (type); int offset = (2 * tdep->wordsize - len) % tdep->wordsize; if (readbuf) { regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (len > tdep->wordsize) regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, regvals + 1 * tdep->wordsize); memcpy (readbuf, regvals + offset, len); } if (writebuf) { memset (regvals, 0, sizeof regvals); memcpy (regvals + offset, writebuf, len); regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (len > tdep->wordsize) regcache_cooked_write (regcache, tdep->ppc_gp0_regnum + 4, regvals + 1 * tdep->wordsize); } 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. */ gdb_byte regvals[MAX_REGISTER_SIZE * 2]; regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 3, regvals + 0 * tdep->wordsize); if (TYPE_LENGTH (type) > tdep->wordsize) regcache_cooked_read (regcache, tdep->ppc_gp0_regnum + 4, regvals + 1 * tdep->wordsize); memcpy (readbuf, regvals, TYPE_LENGTH (type)); } 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; }