summaryrefslogtreecommitdiffstats
path: root/gdb/findvar.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/findvar.c')
-rw-r--r--gdb/findvar.c406
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, &registers[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 (&registers[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 (&registers[REGISTER_BYTE (regno)], buf, size) == 0)
- return;
- }
+ if (register_valid [regno]
+ && memcmp (&registers[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 (&registers[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno));
@@ -610,6 +699,111 @@ supply_register (regno, val)
CLEAN_UP_REGISTER_VALUE(regno, &registers[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. */
OpenPOWER on IntegriCloud