static void mn10300_print_register (const char *name, int regnum, int reg_width) { char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE); if (reg_width) printf_filtered ("%*s: ", reg_width, name); else printf_filtered ("%s: ", name); /* Get the data */ if (!frame_register_read (selected_frame, regnum, raw_buffer)) { printf_filtered ("[invalid]"); return; } else { int byte; if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum); byte < REGISTER_RAW_SIZE (regnum); byte++) printf_filtered ("%02x", (unsigned char) raw_buffer[byte]); } else { for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1; byte >= 0; byte--) printf_filtered ("%02x", (unsigned char) raw_buffer[byte]); } } }
void store_inferior_registers (int ignored) { struct regs inferior_registers; struct fp_status inferior_fp_registers; CORE_ADDR sp = *(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)]; write_inferior_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], 16 * REGISTER_RAW_SIZE (L0_REGNUM)); memcpy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (G1_REGNUM)], 15 * REGISTER_RAW_SIZE (G1_REGNUM)); inferior_registers.r_ps = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)]; inferior_registers.r_pc = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)]; inferior_registers.r_npc = *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)]; inferior_registers.r_y = *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)]; if (ptrace (PTRACE_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0)) perror ("ptrace_setregs"); memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], sizeof inferior_fp_registers.fpu_fr); if (ptrace (PTRACE_SETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) perror ("ptrace_setfpregs"); }
static void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which, CORE_ADDR ignore) { if (which == 0) { /* Integer registers */ #define gregs ((struct regs *)core_reg_sect) /* G0 *always* holds 0. */ *(int *) ®isters[REGISTER_BYTE (0)] = 0; /* The globals and output registers. */ memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &gregs->r_g1, 15 * REGISTER_RAW_SIZE (G1_REGNUM)); *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = gregs->r_ps; *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = gregs->r_pc; *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = gregs->r_npc; *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = gregs->r_y; /* My best guess at where to get the locals and input registers is exactly where they usually are, right above the stack pointer. If the core dump was caused by a bus error from blowing away the stack pointer (as is possible) then this won't work, but it's worth the try. */ { int sp; sp = *(int *) ®isters[REGISTER_BYTE (SP_REGNUM)]; if (0 != target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], 16 * REGISTER_RAW_SIZE (L0_REGNUM))) { /* fprintf_unfiltered so user can still use gdb */ fprintf_unfiltered (gdb_stderr, "Couldn't read input and local registers from core file\n"); } } } else if (which == 2) { /* Floating point registers */ #define fpuregs ((struct fpu *) core_reg_sect) if (core_reg_size >= sizeof (struct fpu)) { memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fpuregs->fpu_regs, sizeof (fpuregs->fpu_regs)); memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &fpuregs->fpu_fsr, sizeof (FPU_FSR_TYPE)); } else fprintf_unfiltered (gdb_stderr, "Couldn't read float regs from core file\n"); } }
static void fetch_register (int regno) { register unsigned int regaddr; char buf[MAX_REGISTER_RAW_SIZE]; register int i; /* Offset of registers within the u area. */ unsigned int offset; offset = U_REGS_OFFSET; regaddr = register_addr (regno, offset); for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { errno = 0; *(int *) &buf[i] = ptrace (PT_RUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, 0); regaddr += sizeof (int); if (errno != 0) { /* Warning, not error, in case we are attached; sometimes the kernel doesn't let us at the registers. */ char *err = safe_strerror (errno); char *msg = alloca (strlen (err) + 128); sprintf (msg, "reading register %s: %s", REGISTER_NAME (regno), err); warning (msg); goto error_exit; } } supply_register (regno, buf); error_exit:; }
void fetch_inferior_registers (int regno) { register unsigned int regaddr; char buf[MAX_REGISTER_RAW_SIZE]; register int i; registers_fetched (); for (regno = 1; regno < NUM_REGS; regno++) { regaddr = REGISTER_PTRACE_ADDR (regno); for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { *(int *) &buf[i] = ptrace (PT_READ_U, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, 0); regaddr += sizeof (int); } supply_register (regno, buf); } supply_register (ZERO_REGNUM, zerobuf); /* Frame ptr reg must appear to be 0; it is faked by stack handling code. */ supply_register (FP_REGNUM, zerobuf); }
void fetch_inferior_registers () { register int regno; register unsigned int regaddr; char buf[MAX_REGISTER_RAW_SIZE]; register int i; struct USER u; unsigned int offset; offset = (char *) &u.pt_r0 - (char *) &u; regaddr = offset; /* byte offset to r0;*/ /* offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; */ for (regno = 0; regno < NUM_REGS; regno++) { /*regaddr = register_addr (regno, offset);*/ /* 88k enhancement */ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0); regaddr += sizeof (int); } supply_register (regno, buf); } /* now load up registers 36 - 38; special pc registers */ *(int *) &buf[0] = ptrace (3,inferior_pid,(char *)&u.pt_sigframe.dg_sigframe.sc_sxip - (char *)&u ,0); supply_register (SXIP_REGNUM, buf); *(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_snip - (char *)&u ,0); supply_register (SNIP_REGNUM, buf); *(int *) &buf[0] = ptrace (3, inferior_pid, (char *)&u.pt_sigframe.dg_sigframe.sc_sfip - (char *)&u ,0); supply_register (SFIP_REGNUM, buf); }
CORE_ADDR generic_read_register_dummy (CORE_ADDR pc, CORE_ADDR fp, int regno) { char *dummy_regs = generic_find_dummy_frame (pc, fp); if (dummy_regs) return extract_address (&dummy_regs[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); else return 0; }
void fetch_inferior_registers (int ignored) { struct regs inferior_registers; struct fp_status inferior_fp_registers; int i; /* Global and Out regs are fetched directly, as well as the control registers. If we're getting one of the in or local regs, and the stack pointer has not yet been fetched, we have to do that first, since they're found in memory relative to the stack pointer. */ if (ptrace (PTRACE_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0)) perror ("ptrace_getregs"); registers[REGISTER_BYTE (0)] = 0; memcpy (®isters[REGISTER_BYTE (1)], &inferior_registers.r_g1, 15 * REGISTER_RAW_SIZE (G0_REGNUM)); *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; /* Floating point registers */ if (ptrace (PTRACE_GETFPREGS, inferior_pid, (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) perror ("ptrace_getfpregs"); memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, sizeof inferior_fp_registers.fpu_fr); /* These regs are saved on the stack by the kernel. Only read them all (16 ptrace calls!) if we really need them. */ read_inferior_memory (*(CORE_ADDR *) & registers[REGISTER_BYTE (SP_REGNUM)], ®isters[REGISTER_BYTE (L0_REGNUM)], 16 * REGISTER_RAW_SIZE (L0_REGNUM)); }
void store_inferior_registers (int regno) { register unsigned int regaddr; char buf[80]; register int i; unsigned int offset = U_REGS_OFFSET; int scratch; if (regno >= 0) { if (CANNOT_STORE_REGISTER (regno)) return; regaddr = register_addr (regno, offset); errno = 0; if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM) { scratch = *(int *) ®isters[REGISTER_BYTE (regno)] | 0x3; ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, scratch); if (errno != 0) { /* Error, even if attached. Failing to write these two registers is pretty serious. */ sprintf (buf, "writing register number %d", regno); perror_with_name (buf); } } else for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { errno = 0; ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, *(int *) ®isters[REGISTER_BYTE (regno) + i]); if (errno != 0) { /* Warning, not error, in case we are attached; sometimes the kernel doesn't let us at the registers. */ char *err = safe_strerror (errno); char *msg = alloca (strlen (err) + 128); sprintf (msg, "writing register %s: %s", REGISTER_NAME (regno), err); warning (msg); return; } regaddr += sizeof (int); } } else for (regno = 0; regno < NUM_REGS; regno++) store_inferior_registers (regno); }
void store_inferior_registers (int regno) { if (regno == -1) { for (regno = 0; regno < NUM_REGS; regno++) store_inferior_registers (regno); } else sim_store_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); }
void store_inferior_registers (int regno) { int reglo, reghi; int i; unsigned long ecp; if (regno == -1) { reglo = 0; reghi = NUM_REGS - 1; } else reglo = reghi = regno; ecp = registers_addr (PIDGET (inferior_ptid)); for (regno = reglo; regno <= reghi; regno++) { int ptrace_fun = PTRACE_POKEUSER; if (CANNOT_STORE_REGISTER (regno)) continue; #ifdef M68K ptrace_fun = regno == SP_REGNUM ? PTRACE_POKEUSP : PTRACE_POKEUSER; #endif for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { unsigned int reg; reg = *(unsigned int *) ®isters[REGISTER_BYTE (regno) + i]; errno = 0; ptrace (ptrace_fun, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), reg); if (errno) perror_with_name ("ptrace(PTRACE_POKEUSP)"); } } }
void fetch_inferior_registers (int regno) { int reglo, reghi; int i; unsigned long ecp; if (regno == -1) { reglo = 0; reghi = NUM_REGS - 1; } else reglo = reghi = regno; ecp = registers_addr (PIDGET (inferior_ptid)); for (regno = reglo; regno <= reghi; regno++) { char buf[MAX_REGISTER_RAW_SIZE]; int ptrace_fun = PTRACE_PEEKTHREAD; #ifdef M68K ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; #endif for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { unsigned int reg; errno = 0; reg = ptrace (ptrace_fun, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) (ecp + regmap[regno] + i), 0); if (errno) perror_with_name ("ptrace(PTRACE_PEEKUSP)"); *(int *) &buf[i] = reg; } supply_register (regno, buf); } }
void fetch_inferior_registers (int regno) { register unsigned int regaddr; char buf[MAX_REGISTER_RAW_SIZE]; register int i; struct USER u; unsigned int offset; offset = (char *) &u.pt_r0 - (char *) &u; regaddr = offset; /* byte offset to r0; */ /* offset = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) offset, 0) - KERNEL_U_ADDR; */ for (regno = 0; regno < NUM_REGS; regno++) { /*regaddr = register_addr (regno, offset); */ /* 88k enhancement */ for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { *(int *) &buf[i] = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) regaddr, 0); regaddr += sizeof (int); } supply_register (regno, buf); } /* now load up registers 36 - 38; special pc registers */ *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) SXIP_OFFSET, 0); supply_register (SXIP_REGNUM, buf); *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) SNIP_OFFSET, 0); supply_register (SNIP_REGNUM, buf); *(int *) &buf[0] = ptrace (3, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) SFIP_OFFSET, 0); supply_register (SFIP_REGNUM, buf); }
/* generic_pop_current_frame calls this function if the current frame isn't a dummy frame. */ static void mn10300_pop_frame_regular (struct frame_info *frame) { int regnum; write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); /* Restore any saved registers. */ for (regnum = 0; regnum < NUM_REGS; regnum++) if (frame->saved_regs[regnum] != 0) { ULONGEST value; value = read_memory_unsigned_integer (frame->saved_regs[regnum], REGISTER_RAW_SIZE (regnum)); write_register (regnum, value); } /* Actually cut back the stack. */ write_register (SP_REGNUM, FRAME_FP (frame)); /* Don't we need to set the PC?!? XXX FIXME. */ }
void store_inferior_registers (register int regno) { thread_state_data_t state; kern_return_t ret; if (!MACH_PORT_VALID (current_thread)) error ("store inferior registers: Invalid thread"); /* Check for read only regs. * @@ If some of these is can be changed, fix this */ if (regno == ZERO_REGNUM || regno == PS_REGNUM || regno == BADVADDR_REGNUM || regno == CAUSE_REGNUM || regno == FCRIR_REGNUM) { message ("You can not alter read-only register `%s'", REGISTER_NAME (regno)); fetch_inferior_registers (regno); return; } if (regno == -1) { /* Don't allow these to change */ /* ZERO_REGNUM */ *(int *) registers = 0; fetch_inferior_registers (PS_REGNUM); fetch_inferior_registers (BADVADDR_REGNUM); fetch_inferior_registers (CAUSE_REGNUM); fetch_inferior_registers (FCRIR_REGNUM); } if (regno == -1 || (ZERO_REGNUM < regno && regno <= PC_REGNUM)) { #if 1 /* Mach 3.0 saves thread's FP to MACH_FP_REGNUM. * GDB wants assigns a pseudo register FP_REGNUM for frame pointer. * * @@@ Here I assume (!) that gdb's FP has the value that * should go to threads frame pointer. If not true, this * fails badly!!!!! */ memcpy (®isters[REGISTER_BYTE (MACH_FP_REGNUM)], ®isters[REGISTER_BYTE (FP_REGNUM)], REGISTER_RAW_SIZE (FP_REGNUM)); #endif /* Save gdb's regs 1..31 to thread saved regs 1..31 * Luckily, they are contiquous */ STORE_REGS (state, 1, 31); /* Save mdlo, mdhi */ STORE_REGS (state, LO_REGNUM, 2); /* Save PC */ STORE_REGS (state, PC_REGNUM, 1); ret = thread_set_state (current_thread, MIPS_THREAD_STATE, state, MIPS_FLOAT_STATE_COUNT); CHK ("store inferior regs : thread_set_state", ret); } if (regno == -1 || regno >= FP0_REGNUM) { /* If thread has floating state, save it */ if (read_register (PS_REGNUM) & MIPS_STATUS_USE_COP1) { /* Do NOT save FCRIR_REGNUM */ STORE_REGS (state, FP0_REGNUM, 33); ret = thread_set_state (current_thread, MIPS_FLOAT_STATE, state, MIPS_FLOAT_STATE_COUNT); CHK ("store inferior registers (floats): thread_set_state", ret); } else if (regno != -1) message ("Thread does not use floating point unit, floating regs not saved"); } }
void generic_get_saved_register (char *raw_buffer, int *optimized, CORE_ADDR *addrp, struct frame_info *frame, int regnum, enum lval_type *lval) { if (!target_has_registers) error ("No registers."); /* Normal systems don't optimize out things with register numbers. */ if (optimized != NULL) *optimized = 0; if (addrp) /* default assumption: not found in memory */ *addrp = 0; /* Note: since the current frame's registers could only have been saved by frames INTERIOR TO the current frame, we skip examining the current frame itself: otherwise, we would be getting the previous frame's registers which were saved by the current frame. */ while (frame && ((frame = frame->next) != NULL)) { if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) { if (lval) /* found it in a CALL_DUMMY frame */ *lval = not_lval; if (raw_buffer) memcpy (raw_buffer, generic_find_dummy_frame (frame->pc, frame->frame) + REGISTER_BYTE (regnum), REGISTER_RAW_SIZE (regnum)); return; } FRAME_INIT_SAVED_REGS (frame); if (frame->saved_regs != NULL && frame->saved_regs[regnum] != 0) { if (lval) /* found it saved on the stack */ *lval = lval_memory; if (regnum == SP_REGNUM) { if (raw_buffer) /* SP register treated specially */ store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), frame->saved_regs[regnum]); } else { if (addrp) /* any other register */ *addrp = frame->saved_regs[regnum]; if (raw_buffer) read_memory (frame->saved_regs[regnum], raw_buffer, REGISTER_RAW_SIZE (regnum)); } return; } } /* If we get thru the loop to this point, it means the register was not saved in any frame. Return the actual live-register value. */ if (lval) /* found it in a live register */ *lval = lval_register; if (addrp) *addrp = REGISTER_BYTE (regnum); if (raw_buffer) read_register_gen (regnum, raw_buffer); }
void store_inferior_registers (int regno) { int whatregs = 0; if (regno == -1) whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; else if (regno >= L0_REGNUM && regno <= I7_REGNUM) whatregs = WHATREGS_STACK; else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) whatregs = WHATREGS_FLOAT; else if (regno == SP_REGNUM) whatregs = WHATREGS_STACK | WHATREGS_GEN; else whatregs = WHATREGS_GEN; if (whatregs & WHATREGS_GEN) { struct econtext ec; /* general regs */ int retval; ec.tbr = read_register (TBR_REGNUM); memcpy (&ec.g1, ®isters[REGISTER_BYTE (G1_REGNUM)], 4 * REGISTER_RAW_SIZE (G1_REGNUM)); ec.psr = read_register (PS_REGNUM); ec.y = read_register (Y_REGNUM); ec.pc = read_register (PC_REGNUM); ec.npc = read_register (NPC_REGNUM); ec.wim = read_register (WIM_REGNUM); memcpy (ec.o, ®isters[REGISTER_BYTE (O0_REGNUM)], 8 * REGISTER_RAW_SIZE (O0_REGNUM)); errno = 0; retval = ptrace (PTRACE_SETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & ec, 0); if (errno) perror_with_name ("ptrace(PTRACE_SETREGS)"); } if (whatregs & WHATREGS_STACK) { int regoffset; CORE_ADDR sp; sp = read_register (SP_REGNUM); if (regno == -1 || regno == SP_REGNUM) { if (!register_valid[L0_REGNUM + 5]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); target_write_memory (sp + FRAME_SAVED_I0, ®isters[REGISTER_BYTE (I0_REGNUM)], 8 * REGISTER_RAW_SIZE (I0_REGNUM)); target_write_memory (sp + FRAME_SAVED_L0, ®isters[REGISTER_BYTE (L0_REGNUM)], 8 * REGISTER_RAW_SIZE (L0_REGNUM)); } else if (regno >= L0_REGNUM && regno <= I7_REGNUM) { if (!register_valid[regno]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); if (regno >= L0_REGNUM && regno <= L0_REGNUM + 7) regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM) + FRAME_SAVED_L0; else regoffset = REGISTER_BYTE (regno) - REGISTER_BYTE (I0_REGNUM) + FRAME_SAVED_I0; target_write_memory (sp + regoffset, ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); } } if (whatregs & WHATREGS_FLOAT) { struct fcontext fc; /* fp regs */ int retval; /* We read fcontext first so that we can get good values for fq_t... */ errno = 0; retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & fc, 0); if (errno) perror_with_name ("ptrace(PTRACE_GETFPREGS)"); memcpy (fc.f.fregs, ®isters[REGISTER_BYTE (FP0_REGNUM)], 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); fc.fsr = read_register (FPS_REGNUM); errno = 0; retval = ptrace (PTRACE_SETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & fc, 0); if (errno) perror_with_name ("ptrace(PTRACE_SETFPREGS)"); } }
void fetch_inferior_registers (int regno) { int whatregs = 0; #define WHATREGS_FLOAT 1 #define WHATREGS_GEN 2 #define WHATREGS_STACK 4 if (regno == -1) whatregs = WHATREGS_FLOAT | WHATREGS_GEN | WHATREGS_STACK; else if (regno >= L0_REGNUM && regno <= I7_REGNUM) whatregs = WHATREGS_STACK; else if (regno >= FP0_REGNUM && regno < FP0_REGNUM + 32) whatregs = WHATREGS_FLOAT; else whatregs = WHATREGS_GEN; if (whatregs & WHATREGS_GEN) { struct econtext ec; /* general regs */ char buf[MAX_REGISTER_RAW_SIZE]; int retval; int i; errno = 0; retval = ptrace (PTRACE_GETREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & ec, 0); if (errno) perror_with_name ("ptrace(PTRACE_GETREGS)"); memset (buf, 0, REGISTER_RAW_SIZE (G0_REGNUM)); supply_register (G0_REGNUM, buf); supply_register (TBR_REGNUM, (char *) &ec.tbr); memcpy (®isters[REGISTER_BYTE (G1_REGNUM)], &ec.g1, 4 * REGISTER_RAW_SIZE (G1_REGNUM)); for (i = G1_REGNUM; i <= G1_REGNUM + 3; i++) register_valid[i] = 1; supply_register (PS_REGNUM, (char *) &ec.psr); supply_register (Y_REGNUM, (char *) &ec.y); supply_register (PC_REGNUM, (char *) &ec.pc); supply_register (NPC_REGNUM, (char *) &ec.npc); supply_register (WIM_REGNUM, (char *) &ec.wim); memcpy (®isters[REGISTER_BYTE (O0_REGNUM)], ec.o, 8 * REGISTER_RAW_SIZE (O0_REGNUM)); for (i = O0_REGNUM; i <= O0_REGNUM + 7; i++) register_valid[i] = 1; } if (whatregs & WHATREGS_STACK) { CORE_ADDR sp; int i; sp = read_register (SP_REGNUM); target_read_memory (sp + FRAME_SAVED_I0, ®isters[REGISTER_BYTE (I0_REGNUM)], 8 * REGISTER_RAW_SIZE (I0_REGNUM)); for (i = I0_REGNUM; i <= I7_REGNUM; i++) register_valid[i] = 1; target_read_memory (sp + FRAME_SAVED_L0, ®isters[REGISTER_BYTE (L0_REGNUM)], 8 * REGISTER_RAW_SIZE (L0_REGNUM)); for (i = L0_REGNUM; i <= L0_REGNUM + 7; i++) register_valid[i] = 1; } if (whatregs & WHATREGS_FLOAT) { struct fcontext fc; /* fp regs */ int retval; int i; errno = 0; retval = ptrace (PTRACE_GETFPREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) & fc, 0); if (errno) perror_with_name ("ptrace(PTRACE_GETFPREGS)"); memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], fc.f.fregs, 32 * REGISTER_RAW_SIZE (FP0_REGNUM)); for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) register_valid[i] = 1; supply_register (FPS_REGNUM, (char *) &fc.fsr); } }
static void fetch_register (int regno) { sim_fetch_register (gdbsim_desc, regno, ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); }
static CORE_ADDR mn10300_extract_struct_value_address (char *regbuf) { return extract_address (regbuf + REGISTER_BYTE (4), REGISTER_RAW_SIZE (4)); }
void fetch_inferior_registers (int regno) { struct regs inferior_registers; struct fp_status inferior_fp_registers; int i; int fetch_pid; /* NOTE: cagney/2002-12-03: This code assumes that the currently selected light weight processes' registers can be written directly into the selected thread's register cache. This works fine when given an 1:1 LWP:thread model (such as found on GNU/Linux) but will, likely, have problems when used on an N:1 (userland threads) or N:M (userland multiple LWP) model. In the case of the latter two, the LWP's registers do not necessarily belong to the selected thread (the LWP could be in the middle of executing the thread switch code). These functions should instead be paramaterized with an explicit object (struct regcache, struct thread_info?) into which the LWPs registers can be written. */ fetch_pid = TIDGET (inferior_ptid); if (fetch_pid == 0) fetch_pid = PIDGET (inferior_ptid); /* We should never be called with deferred stores, because a prerequisite for writing regs is to have fetched them all (PREPARE_TO_STORE), sigh. */ if (deferred_stores) internal_error (__FILE__, __LINE__, "failed internal consistency check"); DO_DEFERRED_STORES; /* Global and Out regs are fetched directly, as well as the control registers. If we're getting one of the in or local regs, and the stack pointer has not yet been fetched, we have to do that first, since they're found in memory relative to the stack pointer. */ if (regno < O7_REGNUM /* including -1 */ || regno >= Y_REGNUM || (!register_valid[SP_REGNUM] && regno < I7_REGNUM)) { if (0 != ptrace (PTRACE_GETREGS, fetch_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0)) perror ("ptrace_getregs"); registers[REGISTER_BYTE (0)] = 0; memcpy (®isters[REGISTER_BYTE (1)], &inferior_registers.r_g1, 15 * REGISTER_RAW_SIZE (G0_REGNUM)); *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc; *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y; for (i = G0_REGNUM; i <= O7_REGNUM; i++) register_valid[i] = 1; register_valid[Y_REGNUM] = 1; register_valid[PS_REGNUM] = 1; register_valid[PC_REGNUM] = 1; register_valid[NPC_REGNUM] = 1; /* If we don't set these valid, read_register_bytes() rereads all the regs every time it is called! FIXME. */ register_valid[WIM_REGNUM] = 1; /* Not true yet, FIXME */ register_valid[TBR_REGNUM] = 1; /* Not true yet, FIXME */ register_valid[CPS_REGNUM] = 1; /* Not true yet, FIXME */ } /* Floating point registers */ if (regno == -1 || regno == FPS_REGNUM || (regno >= FP0_REGNUM && regno <= FP0_REGNUM + 31)) { if (0 != ptrace (PTRACE_GETFPREGS, fetch_pid, (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) perror ("ptrace_getfpregs"); memcpy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, sizeof inferior_fp_registers.fpu_fr); memcpy (®isters[REGISTER_BYTE (FPS_REGNUM)], &inferior_fp_registers.Fpu_fsr, sizeof (FPU_FSR_TYPE)); for (i = FP0_REGNUM; i <= FP0_REGNUM + 31; i++) register_valid[i] = 1; register_valid[FPS_REGNUM] = 1; } /* These regs are saved on the stack by the kernel. Only read them all (16 ptrace calls!) if we really need them. */ if (regno == -1) { CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; target_read_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], 16 * REGISTER_RAW_SIZE (L0_REGNUM)); for (i = L0_REGNUM; i <= I7_REGNUM; i++) register_valid[i] = 1; } else if (regno >= L0_REGNUM && regno <= I7_REGNUM) { CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; i = REGISTER_BYTE (regno); if (register_valid[regno]) printf_unfiltered ("register %d valid and read\n", regno); target_read_memory (sp + i - REGISTER_BYTE (L0_REGNUM), ®isters[i], REGISTER_RAW_SIZE (regno)); register_valid[regno] = 1; } }
void store_inferior_registers (int regno) { struct regs inferior_registers; struct fp_status inferior_fp_registers; int wanna_store = INT_REGS + STACK_REGS + FP_REGS; int store_pid; /* NOTE: cagney/2002-12-02: See comment in fetch_inferior_registers about threaded assumptions. */ store_pid = TIDGET (inferior_ptid); if (store_pid == 0) store_pid = PIDGET (inferior_ptid); /* First decide which pieces of machine-state we need to modify. Default for regno == -1 case is all pieces. */ if (regno >= 0) { if (FP0_REGNUM <= regno && regno < FP0_REGNUM + 32) { wanna_store = FP_REGS; } else { if (regno == SP_REGNUM) wanna_store = INT_REGS + STACK_REGS; else if (regno < L0_REGNUM || regno > I7_REGNUM) wanna_store = INT_REGS; else if (regno == FPS_REGNUM) wanna_store = FP_REGS; else wanna_store = STACK_REGS; } } /* See if we're forcing the stores to happen now, or deferring. */ if (regno == -2) { wanna_store = deferred_stores; deferred_stores = 0; } else { if (wanna_store == STACK_REGS) { /* Fall through and just store one stack reg. If we deferred it, we'd have to store them all, or remember more info. */ } else { deferred_stores |= wanna_store; return; } } if (wanna_store & STACK_REGS) { CORE_ADDR sp = *(unsigned int *) & registers[REGISTER_BYTE (SP_REGNUM)]; if (regno < 0 || regno == SP_REGNUM) { if (!register_valid[L0_REGNUM + 5]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); target_write_memory (sp, ®isters[REGISTER_BYTE (L0_REGNUM)], 16 * REGISTER_RAW_SIZE (L0_REGNUM)); } else { if (!register_valid[regno]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); target_write_memory (sp + REGISTER_BYTE (regno) - REGISTER_BYTE (L0_REGNUM), ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); } } if (wanna_store & INT_REGS) { if (!register_valid[G1_REGNUM]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); memcpy (&inferior_registers.r_g1, ®isters[REGISTER_BYTE (G1_REGNUM)], 15 * REGISTER_RAW_SIZE (G1_REGNUM)); inferior_registers.r_ps = *(int *) ®isters[REGISTER_BYTE (PS_REGNUM)]; inferior_registers.r_pc = *(int *) ®isters[REGISTER_BYTE (PC_REGNUM)]; inferior_registers.r_npc = *(int *) ®isters[REGISTER_BYTE (NPC_REGNUM)]; inferior_registers.r_y = *(int *) ®isters[REGISTER_BYTE (Y_REGNUM)]; if (0 != ptrace (PTRACE_SETREGS, store_pid, (PTRACE_ARG3_TYPE) & inferior_registers, 0)) perror ("ptrace_setregs"); } if (wanna_store & FP_REGS) { if (!register_valid[FP0_REGNUM + 9]) internal_error (__FILE__, __LINE__, "failed internal consistency check"); memcpy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], sizeof inferior_fp_registers.fpu_fr); memcpy (&inferior_fp_registers.Fpu_fsr, ®isters[REGISTER_BYTE (FPS_REGNUM)], sizeof (FPU_FSR_TYPE)); if (0 != ptrace (PTRACE_SETFPREGS, store_pid, (PTRACE_ARG3_TYPE) & inferior_fp_registers, 0)) perror ("ptrace_setfpregs"); } }
/* Store at least register REGNO, or all regs if REGNO == -1. */ void gnu_store_registers (int regno) { struct proc *thread; /* Make sure we know about new threads. */ inf_update_procs (current_inferior); thread = inf_tid_to_thread (current_inferior, PIDGET (inferior_ptid)); if (!thread) error ("Couldn't store registers into thread %d: No such thread", PIDGET (inferior_ptid)); if (regno < I386_NUM_GREGS || regno == -1) { thread_state_t state; thread_state_data_t old_state; int was_aborted = thread->aborted; int was_valid = thread->state_valid; int trace; if (!was_aborted && was_valid) memcpy (&old_state, &thread->state, sizeof (old_state)); state = proc_get_state (thread, 1); if (!state) { warning ("Couldn't store registers into %s", proc_string (thread)); return; } /* Save the T bit. We might try to restore the %eflags register below, but changing the T bit would seriously confuse GDB. */ trace = ((struct i386_thread_state *)state)->efl & 0x100; if (!was_aborted && was_valid) /* See which registers have changed after aborting the thread. */ { int check_regno; for (check_regno = 0; check_regno < I386_NUM_GREGS; check_regno++) if ((thread->fetched_regs & (1 << check_regno)) && memcpy (REG_ADDR (&old_state, check_regno), REG_ADDR (state, check_regno), REGISTER_RAW_SIZE (check_regno))) /* Register CHECK_REGNO has changed! Ack! */ { warning ("Register %s changed after the thread was aborted", REGISTER_NAME (check_regno)); if (regno >= 0 && regno != check_regno) /* Update GDB's copy of the register. */ supply_register (check_regno, REG_ADDR (state, check_regno)); else warning ("... also writing this register! Suspicious..."); } } #define fill(state, regno) \ memcpy (REG_ADDR(state, regno), ®isters[REGISTER_BYTE (regno)], \ REGISTER_RAW_SIZE (regno)) if (regno == -1) { int i; proc_debug (thread, "storing all registers"); for (i = 0; i < I386_NUM_GREGS; i++) if (register_valid[i]) fill (state, i); } else { proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); gdb_assert (register_valid[regno]); fill (state, regno); } /* Restore the T bit. */ ((struct i386_thread_state *)state)->efl &= ~0x100; ((struct i386_thread_state *)state)->efl |= trace; } #undef fill if (regno >= I386_NUM_GREGS || regno == -1) { proc_debug (thread, "storing floating-point registers"); store_fpregs (thread, regno); } }