X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ffindvar.c;h=d0051455109a5dc203d08888e138745fe862a44c;hb=fbd5db48c538738520ee7b9a0699499b56bc9411;hp=58da6b6a3fbdcb366908e6289108a2f8032bada6;hpb=36b9d39cf464e3511c08399cbce1da7e098fde69;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/findvar.c b/gdb/findvar.c index 58da6b6a3f..d005145510 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -1,700 +1,794 @@ /* Find a variable's value in memory, for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. -This file is part of GDB. + Copyright (C) 1986-2001, 2003-2005, 2007-2012 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 3 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, see . */ -#include #include "defs.h" -#include "param.h" #include "symtab.h" +#include "gdbtypes.h" #include "frame.h" #include "value.h" #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 "user-regs.h" +#include "block.h" +#include "objfiles.h" +#include "language.h" + +/* Basic byte-swapping routines. All 'extract' functions return a + host-format integer from a target-format integer at ADDR which is + LEN bytes long. */ + +#if TARGET_CHAR_BIT != 8 || HOST_CHAR_BIT != 8 + /* 8 bit characters are a pretty safe assumption these days, so we + 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 +#endif -#if !defined (GET_SAVED_REGISTER) +LONGEST +extract_signed_integer (const gdb_byte *addr, int len, + enum bfd_endian byte_order) +{ + LONGEST retval; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; + + if (len > (int) sizeof (LONGEST)) + error (_("\ +That operation is not available on integers of more than %d bytes."), + (int) sizeof (LONGEST)); + + /* Start at the most significant end of the integer, and work towards + the least significant. */ + if (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 + { + 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; +} -/* 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. */ +ULONGEST +extract_unsigned_integer (const gdb_byte *addr, int len, + enum bfd_endian byte_order) +{ + ULONGEST retval; + const unsigned char *p; + const unsigned char *startaddr = addr; + const unsigned char *endaddr = startaddr + len; + + if (len > (int) sizeof (ULONGEST)) + error (_("\ +That operation is not available on integers of more than %d bytes."), + (int) sizeof (ULONGEST)); + + /* Start at the most significant end of the integer, and work towards + the least significant. */ + retval = 0; + if (byte_order == BFD_ENDIAN_BIG) + { + 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 -find_saved_register (frame, regnum) - FRAME frame; - int regnum; +/* 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. */ + +int +extract_long_unsigned_integer (const gdb_byte *addr, int orig_len, + enum bfd_endian byte_order, LONGEST *pval) { - 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)) + const gdb_byte *p; + const gdb_byte *first_addr; + int len; + + len = orig_len; + if (byte_order == BFD_ENDIAN_BIG) { - 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 */ + for (p = addr; + len > (int) sizeof (LONGEST) && p < addr + orig_len; + p++) + { + if (*p == 0) + len--; + else + break; + } + first_addr = p; + } + else + { + first_addr = addr; + for (p = addr + orig_len - 1; + len > (int) sizeof (LONGEST) && p >= addr; + p--) + { + if (*p == 0) + len--; + else + break; + } } -#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) + if (len <= (int) sizeof (LONGEST)) { - 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]; + *pval = (LONGEST) extract_unsigned_integer (first_addr, + sizeof (LONGEST), + byte_order); + return 1; } - return addr; + return 0; } -/* Find register number REGNUM relative to FRAME and put its - (raw) 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. +/* Treat the bytes at BUF as a pointer of type TYPE, and return the + address it represents. */ +CORE_ADDR +extract_typed_address (const gdb_byte *buf, struct type *type) +{ + 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 gdbarch_pointer_to_address (get_type_arch (type), type, buf); +} + +/* All 'store' functions accept a host-format integer and store a + target-format integer at ADDR which is LEN bytes long. */ - The argument RAW_BUFFER must point to aligned memory. */ 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_signed_integer (gdb_byte *addr, int len, + enum bfd_endian byte_order, LONGEST 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 != NULL) + gdb_byte *p; + gdb_byte *startaddr = addr; + gdb_byte *endaddr = startaddr + len; + + /* Start at the least significant end of the integer, and work towards + the most significant. */ + if (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) - *(CORE_ADDR *)raw_buffer = 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). - Returns 1 if could not be read, 0 if could. */ - -int -read_relative_register_raw_bytes (regnum, myaddr) - int regnum; - char *myaddr; +void +store_unsigned_integer (gdb_byte *addr, int len, + enum bfd_endian byte_order, ULONGEST val) { - int optim; - if (regnum == FP_REGNUM && selected_frame) + 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 (byte_order == BFD_ENDIAN_BIG) { - bcopy (&FRAME_FP(selected_frame), myaddr, sizeof (CORE_ADDR)); - SWAP_TARGET_AND_HOST (myaddr, sizeof (CORE_ADDR)); /* in target order */ - return 0; + for (p = endaddr - 1; p >= startaddr; --p) + { + *p = val & 0xff; + val >>= 8; + } + } + else + { + for (p = startaddr; p < endaddr; ++p) + { + *p = val & 0xff; + val >>= 8; + } } +} - get_saved_register (myaddr, &optim, (CORE_ADDR *) NULL, selected_frame, - regnum, (enum lval_type *)NULL); - return optim; +/* Store the address ADDR as a pointer of type TYPE at BUF, in target + form. */ +void +store_typed_address (gdb_byte *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")); + + gdbarch_address_to_pointer (get_type_arch (type), 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_type(). */ + +struct value * +value_of_register (int regnum, struct frame_info *frame) { + struct gdbarch *gdbarch = get_frame_arch (frame); CORE_ADDR addr; int optim; - register value val; - char raw_buffer[MAX_REGISTER_RAW_SIZE]; - char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; + int unavail; + struct value *reg_val; + int realnum; + gdb_byte raw_buffer[MAX_REGISTER_SIZE]; enum lval_type lval; - get_saved_register (raw_buffer, &optim, &addr, - selected_frame, regnum, &lval); - - target_convert_to_virtual (regnum, raw_buffer, virtual_buffer); - val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum)); - bcopy (virtual_buffer, VALUE_CONTENTS_RAW (val), - 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. + /* User registers lie completely outside of the range of normal + registers. Catch them early so that the target never sees them. */ + if (regnum >= gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch)) + return value_of_user_reg (regnum, frame); - 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). */ + frame_register (frame, regnum, &optim, &unavail, + &lval, &addr, &realnum, raw_buffer); -/* Contents of the registers in target byte order. - We allocate some extra slop since we do a lot of bcopy's around `registers', - and failing-soft is better than failing hard. */ -char registers[REGISTER_BYTES + /* SLOP */ 256]; + reg_val = allocate_value (register_type (gdbarch, regnum)); -/* Nonzero if that register has been fetched. */ -char register_valid[NUM_REGS]; + if (!optim && !unavail) + memcpy (value_contents_raw (reg_val), raw_buffer, + register_size (gdbarch, regnum)); + else + memset (value_contents_raw (reg_val), 0, + register_size (gdbarch, regnum)); + + VALUE_LVAL (reg_val) = lval; + set_value_address (reg_val, addr); + VALUE_REGNUM (reg_val) = regnum; + set_value_optimized_out (reg_val, optim); + if (unavail) + mark_value_bytes_unavailable (reg_val, 0, register_size (gdbarch, regnum)); + VALUE_FRAME_ID (reg_val) = get_frame_id (frame); + return reg_val; +} -/* Indicate that registers may have changed, so invalidate the cache. */ -void -registers_changed () +/* 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_type(). The value is not fetched. */ + +struct value * +value_of_register_lazy (struct frame_info *frame, int regnum) { - int i; - for (i = 0; i < NUM_REGS; i++) - register_valid[i] = 0; + struct gdbarch *gdbarch = get_frame_arch (frame); + struct value *reg_val; + + gdb_assert (regnum < (gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch))); + + /* We should have a valid (i.e. non-sentinel) frame. */ + gdb_assert (frame_id_p (get_frame_id (frame))); + + reg_val = allocate_value_lazy (register_type (gdbarch, regnum)); + VALUE_LVAL (reg_val) = lval_register; + VALUE_REGNUM (reg_val) = regnum; + VALUE_FRAME_ID (reg_val) = get_frame_id (frame); + return reg_val; } -/* Indicate that all registers have been fetched, so mark them all valid. */ -void -registers_fetched () +/* Given a pointer of type TYPE in target form in BUF, return the + address it represents. */ +CORE_ADDR +unsigned_pointer_to_address (struct gdbarch *gdbarch, + struct type *type, const gdb_byte *buf) { - int i; - for (i = 0; i < NUM_REGS; i++) - register_valid[i] = 1; -} + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); -/* Copy LEN bytes of consecutive data from registers - starting with the REGBYTE'th byte of register data - into memory at MYADDR. */ + return extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order); +} -void -read_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; +CORE_ADDR +signed_pointer_to_address (struct gdbarch *gdbarch, + struct type *type, const gdb_byte *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) - bcopy (®isters[regbyte], myaddr, len); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + + return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order); } -/* 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. */ +/* Given an address, store it as a pointer of type TYPE in target + format in BUF. */ void -read_register_gen (regno, myaddr) - int regno; - char *myaddr; +unsigned_address_to_pointer (struct gdbarch *gdbarch, struct type *type, + gdb_byte *buf, CORE_ADDR addr) { - if (!register_valid[regno]) - target_fetch_registers (regno); - bcopy (®isters[REGISTER_BYTE (regno)], myaddr, REGISTER_RAW_SIZE (regno)); -} + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); -/* Copy LEN bytes of consecutive data from memory at MYADDR - into registers starting with the REGBYTE'th byte of register data. */ + store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr); +} void -write_register_bytes (regbyte, myaddr, len) - int regbyte; - char *myaddr; - int len; +address_to_signed_pointer (struct gdbarch *gdbarch, struct type *type, + gdb_byte *buf, CORE_ADDR addr) { - /* Make sure the entire registers array is valid. */ - read_register_bytes (0, (char *)NULL, REGISTER_BYTES); - bcopy (myaddr, ®isters[regbyte], len); - target_store_registers (-1); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + + store_signed_integer (buf, TYPE_LENGTH (type), byte_order, addr); } + +/* 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) +{ + switch (SYMBOL_CLASS (sym)) + { + /* All cases listed explicitly so that gcc -Wall will detect it if + we failed to consider one. */ + case LOC_COMPUTED: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_COMPUTED_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + return SYMBOL_COMPUTED_OPS (sym)->read_needs_frame (sym); + + case LOC_REGISTER: + case LOC_ARG: + case LOC_REF_ARG: + case LOC_REGPARM_ADDR: + case LOC_LOCAL: + return 1; -/* Return the contents of register REGNO, regarding it as an integer. */ + case LOC_UNDEF: + case LOC_CONST: + case LOC_STATIC: + case LOC_TYPEDEF: -CORE_ADDR -read_register (regno) - int regno; -{ - int reg; - if (!register_valid[regno]) - target_fetch_registers (regno); - /* FIXME, this loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */ - reg = *(int *) ®isters[REGISTER_BYTE (regno)]; - SWAP_TARGET_AND_HOST (®, sizeof (int)); - return reg; -} + 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. */ -/* Registers we shouldn't try to store. */ -#if !defined (CANNOT_STORE_REGISTER) -#define CANNOT_STORE_REGISTER(regno) 0 -#endif + case LOC_BLOCK: + case LOC_CONST_BYTES: + case LOC_UNRESOLVED: + case LOC_OPTIMIZED_OUT: + return 0; + } + return 1; +} -/* Store VALUE in the register number REGNO, regarded as an integer. */ +/* Private data to be used with minsym_lookup_iterator_cb. */ -void -write_register (regno, val) - int regno, val; +struct minsym_lookup_data { - /* 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; - - SWAP_TARGET_AND_HOST (&val, sizeof (int)); + /* The name of the minimal symbol we are searching for. */ + const char *name; + + /* The field where the callback should store the minimal symbol + if found. It should be initialized to NULL before the search + is started. */ + struct minimal_symbol *result; +}; + +/* A callback function for gdbarch_iterate_over_objfiles_in_search_order. + It searches by name for a minimal symbol within the given OBJFILE. + The arguments are passed via CB_DATA, which in reality is a pointer + to struct minsym_lookup_data. */ + +static int +minsym_lookup_iterator_cb (struct objfile *objfile, void *cb_data) +{ + struct minsym_lookup_data *data = (struct minsym_lookup_data *) cb_data; - target_prepare_to_store (); + gdb_assert (data->result == NULL); - register_valid [regno] = 1; - /* FIXME, this loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */ - /* FIXME, this depends on REGISTER_BYTE (regno) being aligned for host */ - *(int *) ®isters[REGISTER_BYTE (regno)] = val; + data->result = lookup_minimal_symbol (data->name, NULL, objfile); - target_store_registers (regno); + /* The iterator should stop iff a match was found. */ + return (data->result != NULL); } -/* 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. */ +/* A default implementation for the "la_read_var_value" hook in + the language vector which should work in most situations. */ -void -supply_register (regno, val) - int regno; - char *val; -{ - register_valid[regno] = 1; - bcopy (val, ®isters[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno)); -} - -/* 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. */ - -value -read_var_value (var, frame) - register struct symbol *var; - FRAME frame; +struct value * +default_read_var_value (struct symbol *var, struct frame_info *frame) { - register value v; - struct frame_info *fi; + 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. */ - len = TYPE_LENGTH (type); + /* Call check_typedef on our type to make sure that, if TYPE is + a TYPE_CODE_TYPEDEF, its length is set to the length of the target type + instead of zero. However, we do not replace the typedef type by the + target type, because we want to keep the typedef in order to be able to + set the returned value type description correctly. */ + check_typedef (type); - if (frame == 0) frame = selected_frame; + if (symbol_read_needs_frame (var)) + gdb_assert (frame); switch (SYMBOL_CLASS (var)) { case LOC_CONST: - bcopy (&SYMBOL_VALUE (var), VALUE_CONTENTS_RAW (v), len); - SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (v), len); + /* Put the constant back in target format. */ + v = allocate_value (type); + store_signed_integer (value_contents_raw (v), TYPE_LENGTH (type), + gdbarch_byte_order (get_type_arch (type)), + (LONGEST) SYMBOL_VALUE (var)); VALUE_LVAL (v) = not_lval; return v; case LOC_LABEL: - addr = SYMBOL_VALUE_ADDRESS (var); - bcopy (&addr, VALUE_CONTENTS_RAW (v), len); - SWAP_TARGET_AND_HOST (VALUE_CONTENTS_RAW (v), len); + /* Put the constant back in target format. */ + v = allocate_value (type); + if (overlay_debugging) + { + CORE_ADDR addr + = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), + SYMBOL_OBJ_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; case LOC_CONST_BYTES: - { - char *bytes_addr; - bytes_addr = SYMBOL_VALUE_BYTES (var); - bcopy (bytes_addr, VALUE_CONTENTS_RAW (v), len); - VALUE_LVAL (v) = not_lval; - return v; - } + v = allocate_value (type); + memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), + TYPE_LENGTH (type)); + VALUE_LVAL (v) = not_lval; + return v; case LOC_STATIC: - case LOC_EXTERNAL: - addr = SYMBOL_VALUE_ADDRESS (var); + v = allocate_value_lazy (type); + if (overlay_debugging) + addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var), + SYMBOL_OBJ_SECTION (var)); + else + addr = SYMBOL_VALUE_ADDRESS (var); break; -/* Nonzero if a struct which is located in a register or a LOC_ARG - really contains - the address of the struct, not the struct itself. GCC_P is nonzero - if the function was compiled with GCC. */ -#if !defined (REG_STRUCT_HAS_ADDR) -#define REG_STRUCT_HAS_ADDR(gcc_p) 0 -#endif - case LOC_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = FRAME_ARGS_ADDRESS (fi); - if (!addr) { - return 0; - } + addr = get_frame_args_address (frame); + if (!addr) + error (_("Unknown argument list address for `%s'."), + SYMBOL_PRINT_NAME (var)); addr += SYMBOL_VALUE (var); + v = allocate_value_lazy (type); break; - + case LOC_REF_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = FRAME_ARGS_ADDRESS (fi); - if (!addr) { - return 0; + { + struct value *ref; + CORE_ADDR argref; + + argref = get_frame_args_address (frame); + if (!argref) + error (_("Unknown argument list address for `%s'."), + SYMBOL_PRINT_NAME (var)); + argref += SYMBOL_VALUE (var); + ref = value_at (lookup_pointer_type (type), argref); + addr = value_as_address (ref); + v = allocate_value_lazy (type); + break; } - addr += SYMBOL_VALUE (var); - read_memory (addr, &addr, sizeof (CORE_ADDR)); - break; - + case LOC_LOCAL: - case LOC_LOCAL_ARG: - fi = get_frame_info (frame); - if (fi == NULL) - return 0; - addr = SYMBOL_VALUE (var) + FRAME_LOCALS_ADDRESS (fi); + addr = get_frame_locals_address (frame); + addr += SYMBOL_VALUE (var); + v = allocate_value_lazy (type); break; case LOC_TYPEDEF: - error ("Cannot look up value of a typedef"); + error (_("Cannot look up value of a typedef `%s'."), + SYMBOL_PRINT_NAME (var)); break; case LOC_BLOCK: - VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); - return v; + v = allocate_value_lazy (type); + if (overlay_debugging) + addr = symbol_overlayed_address + (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)); + else + addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var)); + break; case LOC_REGISTER: - case LOC_REGPARM: + case LOC_REGPARM_ADDR: { - struct block *b; + int regno = SYMBOL_REGISTER_OPS (var) + ->register_number (var, get_frame_arch (frame)); + struct value *regval; + + if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR) + { + regval = value_from_register (lookup_pointer_type (type), + regno, + frame); + + if (regval == NULL) + error (_("Value of register variable not available for `%s'."), + SYMBOL_PRINT_NAME (var)); + + addr = value_as_address (regval); + v = allocate_value_lazy (type); + } + else + { + regval = value_from_register (type, regno, frame); + + if (regval == NULL) + error (_("Value of register variable not available for `%s'."), + SYMBOL_PRINT_NAME (var)); + return regval; + } + } + break; - if (frame == NULL) - return 0; - b = get_frame_block (frame); - - v = value_from_register (type, SYMBOL_VALUE (var), frame); + case LOC_COMPUTED: + /* FIXME: cagney/2004-01-26: It should be possible to + unconditionally call the SYMBOL_COMPUTED_OPS method when available. + Unfortunately DWARF 2 stores the frame-base (instead of the + function) location in a function's symbol. Oops! For the + moment enable this when/where applicable. */ + return SYMBOL_COMPUTED_OPS (var)->read_variable (var, frame); - if (REG_STRUCT_HAS_ADDR (BLOCK_GCC_COMPILED (b)) - && TYPE_CODE (type) == TYPE_CODE_STRUCT) - addr = *(CORE_ADDR *)VALUE_CONTENTS (v); + case LOC_UNRESOLVED: + { + struct minsym_lookup_data lookup_data; + struct minimal_symbol *msym; + struct obj_section *obj_section; + + memset (&lookup_data, 0, sizeof (lookup_data)); + lookup_data.name = SYMBOL_LINKAGE_NAME (var); + + gdbarch_iterate_over_objfiles_in_search_order + (get_objfile_arch (SYMBOL_SYMTAB (var)->objfile), + minsym_lookup_iterator_cb, &lookup_data, + SYMBOL_SYMTAB (var)->objfile); + msym = lookup_data.result; + + if (msym == NULL) + error (_("No global symbol \"%s\"."), SYMBOL_LINKAGE_NAME (var)); + if (overlay_debugging) + addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym), + SYMBOL_OBJ_SECTION (msym)); else - return v; + addr = SYMBOL_VALUE_ADDRESS (msym); + + obj_section = SYMBOL_OBJ_SECTION (msym); + if (obj_section + && (obj_section->the_bfd_section->flags & SEC_THREAD_LOCAL) != 0) + addr = target_translate_tls_address (obj_section->objfile, addr); + v = allocate_value_lazy (type); } break; + case LOC_OPTIMIZED_OUT: + return allocate_optimized_out_value (type); + default: - error ("Cannot look up value of a botched symbol."); + error (_("Cannot look up value of a botched symbol `%s'."), + SYMBOL_PRINT_NAME (var)); break; } - VALUE_ADDRESS (v) = addr; - VALUE_LAZY (v) = 1; + VALUE_LVAL (v) = lval_memory; + set_value_address (v, addr); return v; } -/* Return a value of type TYPE, stored in register REGNUM, in frame - FRAME. */ +/* Calls VAR's language la_read_var_value hook with the given arguments. */ -value -value_from_register (type, regnum, frame) - struct type *type; - int regnum; - FRAME frame; +struct value * +read_var_value (struct symbol *var, struct frame_info *frame) { - char raw_buffer [MAX_REGISTER_RAW_SIZE]; - char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; - CORE_ADDR addr; - int optim; - value v = allocate_value (type); - int len = TYPE_LENGTH (type); - char *value_bytes = 0; - int value_bytes_copied = 0; - int num_storage_locs; - enum lval_type lval; + const struct language_defn *lang = language_def (SYMBOL_LANGUAGE (var)); - VALUE_REGNO (v) = regnum; + gdb_assert (lang != NULL); + gdb_assert (lang->la_read_var_value != NULL); - num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ? - ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 : - 1); + return lang->la_read_var_value (var, frame); +} - if (num_storage_locs > 1) - { - /* Value spread across multiple storage locations. */ - - int local_regnum; - int mem_stor = 0, reg_stor = 0; - int mem_tracking = 1; - CORE_ADDR last_addr = 0; - CORE_ADDR first_addr; - - value_bytes = (char *) alloca (len + MAX_REGISTER_RAW_SIZE); - - /* Copy all of the data out, whereever it may be. */ - - for (local_regnum = regnum; - value_bytes_copied < len; - (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum), - ++local_regnum)) - { - get_saved_register (value_bytes + value_bytes_copied, - &optim, - &addr, - frame, - local_regnum, - &lval); - if (lval == lval_register) - reg_stor++; - else - { - mem_stor++; - - if (regnum == local_regnum) - first_addr = addr; - - mem_tracking = - (mem_tracking - && (regnum == local_regnum - || addr == last_addr)); - } - last_addr = addr; - } +/* Install default attributes for register values. */ - if ((reg_stor && mem_stor) - || (mem_stor && !mem_tracking)) - /* Mixed storage; all of the hassle we just went through was - for some good purpose. */ - { - VALUE_LVAL (v) = lval_reg_frame_relative; - VALUE_FRAME (v) = FRAME_FP (frame); - VALUE_FRAME_REGNUM (v) = regnum; - } - else if (mem_stor) - { - VALUE_LVAL (v) = lval_memory; - VALUE_ADDRESS (v) = first_addr; - } - else if (reg_stor) - { - VALUE_LVAL (v) = lval_register; - VALUE_ADDRESS (v) = first_addr; - } - else - fatal ("value_from_register: Value not stored anywhere!"); +struct value * +default_value_from_register (struct type *type, int regnum, + struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int len = TYPE_LENGTH (type); + struct value *value = allocate_value (type); + + VALUE_LVAL (value) = lval_register; + VALUE_FRAME_ID (value) = get_frame_id (frame); + VALUE_REGNUM (value) = regnum; + + /* Any structure stored in more than one register will always be + an integral number of registers. Otherwise, you need to do + some fiddling with the last register copied here for little + endian machines. */ + if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG + && len < register_size (gdbarch, regnum)) + /* Big-endian, and we want less than full size. */ + set_value_offset (value, register_size (gdbarch, regnum) - len); + else + set_value_offset (value, 0); - VALUE_OPTIMIZED_OUT (v) = optim; + return value; +} - /* 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. */ +/* VALUE must be an lval_register value. If regnum is the value's + associated register number, and len the length of the values type, + read one or more registers in FRAME, starting with register REGNUM, + until we've read LEN bytes. - /* Copy into the contents section of the value. */ - bcopy (value_bytes, VALUE_CONTENTS_RAW (v), len); + If any of the registers we try to read are optimized out, then mark the + complete resulting value as optimized out. */ - return v; - } +void +read_frame_register_value (struct value *value, struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + int offset = 0; + int reg_offset = value_offset (value); + int regnum = VALUE_REGNUM (value); + int len = TYPE_LENGTH (check_typedef (value_type (value))); + + gdb_assert (VALUE_LVAL (value) == lval_register); - /* Data is completely contained within a single register. Locate the - register's contents in a real register or in core; - read the data in raw format. */ - - get_saved_register (raw_buffer, &optim, &addr, frame, regnum, &lval); - 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.) */ - - target_convert_to_virtual (regnum, raw_buffer, virtual_buffer); - - if (REGISTER_CONVERTIBLE (regnum)) + /* Skip registers wholly inside of REG_OFFSET. */ + while (reg_offset >= register_size (gdbarch, 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)); - bcopy (virtual_buffer, VALUE_CONTENTS_RAW (v), len); - v = value_cast (type, v); - } - else - bcopy (virtual_buffer, VALUE_CONTENTS_RAW (v), len); + reg_offset -= register_size (gdbarch, regnum); + regnum++; } - else + + /* Copy the data. */ + while (len > 0) { - /* Raw and virtual formats are the same for this register. */ + struct value *regval = get_frame_register_value (frame, regnum); + int reg_len = TYPE_LENGTH (value_type (regval)) - reg_offset; -#if TARGET_BYTE_ORDER == BIG_ENDIAN - if (len < REGISTER_RAW_SIZE (regnum)) + if (value_optimized_out (regval)) { - /* Big-endian, and we want less than full size. */ - VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len; + set_value_optimized_out (value, 1); + break; } -#endif - bcopy (virtual_buffer + VALUE_OFFSET (v), - VALUE_CONTENTS_RAW (v), len); + /* If the register length is larger than the number of bytes + remaining to copy, then only copy the appropriate bytes. */ + if (reg_len > len) + reg_len = len; + + value_contents_copy (value, offset, regval, reg_offset, reg_len); + + offset += reg_len; + len -= reg_len; + reg_offset = 0; + regnum++; } - - return v; } - -/* Given a struct symbol for a variable or function, - and a stack frame id, - return a (pointer to a) struct value containing the properly typed - address. */ - -value -locate_var_value (var, frame) - register struct symbol *var; - FRAME frame; -{ - CORE_ADDR addr = 0; - struct type *type = SYMBOL_TYPE (var); - struct type *result_type; - value lazy_value; - /* Evaluate it first; if the result is a memory address, we're fine. - Lazy evaluation pays off here. */ +/* Return a value of type TYPE, stored in register REGNUM, in frame FRAME. */ - lazy_value = read_var_value (var, frame); - if (lazy_value == 0) - error ("Address of \"%s\" is unknown.", SYMBOL_NAME (var)); +struct value * +value_from_register (struct type *type, int regnum, struct frame_info *frame) +{ + struct gdbarch *gdbarch = get_frame_arch (frame); + struct type *type1 = check_typedef (type); + struct value *v; - if (VALUE_LAZY (lazy_value) - || TYPE_CODE (type) == TYPE_CODE_FUNC) + if (gdbarch_convert_register_p (gdbarch, regnum, type1)) { - addr = VALUE_ADDRESS (lazy_value); - - /* C++: The "address" of a reference should yield the address - * of the object pointed to. So force an extra de-reference. */ - - if (TYPE_CODE (type) == TYPE_CODE_REF) + int optim, unavail, ok; + + /* The ISA/ABI need to something weird when obtaining the + specified value from this register. It might need to + re-order non-adjacent, starting with REGNUM (see MIPS and + i386). It might need to convert the [float] register into + the corresponding [integer] type (see Alpha). The assumption + is that gdbarch_register_to_value populates the entire value + including the location. */ + v = allocate_value (type); + VALUE_LVAL (v) = lval_register; + VALUE_FRAME_ID (v) = get_frame_id (frame); + VALUE_REGNUM (v) = regnum; + ok = gdbarch_register_to_value (gdbarch, frame, regnum, type1, + value_contents_raw (v), &optim, + &unavail); + + if (!ok) { - char *buf = alloca (TYPE_LENGTH (type)); - read_memory (addr, buf, TYPE_LENGTH (type)); - addr = unpack_pointer (type, buf); - type = TYPE_TARGET_TYPE (type); + if (optim) + set_value_optimized_out (v, 1); + if (unavail) + mark_value_bytes_unavailable (v, 0, TYPE_LENGTH (type)); } - - /* Address of an array is of the type of address of it's elements. */ - /* FIXME, this is probably wrong now for ANSI C. */ - result_type = - lookup_pointer_type (TYPE_CODE (type) == TYPE_CODE_ARRAY ? - TYPE_TARGET_TYPE (type) : type); - - return value_cast (result_type, - value_from_long (builtin_type_long, (LONGEST) addr)); } - - /* Not a memory address; check what the problem was. */ - switch (VALUE_LVAL (lazy_value)) + else { - case lval_register: - case lval_reg_frame_relative: - error ("Address requested for identifier \"%s\" which is in a register.", - SYMBOL_NAME (var)); - break; + /* Construct the value. */ + v = gdbarch_value_from_register (gdbarch, type, regnum, frame); - default: - error ("Can't take address of \"%s\" which isn't an lvalue.", - SYMBOL_NAME (var)); - break; + /* Get the data. */ + read_frame_register_value (v, frame); } - return 0; /* For lint -- never reached */ + + return v; +} + +/* Return contents of register REGNUM in frame FRAME as address, + interpreted as value of type TYPE. Will abort if register + value is not available. */ + +CORE_ADDR +address_from_register (struct type *type, int regnum, struct frame_info *frame) +{ + struct value *value; + CORE_ADDR result; + + value = value_from_register (type, regnum, frame); + gdb_assert (value); + + result = value_as_address (value); + release_value (value); + value_free (value); + + return result; } +