/* Find a variable's value in memory, for GDB, the GNU debugger.
Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
- 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008
- Free Software Foundation, Inc.
+ 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2007, 2008, 2009,
+ 2010 Free Software Foundation, Inc.
This file is part of GDB.
#include "regcache.h"
#include "user-regs.h"
#include "block.h"
+#include "objfiles.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. */
+/* 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
#endif
LONGEST
-extract_signed_integer (const gdb_byte *addr, int len)
+extract_signed_integer (const gdb_byte *addr, int len,
+ enum bfd_endian byte_order)
{
LONGEST retval;
const unsigned char *p;
/* Start at the most significant end of the integer, and work towards
the least significant. */
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
p = startaddr;
/* Do the sign extension once at the start. */
}
ULONGEST
-extract_unsigned_integer (const gdb_byte *addr, int len)
+extract_unsigned_integer (const gdb_byte *addr, int len,
+ enum bfd_endian byte_order)
{
ULONGEST retval;
const unsigned char *p;
/* Start at the most significant end of the integer, and work towards
the least significant. */
retval = 0;
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = startaddr; p < endaddr; ++p)
retval = (retval << 8) | *p;
int
extract_long_unsigned_integer (const gdb_byte *addr, int orig_len,
- LONGEST *pval)
+ enum bfd_endian byte_order, LONGEST *pval)
{
const gdb_byte *p;
const gdb_byte *first_addr;
int len;
len = orig_len;
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = addr;
len > (int) sizeof (LONGEST) && p < addr + orig_len;
if (len <= (int) sizeof (LONGEST))
{
*pval = (LONGEST) extract_unsigned_integer (first_addr,
- sizeof (LONGEST));
+ sizeof (LONGEST),
+ byte_order);
return 1;
}
_("extract_typed_address: "
"type is not a pointer or reference"));
- return gdbarch_pointer_to_address (current_gdbarch, type, buf);
+ 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. */
void
-store_signed_integer (gdb_byte *addr, int len, LONGEST val)
+store_signed_integer (gdb_byte *addr, int len,
+ enum bfd_endian byte_order, LONGEST val)
{
gdb_byte *p;
gdb_byte *startaddr = addr;
/* Start at the least significant end of the integer, and work towards
the most significant. */
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = endaddr - 1; p >= startaddr; --p)
{
}
void
-store_unsigned_integer (gdb_byte *addr, int len, ULONGEST val)
+store_unsigned_integer (gdb_byte *addr, int len,
+ enum bfd_endian byte_order, ULONGEST val)
{
unsigned char *p;
unsigned char *startaddr = (unsigned char *) addr;
/* Start at the least significant end of the integer, and work towards
the most significant. */
- if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
+ if (byte_order == BFD_ENDIAN_BIG)
{
for (p = endaddr - 1; p >= startaddr; --p)
{
_("store_typed_address: "
"type is not a pointer or reference"));
- gdbarch_address_to_pointer (current_gdbarch, type, buf, addr);
+ gdbarch_address_to_pointer (get_type_arch (type), type, buf, addr);
}
memcpy (value_contents_raw (reg_val), raw_buffer,
register_size (gdbarch, regnum));
VALUE_LVAL (reg_val) = lval;
- VALUE_ADDRESS (reg_val) = addr;
+ set_value_address (reg_val, addr);
VALUE_REGNUM (reg_val) = regnum;
set_value_optimized_out (reg_val, optim);
VALUE_FRAME_ID (reg_val) = get_frame_id (frame);
/* 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 gdb_byte *buf)
+unsigned_pointer_to_address (struct gdbarch *gdbarch,
+ struct type *type, const gdb_byte *buf)
{
- return extract_unsigned_integer (buf, TYPE_LENGTH (type));
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+ return extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
}
CORE_ADDR
-signed_pointer_to_address (struct type *type, const gdb_byte *buf)
+signed_pointer_to_address (struct gdbarch *gdbarch,
+ struct type *type, const gdb_byte *buf)
{
- return extract_signed_integer (buf, TYPE_LENGTH (type));
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+ return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order);
}
/* Given an address, store it as a pointer of type TYPE in target
format in BUF. */
void
-unsigned_address_to_pointer (struct type *type, gdb_byte *buf,
- CORE_ADDR addr)
+unsigned_address_to_pointer (struct gdbarch *gdbarch, struct type *type,
+ gdb_byte *buf, CORE_ADDR addr)
{
- store_unsigned_integer (buf, TYPE_LENGTH (type), addr);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+ store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order, addr);
}
void
-address_to_signed_pointer (struct type *type, gdb_byte *buf, CORE_ADDR addr)
+address_to_signed_pointer (struct gdbarch *gdbarch, struct type *type,
+ gdb_byte *buf, CORE_ADDR addr)
{
- store_signed_integer (buf, TYPE_LENGTH (type), addr);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+ store_signed_integer (buf, TYPE_LENGTH (type), byte_order, addr);
}
\f
/* Will calling read_var_value or locate_var_value on SYM end
/* All cases listed explicitly so that gcc -Wall will detect it if
we failed to consider one. */
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ 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_OPS (sym)->read_needs_frame (sym);
+ return SYMBOL_COMPUTED_OPS (sym)->read_needs_frame (sym);
case LOC_REGISTER:
case LOC_ARG:
case LOC_REF_ARG:
- case LOC_REGPARM:
case LOC_REGPARM_ADDR:
case LOC_LOCAL:
return 1;
/* 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 the variable cannot be found, return a zero pointer. */
struct value *
read_var_value (struct symbol *var, struct frame_info *frame)
int len;
if (SYMBOL_CLASS (var) == LOC_COMPUTED
- || SYMBOL_CLASS (var) == LOC_COMPUTED_ARG
- || SYMBOL_CLASS (var) == LOC_REGISTER
- || SYMBOL_CLASS (var) == LOC_REGPARM)
+ || SYMBOL_CLASS (var) == LOC_REGISTER)
/* These cases do not use V. */
v = NULL;
else
len = TYPE_LENGTH (type);
- /* FIXME drow/2003-09-06: this call to the selected frame should be
- pushed upwards to the callers. */
- if (frame == NULL)
- frame = deprecated_safe_get_selected_frame ();
+ if (symbol_read_needs_frame (var))
+ gdb_assert (frame);
switch (SYMBOL_CLASS (var))
{
case LOC_CONST:
/* Put the constant back in target format. */
store_signed_integer (value_contents_raw (v), len,
+ gdbarch_byte_order (get_type_arch (type)),
(LONGEST) SYMBOL_VALUE (var));
VALUE_LVAL (v) = not_lval;
return v;
{
CORE_ADDR addr
= symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
- SYMBOL_BFD_SECTION (var));
+ SYMBOL_OBJ_SECTION (var));
+
store_typed_address (value_contents_raw (v), type, addr);
}
else
return v;
case LOC_CONST_BYTES:
- {
- memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len);
- VALUE_LVAL (v) = not_lval;
- return v;
- }
+ memcpy (value_contents_raw (v), SYMBOL_VALUE_BYTES (var), len);
+ VALUE_LVAL (v) = not_lval;
+ return v;
case LOC_STATIC:
if (overlay_debugging)
addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (var),
- SYMBOL_BFD_SECTION (var));
+ SYMBOL_OBJ_SECTION (var));
else
addr = SYMBOL_VALUE_ADDRESS (var);
break;
case LOC_ARG:
- if (frame == NULL)
- return 0;
addr = get_frame_args_address (frame);
if (!addr)
return 0;
{
struct value *ref;
CORE_ADDR argref;
- if (frame == NULL)
- return 0;
+
argref = get_frame_args_address (frame);
if (!argref)
return 0;
}
case LOC_LOCAL:
- if (frame == NULL)
- return 0;
addr = get_frame_locals_address (frame);
addr += SYMBOL_VALUE (var);
break;
case LOC_BLOCK:
if (overlay_debugging)
- VALUE_ADDRESS (v) = symbol_overlayed_address
- (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_BFD_SECTION (var));
+ set_value_address (v, symbol_overlayed_address
+ (BLOCK_START (SYMBOL_BLOCK_VALUE (var)), SYMBOL_OBJ_SECTION (var)));
else
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
+ set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (var)));
return v;
case LOC_REGISTER:
- case LOC_REGPARM:
case LOC_REGPARM_ADDR:
{
- struct block *b;
- int regno = SYMBOL_VALUE (var);
+ int regno = SYMBOL_REGISTER_OPS (var)
+ ->register_number (var, get_frame_arch (frame));
struct value *regval;
- if (frame == NULL)
- return 0;
- b = get_frame_block (frame, 0);
-
if (SYMBOL_CLASS (var) == LOC_REGPARM_ADDR)
{
regval = value_from_register (lookup_pointer_type (type),
break;
case LOC_COMPUTED:
- case LOC_COMPUTED_ARG:
/* FIXME: cagney/2004-01-26: It should be possible to
- unconditionally call the SYMBOL_OPS method when available.
+ 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. */
- if (frame == 0 && SYMBOL_OPS (var)->read_needs_frame (var))
- return 0;
- return SYMBOL_OPS (var)->read_variable (var, frame);
+ return SYMBOL_COMPUTED_OPS (var)->read_variable (var, frame);
case LOC_UNRESOLVED:
{
struct minimal_symbol *msym;
+ struct obj_section *obj_section;
- msym = lookup_minimal_symbol (DEPRECATED_SYMBOL_NAME (var), NULL, NULL);
+ msym = lookup_minimal_symbol (SYMBOL_LINKAGE_NAME (var), NULL, NULL);
if (msym == NULL)
return 0;
if (overlay_debugging)
addr = symbol_overlayed_address (SYMBOL_VALUE_ADDRESS (msym),
- SYMBOL_BFD_SECTION (msym));
+ SYMBOL_OBJ_SECTION (msym));
else
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);
}
break;
break;
}
- VALUE_ADDRESS (v) = addr;
+ set_value_address (v, addr);
set_value_lazy (v, 1);
return v;
}
return result;
}
-
-\f
-/* 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. */
-
-struct value *
-locate_var_value (struct symbol *var, struct frame_info *frame)
-{
- struct gdbarch *gdbarch = get_frame_arch (frame);
- CORE_ADDR addr = 0;
- struct type *type = SYMBOL_TYPE (var);
- struct value *lazy_value;
-
- /* Evaluate it first; if the result is a memory address, we're fine.
- Lazy evaluation pays off here. */
-
- lazy_value = read_var_value (var, frame);
- if (lazy_value == 0)
- error (_("Address of \"%s\" is unknown."), SYMBOL_PRINT_NAME (var));
-
- if ((VALUE_LVAL (lazy_value) == lval_memory && value_lazy (lazy_value))
- || TYPE_CODE (type) == TYPE_CODE_FUNC)
- {
- struct value *val;
-
- addr = VALUE_ADDRESS (lazy_value);
- val = value_from_pointer (lookup_pointer_type (type), addr);
- return val;
- }
-
- /* Not a memory address; check what the problem was. */
- switch (VALUE_LVAL (lazy_value))
- {
- case lval_register:
- gdb_assert (gdbarch_register_name
- (gdbarch, VALUE_REGNUM (lazy_value)) != NULL
- && *gdbarch_register_name
- (gdbarch, VALUE_REGNUM (lazy_value)) != '\0');
- error (_("Address requested for identifier "
- "\"%s\" which is in register $%s"),
- SYMBOL_PRINT_NAME (var),
- gdbarch_register_name (gdbarch, VALUE_REGNUM (lazy_value)));
- break;
-
- default:
- error (_("Can't take address of \"%s\" which isn't an lvalue."),
- SYMBOL_PRINT_NAME (var));
- break;
- }
- return 0; /* For lint -- never reached */
-}