static enum return_value_convention m68k_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); /* GCC returns a `long double' in memory too. */ if (((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) && !m68k_reg_struct_return_p (gdbarch, type)) || (code == TYPE_CODE_FLT && TYPE_LENGTH (type) == 12)) { /* The default on m68k is to return structures in static memory. Consequently a function must return the address where we can find the return value. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned (regcache, M68K_D0_REGNUM, &addr); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } if (readbuf) m68k_extract_return_value (type, regcache, readbuf); if (writebuf) m68k_store_return_value (type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; }
static int i386_linux_record_signal (struct gdbarch *gdbarch, struct regcache *regcache, enum gdb_signal signal) { ULONGEST esp; if (i386_all_but_ip_registers_record (regcache)) return -1; if (record_arch_list_add_reg (regcache, I386_EIP_REGNUM)) return -1; /* Record the change in the stack. */ regcache_raw_read_unsigned (regcache, I386_ESP_REGNUM, &esp); /* This is for xstate. sp -= sizeof (struct _fpstate); */ esp -= I386_LINUX_xstate; /* This is for frame_size. sp -= sizeof (struct rt_sigframe); */ esp -= I386_LINUX_frame_size; if (record_arch_list_add_mem (esp, I386_LINUX_xstate + I386_LINUX_frame_size)) return -1; if (record_arch_list_add_end ()) return -1; return 0; }
ULONGEST regcache_raw_get_unsigned (struct regcache *regcache, int regnum) { ULONGEST value; enum register_status status; status = regcache_raw_read_unsigned (regcache, regnum, &value); if (status == REG_UNAVAILABLE) throw_error (NOT_AVAILABLE_ERROR, _("Register %d is not available"), regnum); return value; }
static enum return_value_convention m68k_svr4_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { enum type_code code = TYPE_CODE (type); if ((code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION || code == TYPE_CODE_COMPLEX) && !m68k_reg_struct_return_p (gdbarch, type)) { /* The System V ABI says that: "A function returning a structure or union also sets %a0 to the value it finds in %a0. Thus when the caller receives control again, the address of the returned object resides in register %a0." So the ABI guarantees that we can always find the return value just after the function has returned. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned (regcache, M68K_A0_REGNUM, &addr); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } /* This special case is for structures consisting of a single `float' or `double' member. These structures are returned in %fp0. For these structures, we call ourselves recursively, changing TYPE into the type of the first member of the structure. Since that should work for all structures that have only one member, we don't bother to check the member's type here. */ if (code == TYPE_CODE_STRUCT && TYPE_NFIELDS (type) == 1) { type = check_typedef (TYPE_FIELD_TYPE (type, 0)); return m68k_svr4_return_value (gdbarch, function, type, regcache, readbuf, writebuf); } if (readbuf) m68k_svr4_extract_return_value (type, regcache, readbuf); if (writebuf) m68k_svr4_store_return_value (type, regcache, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; }
static enum return_value_convention amd64_windows_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { int len = TYPE_LENGTH (type); int regnum = -1; /* See if our value is returned through a register. If it is, then store the associated register number in REGNUM. */ switch (TYPE_CODE (type)) { case TYPE_CODE_FLT: case TYPE_CODE_DECFLOAT: /* __m128, __m128i, __m128d, floats, and doubles are returned via XMM0. */ if (len == 4 || len == 8 || len == 16) regnum = AMD64_XMM0_REGNUM; break; default: /* All other values that are 1, 2, 4 or 8 bytes long are returned via RAX. */ if (len == 1 || len == 2 || len == 4 || len == 8) regnum = AMD64_RAX_REGNUM; break; } if (regnum < 0) { /* RAX contains the address where the return value has been stored. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr); read_memory (addr, readbuf, TYPE_LENGTH (type)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } else { /* Extract the return value from the register where it was stored. */ if (readbuf) regcache_raw_read_part (regcache, regnum, 0, len, readbuf); if (writebuf) regcache_raw_write_part (regcache, regnum, 0, len, writebuf); return RETURN_VALUE_REGISTER_CONVENTION; } }
static enum return_value_convention vax_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { int len = TYPE_LENGTH (type); gdb_byte buf[8]; if (TYPE_CODE (type) == TYPE_CODE_STRUCT || TYPE_CODE (type) == TYPE_CODE_UNION || TYPE_CODE (type) == TYPE_CODE_ARRAY) { /* The default on VAX is to return structures in static memory. Consequently a function must return the address where we can find the return value. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned (regcache, VAX_R0_REGNUM, &addr); read_memory (addr, readbuf, len); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } if (readbuf) { /* Read the contents of R0 and (if necessary) R1. */ regcache_cooked_read (regcache, VAX_R0_REGNUM, buf); if (len > 4) regcache_cooked_read (regcache, VAX_R1_REGNUM, buf + 4); memcpy (readbuf, buf, len); } if (writebuf) { /* Read the contents to R0 and (if necessary) R1. */ memcpy (buf, writebuf, len); regcache_cooked_write (regcache, VAX_R0_REGNUM, buf); if (len > 4) regcache_cooked_write (regcache, VAX_R1_REGNUM, buf + 4); } return RETURN_VALUE_REGISTER_CONVENTION; }
static void ia64_hpux_fetch_rnat_register (struct regcache *regcache) { CORE_ADDR addr; gdb_byte buf[8]; int status; /* The value of RNAT is stored at bsp|0x1f8, and must be read using TT_LWP_RDRSEBS. */ regcache_raw_read_unsigned (regcache, IA64_BSP_REGNUM, &addr); addr |= 0x1f8; status = ttrace (TT_LWP_RDRSEBS, ptid_get_pid (inferior_ptid), ptid_get_lwp (inferior_ptid), addr, sizeof (buf), (uintptr_t) buf); if (status < 0) error (_("failed to read RNAT register at %s"), paddress (get_regcache_arch(regcache), addr)); regcache_raw_supply (regcache, IA64_RNAT_REGNUM, buf); }
static enum register_status msp430_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int regnum, gdb_byte *buffer) { enum register_status status = REG_UNKNOWN; if (MSP430_NUM_REGS <= regnum && regnum < MSP430_NUM_TOTAL_REGS) { ULONGEST val; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int regsize = register_size (gdbarch, regnum); int raw_regnum = regnum - MSP430_NUM_REGS; status = regcache_raw_read_unsigned (regcache, raw_regnum, &val); if (status == REG_VALID) store_unsigned_integer (buffer, regsize, byte_order, val); } else gdb_assert_not_reached ("invalid pseudo register number"); return status; }
static LONGEST ia64_hpux_xfer_memory (struct target_ops *ops, const char *annex, gdb_byte *readbuf, const gdb_byte *writebuf, CORE_ADDR addr, LONGEST len) { CORE_ADDR bsp, bspstore; CORE_ADDR start_addr, short_len; int status = 0; /* The back-store region cannot be read/written by the standard memory read/write operations. So we handle the memory region piecemeal: (1) and (2) The regions before and after the backing-store region, which can be treated as normal memory; (3) The region inside the backing-store, which needs to be read/written specially. */ regcache_raw_read_unsigned (get_current_regcache (), IA64_BSP_REGNUM, &bsp); regcache_raw_read_unsigned (get_current_regcache (), IA64_BSPSTORE_REGNUM, &bspstore); /* 1. Memory region before BSPSTORE. */ if (addr < bspstore) { short_len = len; if (addr + len > bspstore) short_len = bspstore - addr; status = ia64_hpux_xfer_memory_no_bs (ops, annex, readbuf, writebuf, addr, short_len); if (status <= 0) return 0; } /* 2. Memory region after BSP. */ if (addr + len > bsp) { start_addr = addr; if (start_addr < bsp) start_addr = bsp; short_len = len + addr - start_addr; status = ia64_hpux_xfer_memory_no_bs (ops, annex, readbuf ? readbuf + (start_addr - addr) : NULL, writebuf ? writebuf + (start_addr - addr) : NULL, start_addr, short_len); if (status <= 0) return 0; } /* 3. Memory region between BSPSTORE and BSP. */ if (bspstore != bsp && ((addr < bspstore && addr + len > bspstore) || (addr + len <= bsp && addr + len > bsp))) { start_addr = addr; if (addr < bspstore) start_addr = bspstore; short_len = len + addr - start_addr; if (start_addr + short_len > bsp) short_len = bsp - start_addr; gdb_assert (short_len > 0); status = ia64_hpux_xfer_memory_bs (ops, annex, readbuf ? readbuf + (start_addr - addr) : NULL, writebuf ? writebuf + (start_addr - addr) : NULL, start_addr, short_len); if (status < 0) return 0; } return len; }
static enum return_value_convention amd64_return_value(struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { enum amd64_reg_class reg_class[2]; int len = TYPE_LENGTH(type); static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM }; static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM }; int integer_reg = 0; int sse_reg = 0; int i; gdb_assert(!(readbuf && writebuf)); /* 1. Classify the return type with the classification algorithm: */ amd64_classify(type, reg_class); /* 2. If the type has class MEMORY, then the caller provides space for the return value and passes the address of this storage in %rdi as if it were the first argument to the function. In effect, this address becomes a hidden first argument. On return %rax will contain the address that has been passed in by the caller in %rdi. */ if (reg_class[0] == AMD64_MEMORY) { /* As indicated by the comment above, the ABI guarantees that we can always find the return value just after the function has returned. */ if (readbuf) { ULONGEST addr; regcache_raw_read_unsigned(regcache, AMD64_RAX_REGNUM, &addr); read_memory(addr, readbuf, TYPE_LENGTH(type)); } return RETURN_VALUE_ABI_RETURNS_ADDRESS; } gdb_assert(reg_class[1] != AMD64_MEMORY); gdb_assert(len <= 16); for (i = 0; len > 0; i++, len -= 8) { int regnum = -1; int offset = 0; switch (reg_class[i]) { case AMD64_INTEGER: /* 3. If the class is INTEGER, the next available register of the sequence %rax, %rdx is used. */ regnum = integer_regnum[integer_reg++]; break; case AMD64_SSE: /* 4. If the class is SSE, the next available SSE register of the sequence %xmm0, %xmm1 is used. */ regnum = sse_regnum[sse_reg++]; break; case AMD64_SSEUP: /* 5. If the class is SSEUP, the eightbyte is passed in the upper half of the last used SSE register. */ gdb_assert (sse_reg > 0); regnum = sse_regnum[sse_reg - 1]; offset = 8; break; case AMD64_X87: /* 6. If the class is X87, the value is returned on the X87 stack in %st0 as 80-bit x87 number. */ regnum = AMD64_ST0_REGNUM; if (writebuf) i387_return_value(gdbarch, regcache); break; case AMD64_X87UP: /* 7. If the class is X87UP, the value is returned together with the previous X87 value in %st0. */ gdb_assert((i > 0) && (reg_class[0] == AMD64_X87)); regnum = AMD64_ST0_REGNUM; offset = 8; len = 2; break; case AMD64_NO_CLASS: continue; default: gdb_assert(!"Unexpected register class."); } gdb_assert(regnum != -1); /* APPLE LOCAL: We keep the XMM registers in the "user's view" byte order inside gdb so we need to unswap them before the ABI read/writes which assume the actual machine byte order. */ if ((readbuf || writebuf) && ((regnum == sse_regnum[0]) || (regnum == sse_regnum[1]))) { if (readbuf) swapped_regcache_raw_read_part(regcache, regnum, offset, min(len, 8), readbuf + i * 8); if (writebuf) swapped_regcache_raw_write_part(regcache, regnum, offset, min(len, 8), writebuf + i * 8); continue; } if (readbuf) regcache_raw_read_part(regcache, regnum, offset, min(len, 8), readbuf + i * 8); if (writebuf) regcache_raw_write_part(regcache, regnum, offset, min(len, 8), writebuf + i * 8); } return RETURN_VALUE_REGISTER_CONVENTION; }