diff options
Diffstat (limited to 'gdb/findvar.c')
-rw-r--r-- | gdb/findvar.c | 406 |
1 files changed, 296 insertions, 110 deletions
diff --git a/gdb/findvar.c b/gdb/findvar.c index 531075eabc..922572786b 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "inferior.h" #include "target.h" +static void write_register_pid PARAMS ((int regno, LONGEST val, int pid)); + /* Basic byte-swapping routines. GDB has needed these for a long time... All extract a target-format integer at ADDR which is LEN bytes long. */ @@ -54,20 +56,21 @@ That operation is not available on integers of more than %d bytes.", /* Start at the most significant end of the integer, and work towards the least significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - p = startaddr; -#else - p = endaddr - 1; -#endif - /* Do the sign extension once at the start. */ - retval = ((LONGEST)*p ^ 0x80) - 0x80; -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (++p; p < endaddr; ++p) -#else - for (--p; p >= startaddr; --p) -#endif + if (TARGET_BYTE_ORDER == BIG_ENDIAN) { - retval = (retval << 8) | *p; + p = startaddr; + /* Do the sign extension once at the start. */ + retval = ((LONGEST)*p ^ 0x80) - 0x80; + for (++p; p < endaddr; ++p) + retval = (retval << 8) | *p; + } + else + { + p = endaddr - 1; + /* Do the sign extension once at the start. */ + retval = ((LONGEST)*p ^ 0x80) - 0x80; + for (--p; p >= startaddr; --p) + retval = (retval << 8) | *p; } return retval; } @@ -90,13 +93,15 @@ That operation is not available on integers of more than %d bytes.", /* Start at the most significant end of the integer, and work towards the least significant. */ retval = 0; -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = startaddr; p < endaddr; ++p) -#else - for (p = endaddr - 1; p >= startaddr; --p) -#endif + if (TARGET_BYTE_ORDER == BIG_ENDIAN) { - retval = (retval << 8) | *p; + for (p = startaddr; p < endaddr; ++p) + retval = (retval << 8) | *p; + } + else + { + for (p = endaddr - 1; p >= startaddr; --p) + retval = (retval << 8) | *p; } return retval; } @@ -123,14 +128,21 @@ store_signed_integer (addr, len, val) /* Start at the least significant end of the integer, and work towards the most significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = endaddr - 1; p >= startaddr; --p) -#else - for (p = startaddr; p < endaddr; ++p) -#endif + if (TARGET_BYTE_ORDER == BIG_ENDIAN) { - *p = val & 0xff; - val >>= 8; + for (p = endaddr - 1; p >= startaddr; --p) + { + *p = val & 0xff; + val >>= 8; + } + } + else + { + for (p = startaddr; p < endaddr; ++p) + { + *p = val & 0xff; + val >>= 8; + } } } @@ -146,14 +158,21 @@ store_unsigned_integer (addr, len, val) /* Start at the least significant end of the integer, and work towards the most significant. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - for (p = endaddr - 1; p >= startaddr; --p) -#else - for (p = startaddr; p < endaddr; ++p) -#endif + if (TARGET_BYTE_ORDER == BIG_ENDIAN) { - *p = val & 0xff; - val >>= 8; + for (p = endaddr - 1; p >= startaddr; --p) + { + *p = val & 0xff; + val >>= 8; + } + } + else + { + for (p = startaddr; p < endaddr; ++p) + { + *p = val & 0xff; + val >>= 8; + } } } @@ -168,28 +187,9 @@ store_address (addr, len, val) store_unsigned_integer (addr, len, (LONGEST)val); } -/* Swap LEN bytes at BUFFER between target and host byte-order. This is - the wrong way to do byte-swapping because it assumes that you have a way - to have a host variable of exactly the right size. Once extract_floating - and store_floating have been fixed, this can go away. */ -#if TARGET_BYTE_ORDER == HOST_BYTE_ORDER -#define SWAP_TARGET_AND_HOST(buffer,len) -#else /* Target and host byte order differ. */ -#define SWAP_TARGET_AND_HOST(buffer,len) \ - { \ - char tmp; \ - char *p = (char *)(buffer); \ - char *q = ((char *)(buffer)) + len - 1; \ - for (; p < q; p++, q--) \ - { \ - tmp = *q; \ - *q = *p; \ - *p = tmp; \ - } \ - } -#endif /* Target and host byte order differ. */ - -/* There are many problems with floating point cross-debugging. + +/* There are many problems with floating point cross-debugging + in macro SWAP_TARGET_AND_HOST(). 1. These routines only handle byte-swapping, not conversion of formats. So if host is IEEE floating and target is VAX floating, @@ -261,16 +261,15 @@ store_floating (addr, len, val) CORE_ADDR find_saved_register (frame, regnum) - FRAME frame; + struct frame_info *frame; int regnum; { - struct frame_info *fi; struct frame_saved_regs saved_regs; - register FRAME frame1 = 0; + register struct frame_info *frame1 = NULL; register CORE_ADDR addr = 0; - if (frame == 0) /* No regs saved if want current frame */ + if (frame == NULL) /* No regs saved if want current frame */ return 0; #ifdef HAVE_REGISTER_WINDOWS @@ -290,20 +289,17 @@ find_saved_register (frame, regnum) stack pointer saved for *this* frame; this is returned from the next frame. */ - if (REGISTER_IN_WINDOW_P(regnum)) { frame1 = get_next_frame (frame); - if (!frame1) return 0; /* Registers of this frame are - active. */ + if (!frame1) return 0; /* Registers of this frame are active. */ /* Get the SP from the next frame in; it will be this current frame. */ if (regnum != SP_REGNUM) frame1 = frame; - fi = get_frame_info (frame1); - get_frame_saved_regs (fi, &saved_regs); + get_frame_saved_regs (frame1, &saved_regs); return saved_regs.regs[regnum]; /* ... which might be zero */ } #endif /* HAVE_REGISTER_WINDOWS */ @@ -318,8 +314,7 @@ find_saved_register (frame, regnum) frame1 = get_prev_frame (frame1); if (frame1 == 0 || frame1 == frame) break; - fi = get_frame_info (frame1); - get_frame_saved_regs (fi, &saved_regs); + get_frame_saved_regs (frame1, &saved_regs); if (saved_regs.regs[regnum]) addr = saved_regs.regs[regnum]; } @@ -347,11 +342,15 @@ get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) char *raw_buffer; int *optimized; CORE_ADDR *addrp; - FRAME frame; + struct frame_info *frame; int regnum; enum lval_type *lval; { CORE_ADDR addr; + + if (!target_has_registers) + error ("No registers."); + /* Normal systems don't optimize out things with register numbers. */ if (optimized != NULL) *optimized = 0; @@ -416,13 +415,13 @@ read_relative_register_raw_bytes (regnum, myaddr) in its virtual format, with the type specified by REGISTER_VIRTUAL_TYPE. */ -value +value_ptr value_of_register (regnum) int regnum; { CORE_ADDR addr; int optim; - register value reg_val; + register value_ptr reg_val; char raw_buffer[MAX_REGISTER_RAW_SIZE]; enum lval_type lval; @@ -465,12 +464,21 @@ char registers[REGISTER_BYTES + /* SLOP */ 256]; /* Nonzero if that register has been fetched. */ char register_valid[NUM_REGS]; +/* The thread/process associated with the current set of registers. For now, + -1 is special, and means `no current process'. */ +int registers_pid = -1; + /* Indicate that registers may have changed, so invalidate the cache. */ + void registers_changed () { int i; - for (i = 0; i < NUM_REGS; i++) + int numregs = ARCH_NUM_REGS; + + registers_pid = -1; + + for (i = 0; i < numregs; i++) register_valid[i] = 0; } @@ -479,7 +487,8 @@ void registers_fetched () { int i; - for (i = 0; i < NUM_REGS; i++) + int numregs = ARCH_NUM_REGS; + for (i = 0; i < numregs; i++) register_valid[i] = 1; } @@ -494,8 +503,16 @@ read_register_bytes (regbyte, myaddr, len) int len; { /* Fetch all registers. */ - int i; - for (i = 0; i < NUM_REGS; i++) + int i, numregs; + + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + + numregs = ARCH_NUM_REGS; + for (i = 0; i < numregs; i++) if (!register_valid[i]) { target_fetch_registers (-1); @@ -514,6 +531,12 @@ read_register_gen (regno, myaddr) int regno; char *myaddr; { + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + if (!register_valid[regno]) target_fetch_registers (regno); memcpy (myaddr, ®isters[REGISTER_BYTE (regno)], @@ -529,6 +552,12 @@ write_register_bytes (regbyte, myaddr, len) char *myaddr; int len; { + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + /* Make sure the entire registers array is valid. */ read_register_bytes (0, (char *)NULL, REGISTER_BYTES); memcpy (®isters[regbyte], myaddr, len); @@ -542,6 +571,12 @@ CORE_ADDR read_register (regno) int regno; { + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + if (!register_valid[regno]) target_fetch_registers (regno); @@ -549,6 +584,27 @@ read_register (regno) REGISTER_RAW_SIZE(regno)); } +CORE_ADDR +read_register_pid (regno, pid) + int regno, pid; +{ + int save_pid; + CORE_ADDR retval; + + if (pid == inferior_pid) + return read_register (regno); + + save_pid = inferior_pid; + + inferior_pid = pid; + + retval = read_register (regno); + + inferior_pid = save_pid; + + return retval; +} + /* Registers we shouldn't try to store. */ #if !defined (CANNOT_STORE_REGISTER) #define CANNOT_STORE_REGISTER(regno) 0 @@ -570,6 +626,12 @@ write_register (regno, val) if (CANNOT_STORE_REGISTER (regno)) return; + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + size = REGISTER_RAW_SIZE(regno); buf = alloca (size); store_signed_integer (buf, size, (LONGEST) val); @@ -577,11 +639,9 @@ write_register (regno, 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_valid [regno]) - { - if (memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0) - return; - } + if (register_valid [regno] + && memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0) + return; target_prepare_to_store (); @@ -592,6 +652,29 @@ write_register (regno, val) target_store_registers (regno); } +static void +write_register_pid (regno, val, pid) + int regno; + LONGEST val; + int pid; +{ + int save_pid; + + if (pid == inferior_pid) + { + write_register (regno, val); + return; + } + + save_pid = inferior_pid; + + inferior_pid = pid; + + write_register (regno, val); + + inferior_pid = save_pid; +} + /* Record that register REGNO contains VAL. This is used when the value is obtained from the inferior or core dump, so there is no need to store the value there. */ @@ -601,6 +684,12 @@ supply_register (regno, val) int regno; char *val; { + if (registers_pid != inferior_pid) + { + registers_changed (); + registers_pid = inferior_pid; + } + register_valid[regno] = 1; memcpy (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno)); @@ -610,6 +699,111 @@ supply_register (regno, val) CLEAN_UP_REGISTER_VALUE(regno, ®isters[REGISTER_BYTE(regno)]); #endif } + + +/* This routine is getting awfully cluttered with #if's. It's probably + time to turn this into READ_PC and define it in the tm.h file. + Ditto for write_pc. */ + +CORE_ADDR +read_pc () +{ +#ifdef TARGET_READ_PC + return TARGET_READ_PC (inferior_pid); +#else + return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, inferior_pid)); +#endif +} + +CORE_ADDR +read_pc_pid (pid) + int pid; +{ +#ifdef TARGET_READ_PC + return TARGET_READ_PC (pid); +#else + return ADDR_BITS_REMOVE ((CORE_ADDR) read_register_pid (PC_REGNUM, pid)); +#endif +} + +void +write_pc (val) + CORE_ADDR val; +{ +#ifdef TARGET_WRITE_PC + TARGET_WRITE_PC (val, inferior_pid); +#else + write_register_pid (PC_REGNUM, val, inferior_pid); +#ifdef NPC_REGNUM + write_register_pid (NPC_REGNUM, val + 4, inferior_pid); +#ifdef NNPC_REGNUM + write_register_pid (NNPC_REGNUM, val + 8, inferior_pid); +#endif +#endif +#endif +} + +void +write_pc_pid (val, pid) + CORE_ADDR val; + int pid; +{ +#ifdef TARGET_WRITE_PC + TARGET_WRITE_PC (val, pid); +#else + write_register_pid (PC_REGNUM, val, pid); +#ifdef NPC_REGNUM + write_register_pid (NPC_REGNUM, val + 4, pid); +#ifdef NNPC_REGNUM + write_register_pid (NNPC_REGNUM, val + 8, pid); +#endif +#endif +#endif +} + +/* Cope with strage ways of getting to the stack and frame pointers */ + +CORE_ADDR +read_sp () +{ +#ifdef TARGET_READ_SP + return TARGET_READ_SP (); +#else + return read_register (SP_REGNUM); +#endif +} + +void +write_sp (val) + CORE_ADDR val; +{ +#ifdef TARGET_WRITE_SP + TARGET_WRITE_SP (val); +#else + write_register (SP_REGNUM, val); +#endif +} + +CORE_ADDR +read_fp () +{ +#ifdef TARGET_READ_FP + return TARGET_READ_FP (); +#else + return read_register (FP_REGNUM); +#endif +} + +void +write_fp (val) + CORE_ADDR val; +{ +#ifdef TARGET_WRITE_FP + TARGET_WRITE_FP (val); +#else + write_register (FP_REGNUM, val); +#endif +} /* Will calling read_var_value or locate_var_value on SYM end up caring what frame it is being evaluated relative to? SYM must @@ -657,13 +851,12 @@ symbol_read_needs_frame (sym) If the variable cannot be found, return a zero pointer. If FRAME is NULL, use the selected_frame. */ -value +value_ptr read_var_value (var, frame) register struct symbol *var; - FRAME frame; + struct frame_info *frame; { - register value v; - struct frame_info *fi; + register value_ptr v; struct type *type = SYMBOL_TYPE (var); CORE_ADDR addr; register int len; @@ -672,7 +865,7 @@ read_var_value (var, frame) VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ len = TYPE_LENGTH (type); - if (frame == 0) frame = selected_frame; + if (frame == NULL) frame = selected_frame; switch (SYMBOL_CLASS (var)) { @@ -703,26 +896,20 @@ read_var_value (var, frame) break; case LOC_ARG: - fi = get_frame_info (frame); - if (fi == NULL) + if (frame == NULL) return 0; - addr = FRAME_ARGS_ADDRESS (fi); + addr = FRAME_ARGS_ADDRESS (frame); if (!addr) - { - return 0; - } + return 0; addr += SYMBOL_VALUE (var); break; case LOC_REF_ARG: - fi = get_frame_info (frame); - if (fi == NULL) + if (frame == NULL) return 0; - addr = FRAME_ARGS_ADDRESS (fi); + addr = FRAME_ARGS_ADDRESS (frame); if (!addr) - { - return 0; - } + return 0; addr += SYMBOL_VALUE (var); addr = read_memory_unsigned_integer (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT); @@ -730,10 +917,9 @@ read_var_value (var, frame) case LOC_LOCAL: case LOC_LOCAL_ARG: - fi = get_frame_info (frame); - if (fi == NULL) + if (frame == NULL) return 0; - addr = FRAME_LOCALS_ADDRESS (fi); + addr = FRAME_LOCALS_ADDRESS (frame); addr += SYMBOL_VALUE (var); break; @@ -766,15 +952,17 @@ read_var_value (var, frame) return 0; b = get_frame_block (frame); - v = value_from_register (type, SYMBOL_VALUE (var), frame); if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) { - addr = *(CORE_ADDR *)VALUE_CONTENTS (v); + addr = + value_as_pointer (value_from_register (lookup_pointer_type (type), + SYMBOL_VALUE (var), + frame)); VALUE_LVAL (v) = lval_memory; } else - return v; + return value_from_register (type, SYMBOL_VALUE (var), frame); } break; @@ -796,16 +984,16 @@ read_var_value (var, frame) /* Return a value of type TYPE, stored in register REGNUM, in frame FRAME. */ -value +value_ptr value_from_register (type, regnum, frame) struct type *type; int regnum; - FRAME frame; + struct frame_info *frame; { char raw_buffer [MAX_REGISTER_RAW_SIZE]; CORE_ADDR addr; int optim; - value v = allocate_value (type); + value_ptr v = allocate_value (type); int len = TYPE_LENGTH (type); char *value_bytes = 0; int value_bytes_copied = 0; @@ -985,13 +1173,11 @@ value_from_register (type, regnum, frame) { /* Raw and virtual formats are the same for this register. */ -#if TARGET_BYTE_ORDER == BIG_ENDIAN - if (len < REGISTER_RAW_SIZE (regnum)) + if (TARGET_BYTE_ORDER == BIG_ENDIAN && len < REGISTER_RAW_SIZE (regnum)) { /* Big-endian, and we want less than full size. */ VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len; } -#endif memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len); } @@ -1004,14 +1190,14 @@ value_from_register (type, regnum, frame) return a (pointer to a) struct value containing the properly typed address. */ -value +value_ptr locate_var_value (var, frame) register struct symbol *var; - FRAME frame; + struct frame_info *frame; { CORE_ADDR addr = 0; struct type *type = SYMBOL_TYPE (var); - value lazy_value; + value_ptr lazy_value; /* Evaluate it first; if the result is a memory address, we're fine. Lazy evaluation pays off here. */ |