diff options
author | Jason Molenda <jmolenda@apple.com> | 1998-12-09 00:38:46 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 1998-12-09 00:38:46 +0000 |
commit | ac95dc5eebaa4f45ab2b928be390f9b1678de1bc (patch) | |
tree | 4cb14e44d5339cce802ae85f38470ee3989bec36 /gdb/findvar.c | |
parent | c4efea12c8db0689c52114352e79e07994ced938 (diff) | |
download | gdb-ac95dc5eebaa4f45ab2b928be390f9b1678de1bc.zip gdb-ac95dc5eebaa4f45ab2b928be390f9b1678de1bc.tar.gz gdb-ac95dc5eebaa4f45ab2b928be390f9b1678de1bc.tar.bz2 |
1998-12-08 Philippe De Muyter <phdm@macqel.be>
* config/xm-aix4.h (SIGWINCH_HANDLER): Function `aix_resize_window'
must accept a signal number as parameter.
* config/rs6000/xm-rs6000.h (SIGWINCH_HANDLER): Ditto.
* utils.c (initialize_utils): Give a parameter to `SIGWINCH_HANDLER'.
* inferior.h (register_valid): Variable's type is `SIGNED char', not
`char'.
* findvar.c (register_valid): Ditto.
* defs.h (make_cleanup_func): Protect parameter list by `PARAMS'.
* gdbthread.h (unbind_target_thread_vector): Likewise.
Diffstat (limited to 'gdb/findvar.c')
-rw-r--r-- | gdb/findvar.c | 232 |
1 files changed, 152 insertions, 80 deletions
diff --git a/gdb/findvar.c b/gdb/findvar.c index 6cb7d37..9c3d580 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -1,5 +1,6 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1994, 1995, 1996 Free Software Foundation, Inc. + Copyright 1986, 87, 89, 91, 94, 95, 96, 1998 + Free Software Foundation, Inc. This file is part of GDB. @@ -27,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "target.h" #include "gdb_string.h" #include "floatformat.h" +#include "symfile.h" /* for overlay functions */ /* This is used to indicate that we don't know the format of the floating point number. Typically, this is useful for native ports, where the actual format @@ -39,7 +41,8 @@ const struct floatformat floatformat_unknown; #define CANNOT_STORE_REGISTER(regno) 0 #endif -static void write_register_pid PARAMS ((int regno, LONGEST val, int pid)); +static void +write_register_gen PARAMS ((int, char *)); /* 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. */ @@ -88,20 +91,20 @@ That operation is not available on integers of more than %d bytes.", return retval; } -unsigned LONGEST +ULONGEST extract_unsigned_integer (addr, len) PTR addr; int len; { - unsigned LONGEST retval; + ULONGEST retval; unsigned char *p; unsigned char *startaddr = (unsigned char *)addr; unsigned char *endaddr = startaddr + len; - if (len > (int) sizeof (unsigned LONGEST)) + if (len > (int) sizeof (ULONGEST)) error ("\ That operation is not available on integers of more than %d bytes.", - sizeof (unsigned LONGEST)); + sizeof (ULONGEST)); /* Start at the most significant end of the integer, and work towards the least significant. */ @@ -215,7 +218,7 @@ void store_unsigned_integer (addr, len, val) PTR addr; int len; - unsigned LONGEST val; + ULONGEST val; { unsigned char *p; unsigned char *startaddr = (unsigned char *)addr; @@ -271,21 +274,13 @@ store_address (addr, len, val) } \ while (0) -/* There are various problems with the extract_floating and store_floating - routines. - - 1. These routines only handle byte-swapping, not conversion of - formats. So if host is IEEE floating and target is VAX floating, - or vice-versa, it loses. This means that we can't (yet) use these - routines for extendeds. Extendeds are handled by - REGISTER_CONVERTIBLE. What we want is to use floatformat.h, but that - doesn't yet handle VAX floating at all. +/* Extract a floating-point number from a target-order byte-stream at ADDR. + Returns the value as type DOUBLEST. - 2. We can't deal with it if there is more than one floating point - format in use. This has to be fixed at the unpack_double level. - - 3. We probably should have a LONGEST_DOUBLE or DOUBLEST or whatever - we want to call it which is long double where available. */ + If the host and target formats agree, we just copy the raw data into the + appropriate type of variable and return, letting the host increase precision + as necessary. Otherwise, we call the conversion routine and let it do the + dirty work. */ DOUBLEST extract_floating (addr, len) @@ -304,7 +299,7 @@ extract_floating (addr, len) return retval; } else - FLOATFORMAT_TO_DOUBLEST (TARGET_FLOAT_FORMAT, addr, &dretval); + floatformat_to_doublest (TARGET_FLOAT_FORMAT, addr, &dretval); } else if (len == sizeof (double)) { @@ -316,7 +311,7 @@ extract_floating (addr, len) return retval; } else - FLOATFORMAT_TO_DOUBLEST (TARGET_DOUBLE_FORMAT, addr, &dretval); + floatformat_to_doublest (TARGET_DOUBLE_FORMAT, addr, &dretval); } else if (len == sizeof (DOUBLEST)) { @@ -328,7 +323,7 @@ extract_floating (addr, len) return retval; } else - FLOATFORMAT_TO_DOUBLEST (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval); + floatformat_to_doublest (TARGET_LONG_DOUBLE_FORMAT, addr, &dretval); } else { @@ -353,7 +348,7 @@ store_floating (addr, len, val) memcpy (addr, &floatval, sizeof (floatval)); } else - FLOATFORMAT_FROM_DOUBLEST (TARGET_FLOAT_FORMAT, &val, addr); + floatformat_from_doublest (TARGET_FLOAT_FORMAT, &val, addr); } else if (len == sizeof (double)) { @@ -364,14 +359,14 @@ store_floating (addr, len, val) memcpy (addr, &doubleval, sizeof (doubleval)); } else - FLOATFORMAT_FROM_DOUBLEST (TARGET_DOUBLE_FORMAT, &val, addr); + floatformat_from_doublest (TARGET_DOUBLE_FORMAT, &val, addr); } else if (len == sizeof (DOUBLEST)) { if (HOST_LONG_DOUBLE_FORMAT == TARGET_LONG_DOUBLE_FORMAT) memcpy (addr, &val, sizeof (val)); else - FLOATFORMAT_FROM_DOUBLEST (TARGET_LONG_DOUBLE_FORMAT, &val, addr); + floatformat_from_doublest (TARGET_LONG_DOUBLE_FORMAT, &val, addr); } else { @@ -535,12 +530,19 @@ read_relative_register_raw_bytes (regnum, myaddr) get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame, regnum, (enum lval_type *)NULL); + + if (register_valid [regnum] < 0) + return 1; /* register value not available */ + return optim; } /* Return a `value' with the contents of register REGNUM in its virtual format, with the type specified by - REGISTER_VIRTUAL_TYPE. */ + REGISTER_VIRTUAL_TYPE. + + NOTE: returns NULL if register value is not available. + Caller will check return value or die! */ value_ptr value_of_register (regnum) @@ -555,6 +557,9 @@ value_of_register (regnum) get_saved_register (raw_buffer, &optim, &addr, selected_frame, regnum, &lval); + if (register_valid[regnum] < 0) + return NULL; /* register value not available */ + reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); /* Convert raw data to virtual format if necessary. */ @@ -567,8 +572,13 @@ value_of_register (regnum) } else #endif - memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, - REGISTER_RAW_SIZE (regnum)); + if (REGISTER_RAW_SIZE (regnum) == REGISTER_VIRTUAL_SIZE (regnum)) + memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, + REGISTER_RAW_SIZE (regnum)); + else + fatal ("Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size", + reg_names [regnum], regnum, + REGISTER_RAW_SIZE (regnum), REGISTER_VIRTUAL_SIZE (regnum)); VALUE_LVAL (reg_val) = lval; VALUE_ADDRESS (reg_val) = addr; VALUE_REGNO (reg_val) = regnum; @@ -584,12 +594,14 @@ value_of_register (regnum) the caller got the value from the last stop). */ /* Contents of the registers in target byte order. - We allocate some extra slop since we do a lot of memcpy's around `registers', - and failing-soft is better than failing hard. */ + We allocate some extra slop since we do a lot of memcpy's around + `registers', and failing-soft is better than failing hard. */ + char registers[REGISTER_BYTES + /* SLOP */ 256]; -/* Nonzero if that register has been fetched. */ -char register_valid[NUM_REGS]; +/* Nonzero if that register has been fetched, + -1 if register value not available. */ +SIGNED 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'. */ @@ -605,6 +617,13 @@ registers_changed () registers_pid = -1; + /* Force cleanup of any alloca areas if using C alloca instead of + a builtin alloca. This particular call is used to clean up + areas allocated by low level target code which may build up + during lengthy interactions between gdb and the target before + gdb gives control to the user (ie watchpoints). */ + alloca (0); + for (i = 0; i < numregs; i++) register_valid[i] = 0; @@ -667,6 +686,9 @@ read_register_bytes (inregbyte, myaddr, inlen) if (register_valid[regno]) continue; + if (reg_names[regno] == NULL || *reg_names[regno] == '\0') + continue; + regstart = REGISTER_BYTE (regno); regend = regstart + REGISTER_RAW_SIZE (regno); @@ -713,7 +735,7 @@ read_register_gen (regno, myaddr) /* Write register REGNO at MYADDR to the target. MYADDR points at REGISTER_RAW_BYTES(REGNO), which must be in target byte-order. */ -void +static void write_register_gen (regno, myaddr) int regno; char *myaddr; @@ -747,6 +769,9 @@ write_register_gen (regno, myaddr) register_valid [regno] = 1; target_store_registers (regno); + + if (regno == PC_REGNUM && pc_changed_hook) + pc_changed_hook (); } /* Copy INLEN bytes of consecutive data from memory at MYADDR @@ -887,7 +912,7 @@ write_register (regno, val) target_store_registers (regno); } -static void +void write_register_pid (regno, val, pid) int regno; LONGEST val; @@ -912,21 +937,31 @@ write_register_pid (regno, val, 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. */ + so there is no need to store the value there. + + If VAL is a NULL pointer, then it's probably an unsupported register. We + just set it's value to all zeros. We might want to record this fact, and + report it to the users of read_register and friends. +*/ void supply_register (regno, val) int regno; char *val; { +#if 1 if (registers_pid != inferior_pid) { registers_changed (); registers_pid = inferior_pid; } +#endif register_valid[regno] = 1; - memcpy (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno)); + if (val) + memcpy (®isters[REGISTER_BYTE (regno)], val, REGISTER_RAW_SIZE (regno)); + else + memset (®isters[REGISTER_BYTE (regno)], '\000', REGISTER_RAW_SIZE (regno)); /* 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. */ @@ -941,16 +976,6 @@ supply_register (regno, val) 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; { @@ -961,41 +986,37 @@ read_pc_pid (pid) #endif } -void -write_pc (val) - CORE_ADDR val; +CORE_ADDR +read_pc () { -#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 + return read_pc_pid (inferior_pid); } void -write_pc_pid (val, pid) - CORE_ADDR val; +write_pc_pid (pc, pid) + CORE_ADDR pc; int pid; { #ifdef TARGET_WRITE_PC - TARGET_WRITE_PC (val, pid); + TARGET_WRITE_PC (pc, pid); #else - write_register_pid (PC_REGNUM, val, pid); + write_register_pid (PC_REGNUM, pc, pid); #ifdef NPC_REGNUM - write_register_pid (NPC_REGNUM, val + 4, pid); + write_register_pid (NPC_REGNUM, pc + 4, pid); #ifdef NNPC_REGNUM - write_register_pid (NNPC_REGNUM, val + 8, pid); + write_register_pid (NNPC_REGNUM, pc + 8, pid); #endif #endif #endif } +void +write_pc (pc) + CORE_ADDR pc; +{ + write_pc_pid (pc, inferior_pid); +} + /* Cope with strage ways of getting to the stack and frame pointers */ CORE_ADDR @@ -1099,6 +1120,8 @@ read_var_value (var, frame) v = allocate_value (type); VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ + VALUE_BFD_SECTION (v) = SYMBOL_BFD_SECTION (var); + len = TYPE_LENGTH (type); if (frame == NULL) frame = selected_frame; @@ -1114,7 +1137,13 @@ read_var_value (var, frame) case LOC_LABEL: /* Put the constant back in target format. */ - store_address (VALUE_CONTENTS_RAW (v), len, SYMBOL_VALUE_ADDRESS (var)); + if (overlay_debugging) + store_address (VALUE_CONTENTS_RAW (v), len, + symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), + SYMBOL_BFD_SECTION (var))); + else + store_address (VALUE_CONTENTS_RAW (v), len, + SYMBOL_VALUE_ADDRESS (var)); VALUE_LVAL (v) = not_lval; return v; @@ -1128,7 +1157,11 @@ read_var_value (var, frame) } case LOC_STATIC: - addr = SYMBOL_VALUE_ADDRESS (var); + if (overlay_debugging) + addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), + SYMBOL_BFD_SECTION (var)); + else + addr = SYMBOL_VALUE_ADDRESS (var); break; case LOC_ARG: @@ -1175,7 +1208,11 @@ read_var_value (var, frame) break; case LOC_BLOCK: - VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); + if (overlay_debugging) + VALUE_ADDRESS (v) = symbol_overlayed_address + (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var)); + else + VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); return v; case LOC_REGISTER: @@ -1183,22 +1220,33 @@ read_var_value (var, frame) case LOC_REGPARM_ADDR: { struct block *b; + int regno = SYMBOL_VALUE (var); + value_ptr regval; if (frame == NULL) return 0; b = get_frame_block (frame); - if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) { - addr = - value_as_pointer (value_from_register (lookup_pointer_type (type), - SYMBOL_VALUE (var), - frame)); + regval = value_from_register (lookup_pointer_type (type), + regno, + frame); + + if (regval == NULL) + error ("Value of register variable not available."); + + addr = value_as_pointer (regval); VALUE_LVAL (v) = lval_memory; } else - return value_from_register (type, SYMBOL_VALUE (var), frame); + { + regval = value_from_register (type, regno, frame); + + if (regval == NULL) + error ("Value of register variable not available."); + return regval; + } } break; @@ -1209,7 +1257,11 @@ read_var_value (var, frame) msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL); if (msym == NULL) return 0; - addr = SYMBOL_VALUE_ADDRESS (msym); + if (overlay_debugging) + addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym), + SYMBOL_BFD_SECTION (msym)); + else + addr = SYMBOL_VALUE_ADDRESS (msym); } break; @@ -1229,7 +1281,10 @@ read_var_value (var, frame) } /* Return a value of type TYPE, stored in register REGNUM, in frame - FRAME. */ + FRAME. + + NOTE: returns NULL if register value is not available. + Caller will check return value or die! */ value_ptr value_from_register (type, regnum, frame) @@ -1308,6 +1363,9 @@ value_from_register (type, regnum, frame) page_regnum, &lval); + if (register_valid[page_regnum] == -1) + return NULL; /* register value not available */ + if (lval == lval_register) reg_stor++; else @@ -1322,6 +1380,9 @@ value_from_register (type, regnum, frame) regnum, &lval); + if (register_valid[regnum] == -1) + return NULL; /* register value not available */ + if (lval == lval_register) reg_stor++; else @@ -1345,6 +1406,9 @@ value_from_register (type, regnum, frame) local_regnum, &lval); + if (register_valid[local_regnum] == -1) + return NULL; /* register value not available */ + if (regnum == local_regnum) first_addr = addr; if (lval == lval_register) @@ -1406,6 +1470,10 @@ value_from_register (type, regnum, frame) read the data in raw format. */ get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval); + + if (register_valid[regnum] == -1) + return NULL; /* register value not available */ + VALUE_OPTIMIZED_OUT (v) = optim; VALUE_LVAL (v) = lval; VALUE_ADDRESS (v) = addr; @@ -1459,8 +1527,12 @@ locate_var_value (var, frame) if (VALUE_LAZY (lazy_value) || TYPE_CODE (type) == TYPE_CODE_FUNC) { + value_ptr val; + addr = VALUE_ADDRESS (lazy_value); - return value_from_longest (lookup_pointer_type (type), (LONGEST) addr); + val = value_from_longest (lookup_pointer_type (type), (LONGEST) addr); + VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value); + return val; } /* Not a memory address; check what the problem was. */ |