static void bdm_ppc_store_registers (int regno) { struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); int i; int first_regno, last_regno; int first_bdm_regno, last_bdm_regno; if (regno == -1) { first_regno = 0; last_regno = NUM_REGS - 1; first_bdm_regno = 0; last_bdm_regno = BDM_NUM_REGS - 1; } else { first_regno = regno; last_regno = regno; first_bdm_regno = bdm_regmap[regno]; last_bdm_regno = bdm_regmap[regno]; } if (first_bdm_regno == -1) return; /* Unsupported register */ /* FIXME: jimb/2004-05-04: I'm not sure how to adapt this code to processors that lack floating point registers, and I don't have have the equipment to test it. So we'll leave that case for the next person who encounters it. */ gdb_assert (ppc_floating_point_unit_p (current_gdbarch)); for (i = first_regno; i <= last_regno; i++) { int bdm_regno; bdm_regno = bdm_regmap[i]; /* only attempt to write if it's a valid ppc 8xx register */ /* (need to avoid FP regs and MQ reg) */ if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) && ((i < tdep->ppc_fp0_regnum) || (i >= tdep->ppc_fp0_regnum + ppc_num_fprs))) { /* printf("write valid reg %d\n", bdm_regno); */ ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4); } /* else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno); else printf("don't write invalid reg %d\n", bdm_regno); */ } }
static int register_changed_p (int regnum) { gdb_byte raw_buffer[MAX_REGISTER_SIZE]; if (! frame_register_read (get_selected_frame (NULL), regnum, raw_buffer)) return -1; if (memcmp (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, register_size (current_gdbarch, regnum)) == 0) return 0; /* Found a changed register. Return 1. */ memcpy (&old_regs[DEPRECATED_REGISTER_BYTE (regnum)], raw_buffer, register_size (current_gdbarch, regnum)); return 1; }
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 fill_fpregset (fpregset_t *fpregsetp, int regno) { int regi; char *from, *to; for (regi = mips_regnum (current_gdbarch)->fp0; regi < mips_regnum (current_gdbarch)->fp0 + 32; regi++) { if ((regno == -1) || (regno == regi)) { from = (char *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)]; to = (char *) &(fpregsetp->fp_r.fp_regs[regi - mips_regnum (current_gdbarch)->fp0]); memcpy (to, from, register_size (current_gdbarch, regi)); } } if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->fp_control_status)) fpregsetp->fp_csr = *(unsigned *) &deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->fp_control_status)]; }
void fill_gregset (gregset_t *gregsetp, int regno) { int regi; greg_t *regp = &(*gregsetp)[0]; for (regi = 0; regi <= 32; regi++) if ((regno == -1) || (regno == regi)) *(regp + regi) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (regi)]; if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->pc)) *(regp + CXT_EPC) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->pc)]; if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->cause)) *(regp + CXT_CAUSE) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->cause)]; if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->hi)) *(regp + CXT_MDHI) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->hi)]; if ((regno == -1) || (regno == mips_regnum (current_gdbarch)->lo)) *(regp + CXT_MDLO) = *(greg_t *) & deprecated_registers[DEPRECATED_REGISTER_BYTE (mips_regnum (current_gdbarch)->lo)]; }
static void bdm_ppc_store_registers (int regno) { int i; int first_regno, last_regno; int first_bdm_regno, last_bdm_regno; if (regno == -1) { first_regno = 0; last_regno = NUM_REGS - 1; first_bdm_regno = 0; last_bdm_regno = BDM_NUM_REGS - 1; } else { first_regno = regno; last_regno = regno; first_bdm_regno = bdm_regmap[regno]; last_bdm_regno = bdm_regmap[regno]; } if (first_bdm_regno == -1) return; /* Unsupported register */ for (i = first_regno; i <= last_regno; i++) { int bdm_regno; bdm_regno = bdm_regmap[i]; /* only attempt to write if it's a valid ppc 8xx register */ /* (need to avoid FP regs and MQ reg) */ if ((i != gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) && (i != gdbarch_tdep (current_gdbarch)->ppc_fpscr_regnum) && ((i < FP0_REGNUM) || (i > FPLAST_REGNUM))) { /* printf("write valid reg %d\n", bdm_regno); */ ocd_write_bdm_registers (bdm_regno, deprecated_registers + DEPRECATED_REGISTER_BYTE (i), 4); } /* else if (i == gdbarch_tdep (current_gdbarch)->ppc_mq_regnum) printf("don't write invalid reg %d (PPC_MQ_REGNUM)\n", bdm_regno); else printf("don't write invalid reg %d\n", bdm_regno); */ } }
/* FIXME rearnsha/2002-02-23: This function shouldn't be necessary. The ARM generic one should be able to handle the model used by linux and the low-level formatting of the registers should be hidden behind the regcache abstraction. */ static void arm_linux_extract_return_value (struct type *type, char regbuf[], char *valbuf) { /* ScottB: This needs to be looked at to handle the different floating point emulators on ARM GNU/Linux. Right now the code assumes that fetch inferior registers does the right thing for GDB. I suspect this won't handle NWFPE registers correctly, nor will the default ARM version (arm_extract_return_value()). */ int regnum = ((TYPE_CODE_FLT == TYPE_CODE (type)) ? ARM_F0_REGNUM : ARM_A1_REGNUM); memcpy (valbuf, ®buf[DEPRECATED_REGISTER_BYTE (regnum)], TYPE_LENGTH (type)); }
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)"); } } }
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 + NUM_PSEUDO_REGS; if (argc == 0) { mi_error_message = xstrprintf ("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) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No registers."); return MI_CMD_ERROR; } if (!(argc - 1)) { mi_error_message = xstrprintf ("mi_cmd_data_write_register_values: No regs and values specified."); return MI_CMD_ERROR; } if ((argc - 1) % 2) { mi_error_message = xstrprintf ("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, register_size (current_gdbarch, regnum)); /* Free the buffer. */ do_cleanups (old_chain); } else { mi_error_message = xstrprintf ("bad register number"); return MI_CMD_ERROR; } } return MI_CMD_DONE; }