static void gdbsim_store_register (int regno) { if (regno == -1) { for (regno = 0; regno < NUM_REGS; regno++) gdbsim_store_register (regno); return; } else if (REGISTER_SIM_REGNO (regno) >= 0) { char tmp[MAX_REGISTER_SIZE]; int nr_bytes; deprecated_read_register_gen (regno, tmp); nr_bytes = sim_store_register (gdbsim_desc, REGISTER_SIM_REGNO (regno), tmp, DEPRECATED_REGISTER_RAW_SIZE (regno)); if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno)) internal_error (__FILE__, __LINE__, "Register size different to expected"); /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' indicating that GDB and the SIM have different ideas about which registers are fetchable. */ if (sr_get_debug ()) { printf_filtered ("gdbsim_store_register: %d", regno); /* FIXME: We could print something more intelligible. */ dump_mem (tmp, DEPRECATED_REGISTER_RAW_SIZE (regno)); } } }
static void gdbsim_fetch_register (int regno) { if (regno == -1) { for (regno = 0; regno < NUM_REGS; regno++) gdbsim_fetch_register (regno); return; } switch (REGISTER_SIM_REGNO (regno)) { case LEGACY_SIM_REGNO_IGNORE: break; case SIM_REGNO_DOES_NOT_EXIST: { /* For moment treat a `does not exist' register the same way as an ``unavailable'' register. */ char buf[MAX_REGISTER_SIZE]; int nr_bytes; memset (buf, 0, MAX_REGISTER_SIZE); supply_register (regno, buf); set_register_cached (regno, -1); break; } default: { static int warn_user = 1; char buf[MAX_REGISTER_SIZE]; int nr_bytes; gdb_assert (regno >= 0 && regno < NUM_REGS); memset (buf, 0, MAX_REGISTER_SIZE); nr_bytes = sim_fetch_register (gdbsim_desc, REGISTER_SIM_REGNO (regno), buf, DEPRECATED_REGISTER_RAW_SIZE (regno)); if (nr_bytes > 0 && nr_bytes != DEPRECATED_REGISTER_RAW_SIZE (regno) && warn_user) { fprintf_unfiltered (gdb_stderr, "Size of register %s (%d/%d) incorrect (%d instead of %d))", REGISTER_NAME (regno), regno, REGISTER_SIM_REGNO (regno), nr_bytes, DEPRECATED_REGISTER_RAW_SIZE (regno)); warn_user = 0; } /* FIXME: cagney/2002-05-27: Should check `nr_bytes == 0' indicating that GDB and the SIM have different ideas about which registers are fetchable. */ /* Else if (nr_bytes < 0): an old simulator, that doesn't think to return the register size. Just assume all is ok. */ supply_register (regno, buf); if (sr_get_debug ()) { printf_filtered ("gdbsim_fetch_register: %d", regno); /* FIXME: We could print something more intelligible. */ dump_mem (buf, DEPRECATED_REGISTER_RAW_SIZE (regno)); } break; } } }
void fetch_inferior_registers (int regno) { unsigned int regaddr; char buf[MAX_REGISTER_SIZE]; int i; char zerobuf[MAX_REGISTER_SIZE]; memset (zerobuf, 0, MAX_REGISTER_SIZE); deprecated_registers_fetched (); for (regno = 1; regno < NUM_REGS; regno++) { regaddr = register_ptrace_addr (regno); for (i = 0; i < DEPRECATED_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 (DEPRECATED_FP_REGNUM, zerobuf); }
static int register_changed_p (int regnum) { char raw_buffer[MAX_REGISTER_SIZE]; if (! frame_register_read (deprecated_selected_frame, regnum, raw_buffer)) return -1; if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, DEPRECATED_REGISTER_RAW_SIZE (regnum)) == 0) return 0; /* Found a changed register. Return 1. */ memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, DEPRECATED_REGISTER_RAW_SIZE (regnum)); return 1; }
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)); { char buf[MAX_REGISTER_SIZE]; for (regno = reglo; regno <= reghi; regno++) { int ptrace_fun = PTRACE_PEEKTHREAD; #ifdef M68K ptrace_fun = regno == SP_REGNUM ? PTRACE_PEEKUSP : PTRACE_PEEKTHREAD; #endif for (i = 0; i < DEPRECATED_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 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 < DEPRECATED_REGISTER_RAW_SIZE (regno); i += sizeof (int)) { unsigned int reg; reg = *(unsigned int *) &deprecated_registers[DEPRECATED_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)"); } } }
/* Parse a string of hex digits starting at HEX, supply them as the value of register REGNO, skip any whitespace, and return a pointer to the next character. There is a function in monitor.c, monitor_supply_register, which is supposed to do this job. However, there is some rather odd stuff in there (whitespace characters don't terminate numbers, for example) that is incorrect for ROM68k. It's basically impossible to safely tweak monitor_supply_register --- it's used by a zillion other monitors; who knows what behaviors they're depending on. So instead, we'll just use our own function, which can behave exactly the way we want it to. */ static char * rom68k_supply_one_register (int regno, unsigned char *hex) { ULONGEST value; unsigned char regbuf[MAX_REGISTER_SIZE]; value = 0; while (*hex != '\0') if (is_hex_digit (*hex)) value = (value * 16) + hex_digit_value (*hex++); else break; /* Skip any whitespace. */ while (is_whitespace (*hex)) hex++; store_unsigned_integer (regbuf, DEPRECATED_REGISTER_RAW_SIZE (regno), value); supply_register (regno, regbuf); return hex; }
/* 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), DEPRECATED_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), &deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)], \ DEPRECATED_REGISTER_RAW_SIZE (regno)) if (regno == -1) { int i; proc_debug (thread, "storing all registers"); for (i = 0; i < I386_NUM_GREGS; i++) if (deprecated_register_valid[i]) fill (state, i); } else { proc_debug (thread, "storing register %s", REGISTER_NAME (regno)); gdb_assert (deprecated_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); } }
void store_inferior_registers (int regno) { unsigned int regaddr; char buf[80]; int i; unsigned int offset = U_REGS_OFFSET; int scratch; if (regno >= 0) { unsigned int addr, len, offset; if (CANNOT_STORE_REGISTER (regno)) return; offset = 0; len = DEPRECATED_REGISTER_RAW_SIZE (regno); /* Requests for register zero actually want the save_state's ss_flags member. As RM says: "Oh, what a hack!" */ if (regno == 0) { save_state_t ss; addr = HPPAH_OFFSETOF (save_state_t, ss_flags); len = sizeof (ss.ss_flags); /* Note that ss_flags is always an int, no matter what DEPRECATED_REGISTER_RAW_SIZE(0) says. Assuming all HP-UX PA machines are big-endian, put it at the least significant end of the value, and zap the rest of the buffer. */ offset = DEPRECATED_REGISTER_RAW_SIZE (0) - len; } /* Floating-point registers come from the ss_fpblock area. */ else if (regno >= HPPA_FP0_REGNUM) addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock) + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (HPPA_FP0_REGNUM))); /* Wide registers come from the ss_wide area. I think it's more PC to test (ss_flags & SS_WIDEREGS) to select between ss_wide and ss_narrow than to use the raw register size. But checking ss_flags would require an extra ptrace call for every register reference. Bleah. */ else if (len == 8) addr = (HPPAH_OFFSETOF (save_state_t, ss_wide) + DEPRECATED_REGISTER_BYTE (regno)); /* Narrow registers come from the ss_narrow area. Note that ss_narrow starts with gr1, not gr0. */ else if (len == 4) addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow) + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (1))); else internal_error (__FILE__, __LINE__, "hppah-nat.c (write_register): unexpected register size"); #ifdef GDB_TARGET_IS_HPPA_20W /* Unbelieveable. The PC head and tail must be written in 64bit hunks or we will get an error. Worse yet, the oddball ptrace/ttrace layering will not allow us to perform a 64bit register store. What a crock. */ if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM && len == 8) { CORE_ADDR temp; temp = *(CORE_ADDR *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)]; /* Set the priv level (stored in the low two bits of the PC. */ temp |= 0x3; ttrace_write_reg_64 (PIDGET (inferior_ptid), (CORE_ADDR)addr, (CORE_ADDR)&temp); /* If we fail to write the PC, give a true error instead of just a warning. */ if (errno != 0) { char *err = safe_strerror (errno); char *msg = alloca (strlen (err) + 128); sprintf (msg, "writing `%s' register: %s", REGISTER_NAME (regno), err); perror_with_name (msg); } return; } /* Another crock. HPUX complains if you write a nonzero value to the high part of IPSW. What will it take for HP to catch a clue about building sensible interfaces? */ if (regno == HPPA_IPSW_REGNUM && len == 8) *(int *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)] = 0; #endif for (i = 0; i < len; i += sizeof (int)) { errno = 0; call_ptrace (PT_WUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr + i, *(int *) &deprecated_registers[DEPRECATED_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 `%s' register: %s", REGISTER_NAME (regno), err); /* If we fail to write the PC, give a true error instead of just a warning. */ if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM) perror_with_name (msg); else warning (msg); return; } } } else for (regno = 0; regno < NUM_REGS; regno++) store_inferior_registers (regno); }
/* Fetch a register's value from the process's U area. */ static void fetch_register (int regno) { char buf[MAX_REGISTER_SIZE]; unsigned int addr, len, offset; int i; offset = 0; len = DEPRECATED_REGISTER_RAW_SIZE (regno); /* Requests for register zero actually want the save_state's ss_flags member. As RM says: "Oh, what a hack!" */ if (regno == 0) { save_state_t ss; addr = HPPAH_OFFSETOF (save_state_t, ss_flags); len = sizeof (ss.ss_flags); /* Note that ss_flags is always an int, no matter what DEPRECATED_REGISTER_RAW_SIZE(0) says. Assuming all HP-UX PA machines are big-endian, put it at the least significant end of the value, and zap the rest of the buffer. */ offset = DEPRECATED_REGISTER_RAW_SIZE (0) - len; memset (buf, 0, sizeof (buf)); } /* Floating-point registers come from the ss_fpblock area. */ else if (regno >= HPPA_FP0_REGNUM) addr = (HPPAH_OFFSETOF (save_state_t, ss_fpblock) + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (HPPA_FP0_REGNUM))); /* Wide registers come from the ss_wide area. I think it's more PC to test (ss_flags & SS_WIDEREGS) to select between ss_wide and ss_narrow than to use the raw register size. But checking ss_flags would require an extra ptrace call for every register reference. Bleah. */ else if (len == 8) addr = (HPPAH_OFFSETOF (save_state_t, ss_wide) + DEPRECATED_REGISTER_BYTE (regno)); /* Narrow registers come from the ss_narrow area. Note that ss_narrow starts with gr1, not gr0. */ else if (len == 4) addr = (HPPAH_OFFSETOF (save_state_t, ss_narrow) + (DEPRECATED_REGISTER_BYTE (regno) - DEPRECATED_REGISTER_BYTE (1))); else internal_error (__FILE__, __LINE__, "hppa-nat.c (fetch_register): unexpected register size"); for (i = 0; i < len; i += sizeof (int)) { errno = 0; /* Copy an int from the U area to buf. Fill the least significant end if len != raw_size. */ * (int *) &buf[offset + i] = call_ptrace (PT_RUREGS, PIDGET (inferior_ptid), (PTRACE_ARG3_TYPE) addr + i, 0); 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 `%s' register: %s", REGISTER_NAME (regno), err); warning (msg); return; } } /* If we're reading an address from the instruction address queue, mask out the bottom two bits --- they contain the privilege level. */ if (regno == HPPA_PCOQ_HEAD_REGNUM || regno == HPPA_PCOQ_TAIL_REGNUM) buf[len - 1] &= ~0x3; supply_register (regno, buf); }
/* Write given values into registers. The registers and values are given as pairs. The corresponding MI command is -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]*/ enum mi_cmd_result mi_cmd_data_write_register_values (char *command, char **argv, int argc) { int regnum; int i; int numregs; LONGEST value; char format; /* Note that the test for a valid register must include checking the REGISTER_NAME because NUM_REGS may be allocated for the union of the register sets within a family of related processors. In this case, some entries of REGISTER_NAME will change depending upon the particular processor being debugged. */ numregs = NUM_REGS; if (argc == 0) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: Usage: -data-write-register-values <format> [<regnum1> <value1>...<regnumN> <valueN>]"); return MI_CMD_ERROR; } format = (int) argv[0][0]; if (!target_has_registers) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: No registers."); return MI_CMD_ERROR; } if (!(argc - 1)) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: No regs and values specified."); return MI_CMD_ERROR; } if ((argc - 1) % 2) { xasprintf (&mi_error_message, "mi_cmd_data_write_register_values: Regs and vals are not in pairs."); return MI_CMD_ERROR; } for (i = 1; i < argc; i = i + 2) { regnum = atoi (argv[i]); if (regnum >= 0 && regnum < numregs && REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\000') { void *buffer; struct cleanup *old_chain; /* Get the value as a number */ value = parse_and_eval_address (argv[i + 1]); /* Get the value into an array */ buffer = xmalloc (DEPRECATED_REGISTER_SIZE); old_chain = make_cleanup (xfree, buffer); store_signed_integer (buffer, DEPRECATED_REGISTER_SIZE, value); /* Write it down */ deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (regnum), buffer, DEPRECATED_REGISTER_RAW_SIZE (regnum)); /* Free the buffer. */ do_cleanups (old_chain); } else { xasprintf (&mi_error_message, "bad register number"); return MI_CMD_ERROR; } } return MI_CMD_DONE; }
/* Output one register's contents in the desired format. */ static int get_register (int regnum, int format) { char raw_buffer[MAX_REGISTER_SIZE]; char virtual_buffer[MAX_REGISTER_SIZE]; int optim; int realnum; CORE_ADDR addr; enum lval_type lval; static struct ui_stream *stb = NULL; stb = ui_out_stream_new (uiout); if (format == 'N') format = 0; frame_register (deprecated_selected_frame, regnum, &optim, &lval, &addr, &realnum, raw_buffer); if (optim) { xasprintf (&mi_error_message, "Optimized out"); return -1; } /* Convert raw data to virtual format if necessary. */ if (DEPRECATED_REGISTER_CONVERTIBLE_P () && DEPRECATED_REGISTER_CONVERTIBLE (regnum)) { DEPRECATED_REGISTER_CONVERT_TO_VIRTUAL (regnum, register_type (current_gdbarch, regnum), raw_buffer, virtual_buffer); } else memcpy (virtual_buffer, raw_buffer, DEPRECATED_REGISTER_VIRTUAL_SIZE (regnum)); if (format == 'r') { int j; char *ptr, buf[1024]; strcpy (buf, "0x"); ptr = buf + 2; for (j = 0; j < DEPRECATED_REGISTER_RAW_SIZE (regnum); j++) { int idx = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? j : DEPRECATED_REGISTER_RAW_SIZE (regnum) - 1 - j; sprintf (ptr, "%02x", (unsigned char) raw_buffer[idx]); ptr += 2; } ui_out_field_string (uiout, "value", buf); /*fputs_filtered (buf, gdb_stdout); */ } else { val_print (register_type (current_gdbarch, regnum), virtual_buffer, 0, 0, stb->stream, format, 1, 0, Val_pretty_default); ui_out_field_stream (uiout, "value", stb); ui_out_stream_delete (stb); } return 1; }