X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Ffindvar.c;h=577b8afa083e092beff26e7c2b3ac8ba32a8a645;hb=fe898f56a1df2d8a610899df50e38d1590f3e57a;hp=36c72f6e65aa1008f7d759174a5c0979d0e9d8d2;hpb=5573d7d4b1ed201ca3ac71dcdcf359d7eda8c3d3;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/findvar.c b/gdb/findvar.c index 36c72f6e65..577b8afa08 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -1,21 +1,25 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. -This file is part of GDB. + Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, + 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003 Free Software + Foundation, Inc. -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + This file is part of GDB. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ #include "defs.h" #include "symtab.h" @@ -25,6 +29,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "inferior.h" #include "target.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "floatformat.h" +#include "symfile.h" /* for overlay functions */ +#include "regcache.h" +#include "builtin-regs.h" +#include "block.h" /* 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. */ @@ -34,512 +45,399 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ assume it throughout all these swapping routines. If we had to deal with 9 bit characters, we would need to make len be in bits and would have to re-write these routines... */ - you lose +you lose #endif LONGEST -extract_signed_integer (addr, len) - PTR addr; - int len; +extract_signed_integer (const void *addr, int len) { LONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; - if (len > sizeof (LONGEST)) + if (len > (int) sizeof (LONGEST)) error ("\ That operation is not available on integers of more than %d bytes.", - sizeof (LONGEST)); + (int) sizeof (LONGEST)); /* 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 == BFD_ENDIAN_BIG) + { + 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 { - retval = (retval << 8) | *p; + 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; } -unsigned LONGEST -extract_unsigned_integer (addr, len) - PTR addr; - int len; +ULONGEST +extract_unsigned_integer (const void *addr, int len) { - unsigned LONGEST retval; - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; + ULONGEST retval; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; - if (len > sizeof (unsigned LONGEST)) + if (len > (int) sizeof (ULONGEST)) error ("\ That operation is not available on integers of more than %d bytes.", - sizeof (unsigned LONGEST)); + (int) sizeof (ULONGEST)); /* 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 == BFD_ENDIAN_BIG) { - 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; } -CORE_ADDR -extract_address (addr, len) - PTR addr; - int len; -{ - /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure - whether we want this to be true eventually. */ - return extract_unsigned_integer (addr, len); -} +/* Sometimes a long long unsigned integer can be extracted as a + LONGEST value. This is done so that we can print these values + better. If this integer can be converted to a LONGEST, this + function returns 1 and sets *PVAL. Otherwise it returns 0. */ -void -store_signed_integer (addr, len, val) - PTR addr; - int len; - LONGEST val; +int +extract_long_unsigned_integer (const void *addr, int orig_len, LONGEST *pval) { - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; + char *p, *first_addr; + int len; - /* 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 + len = orig_len; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { - *p = val & 0xff; - val >>= 8; + for (p = (char *) addr; + len > (int) sizeof (LONGEST) && p < (char *) addr + orig_len; + p++) + { + if (*p == 0) + len--; + else + break; + } + first_addr = p; + } + else + { + first_addr = (char *) addr; + for (p = (char *) addr + orig_len - 1; + len > (int) sizeof (LONGEST) && p >= (char *) addr; + p--) + { + if (*p == 0) + len--; + else + break; + } } -} - -void -store_unsigned_integer (addr, len, val) - PTR addr; - int len; - unsigned LONGEST val; -{ - unsigned char *p; - unsigned char *startaddr = (unsigned char *)addr; - unsigned char *endaddr = startaddr + len; - /* 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 (len <= (int) sizeof (LONGEST)) { - *p = val & 0xff; - val >>= 8; + *pval = (LONGEST) extract_unsigned_integer (first_addr, + sizeof (LONGEST)); + return 1; } + + return 0; } -void -store_address (addr, len, val) - PTR addr; - int len; - CORE_ADDR val; + +/* Treat the LEN bytes at ADDR as a target-format address, and return + that address. ADDR is a buffer in the GDB process, not in the + inferior. + + This function should only be used by target-specific code. It + assumes that a pointer has the same representation as that thing's + address represented as an integer. Some machines use word + addresses, or similarly munged things, for certain types of + pointers, so that assumption doesn't hold everywhere. + + Common code should use extract_typed_address instead, or something + else based on POINTER_TO_ADDRESS. */ + +CORE_ADDR +extract_address (const void *addr, int len) { /* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure whether we want this to be true eventually. */ - store_unsigned_integer (addr, len, (LONGEST)val); + return (CORE_ADDR) extract_unsigned_integer (addr, len); } - -#if !defined (GET_SAVED_REGISTER) -/* Return the address in which frame FRAME's value of register REGNUM - has been saved in memory. Or return zero if it has not been saved. - If REGNUM specifies the SP, the value we return is actually - the SP value, not an address where it was saved. */ +/* Treat the bytes at BUF as a pointer of type TYPE, and return the + address it represents. */ CORE_ADDR -find_saved_register (frame, regnum) - FRAME frame; - int regnum; +extract_typed_address (const void *buf, struct type *type) { - struct frame_info *fi; - struct frame_saved_regs saved_regs; - - register FRAME frame1 = 0; - register CORE_ADDR addr = 0; - - if (frame == 0) /* No regs saved if want current frame */ - return 0; - -#ifdef HAVE_REGISTER_WINDOWS - /* We assume that a register in a register window will only be saved - in one place (since the name changes and/or disappears as you go - towards inner frames), so we only call get_frame_saved_regs on - the current frame. This is directly in contradiction to the - usage below, which assumes that registers used in a frame must be - saved in a lower (more interior) frame. This change is a result - of working on a register window machine; get_frame_saved_regs - always returns the registers saved within a frame, within the - context (register namespace) of that frame. */ - - /* However, note that we don't want this to return anything if - nothing is saved (if there's a frame inside of this one). Also, - callers to this routine asking for the stack pointer want the - 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. */ - - /* 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); - return saved_regs.regs[regnum]; /* ... which might be zero */ - } -#endif /* HAVE_REGISTER_WINDOWS */ - - /* Note that this next routine assumes that registers used in - frame x will be saved only in the frame that x calls and - frames interior to it. This is not true on the sparc, but the - above macro takes care of it, so we should be all right. */ - while (1) - { - QUIT; - frame1 = get_prev_frame (frame1); - if (frame1 == 0 || frame1 == frame) - break; - fi = get_frame_info (frame1); - get_frame_saved_regs (fi, &saved_regs); - if (saved_regs.regs[regnum]) - addr = saved_regs.regs[regnum]; - } + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + internal_error (__FILE__, __LINE__, + "extract_typed_address: " + "type is not a pointer or reference"); - return addr; + return POINTER_TO_ADDRESS (type, buf); } -/* Find register number REGNUM relative to FRAME and put its (raw, - target format) contents in *RAW_BUFFER. Set *OPTIMIZED if the - variable was optimized out (and thus can't be fetched). Set *LVAL - to lval_memory, lval_register, or not_lval, depending on whether - the value was fetched from memory, from a register, or in a strange - and non-modifiable way (e.g. a frame pointer which was calculated - rather than fetched). Set *ADDRP to the address, either in memory - on as a REGISTER_BYTE offset into the registers array. - Note that this implementation never sets *LVAL to not_lval. But - it can be replaced by defining GET_SAVED_REGISTER and supplying - your own. +void +store_signed_integer (void *addr, int len, LONGEST val) +{ + unsigned char *p; + unsigned char *startaddr = (unsigned char *) addr; + unsigned char *endaddr = startaddr + len; - The argument RAW_BUFFER must point to aligned memory. */ + /* Start at the least significant end of the integer, and work towards + the most significant. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + { + for (p = endaddr - 1; p >= startaddr; --p) + { + *p = val & 0xff; + val >>= 8; + } + } + else + { + for (p = startaddr; p < endaddr; ++p) + { + *p = val & 0xff; + val >>= 8; + } + } +} void -get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) - char *raw_buffer; - int *optimized; - CORE_ADDR *addrp; - FRAME frame; - int regnum; - enum lval_type *lval; +store_unsigned_integer (void *addr, int len, ULONGEST val) { - CORE_ADDR addr; - /* Normal systems don't optimize out things with register numbers. */ - if (optimized != NULL) - *optimized = 0; - addr = find_saved_register (frame, regnum); - if (addr != 0) + unsigned char *p; + unsigned char *startaddr = (unsigned char *) addr; + unsigned char *endaddr = startaddr + len; + + /* Start at the least significant end of the integer, and work towards + the most significant. */ + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) { - if (lval != NULL) - *lval = lval_memory; - if (regnum == SP_REGNUM) + for (p = endaddr - 1; p >= startaddr; --p) { - if (raw_buffer != NULL) - { - /* Put it back in target format. */ - store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), addr); - } - if (addrp != NULL) - *addrp = 0; - return; + *p = val & 0xff; + val >>= 8; } - if (raw_buffer != NULL) - read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum)); } else { - if (lval != NULL) - *lval = lval_register; - addr = REGISTER_BYTE (regnum); - if (raw_buffer != NULL) - read_register_gen (regnum, raw_buffer); + for (p = startaddr; p < endaddr; ++p) + { + *p = val & 0xff; + val >>= 8; + } } - if (addrp != NULL) - *addrp = addr; } -#endif /* GET_SAVED_REGISTER. */ -/* Copy the bytes of register REGNUM, relative to the current stack frame, - into our memory at MYADDR, in target byte order. - The number of bytes copied is REGISTER_RAW_SIZE (REGNUM). +/* Store the address VAL as a LEN-byte value in target byte order at + ADDR. ADDR is a buffer in the GDB process, not in the inferior. - Returns 1 if could not be read, 0 if could. */ + This function should only be used by target-specific code. It + assumes that a pointer has the same representation as that thing's + address represented as an integer. Some machines use word + addresses, or similarly munged things, for certain types of + pointers, so that assumption doesn't hold everywhere. -int -read_relative_register_raw_bytes (regnum, myaddr) - int regnum; - char *myaddr; + Common code should use store_typed_address instead, or something else + based on ADDRESS_TO_POINTER. */ +void +store_address (void *addr, int len, LONGEST val) { - int optim; - if (regnum == FP_REGNUM && selected_frame) - { - /* Put it back in target format. */ - store_address (myaddr, REGISTER_RAW_SIZE(FP_REGNUM), - FRAME_FP(selected_frame)); - return 0; - } + store_unsigned_integer (addr, len, val); +} + + +/* Store the address ADDR as a pointer of type TYPE at BUF, in target + form. */ +void +store_typed_address (void *buf, struct type *type, CORE_ADDR addr) +{ + if (TYPE_CODE (type) != TYPE_CODE_PTR + && TYPE_CODE (type) != TYPE_CODE_REF) + internal_error (__FILE__, __LINE__, + "store_typed_address: " + "type is not a pointer or reference"); - get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame, - regnum, (enum lval_type *)NULL); - return optim; + ADDRESS_TO_POINTER (type, buf, addr); } -/* Return a `value' with the contents of register REGNUM - in its virtual format, with the type specified by - REGISTER_VIRTUAL_TYPE. */ -value -value_of_register (regnum) - int regnum; + +/* Return a `value' with the contents of (virtual or cooked) register + REGNUM as found in the specified FRAME. The register's type is + determined by REGISTER_VIRTUAL_TYPE. + + NOTE: returns NULL if register value is not available. Caller will + check return value or die! */ + +struct value * +value_of_register (int regnum, struct frame_info *frame) { CORE_ADDR addr; int optim; - register value val; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; + struct value *reg_val; + char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); enum lval_type lval; + /* Builtin registers lie completly outside of the range of normal + registers. Catch them early so that the target never sees them. */ + if (regnum >= NUM_REGS + NUM_PSEUDO_REGS) + return value_of_builtin_reg (regnum, deprecated_selected_frame); + get_saved_register (raw_buffer, &optim, &addr, - selected_frame, regnum, &lval); - - REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer); - val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); - memcpy (VALUE_CONTENTS_RAW (val), virtual_buffer, - REGISTER_VIRTUAL_SIZE (regnum)); - VALUE_LVAL (val) = lval; - VALUE_ADDRESS (val) = addr; - VALUE_REGNO (val) = regnum; - VALUE_OPTIMIZED_OUT (val) = optim; - return val; -} - -/* Low level examining and depositing of registers. + frame, regnum, &lval); - The caller is responsible for making - sure that the inferior is stopped before calling the fetching routines, - or it will get garbage. (a change from GDB version 3, in which - the caller got the value from the last stop). */ + /* FIXME: cagney/2002-05-15: This test is just bogus. -/* 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. */ -char registers[REGISTER_BYTES + /* SLOP */ 256]; + It indicates that the target failed to supply a value for a + register because it was "not available" at this time. Problem + is, the target still has the register and so get saved_register() + may be returning a value saved on the stack. */ -/* Nonzero if that register has been fetched. */ -char register_valid[NUM_REGS]; + if (register_cached (regnum) < 0) + return NULL; /* register value not available */ -/* Indicate that registers may have changed, so invalidate the cache. */ -void -registers_changed () -{ - int i; - for (i = 0; i < NUM_REGS; i++) - register_valid[i] = 0; -} + reg_val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); -/* Indicate that all registers have been fetched, so mark them all valid. */ -void -registers_fetched () -{ - int i; - for (i = 0; i < NUM_REGS; i++) - register_valid[i] = 1; -} + /* Convert raw data to virtual format if necessary. */ -/* Copy LEN bytes of consecutive data from registers - starting with the REGBYTE'th byte of register data - into memory at MYADDR. */ + if (REGISTER_CONVERTIBLE (regnum)) + { + REGISTER_CONVERT_TO_VIRTUAL (regnum, REGISTER_VIRTUAL_TYPE (regnum), + raw_buffer, VALUE_CONTENTS_RAW (reg_val)); + } + else if (REGISTER_RAW_SIZE (regnum) == REGISTER_VIRTUAL_SIZE (regnum)) + memcpy (VALUE_CONTENTS_RAW (reg_val), raw_buffer, + REGISTER_RAW_SIZE (regnum)); + else + internal_error (__FILE__, __LINE__, + "Register \"%s\" (%d) has conflicting raw (%d) and virtual (%d) size", + REGISTER_NAME (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; + VALUE_OPTIMIZED_OUT (reg_val) = optim; + return reg_val; +} -void -read_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; +/* Given a pointer of type TYPE in target form in BUF, return the + address it represents. */ +CORE_ADDR +unsigned_pointer_to_address (struct type *type, const void *buf) { - /* Fetch all registers. */ - int i; - for (i = 0; i < NUM_REGS; i++) - if (!register_valid[i]) - { - target_fetch_registers (-1); - break; - } - if (myaddr != NULL) - memcpy (myaddr, ®isters[regbyte], len); + return extract_address (buf, TYPE_LENGTH (type)); } -/* Read register REGNO into memory at MYADDR, which must be large enough - for REGISTER_RAW_BYTES (REGNO). Target byte-order. - If the register is known to be the size of a CORE_ADDR or smaller, - read_register can be used instead. */ -void -read_register_gen (regno, myaddr) - int regno; - char *myaddr; +CORE_ADDR +signed_pointer_to_address (struct type *type, const void *buf) { - if (!register_valid[regno]) - target_fetch_registers (regno); - memcpy (myaddr, ®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE (regno)); + return extract_signed_integer (buf, TYPE_LENGTH (type)); } -/* Copy LEN bytes of consecutive data from memory at MYADDR - into registers starting with the REGBYTE'th byte of register data. */ - +/* Given an address, store it as a pointer of type TYPE in target + format in BUF. */ void -write_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; +unsigned_address_to_pointer (struct type *type, void *buf, CORE_ADDR addr) { - /* Make sure the entire registers array is valid. */ - read_register_bytes (0, (char *)NULL, REGISTER_BYTES); - memcpy (®isters[regbyte], myaddr, len); - target_store_registers (-1); + store_address (buf, TYPE_LENGTH (type), addr); } -/* Return the raw contents of register REGNO, regarding it as an integer. */ -/* This probably should be returning LONGEST rather than CORE_ADDR. */ - -CORE_ADDR -read_register (regno) - int regno; +void +address_to_signed_pointer (struct type *type, void *buf, CORE_ADDR addr) { - if (!register_valid[regno]) - target_fetch_registers (regno); - - return extract_address (®isters[REGISTER_BYTE (regno)], - REGISTER_RAW_SIZE(regno)); + store_signed_integer (buf, TYPE_LENGTH (type), addr); } - -/* Registers we shouldn't try to store. */ -#if !defined (CANNOT_STORE_REGISTER) -#define CANNOT_STORE_REGISTER(regno) 0 -#endif - -/* Store VALUE, into the raw contents of register number REGNO. */ -/* FIXME: The val arg should probably be a LONGEST. */ - -void -write_register (regno, val) - int regno; - long val; + +/* Will calling read_var_value or locate_var_value on SYM end + up caring what frame it is being evaluated relative to? SYM must + be non-NULL. */ +int +symbol_read_needs_frame (struct symbol *sym) { - PTR 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 (regno)) - return; - - size = REGISTER_RAW_SIZE(regno); - 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_valid [regno]) + switch (SYMBOL_CLASS (sym)) { - if (memcmp (®isters[REGISTER_BYTE (regno)], buf, size) == 0) - return; - } - - target_prepare_to_store (); + /* All cases listed explicitly so that gcc -Wall will detect it if + we failed to consider one. */ + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + case LOC_LOCAL_ARG: + case LOC_BASEREG: + case LOC_BASEREG_ARG: + case LOC_HP_THREAD_LOCAL_STATIC: + return 1; - memcpy (®isters[REGISTER_BYTE (regno)], buf, size); + case LOC_UNDEF: + case LOC_CONST: + case LOC_STATIC: + case LOC_INDIRECT: + case LOC_TYPEDEF: - register_valid [regno] = 1; + case LOC_LABEL: + /* Getting the address of a label can be done independently of the block, + even if some *uses* of that address wouldn't work so well without + the right frame. */ - target_store_registers (regno); + case LOC_BLOCK: + case LOC_CONST_BYTES: + case LOC_UNRESOLVED: + case LOC_OPTIMIZED_OUT: + return 0; + } + return 1; } -/* 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. */ - -void -supply_register (regno, val) - int regno; - char *val; -{ - register_valid[regno] = 1; - memcpy (®isters[REGISTER_BYTE (regno)], val, 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. */ -#ifdef CLEAN_UP_REGISTER_VALUE - CLEAN_UP_REGISTER_VALUE(regno, ®isters[REGISTER_BYTE(regno)]); -#endif -} - /* Given a struct symbol for a variable, and a stack frame id, read the value of the variable and return a (pointer to a) struct value containing the value. If the variable cannot be found, return a zero pointer. - If FRAME is NULL, use the selected_frame. */ + If FRAME is NULL, use the deprecated_selected_frame. */ -value -read_var_value (var, frame) - register struct symbol *var; - FRAME frame; +struct value * +read_var_value (register struct symbol *var, struct frame_info *frame) { - register value v; - struct frame_info *fi; + register struct value *v; struct type *type = SYMBOL_TYPE (var); CORE_ADDR addr; register int len; 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 == 0) frame = selected_frame; + if (frame == NULL) + frame = deprecated_selected_frame; switch (SYMBOL_CLASS (var)) { @@ -552,7 +450,16 @@ 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) + { + CORE_ADDR addr + = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), + SYMBOL_BFD_SECTION (var)); + store_typed_address (VALUE_CONTENTS_RAW (v), type, addr); + } + else + store_typed_address (VALUE_CONTENTS_RAW (v), type, + SYMBOL_VALUE_ADDRESS (var)); VALUE_LVAL (v) = not_lval; return v; @@ -566,61 +473,101 @@ 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_INDIRECT: + { + /* The import slot does not have a real address in it from the + dynamic loader (dld.sl on HP-UX), if the target hasn't + begun execution yet, so check for that. */ + CORE_ADDR locaddr; + struct value *loc; + if (!target_has_execution) + error ("\ +Attempt to access variable defined in different shared object or load module when\n\ +addresses have not been bound by the dynamic loader. Try again when executable is running."); + + locaddr = SYMBOL_VALUE_ADDRESS (var); + loc = value_at (lookup_pointer_type (type), locaddr, NULL); + addr = value_as_address (loc); + } + 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) - return 0; - addr = FRAME_ARGS_ADDRESS (fi); - if (!addr) - { + { + struct value *ref; + CORE_ADDR argref; + if (frame == NULL) return 0; - } - addr += SYMBOL_VALUE (var); - addr = read_memory_unsigned_integer - (addr, TARGET_PTR_BIT / TARGET_CHAR_BIT); - break; + argref = FRAME_ARGS_ADDRESS (frame); + if (!argref) + return 0; + argref += SYMBOL_VALUE (var); + ref = value_at (lookup_pointer_type (type), argref, NULL); + addr = value_as_address (ref); + break; + } 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; case LOC_BASEREG: case LOC_BASEREG_ARG: + case LOC_HP_THREAD_LOCAL_STATIC: { - char buf[MAX_REGISTER_RAW_SIZE]; - get_saved_register (buf, NULL, NULL, frame, SYMBOL_BASEREG (var), - NULL); - addr = extract_address (buf, REGISTER_RAW_SIZE (SYMBOL_BASEREG (var))); + struct value *regval; + + regval = value_from_register (lookup_pointer_type (type), + SYMBOL_BASEREG (var), frame); + if (regval == NULL) + error ("Value of base register not available."); + addr = value_as_address (regval); addr += SYMBOL_VALUE (var); break; } - + + case LOC_THREAD_LOCAL_STATIC: + { + if (target_get_thread_local_address_p ()) + addr = target_get_thread_local_address (inferior_ptid, + SYMBOL_OBJFILE (var), + SYMBOL_VALUE_ADDRESS (var)); + /* It wouldn't be wrong here to try a gdbarch method, too; + finding TLS is an ABI-specific thing. But we don't do that + yet. */ + else + error ("Cannot find thread-local variables on this target"); + break; + } + case LOC_TYPEDEF: error ("Cannot look up value of a typedef"); 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: @@ -628,20 +575,48 @@ read_var_value (var, frame) case LOC_REGPARM_ADDR: { struct block *b; + int regno = SYMBOL_VALUE (var); + struct value *regval; if (frame == NULL) return 0; - b = get_frame_block (frame); - - v = value_from_register (type, SYMBOL_VALUE (var), frame); + b = get_frame_block (frame, 0); if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) { - addr = *(CORE_ADDR *)VALUE_CONTENTS (v); + regval = value_from_register (lookup_pointer_type (type), + regno, + frame); + + if (regval == NULL) + error ("Value of register variable not available."); + + addr = value_as_address (regval); VALUE_LVAL (v) = lval_memory; } else - return v; + { + regval = value_from_register (type, regno, frame); + + if (regval == NULL) + error ("Value of register variable not available."); + return regval; + } + } + break; + + case LOC_UNRESOLVED: + { + struct minimal_symbol *msym; + + msym = lookup_minimal_symbol (SYMBOL_NAME (var), NULL, NULL); + if (msym == NULL) + return 0; + if (overlay_debugging) + addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym), + SYMBOL_BFD_SECTION (msym)); + else + addr = SYMBOL_VALUE_ADDRESS (msym); } break; @@ -661,24 +636,26 @@ 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 -value_from_register (type, regnum, frame) - struct type *type; - int regnum; - FRAME frame; +struct value * +value_from_register (struct type *type, int regnum, struct frame_info *frame) { - char raw_buffer [MAX_REGISTER_RAW_SIZE]; - char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; + char *raw_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); CORE_ADDR addr; int optim; - value v = allocate_value (type); - int len = TYPE_LENGTH (type); + struct value *v = allocate_value (type); char *value_bytes = 0; int value_bytes_copied = 0; int num_storage_locs; enum lval_type lval; + int len; + + CHECK_TYPEDEF (type); + len = TYPE_LENGTH (type); VALUE_REGNO (v) = regnum; @@ -687,13 +664,15 @@ value_from_register (type, regnum, frame) 1); if (num_storage_locs > 1 -#ifdef GDB_TARGET_IS_H8500 - || TYPE_CODE (type) == TYPE_CODE_PTR +#if 0 + // OBSOLETE #ifdef GDB_TARGET_IS_H8500 + // OBSOLETE || TYPE_CODE (type) == TYPE_CODE_PTR + // OBSOLETE #endif #endif - ) + ) { /* Value spread across multiple storage locations. */ - + int local_regnum; int mem_stor = 0, reg_stor = 0; int mem_tracking = 1; @@ -704,65 +683,78 @@ value_from_register (type, regnum, frame) /* Copy all of the data out, whereever it may be. */ -#ifdef GDB_TARGET_IS_H8500 -/* This piece of hideosity is required because the H8500 treats registers - differently depending upon whether they are used as pointers or not. As a - pointer, a register needs to have a page register tacked onto the front. - An alternate way to do this would be to have gcc output different register - numbers for the pointer & non-pointer form of the register. But, it - doesn't, so we're stuck with this. */ - - if (TYPE_CODE (type) == TYPE_CODE_PTR - && len > 2) - { - int page_regnum; - - switch (regnum) - { - case R0_REGNUM: case R1_REGNUM: case R2_REGNUM: case R3_REGNUM: - page_regnum = SEG_D_REGNUM; - break; - case R4_REGNUM: case R5_REGNUM: - page_regnum = SEG_E_REGNUM; - break; - case R6_REGNUM: case R7_REGNUM: - page_regnum = SEG_T_REGNUM; - break; - } - - value_bytes[0] = 0; - get_saved_register (value_bytes + 1, - &optim, - &addr, - frame, - page_regnum, - &lval); - - if (lval == lval_register) - reg_stor++; - else - mem_stor++; - first_addr = addr; - last_addr = addr; - - get_saved_register (value_bytes + 2, - &optim, - &addr, - frame, - regnum, - &lval); - - if (lval == lval_register) - reg_stor++; - else - { - mem_stor++; - mem_tracking = mem_tracking && (addr == last_addr); - } - last_addr = addr; - } - else -#endif /* GDB_TARGET_IS_H8500 */ +#if 0 + // OBSOLETE #ifdef GDB_TARGET_IS_H8500 + // OBSOLETE /* This piece of hideosity is required because the H8500 treats registers + // OBSOLETE differently depending upon whether they are used as pointers or not. As a + // OBSOLETE pointer, a register needs to have a page register tacked onto the front. + // OBSOLETE An alternate way to do this would be to have gcc output different register + // OBSOLETE numbers for the pointer & non-pointer form of the register. But, it + // OBSOLETE doesn't, so we're stuck with this. */ + // OBSOLETE + // OBSOLETE if (TYPE_CODE (type) == TYPE_CODE_PTR + // OBSOLETE && len > 2) + // OBSOLETE { + // OBSOLETE int page_regnum; + // OBSOLETE + // OBSOLETE switch (regnum) + // OBSOLETE { + // OBSOLETE case R0_REGNUM: + // OBSOLETE case R1_REGNUM: + // OBSOLETE case R2_REGNUM: + // OBSOLETE case R3_REGNUM: + // OBSOLETE page_regnum = SEG_D_REGNUM; + // OBSOLETE break; + // OBSOLETE case R4_REGNUM: + // OBSOLETE case R5_REGNUM: + // OBSOLETE page_regnum = SEG_E_REGNUM; + // OBSOLETE break; + // OBSOLETE case R6_REGNUM: + // OBSOLETE case R7_REGNUM: + // OBSOLETE page_regnum = SEG_T_REGNUM; + // OBSOLETE break; + // OBSOLETE } + // OBSOLETE + // OBSOLETE value_bytes[0] = 0; + // OBSOLETE get_saved_register (value_bytes + 1, + // OBSOLETE &optim, + // OBSOLETE &addr, + // OBSOLETE frame, + // OBSOLETE page_regnum, + // OBSOLETE &lval); + // OBSOLETE + // OBSOLETE if (register_cached (page_regnum) == -1) + // OBSOLETE return NULL; /* register value not available */ + // OBSOLETE + // OBSOLETE if (lval == lval_register) + // OBSOLETE reg_stor++; + // OBSOLETE else + // OBSOLETE mem_stor++; + // OBSOLETE first_addr = addr; + // OBSOLETE last_addr = addr; + // OBSOLETE + // OBSOLETE get_saved_register (value_bytes + 2, + // OBSOLETE &optim, + // OBSOLETE &addr, + // OBSOLETE frame, + // OBSOLETE regnum, + // OBSOLETE &lval); + // OBSOLETE + // OBSOLETE if (register_cached (regnum) == -1) + // OBSOLETE return NULL; /* register value not available */ + // OBSOLETE + // OBSOLETE if (lval == lval_register) + // OBSOLETE reg_stor++; + // OBSOLETE else + // OBSOLETE { + // OBSOLETE mem_stor++; + // OBSOLETE mem_tracking = mem_tracking && (addr == last_addr); + // OBSOLETE } + // OBSOLETE last_addr = addr; + // OBSOLETE } + // OBSOLETE else + // OBSOLETE #endif /* GDB_TARGET_IS_H8500 */ +#endif for (local_regnum = regnum; value_bytes_copied < len; (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum), @@ -775,6 +767,9 @@ value_from_register (type, regnum, frame) local_regnum, &lval); + if (register_cached (local_regnum) == -1) + return NULL; /* register value not available */ + if (regnum == local_regnum) first_addr = addr; if (lval == lval_register) @@ -782,7 +777,7 @@ value_from_register (type, regnum, frame) else { mem_stor++; - + mem_tracking = (mem_tracking && (regnum == local_regnum @@ -797,7 +792,7 @@ value_from_register (type, regnum, frame) for some good purpose. */ { VALUE_LVAL (v) = lval_reg_frame_relative; - VALUE_FRAME (v) = FRAME_FP (frame); + VALUE_FRAME (v) = get_frame_base (frame); VALUE_FRAME_REGNUM (v) = regnum; } else if (mem_stor) @@ -811,14 +806,15 @@ value_from_register (type, regnum, frame) VALUE_ADDRESS (v) = first_addr; } else - fatal ("value_from_register: Value not stored anywhere!"); + internal_error (__FILE__, __LINE__, + "value_from_register: Value not stored anywhere!"); VALUE_OPTIMIZED_OUT (v) = optim; /* Any structure stored in more than one register will always be - an integral number of registers. Otherwise, you'd need to do - some fiddling with the last register copied here for little - endian machines. */ + an integral number of registers. Otherwise, you'd need to do + some fiddling with the last register copied here for little + endian machines. */ /* Copy into the contents section of the value. */ memcpy (VALUE_CONTENTS_RAW (v), value_bytes, len); @@ -826,7 +822,7 @@ value_from_register (type, regnum, frame) /* Finally do any conversion necessary when extracting this type from more than one register. */ #ifdef REGISTER_CONVERT_TO_TYPE - REGISTER_CONVERT_TO_TYPE(regnum, type, VALUE_CONTENTS_RAW(v)); + REGISTER_CONVERT_TO_TYPE (regnum, type, VALUE_CONTENTS_RAW (v)); #endif return v; } @@ -836,49 +832,34 @@ value_from_register (type, regnum, frame) read the data in raw format. */ get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval); + + if (register_cached (regnum) == -1) + return NULL; /* register value not available */ + VALUE_OPTIMIZED_OUT (v) = optim; VALUE_LVAL (v) = lval; VALUE_ADDRESS (v) = addr; - - /* Convert the raw contents to virtual contents. - (Just copy them if the formats are the same.) */ - - REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer); - - if (REGISTER_CONVERTIBLE (regnum)) + + /* Convert the raw register to the corresponding data value's memory + format, if necessary. */ + + if (CONVERT_REGISTER_P (regnum)) { - /* When the raw and virtual formats differ, the virtual format - corresponds to a specific data type. If we want that type, - copy the data into the value. - Otherwise, do a type-conversion. */ - - if (type != REGISTER_VIRTUAL_TYPE (regnum)) - { - /* eg a variable of type `float' in a 68881 register - with raw type `extended' and virtual type `double'. - Fetch it as a `double' and then convert to `float'. */ - v = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); - memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer, len); - v = value_cast (type, v); - } - else - memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer, len); + REGISTER_TO_VALUE (regnum, type, raw_buffer, VALUE_CONTENTS_RAW (v)); } else { /* 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 == BFD_ENDIAN_BIG && len < REGISTER_RAW_SIZE (regnum)) { - /* Big-endian, and we want less than full size. */ + /* Big-endian, and we want less than full size. */ VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len; } -#endif - memcpy (VALUE_CONTENTS_RAW (v), virtual_buffer + VALUE_OFFSET (v), len); + memcpy (VALUE_CONTENTS_RAW (v), raw_buffer + VALUE_OFFSET (v), len); } - + return v; } @@ -887,14 +868,12 @@ value_from_register (type, regnum, frame) return a (pointer to a) struct value containing the properly typed address. */ -value -locate_var_value (var, frame) - register struct symbol *var; - FRAME frame; +struct value * +locate_var_value (register struct symbol *var, struct frame_info *frame) { CORE_ADDR addr = 0; struct type *type = SYMBOL_TYPE (var); - value lazy_value; + struct value *lazy_value; /* Evaluate it first; if the result is a memory address, we're fine. Lazy evaluation pays off here. */ @@ -906,17 +885,33 @@ locate_var_value (var, frame) if (VALUE_LAZY (lazy_value) || TYPE_CODE (type) == TYPE_CODE_FUNC) { + struct value *val; + addr = VALUE_ADDRESS (lazy_value); - return value_from_longest (lookup_pointer_type (type), (LONGEST) addr); + val = value_from_pointer (lookup_pointer_type (type), addr); + VALUE_BFD_SECTION (val) = VALUE_BFD_SECTION (lazy_value); + return val; } /* Not a memory address; check what the problem was. */ - switch (VALUE_LVAL (lazy_value)) + switch (VALUE_LVAL (lazy_value)) { case lval_register: + gdb_assert (REGISTER_NAME (VALUE_REGNO (lazy_value)) != NULL + && *REGISTER_NAME (VALUE_REGNO (lazy_value)) != '\0'); + error("Address requested for identifier " + "\"%s\" which is in register $%s", + SYMBOL_SOURCE_NAME (var), + REGISTER_NAME (VALUE_REGNO (lazy_value))); + break; + case lval_reg_frame_relative: - error ("Address requested for identifier \"%s\" which is in a register.", - SYMBOL_SOURCE_NAME (var)); + gdb_assert (REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)) != NULL + && *REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value)) != '\0'); + error("Address requested for identifier " + "\"%s\" which is in frame register $%s", + SYMBOL_SOURCE_NAME (var), + REGISTER_NAME (VALUE_FRAME_REGNUM (lazy_value))); break; default: @@ -924,5 +919,5 @@ locate_var_value (var, frame) SYMBOL_SOURCE_NAME (var)); break; } - return 0; /* For lint -- never reached */ + return 0; /* For lint -- never reached */ }