X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=gdb%2Fregcache.c;h=3bf0b47b3517f593e71e9ad99ff15669006d1131;hb=1d9d99f32d861ae85dd59689ada801cc51d3ac91;hp=7b462dedcc9afc182fb859e78b6dc3a0d5f2dcb1;hpb=a728f04251098dd0e74a2aea1e4d8e841e7fb404;p=binutils-gdb.git diff --git a/gdb/regcache.c b/gdb/regcache.c index 7b462dedcc9..3bf0b47b351 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -20,12 +20,12 @@ Boston, MA 02111-1307, USA. */ #include "defs.h" -#include "frame.h" #include "inferior.h" #include "target.h" #include "gdbarch.h" #include "gdbcmd.h" #include "regcache.h" +#include "gdb_assert.h" /* * DATA STRUCTURE @@ -49,10 +49,9 @@ char *registers; signed char *register_valid; -/* The thread/process associated with the current set of registers. - For now, -1 is special, and means `no current process'. */ +/* The thread/process associated with the current set of registers. */ -static int registers_pid = -1; +static ptid_t registers_ptid; /* * FUNCTIONS: @@ -154,7 +153,7 @@ registers_changed (void) { int i; - registers_pid = -1; + registers_ptid = pid_to_ptid (-1); /* Force cleanup of any alloca areas if using C alloca instead of a builtin alloca. This particular call is used to clean up @@ -213,54 +212,69 @@ registers_fetched (void) into memory at MYADDR. */ void -read_register_bytes (int inregbyte, char *myaddr, int inlen) +read_register_bytes (int in_start, char *in_buf, int in_len) { - int inregend = inregbyte + inlen; + int in_end = in_start + in_len; int regnum; - - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } + char *reg_buf = alloca (MAX_REGISTER_RAW_SIZE); /* See if we are trying to read bytes from out-of-date registers. If so, update just those registers. */ for (regnum = 0; regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++) { - int regstart, regend; - - if (register_cached (regnum)) + int reg_start; + int reg_end; + int reg_len; + int start; + int end; + int byte; + + reg_start = REGISTER_BYTE (regnum); + reg_len = REGISTER_RAW_SIZE (regnum); + reg_end = reg_start + reg_len; + + if (reg_end <= in_start || in_end <= reg_start) + /* The range the user wants to read doesn't overlap with regnum. */ continue; - if (REGISTER_NAME (regnum) == NULL || *REGISTER_NAME (regnum) == '\0') + if (REGISTER_NAME (regnum) != NULL && *REGISTER_NAME (regnum) != '\0') + /* Force the cache to fetch the entire register. */ + read_register_gen (regnum, reg_buf); + else + /* Legacy note: even though this register is ``invalid'' we + still need to return something. It would appear that some + code relies on apparent gaps in the register array also + being returned. */ + /* FIXME: cagney/2001-08-18: This is just silly. It defeats + the entire register read/write flow of control. Must + resist temptation to return 0xdeadbeef. */ + memcpy (reg_buf, registers + reg_start, reg_len); + + /* Legacy note: This function, for some reason, allows a NULL + input buffer. If the buffer is NULL, the registers are still + fetched, just the final transfer is skipped. */ + if (in_buf == NULL) continue; - regstart = REGISTER_BYTE (regnum); - regend = regstart + REGISTER_RAW_SIZE (regnum); - - if (regend <= inregbyte || inregend <= regstart) - /* The range the user wants to read doesn't overlap with regnum. */ - continue; + /* start = max (reg_start, in_start) */ + if (reg_start > in_start) + start = reg_start; + else + start = in_start; - /* We've found an uncached register where at least one byte will be read. - Update it from the target. */ - fetch_register (regnum); + /* end = min (reg_end, in_end) */ + if (reg_end < in_end) + end = reg_end; + else + end = in_end; - if (!register_cached (regnum)) + /* Transfer just the bytes common to both IN_BUF and REG_BUF */ + for (byte = start; byte < end; byte++) { - /* Sometimes pseudoregs are never marked valid, so that they - will be fetched every time (it can be complicated to know - if a pseudoreg is valid, while "fetching" them can be cheap). - */ - if (regnum < NUM_REGS) - error ("read_register_bytes: Couldn't update register %d.", regnum); + in_buf[byte - in_start] = reg_buf[byte - reg_start]; } } - - if (myaddr != NULL) - memcpy (myaddr, register_buffer (-1) + inregbyte, inlen); } /* Read register REGNUM into memory at MYADDR, which must be large @@ -268,13 +282,14 @@ read_register_bytes (int inregbyte, char *myaddr, int inlen) register is known to be the size of a CORE_ADDR or smaller, read_register can be used instead. */ -void -read_register_gen (int regnum, char *myaddr) +static void +legacy_read_register_gen (int regnum, char *myaddr) { - if (registers_pid != inferior_pid) + gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS)); + if (! ptid_equal (registers_ptid, inferior_ptid)) { registers_changed (); - registers_pid = inferior_pid; + registers_ptid = inferior_ptid; } if (!register_cached (regnum)) @@ -284,41 +299,58 @@ read_register_gen (int regnum, char *myaddr) REGISTER_RAW_SIZE (regnum)); } +void +regcache_read (int rawnum, char *buf) +{ + gdb_assert (rawnum >= 0 && rawnum < NUM_REGS); + /* For moment, just use underlying legacy code. Ulgh!!! */ + legacy_read_register_gen (rawnum, buf); +} + +void +read_register_gen (int regnum, char *buf) +{ + if (! gdbarch_register_read_p (current_gdbarch)) + { + legacy_read_register_gen (regnum, buf); + return; + } + gdbarch_register_read (current_gdbarch, regnum, buf); +} + + /* Write register REGNUM at MYADDR to the target. MYADDR points at REGISTER_RAW_BYTES(REGNUM), which must be in target byte-order. */ -/* Registers we shouldn't try to store. */ -#if !defined (CANNOT_STORE_REGISTER) -#define CANNOT_STORE_REGISTER(regnum) 0 -#endif - -void -write_register_gen (int regnum, char *myaddr) +static void +legacy_write_register_gen (int regnum, char *myaddr) { int size; + gdb_assert (regnum >= 0 && regnum < (NUM_REGS + NUM_PSEUDO_REGS)); /* On the sparc, writing %g0 is a no-op, so we don't even want to change the registers array if something writes to this register. */ if (CANNOT_STORE_REGISTER (regnum)) return; - if (registers_pid != inferior_pid) + if (! ptid_equal (registers_ptid, inferior_ptid)) { registers_changed (); - registers_pid = inferior_pid; + registers_ptid = inferior_ptid; } size = REGISTER_RAW_SIZE (regnum); - /* If we have a valid copy of the register, and new value == old value, - then don't bother doing the actual store. */ - - if (register_cached (regnum) - && memcmp (register_buffer (regnum), myaddr, size) == 0) - return; - if (real_register (regnum)) - target_prepare_to_store (); + { + /* If we have a valid copy of the register, and new value == old + value, then don't bother doing the actual store. */ + if (register_cached (regnum) + && memcmp (register_buffer (regnum), myaddr, size) == 0) + return; + else + target_prepare_to_store (); + } memcpy (register_buffer (regnum), myaddr, size); @@ -326,6 +358,25 @@ write_register_gen (int regnum, char *myaddr) store_register (regnum); } +void +regcache_write (int rawnum, char *buf) +{ + gdb_assert (rawnum >= 0 && rawnum < NUM_REGS); + /* For moment, just use underlying legacy code. Ulgh!!! */ + legacy_write_register_gen (rawnum, buf); +} + +void +write_register_gen (int regnum, char *buf) +{ + if (! gdbarch_register_write_p (current_gdbarch)) + { + legacy_write_register_gen (regnum, buf); + return; + } + gdbarch_register_write (current_gdbarch, regnum, buf); +} + /* Copy INLEN bytes of consecutive data from memory at MYADDR into registers starting with the MYREGSTART'th byte of register data. */ @@ -385,35 +436,28 @@ write_register_bytes (int myregstart, char *myaddr, int inlen) ULONGEST read_register (int regnum) { - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - if (!register_cached (regnum)) - fetch_register (regnum); - - return (extract_unsigned_integer (register_buffer (regnum), - REGISTER_RAW_SIZE (regnum))); + char *buf = alloca (REGISTER_RAW_SIZE (regnum)); + read_register_gen (regnum, buf); + return (extract_unsigned_integer (buf, REGISTER_RAW_SIZE (regnum))); } ULONGEST -read_register_pid (int regnum, int pid) +read_register_pid (int regnum, ptid_t ptid) { + ptid_t save_ptid; int save_pid; CORE_ADDR retval; - if (pid == inferior_pid) + if (ptid_equal (ptid, inferior_ptid)) return read_register (regnum); - save_pid = inferior_pid; + save_ptid = inferior_ptid; - inferior_pid = pid; + inferior_ptid = ptid; retval = read_register (regnum); - inferior_pid = save_pid; + inferior_ptid = save_ptid; return retval; } @@ -423,35 +467,27 @@ read_register_pid (int regnum, int pid) LONGEST read_signed_register (int regnum) { - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - - if (!register_cached (regnum)) - fetch_register (regnum); - - return (extract_signed_integer (register_buffer (regnum), - REGISTER_RAW_SIZE (regnum))); + void *buf = alloca (REGISTER_RAW_SIZE (regnum)); + read_register_gen (regnum, buf); + return (extract_signed_integer (buf, REGISTER_RAW_SIZE (regnum))); } LONGEST -read_signed_register_pid (int regnum, int pid) +read_signed_register_pid (int regnum, ptid_t ptid) { - int save_pid; + ptid_t save_ptid; LONGEST retval; - if (pid == inferior_pid) + if (ptid_equal (ptid, inferior_ptid)) return read_signed_register (regnum); - save_pid = inferior_pid; + save_ptid = inferior_ptid; - inferior_pid = pid; + inferior_ptid = ptid; retval = read_signed_register (regnum); - inferior_pid = save_pid; + inferior_ptid = save_ptid; return retval; } @@ -461,58 +497,32 @@ read_signed_register_pid (int regnum, int pid) void write_register (int regnum, LONGEST val) { - PTR buf; + void *buf; int size; - - /* On the sparc, writing %g0 is a no-op, so we don't even want to - change the registers array if something writes to this register. */ - if (CANNOT_STORE_REGISTER (regnum)) - return; - - if (registers_pid != inferior_pid) - { - registers_changed (); - registers_pid = inferior_pid; - } - size = REGISTER_RAW_SIZE (regnum); buf = alloca (size); store_signed_integer (buf, size, (LONGEST) val); - - /* If we have a valid copy of the register, and new value == old value, - then don't bother doing the actual store. */ - - if (register_cached (regnum) - && memcmp (register_buffer (regnum), buf, size) == 0) - return; - - if (real_register (regnum)) - target_prepare_to_store (); - - memcpy (register_buffer (regnum), buf, size); - - set_register_cached (regnum, 1); - store_register (regnum); + write_register_gen (regnum, buf); } void -write_register_pid (int regnum, CORE_ADDR val, int pid) +write_register_pid (int regnum, CORE_ADDR val, ptid_t ptid) { - int save_pid; + ptid_t save_ptid; - if (pid == inferior_pid) + if (ptid_equal (ptid, inferior_ptid)) { write_register (regnum, val); return; } - save_pid = inferior_pid; + save_ptid = inferior_ptid; - inferior_pid = pid; + inferior_ptid = ptid; write_register (regnum, val); - inferior_pid = save_pid; + inferior_ptid = save_ptid; } /* SUPPLY_REGISTER() @@ -529,10 +539,10 @@ void supply_register (int regnum, char *val) { #if 1 - if (registers_pid != inferior_pid) + if (! ptid_equal (registers_ptid, inferior_ptid)) { registers_changed (); - registers_pid = inferior_pid; + registers_ptid = inferior_ptid; } #endif @@ -547,6 +557,12 @@ supply_register (int regnum, char *val) /* On some architectures, e.g. HPPA, there are a few stray bits in some registers, that the rest of the code would like to ignore. */ + /* NOTE: cagney/2001-03-16: The macro CLEAN_UP_REGISTER_VALUE is + going to be deprecated. Instead architectures will leave the raw + register value as is and instead clean things up as they pass + through the method gdbarch_register_read() clean up the + values. */ + #ifdef CLEAN_UP_REGISTER_VALUE CLEAN_UP_REGISTER_VALUE (regnum, register_buffer (regnum)); #endif @@ -577,12 +593,12 @@ supply_register (int regnum, char *val) TARGET_READ_PC directly. (cagney). */ CORE_ADDR -generic_target_read_pc (int pid) +generic_target_read_pc (ptid_t ptid) { #ifdef PC_REGNUM if (PC_REGNUM >= 0) { - CORE_ADDR pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid)); + CORE_ADDR pc_val = ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, ptid)); return pc_val; } #endif @@ -592,37 +608,37 @@ generic_target_read_pc (int pid) } CORE_ADDR -read_pc_pid (int pid) +read_pc_pid (ptid_t ptid) { - int saved_inferior_pid; + ptid_t saved_inferior_ptid; CORE_ADDR pc_val; - /* In case pid != inferior_pid. */ - saved_inferior_pid = inferior_pid; - inferior_pid = pid; + /* In case ptid != inferior_ptid. */ + saved_inferior_ptid = inferior_ptid; + inferior_ptid = ptid; - pc_val = TARGET_READ_PC (pid); + pc_val = TARGET_READ_PC (ptid); - inferior_pid = saved_inferior_pid; + inferior_ptid = saved_inferior_ptid; return pc_val; } CORE_ADDR read_pc (void) { - return read_pc_pid (inferior_pid); + return read_pc_pid (inferior_ptid); } void -generic_target_write_pc (CORE_ADDR pc, int pid) +generic_target_write_pc (CORE_ADDR pc, ptid_t ptid) { #ifdef PC_REGNUM if (PC_REGNUM >= 0) - write_register_pid (PC_REGNUM, pc, pid); + write_register_pid (PC_REGNUM, pc, ptid); if (NPC_REGNUM >= 0) - write_register_pid (NPC_REGNUM, pc + 4, pid); + write_register_pid (NPC_REGNUM, pc + 4, ptid); if (NNPC_REGNUM >= 0) - write_register_pid (NNPC_REGNUM, pc + 8, pid); + write_register_pid (NNPC_REGNUM, pc + 8, ptid); #else internal_error (__FILE__, __LINE__, "generic_target_write_pc"); @@ -630,23 +646,23 @@ generic_target_write_pc (CORE_ADDR pc, int pid) } void -write_pc_pid (CORE_ADDR pc, int pid) +write_pc_pid (CORE_ADDR pc, ptid_t ptid) { - int saved_inferior_pid; + ptid_t saved_inferior_ptid; - /* In case pid != inferior_pid. */ - saved_inferior_pid = inferior_pid; - inferior_pid = pid; + /* In case ptid != inferior_ptid. */ + saved_inferior_ptid = inferior_ptid; + inferior_ptid = ptid; - TARGET_WRITE_PC (pc, pid); + TARGET_WRITE_PC (pc, ptid); - inferior_pid = saved_inferior_pid; + inferior_ptid = saved_inferior_ptid; } void write_pc (CORE_ADDR pc) { - write_pc_pid (pc, inferior_pid); + write_pc_pid (pc, inferior_ptid); } /* Cope with strage ways of getting to the stack and frame pointers */ @@ -761,4 +777,8 @@ _initialize_regcache (void) add_com ("flushregs", class_maintenance, reg_flush_command, "Force gdb to flush its register cache (maintainer command)"); + + /* Initialize the thread/process associated with the current set of + registers. For now, -1 is special, and means `no current process'. */ + registers_ptid = pid_to_ptid (-1); }