X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=7566921c80f6785295c0ca81a49c2bcb654d02e1;hb=3b7538c0317072d430eca4e808b183dac5bd5e45;hp=cf9e137d1d54ea5204c0bae06fbed4fd05573ec0;hpb=feb13ab03fc262ada6379aa92441e48e93b29f0a;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/value.c b/gdb/value.c
index cf9e137d1d..7566921c80 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1,14 +1,14 @@
/* Low level packing and unpacking of values for GDB, the GNU Debugger.
- Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
- 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005 Free
- Software Foundation, Inc.
+ Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+ 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
+ 2009 Free Software Foundation, Inc.
This file is part of GDB.
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
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -17,9 +17,7 @@
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. */
+ along with this program. If not, see . */
#include "defs.h"
#include "gdb_string.h"
@@ -31,17 +29,172 @@
#include "gdbcmd.h"
#include "target.h"
#include "language.h"
-#include "scm-lang.h"
#include "demangle.h"
#include "doublest.h"
#include "gdb_assert.h"
#include "regcache.h"
#include "block.h"
+#include "dfp.h"
+#include "objfiles.h"
+#include "valprint.h"
+#include "cli/cli-decode.h"
+
+#include "python/python.h"
/* Prototypes for exported functions. */
void _initialize_values (void);
+/* Definition of a user function. */
+struct internal_function
+{
+ /* The name of the function. It is a bit odd to have this in the
+ function itself -- the user might use a differently-named
+ convenience variable to hold the function. */
+ char *name;
+
+ /* The handler. */
+ internal_function_fn handler;
+
+ /* User data for the handler. */
+ void *cookie;
+};
+
+static struct cmd_list_element *functionlist;
+
+struct value
+{
+ /* Type of value; either not an lval, or one of the various
+ different possible kinds of lval. */
+ enum lval_type lval;
+
+ /* Is it modifiable? Only relevant if lval != not_lval. */
+ int modifiable;
+
+ /* Location of value (if lval). */
+ union
+ {
+ /* If lval == lval_memory, this is the address in the inferior.
+ If lval == lval_register, this is the byte offset into the
+ registers structure. */
+ CORE_ADDR address;
+
+ /* Pointer to internal variable. */
+ struct internalvar *internalvar;
+
+ /* If lval == lval_computed, this is a set of function pointers
+ to use to access and describe the value, and a closure pointer
+ for them to use. */
+ struct
+ {
+ struct lval_funcs *funcs; /* Functions to call. */
+ void *closure; /* Closure for those functions to use. */
+ } computed;
+ } location;
+
+ /* Describes offset of a value within lval of a structure in bytes.
+ If lval == lval_memory, this is an offset to the address. If
+ lval == lval_register, this is a further offset from
+ location.address within the registers structure. Note also the
+ member embedded_offset below. */
+ int offset;
+
+ /* Only used for bitfields; number of bits contained in them. */
+ int bitsize;
+
+ /* Only used for bitfields; position of start of field. For
+ gdbarch_bits_big_endian=0 targets, it is the position of the LSB. For
+ gdbarch_bits_big_endian=1 targets, it is the position of the MSB. */
+ int bitpos;
+
+ /* Frame register value is relative to. This will be described in
+ the lval enum above as "lval_register". */
+ struct frame_id frame_id;
+
+ /* Type of the value. */
+ struct type *type;
+
+ /* If a value represents a C++ object, then the `type' field gives
+ the object's compile-time type. If the object actually belongs
+ to some class derived from `type', perhaps with other base
+ classes and additional members, then `type' is just a subobject
+ of the real thing, and the full object is probably larger than
+ `type' would suggest.
+
+ If `type' is a dynamic class (i.e. one with a vtable), then GDB
+ can actually determine the object's run-time type by looking at
+ the run-time type information in the vtable. When this
+ information is available, we may elect to read in the entire
+ object, for several reasons:
+
+ - When printing the value, the user would probably rather see the
+ full object, not just the limited portion apparent from the
+ compile-time type.
+
+ - If `type' has virtual base classes, then even printing `type'
+ alone may require reaching outside the `type' portion of the
+ object to wherever the virtual base class has been stored.
+
+ When we store the entire object, `enclosing_type' is the run-time
+ type -- the complete object -- and `embedded_offset' is the
+ offset of `type' within that larger type, in bytes. The
+ value_contents() macro takes `embedded_offset' into account, so
+ most GDB code continues to see the `type' portion of the value,
+ just as the inferior would.
+
+ If `type' is a pointer to an object, then `enclosing_type' is a
+ pointer to the object's run-time type, and `pointed_to_offset' is
+ the offset in bytes from the full object to the pointed-to object
+ -- that is, the value `embedded_offset' would have if we followed
+ the pointer and fetched the complete object. (I don't really see
+ the point. Why not just determine the run-time type when you
+ indirect, and avoid the special case? The contents don't matter
+ until you indirect anyway.)
+
+ If we're not doing anything fancy, `enclosing_type' is equal to
+ `type', and `embedded_offset' is zero, so everything works
+ normally. */
+ struct type *enclosing_type;
+ int embedded_offset;
+ int pointed_to_offset;
+
+ /* Values are stored in a chain, so that they can be deleted easily
+ over calls to the inferior. Values assigned to internal
+ variables, put into the value history or exposed to Python are
+ taken off this list. */
+ struct value *next;
+
+ /* Register number if the value is from a register. */
+ short regnum;
+
+ /* If zero, contents of this value are in the contents field. If
+ nonzero, contents are in inferior. If the lval field is lval_memory,
+ the contents are in inferior memory at location.address plus offset.
+ The lval field may also be lval_register.
+
+ WARNING: This field is used by the code which handles watchpoints
+ (see breakpoint.c) to decide whether a particular value can be
+ watched by hardware watchpoints. If the lazy flag is set for
+ some member of a value chain, it is assumed that this member of
+ the chain doesn't need to be watched as part of watching the
+ value itself. This is how GDB avoids watching the entire struct
+ or array when the user wants to watch a single struct member or
+ array element. If you ever change the way lazy flag is set and
+ reset, be sure to consider this use as well! */
+ char lazy;
+
+ /* If nonzero, this is the value of a variable which does not
+ actually exist in the program. */
+ char optimized_out;
+
+ /* If value is a variable, is it initialized or not. */
+ int initialized;
+
+ /* Actual contents of the value. Target byte-order. NULL or not
+ valid if lazy is nonzero. */
+ gdb_byte *contents;
+};
+
/* Prototypes for local functions. */
static void show_values (char *, int);
@@ -68,6 +221,10 @@ struct value_history_chunk
static struct value_history_chunk *value_history_chain;
static int value_history_count; /* Abs number of last entry stored */
+
+/* The type of internal functions. */
+
+static struct type *internal_fn_type;
/* List of all value objects currently allocated
(except for those released by calls to release_value)
@@ -75,36 +232,60 @@ static int value_history_count; /* Abs number of last entry stored */
static struct value *all_values;
-/* Allocate a value that has the correct length for type TYPE. */
+/* Allocate a lazy value for type TYPE. Its actual content is
+ "lazily" allocated too: the content field of the return value is
+ NULL; it will be allocated when it is fetched from the target. */
struct value *
-allocate_value (struct type *type)
+allocate_value_lazy (struct type *type)
{
struct value *val;
struct type *atype = check_typedef (type);
- val = (struct value *) xzalloc (sizeof (struct value) + TYPE_LENGTH (atype));
+ val = (struct value *) xzalloc (sizeof (struct value));
+ val->contents = NULL;
val->next = all_values;
all_values = val;
val->type = type;
val->enclosing_type = type;
VALUE_LVAL (val) = not_lval;
- VALUE_ADDRESS (val) = 0;
+ val->location.address = 0;
VALUE_FRAME_ID (val) = null_frame_id;
val->offset = 0;
val->bitpos = 0;
val->bitsize = 0;
VALUE_REGNUM (val) = -1;
- val->lazy = 0;
+ val->lazy = 1;
val->optimized_out = 0;
- VALUE_EMBEDDED_OFFSET (val) = 0;
- VALUE_POINTED_TO_OFFSET (val) = 0;
+ val->embedded_offset = 0;
+ val->pointed_to_offset = 0;
val->modifiable = 1;
+ val->initialized = 1; /* Default to initialized. */
+ return val;
+}
+
+/* Allocate the contents of VAL if it has not been allocated yet. */
+
+void
+allocate_value_contents (struct value *val)
+{
+ if (!val->contents)
+ val->contents = (gdb_byte *) xzalloc (TYPE_LENGTH (val->enclosing_type));
+}
+
+/* Allocate a value and its contents for type TYPE. */
+
+struct value *
+allocate_value (struct type *type)
+{
+ struct value *val = allocate_value_lazy (type);
+ allocate_value_contents (val);
+ val->lazy = 0;
return val;
}
/* Allocate a value that has the correct length
- for COUNT repetitions type TYPE. */
+ for COUNT repetitions of type TYPE. */
struct value *
allocate_repeat_value (struct type *type, int count)
@@ -113,7 +294,7 @@ allocate_repeat_value (struct type *type, int count)
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
struct type *range_type
- = create_range_type ((struct type *) NULL, builtin_type_int,
+ = create_range_type ((struct type *) NULL, builtin_type_int32,
low_bound, count + low_bound - 1);
/* FIXME-type-allocation: need a way to free this type when we are
done with it. */
@@ -121,42 +302,109 @@ allocate_repeat_value (struct type *type, int count)
type, range_type));
}
+/* Needed if another module needs to maintain its on list of values. */
+void
+value_prepend_to_list (struct value **head, struct value *val)
+{
+ val->next = *head;
+ *head = val;
+}
+
+/* Needed if another module needs to maintain its on list of values. */
+void
+value_remove_from_list (struct value **head, struct value *val)
+{
+ struct value *prev;
+
+ if (*head == val)
+ *head = (*head)->next;
+ else
+ for (prev = *head; prev->next; prev = prev->next)
+ if (prev->next == val)
+ {
+ prev->next = val->next;
+ break;
+ }
+}
+
+struct value *
+allocate_computed_value (struct type *type,
+ struct lval_funcs *funcs,
+ void *closure)
+{
+ struct value *v = allocate_value (type);
+ VALUE_LVAL (v) = lval_computed;
+ v->location.computed.funcs = funcs;
+ v->location.computed.closure = closure;
+ set_value_lazy (v, 1);
+
+ return v;
+}
+
/* Accessor methods. */
+struct value *
+value_next (struct value *value)
+{
+ return value->next;
+}
+
struct type *
value_type (struct value *value)
{
return value->type;
}
+void
+deprecated_set_value_type (struct value *value, struct type *type)
+{
+ value->type = type;
+}
int
value_offset (struct value *value)
{
return value->offset;
}
+void
+set_value_offset (struct value *value, int offset)
+{
+ value->offset = offset;
+}
int
value_bitpos (struct value *value)
{
return value->bitpos;
}
+void
+set_value_bitpos (struct value *value, int bit)
+{
+ value->bitpos = bit;
+}
int
value_bitsize (struct value *value)
{
return value->bitsize;
}
+void
+set_value_bitsize (struct value *value, int bit)
+{
+ value->bitsize = bit;
+}
-bfd_byte *
+gdb_byte *
value_contents_raw (struct value *value)
{
- return value->aligner.contents + value->embedded_offset;
+ allocate_value_contents (value);
+ return value->contents + value->embedded_offset;
}
-bfd_byte *
+gdb_byte *
value_contents_all_raw (struct value *value)
{
- return value->aligner.contents;
+ allocate_value_contents (value);
+ return value->contents;
}
struct type *
@@ -165,12 +413,12 @@ value_enclosing_type (struct value *value)
return value->enclosing_type;
}
-const bfd_byte *
+const gdb_byte *
value_contents_all (struct value *value)
{
if (value->lazy)
value_fetch_lazy (value);
- return value->aligner.contents;
+ return value->contents;
}
int
@@ -179,18 +427,44 @@ value_lazy (struct value *value)
return value->lazy;
}
-const bfd_byte *
+void
+set_value_lazy (struct value *value, int val)
+{
+ value->lazy = val;
+}
+
+const gdb_byte *
value_contents (struct value *value)
{
return value_contents_writeable (value);
}
-bfd_byte *
+gdb_byte *
value_contents_writeable (struct value *value)
{
if (value->lazy)
value_fetch_lazy (value);
- return value->aligner.contents;
+ return value_contents_raw (value);
+}
+
+/* Return non-zero if VAL1 and VAL2 have the same contents. Note that
+ this function is different from value_equal; in C the operator ==
+ can return 0 even if the two values being compared are equal. */
+
+int
+value_contents_equal (struct value *val1, struct value *val2)
+{
+ struct type *type1;
+ struct type *type2;
+ int len;
+
+ type1 = check_typedef (value_type (val1));
+ type2 = check_typedef (value_type (val2));
+ len = TYPE_LENGTH (type1);
+ if (len != TYPE_LENGTH (type2))
+ return 0;
+
+ return (memcmp (value_contents (val1), value_contents (val2), len) == 0);
}
int
@@ -204,6 +478,107 @@ set_value_optimized_out (struct value *value, int val)
{
value->optimized_out = val;
}
+
+int
+value_embedded_offset (struct value *value)
+{
+ return value->embedded_offset;
+}
+
+void
+set_value_embedded_offset (struct value *value, int val)
+{
+ value->embedded_offset = val;
+}
+
+int
+value_pointed_to_offset (struct value *value)
+{
+ return value->pointed_to_offset;
+}
+
+void
+set_value_pointed_to_offset (struct value *value, int val)
+{
+ value->pointed_to_offset = val;
+}
+
+struct lval_funcs *
+value_computed_funcs (struct value *v)
+{
+ gdb_assert (VALUE_LVAL (v) == lval_computed);
+
+ return v->location.computed.funcs;
+}
+
+void *
+value_computed_closure (struct value *v)
+{
+ gdb_assert (VALUE_LVAL (v) == lval_computed);
+
+ return v->location.computed.closure;
+}
+
+enum lval_type *
+deprecated_value_lval_hack (struct value *value)
+{
+ return &value->lval;
+}
+
+CORE_ADDR
+value_address (struct value *value)
+{
+ if (value->lval == lval_internalvar
+ || value->lval == lval_internalvar_component)
+ return 0;
+ return value->location.address + value->offset;
+}
+
+CORE_ADDR
+value_raw_address (struct value *value)
+{
+ if (value->lval == lval_internalvar
+ || value->lval == lval_internalvar_component)
+ return 0;
+ return value->location.address;
+}
+
+void
+set_value_address (struct value *value, CORE_ADDR addr)
+{
+ gdb_assert (value->lval != lval_internalvar
+ && value->lval != lval_internalvar_component);
+ value->location.address = addr;
+}
+
+struct internalvar **
+deprecated_value_internalvar_hack (struct value *value)
+{
+ return &value->location.internalvar;
+}
+
+struct frame_id *
+deprecated_value_frame_id_hack (struct value *value)
+{
+ return &value->frame_id;
+}
+
+short *
+deprecated_value_regnum_hack (struct value *value)
+{
+ return &value->regnum;
+}
+
+int
+deprecated_value_modifiable (struct value *value)
+{
+ return value->modifiable;
+}
+void
+deprecated_set_value_modifiable (struct value *value, int modifiable)
+{
+ value->modifiable = modifiable;
+}
/* Return a mark in the value chain. All values allocated after the
mark is obtained (except for those released) are subject to being freed
@@ -214,6 +589,24 @@ value_mark (void)
return all_values;
}
+void
+value_free (struct value *val)
+{
+ if (val)
+ {
+ if (VALUE_LVAL (val) == lval_computed)
+ {
+ struct lval_funcs *funcs = val->location.computed.funcs;
+
+ if (funcs->free_closure)
+ funcs->free_closure (val);
+ }
+
+ xfree (val->contents);
+ }
+ xfree (val);
+}
+
/* Free all values allocated since MARK was obtained by value_mark
(except for those released). */
void
@@ -298,10 +691,15 @@ struct value *
value_copy (struct value *arg)
{
struct type *encl_type = value_enclosing_type (arg);
- struct value *val = allocate_value (encl_type);
+ struct value *val;
+
+ if (value_lazy (arg))
+ val = allocate_value_lazy (encl_type);
+ else
+ val = allocate_value (encl_type);
val->type = arg->type;
VALUE_LVAL (val) = VALUE_LVAL (arg);
- VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
+ val->location = arg->location;
val->offset = arg->offset;
val->bitpos = arg->bitpos;
val->bitsize = arg->bitsize;
@@ -309,8 +707,8 @@ value_copy (struct value *arg)
VALUE_REGNUM (val) = VALUE_REGNUM (arg);
val->lazy = arg->lazy;
val->optimized_out = arg->optimized_out;
- VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (arg);
- VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (arg);
+ val->embedded_offset = value_embedded_offset (arg);
+ val->pointed_to_offset = arg->pointed_to_offset;
val->modifiable = arg->modifiable;
if (!value_lazy (val))
{
@@ -318,8 +716,34 @@ value_copy (struct value *arg)
TYPE_LENGTH (value_enclosing_type (arg)));
}
+ if (VALUE_LVAL (val) == lval_computed)
+ {
+ struct lval_funcs *funcs = val->location.computed.funcs;
+
+ if (funcs->copy_closure)
+ val->location.computed.closure = funcs->copy_closure (val);
+ }
return val;
}
+
+void
+set_value_component_location (struct value *component, struct value *whole)
+{
+ if (VALUE_LVAL (whole) == lval_internalvar)
+ VALUE_LVAL (component) = lval_internalvar_component;
+ else
+ VALUE_LVAL (component) = VALUE_LVAL (whole);
+
+ component->location = whole->location;
+ if (VALUE_LVAL (whole) == lval_computed)
+ {
+ struct lval_funcs *funcs = whole->location.computed.funcs;
+
+ if (funcs->copy_closure)
+ component->location.computed.closure = funcs->copy_closure (whole);
+ }
+}
+
/* Access to the value history. */
@@ -382,14 +806,14 @@ access_value_history (int num)
if (absnum <= 0)
{
if (num == 0)
- error ("The history is empty.");
+ error (_("The history is empty."));
else if (num == 1)
- error ("There is only one value in the history.");
+ error (_("There is only one value in the history."));
else
- error ("History does not go back to $$%d.", -num);
+ error (_("History does not go back to $$%d."), -num);
}
if (absnum > value_history_count)
- error ("History has not yet reached $%d.", absnum);
+ error (_("History has not yet reached $%d."), absnum);
absnum--;
@@ -403,29 +827,6 @@ access_value_history (int num)
return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
}
-/* Clear the value history entirely.
- Must be done when new symbol tables are loaded,
- because the type pointers become invalid. */
-
-void
-clear_value_history (void)
-{
- struct value_history_chunk *next;
- int i;
- struct value *val;
-
- while (value_history_chain)
- {
- for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
- if ((val = value_history_chain->values[i]) != NULL)
- xfree (val);
- next = value_history_chain->next;
- xfree (value_history_chain);
- value_history_chain = next;
- }
- value_history_count = 0;
-}
-
static void
show_values (char *num_exp, int from_tty)
{
@@ -435,14 +836,14 @@ show_values (char *num_exp, int from_tty)
if (num_exp)
{
- /* "info history +" should print from the stored position.
- "info history " should print around value number . */
+ /* "show values +" should print from the stored position.
+ "show values " should print around value number . */
if (num_exp[0] != '+' || num_exp[1] != '\0')
num = parse_and_eval_long (num_exp) - 5;
}
else
{
- /* "info history" means print the last 10 values. */
+ /* "show values" means print the last 10 values. */
num = value_history_count - 9;
}
@@ -451,18 +852,20 @@ show_values (char *num_exp, int from_tty)
for (i = num; i < num + 10 && i <= value_history_count; i++)
{
+ struct value_print_options opts;
val = access_value_history (i);
- printf_filtered ("$%d = ", i);
- value_print (val, gdb_stdout, 0, Val_pretty_default);
- printf_filtered ("\n");
+ printf_filtered (("$%d = "), i);
+ get_user_print_options (&opts);
+ value_print (val, gdb_stdout, &opts);
+ printf_filtered (("\n"));
}
- /* The next "info history +" should start after what we just printed. */
+ /* The next "show values +" should start after what we just printed. */
num += 10;
/* Hitting just return after this command should do the same thing as
- "info history +". If num_exp is null, this is unnecessary, since
- "info history +" is not useful after "info history". */
+ "show values +". If num_exp is null, this is unnecessary, since
+ "show values +" is not useful after "show values". */
if (from_tty && num_exp)
{
num_exp[0] = '+';
@@ -475,16 +878,75 @@ show_values (char *num_exp, int from_tty)
The user refers to them with a '$' prefix
that does not appear in the variable names stored internally. */
+struct internalvar
+{
+ struct internalvar *next;
+ char *name;
+ struct type *type;
+
+ /* True if this internalvar is the canonical name for a convenience
+ function. */
+ int canonical;
+
+ /* If this function is non-NULL, it is used to compute a fresh value
+ on every access to the internalvar. */
+ internalvar_make_value make_value;
+
+ /* To reduce dependencies on target properties (like byte order) that
+ may change during the lifetime of an internal variable, we store
+ simple scalar values as host objects. */
+ union internalvar_data
+ {
+ struct value *v;
+ struct internal_function *f;
+ LONGEST l;
+ CORE_ADDR a;
+ } u;
+};
+
static struct internalvar *internalvars;
+/* If the variable does not already exist create it and give it the value given.
+ If no value is given then the default is zero. */
+static void
+init_if_undefined_command (char* args, int from_tty)
+{
+ struct internalvar* intvar;
+
+ /* Parse the expression - this is taken from set_command(). */
+ struct expression *expr = parse_expression (args);
+ register struct cleanup *old_chain =
+ make_cleanup (free_current_contents, &expr);
+
+ /* Validate the expression.
+ Was the expression an assignment?
+ Or even an expression at all? */
+ if (expr->nelts == 0 || expr->elts[0].opcode != BINOP_ASSIGN)
+ error (_("Init-if-undefined requires an assignment expression."));
+
+ /* Extract the variable from the parsed expression.
+ In the case of an assign the lvalue will be in elts[1] and elts[2]. */
+ if (expr->elts[1].opcode != OP_INTERNALVAR)
+ error (_("The first parameter to init-if-undefined should be a GDB variable."));
+ intvar = expr->elts[2].internalvar;
+
+ /* Only evaluate the expression if the lvalue is void.
+ This may still fail if the expresssion is invalid. */
+ if (TYPE_CODE (intvar->type) == TYPE_CODE_VOID)
+ evaluate_expression (expr);
+
+ do_cleanups (old_chain);
+}
+
+
/* Look up an internal variable with name NAME. NAME should not
normally include a dollar sign.
If the specified internal variable does not exist,
- one is created, with a void value. */
+ the return value is NULL. */
struct internalvar *
-lookup_internalvar (char *name)
+lookup_only_internalvar (const char *name)
{
struct internalvar *var;
@@ -492,89 +954,410 @@ lookup_internalvar (char *name)
if (strcmp (var->name, name) == 0)
return var;
+ return NULL;
+}
+
+
+/* Create an internal variable with name NAME and with a void value.
+ NAME should not normally include a dollar sign. */
+
+struct internalvar *
+create_internalvar (const char *name)
+{
+ struct internalvar *var;
var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
- var->name = concat (name, NULL);
- var->value = allocate_value (builtin_type_void);
- release_value (var->value);
+ var->name = concat (name, (char *)NULL);
+ var->type = builtin_type_void;
+ var->make_value = NULL;
+ var->canonical = 0;
var->next = internalvars;
internalvars = var;
return var;
}
+/* Create an internal variable with name NAME and register FUN as the
+ function that value_of_internalvar uses to create a value whenever
+ this variable is referenced. NAME should not normally include a
+ dollar sign. */
+
+struct internalvar *
+create_internalvar_type_lazy (char *name, internalvar_make_value fun)
+{
+ struct internalvar *var = create_internalvar (name);
+ var->make_value = fun;
+ return var;
+}
+
+/* Look up an internal variable with name NAME. NAME should not
+ normally include a dollar sign.
+
+ If the specified internal variable does not exist,
+ one is created, with a void value. */
+
+struct internalvar *
+lookup_internalvar (const char *name)
+{
+ struct internalvar *var;
+
+ var = lookup_only_internalvar (name);
+ if (var)
+ return var;
+
+ return create_internalvar (name);
+}
+
struct value *
value_of_internalvar (struct internalvar *var)
{
struct value *val;
- val = value_copy (var->value);
- if (value_lazy (val))
- value_fetch_lazy (val);
- VALUE_LVAL (val) = lval_internalvar;
- VALUE_INTERNALVAR (val) = var;
+ if (var->make_value != NULL)
+ val = (*var->make_value) (var);
+ else
+ {
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ val = allocate_value (var->type);
+ break;
+
+ case TYPE_CODE_INT:
+ val = value_from_longest (var->type, var->u.l);
+ break;
+
+ case TYPE_CODE_PTR:
+ val = value_from_pointer (var->type, var->u.a);
+ break;
+
+ default:
+ val = value_copy (var->u.v);
+ break;
+ }
+
+ if (value_lazy (val))
+ value_fetch_lazy (val);
+
+ /* If the variable's value is a computed lvalue, we want
+ references to it to produce another computed lvalue, where
+ referencces and assignments actually operate through the
+ computed value's functions.
+
+ This means that internal variables with computed values
+ behave a little differently from other internal variables:
+ assignments to them don't just replace the previous value
+ altogether. At the moment, this seems like the behavior we
+ want. */
+ if (val->lval != lval_computed)
+ {
+ VALUE_LVAL (val) = lval_internalvar;
+ VALUE_INTERNALVAR (val) = var;
+ }
+ }
+
return val;
}
+int
+get_internalvar_integer (struct internalvar *var, LONGEST *result)
+{
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_INT:
+ *result = var->u.l;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
+static int
+get_internalvar_function (struct internalvar *var,
+ struct internal_function **result)
+{
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ *result = var->u.f;
+ return 1;
+
+ default:
+ return 0;
+ }
+}
+
void
set_internalvar_component (struct internalvar *var, int offset, int bitpos,
int bitsize, struct value *newval)
{
- bfd_byte *addr = value_contents_writeable (var->value) + offset;
+ gdb_byte *addr;
- if (bitsize)
- modify_field (addr, value_as_long (newval),
- bitpos, bitsize);
- else
- memcpy (addr, value_contents (newval), TYPE_LENGTH (value_type (newval)));
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_PTR:
+ /* We can never get a component of a basic type. */
+ internal_error (__FILE__, __LINE__, "set_internalvar_component");
+
+ default:
+ addr = value_contents_writeable (var->u.v);
+
+ if (bitsize)
+ modify_field (addr + offset,
+ value_as_long (newval), bitpos, bitsize);
+ else
+ memcpy (addr + offset, value_contents (newval),
+ TYPE_LENGTH (value_type (newval)));
+ break;
+ }
}
void
set_internalvar (struct internalvar *var, struct value *val)
{
- struct value *newval;
-
- newval = value_copy (val);
- newval->modifiable = 1;
-
- /* Force the value to be fetched from the target now, to avoid problems
- later when this internalvar is referenced and the target is gone or
- has changed. */
- if (value_lazy (newval))
- value_fetch_lazy (newval);
-
- /* Begin code which must not call error(). If var->value points to
- something free'd, an error() obviously leaves a dangling pointer.
- But we also get a danling pointer if var->value points to
- something in the value chain (i.e., before release_value is
- called), because after the error free_all_values will get called before
- long. */
- xfree (var->value);
- var->value = newval;
- release_value (newval);
+ struct type *new_type = check_typedef (value_type (val));
+ union internalvar_data new_data = { 0 };
+
+ if (var->canonical)
+ error (_("Cannot overwrite convenience function %s"), var->name);
+
+ /* Prepare new contents. */
+ switch (TYPE_CODE (new_type))
+ {
+ case TYPE_CODE_VOID:
+ break;
+
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ gdb_assert (VALUE_LVAL (val) == lval_internalvar);
+ get_internalvar_function (VALUE_INTERNALVAR (val), &new_data.f);
+ break;
+
+ case TYPE_CODE_INT:
+ new_data.l = value_as_long (val);
+ break;
+
+ case TYPE_CODE_PTR:
+ new_data.a = value_as_address (val);
+ break;
+
+ default:
+ new_data.v = value_copy (val);
+ new_data.v->modifiable = 1;
+
+ /* Force the value to be fetched from the target now, to avoid problems
+ later when this internalvar is referenced and the target is gone or
+ has changed. */
+ if (value_lazy (new_data.v))
+ value_fetch_lazy (new_data.v);
+
+ /* Release the value from the value chain to prevent it from being
+ deleted by free_all_values. From here on this function should not
+ call error () until new_data is installed into the var->u to avoid
+ leaking memory. */
+ release_value (new_data.v);
+ break;
+ }
+
+ /* Clean up old contents. */
+ clear_internalvar (var);
+
+ /* Switch over. */
+ var->type = new_type;
+ var->u = new_data;
/* End code which must not call error(). */
}
+void
+set_internalvar_integer (struct internalvar *var, LONGEST l)
+{
+ /* Clean up old contents. */
+ clear_internalvar (var);
+
+ /* Use a platform-independent 32-bit integer type. */
+ var->type = builtin_type_int32;
+ var->u.l = l;
+}
+
+static void
+set_internalvar_function (struct internalvar *var, struct internal_function *f)
+{
+ /* Clean up old contents. */
+ clear_internalvar (var);
+
+ var->type = internal_fn_type;
+ var->u.f = f;
+}
+
+void
+clear_internalvar (struct internalvar *var)
+{
+ /* Clean up old contents. */
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_PTR:
+ break;
+
+ default:
+ value_free (var->u.v);
+ break;
+ }
+
+ /* Set to void type. */
+ var->type = builtin_type_void;
+}
+
char *
internalvar_name (struct internalvar *var)
{
return var->name;
}
-/* Free all internalvars. Done when new symtabs are loaded,
- because that makes the values invalid. */
+static struct internal_function *
+create_internal_function (const char *name,
+ internal_function_fn handler, void *cookie)
+{
+ struct internal_function *ifn = XNEW (struct internal_function);
+ ifn->name = xstrdup (name);
+ ifn->handler = handler;
+ ifn->cookie = cookie;
+ return ifn;
+}
+
+char *
+value_internal_function_name (struct value *val)
+{
+ struct internal_function *ifn;
+ int result;
+
+ gdb_assert (VALUE_LVAL (val) == lval_internalvar);
+ result = get_internalvar_function (VALUE_INTERNALVAR (val), &ifn);
+ gdb_assert (result);
+
+ return ifn->name;
+}
+
+struct value *
+call_internal_function (struct value *func, int argc, struct value **argv)
+{
+ struct internal_function *ifn;
+ int result;
+
+ gdb_assert (VALUE_LVAL (func) == lval_internalvar);
+ result = get_internalvar_function (VALUE_INTERNALVAR (func), &ifn);
+ gdb_assert (result);
+
+ return (*ifn->handler) (ifn->cookie, argc, argv);
+}
+
+/* The 'function' command. This does nothing -- it is just a
+ placeholder to let "help function NAME" work. This is also used as
+ the implementation of the sub-command that is created when
+ registering an internal function. */
+static void
+function_command (char *command, int from_tty)
+{
+ /* Do nothing. */
+}
+
+/* Clean up if an internal function's command is destroyed. */
+static void
+function_destroyer (struct cmd_list_element *self, void *ignore)
+{
+ xfree (self->name);
+ xfree (self->doc);
+}
+
+/* Add a new internal function. NAME is the name of the function; DOC
+ is a documentation string describing the function. HANDLER is
+ called when the function is invoked. COOKIE is an arbitrary
+ pointer which is passed to HANDLER and is intended for "user
+ data". */
+void
+add_internal_function (const char *name, const char *doc,
+ internal_function_fn handler, void *cookie)
+{
+ struct cmd_list_element *cmd;
+ struct internal_function *ifn;
+ struct internalvar *var = lookup_internalvar (name);
+
+ ifn = create_internal_function (name, handler, cookie);
+ set_internalvar_function (var, ifn);
+ var->canonical = 1;
+
+ cmd = add_cmd (xstrdup (name), no_class, function_command, (char *) doc,
+ &functionlist);
+ cmd->destroyer = function_destroyer;
+}
+
+/* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to
+ prevent cycles / duplicates. */
+
+static void
+preserve_one_value (struct value *value, struct objfile *objfile,
+ htab_t copied_types)
+{
+ if (TYPE_OBJFILE (value->type) == objfile)
+ value->type = copy_type_recursive (objfile, value->type, copied_types);
+
+ if (TYPE_OBJFILE (value->enclosing_type) == objfile)
+ value->enclosing_type = copy_type_recursive (objfile,
+ value->enclosing_type,
+ copied_types);
+}
+
+/* Update the internal variables and value history when OBJFILE is
+ discarded; we must copy the types out of the objfile. New global types
+ will be created for every convenience variable which currently points to
+ this objfile's types, and the convenience variables will be adjusted to
+ use the new global types. */
void
-clear_internalvars (void)
+preserve_values (struct objfile *objfile)
{
+ htab_t copied_types;
+ struct value_history_chunk *cur;
struct internalvar *var;
+ struct value *val;
+ int i;
+
+ /* Create the hash table. We allocate on the objfile's obstack, since
+ it is soon to be deleted. */
+ copied_types = create_copied_types_hash (objfile);
+
+ for (cur = value_history_chain; cur; cur = cur->next)
+ for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
+ if (cur->values[i])
+ preserve_one_value (cur->values[i], objfile, copied_types);
- while (internalvars)
+ for (var = internalvars; var; var = var->next)
{
- var = internalvars;
- internalvars = var->next;
- xfree (var->name);
- xfree (var->value);
- xfree (var);
+ if (TYPE_OBJFILE (var->type) == objfile)
+ var->type = copy_type_recursive (objfile, var->type, copied_types);
+
+ switch (TYPE_CODE (var->type))
+ {
+ case TYPE_CODE_VOID:
+ case TYPE_CODE_INTERNAL_FUNCTION:
+ case TYPE_CODE_INT:
+ case TYPE_CODE_PTR:
+ break;
+
+ default:
+ preserve_one_value (var->u.v, objfile, copied_types);
+ break;
+ }
}
+
+ for (val = values_in_python; val; val = val->next)
+ preserve_one_value (val, objfile, copied_types);
+
+ htab_delete (copied_types);
}
static void
@@ -582,21 +1365,25 @@ show_convenience (char *ignore, int from_tty)
{
struct internalvar *var;
int varseen = 0;
+ struct value_print_options opts;
+ get_user_print_options (&opts);
for (var = internalvars; var; var = var->next)
{
if (!varseen)
{
varseen = 1;
}
- printf_filtered ("$%s = ", var->name);
- value_print (var->value, gdb_stdout, 0, Val_pretty_default);
- printf_filtered ("\n");
+ printf_filtered (("$%s = "), var->name);
+ value_print (value_of_internalvar (var), gdb_stdout,
+ &opts);
+ printf_filtered (("\n"));
}
if (!varseen)
- printf_unfiltered ("No debugger convenience variables now defined.\n\
+ printf_unfiltered (_("\
+No debugger convenience variables now defined.\n\
Convenience variables have names starting with \"$\";\n\
-use \"set\" as in \"set $foo = 5\" to define them.\n");
+use \"set\" as in \"set $foo = 5\" to define them.\n"));
}
/* Extract a value as a C number (either long or double).
@@ -622,9 +1409,10 @@ value_as_double (struct value *val)
foo = unpack_double (value_type (val), value_contents (val), &inv);
if (inv)
- error ("Invalid floating value found in program.");
+ error (_("Invalid floating value found in program."));
return foo;
}
+
/* Extract a value as a C pointer. Does not deallocate the value.
Note that val's type may not actually be a pointer; value_as_long
handles all the cases. */
@@ -634,10 +1422,10 @@ value_as_address (struct value *val)
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
#if 0
- /* ADDR_BITS_REMOVE is wrong if we are being called for a
+ /* gdbarch_addr_bits_remove is wrong if we are being called for a
non-address (e.g. argument to "signal", "info break", etc.), or
for pointers to char, in which the low bits *are* significant. */
- return ADDR_BITS_REMOVE (value_as_long (val));
+ return gdbarch_addr_bits_remove (current_gdbarch, value_as_long (val));
#else
/* There are several targets (IA-64, PowerPC, and others) which
@@ -659,7 +1447,7 @@ value_as_address (struct value *val)
Upon entry to this function, if VAL is a value of type `function'
(that is, TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FUNC), then
- VALUE_ADDRESS (val) is the address of the function. This is what
+ value_address (val) is the address of the function. This is what
you'll get if you evaluate an expression like `main'. The call
to COERCE_ARRAY below actually does all the usual unary
conversions, which includes converting values of type `function'
@@ -679,7 +1467,7 @@ value_as_address (struct value *val)
function, just return its address directly. */
if (TYPE_CODE (value_type (val)) == TYPE_CODE_FUNC
|| TYPE_CODE (value_type (val)) == TYPE_CODE_METHOD)
- return VALUE_ADDRESS (val);
+ return value_address (val);
val = coerce_array (val);
@@ -745,25 +1533,23 @@ value_as_address (struct value *val)
to an INT (or some size). After all, it is only an offset. */
LONGEST
-unpack_long (struct type *type, const char *valaddr)
+unpack_long (struct type *type, const gdb_byte *valaddr)
{
enum type_code code = TYPE_CODE (type);
int len = TYPE_LENGTH (type);
int nosign = TYPE_UNSIGNED (type);
- if (current_language->la_language == language_scm
- && is_scmvalue_type (type))
- return scm_unpack (type, valaddr, TYPE_CODE_INT);
-
switch (code)
{
case TYPE_CODE_TYPEDEF:
return unpack_long (check_typedef (type), valaddr);
case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLAGS:
case TYPE_CODE_BOOL:
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_RANGE:
+ case TYPE_CODE_MEMBERPTR:
if (nosign)
return extract_unsigned_integer (valaddr, len);
else
@@ -772,17 +1558,19 @@ unpack_long (struct type *type, const char *valaddr)
case TYPE_CODE_FLT:
return extract_typed_floating (valaddr, type);
+ case TYPE_CODE_DECFLOAT:
+ /* libdecnumber has a function to convert from decimal to integer, but
+ it doesn't work when the decimal number has a fractional part. */
+ return decimal_to_doublest (valaddr, len);
+
case TYPE_CODE_PTR:
case TYPE_CODE_REF:
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
return extract_typed_address (valaddr, type);
- case TYPE_CODE_MEMBER:
- error ("not implemented: member types in unpack_long");
-
default:
- error ("Value can't be converted to integer.");
+ error (_("Value can't be converted to integer."));
}
return 0; /* Placate lint. */
}
@@ -794,7 +1582,7 @@ unpack_long (struct type *type, const char *valaddr)
format, result is in host format. */
DOUBLEST
-unpack_double (struct type *type, const char *valaddr, int *invp)
+unpack_double (struct type *type, const gdb_byte *valaddr, int *invp)
{
enum type_code code;
int len;
@@ -815,7 +1603,7 @@ unpack_double (struct type *type, const char *valaddr, int *invp)
only in a non-portable way. Fixing the portability problem
wouldn't help since the VAX floating-point code is also badly
bit-rotten. The target needs to add definitions for the
- methods TARGET_FLOAT_FORMAT and TARGET_DOUBLE_FORMAT - these
+ methods gdbarch_float_format and gdbarch_double_format - these
exactly describe the target floating-point format. The
problem here is that the corresponding floatformat_vax_f and
floatformat_vax_d values these methods should be set to are
@@ -832,6 +1620,8 @@ unpack_double (struct type *type, const char *valaddr, int *invp)
return extract_typed_floating (valaddr, type);
}
+ else if (code == TYPE_CODE_DECFLOAT)
+ return decimal_to_doublest (valaddr, len);
else if (nosign)
{
/* Unsigned -- be sure we compensate for signed LONGEST. */
@@ -858,7 +1648,7 @@ unpack_double (struct type *type, const char *valaddr, int *invp)
to an INT (or some size). After all, it is only an offset. */
CORE_ADDR
-unpack_pointer (struct type *type, const char *valaddr)
+unpack_pointer (struct type *type, const gdb_byte *valaddr)
{
/* Assume a CORE_ADDR can fit in a LONGEST (for now). Not sure
whether we want this to be true eventually. */
@@ -875,7 +1665,7 @@ value_static_field (struct type *type, int fieldno)
{
struct value *retval;
- if (TYPE_FIELD_STATIC_HAS_ADDR (type, fieldno))
+ if (TYPE_FIELD_LOC_KIND (type, fieldno) == FIELD_LOC_KIND_PHYSADDR)
{
retval = value_at (TYPE_FIELD_TYPE (type, fieldno),
TYPE_FIELD_STATIC_PHYSADDR (type, fieldno));
@@ -883,7 +1673,7 @@ value_static_field (struct type *type, int fieldno)
else
{
char *phys_name = TYPE_FIELD_STATIC_PHYSNAME (type, fieldno);
- struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0, NULL);
+ struct symbol *sym = lookup_symbol (phys_name, 0, VAR_DOMAIN, 0);
if (sym == NULL)
{
/* With some compilers, e.g. HP aCC, static data members are reported
@@ -902,13 +1692,13 @@ value_static_field (struct type *type, int fieldno)
/* SYM should never have a SYMBOL_CLASS which will require
read_var_value to use the FRAME parameter. */
if (symbol_read_needs_frame (sym))
- warning ("static field's value depends on the current "
- "frame - bad debug info?");
+ warning (_("static field's value depends on the current "
+ "frame - bad debug info?"));
retval = read_var_value (sym, NULL);
}
if (retval && VALUE_LVAL (retval) == lval_memory)
SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno),
- VALUE_ADDRESS (retval));
+ value_address (retval));
}
return retval;
}
@@ -922,39 +1712,12 @@ value_static_field (struct type *type, int fieldno)
struct value *
value_change_enclosing_type (struct value *val, struct type *new_encl_type)
{
- if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (value_enclosing_type (val)))
- {
- val->enclosing_type = new_encl_type;
- return val;
- }
- else
- {
- struct value *new_val;
- struct value *prev;
-
- new_val = (struct value *) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (new_encl_type));
-
- new_val->enclosing_type = new_encl_type;
-
- /* We have to make sure this ends up in the same place in the value
- chain as the original copy, so it's clean-up behavior is the same.
- If the value has been released, this is a waste of time, but there
- is no way to tell that in advance, so... */
-
- if (val != all_values)
- {
- for (prev = all_values; prev != NULL; prev = prev->next)
- {
- if (prev->next == val)
- {
- prev->next = new_val;
- break;
- }
- }
- }
-
- return new_val;
- }
+ if (TYPE_LENGTH (new_encl_type) > TYPE_LENGTH (value_enclosing_type (val)))
+ val->contents =
+ (gdb_byte *) xrealloc (val->contents, TYPE_LENGTH (new_encl_type));
+
+ val->enclosing_type = new_encl_type;
+ return val;
}
/* Given a value ARG1 (offset by OFFSET bytes)
@@ -991,41 +1754,48 @@ value_primitive_field (struct value *arg1, int offset,
/* This field is actually a base subobject, so preserve the
entire object's contents for later references to virtual
bases, etc. */
- v = allocate_value (value_enclosing_type (arg1));
- v->type = type;
+
+ /* Lazy register values with offsets are not supported. */
+ if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
+ value_fetch_lazy (arg1);
+
if (value_lazy (arg1))
- VALUE_LAZY (v) = 1;
+ v = allocate_value_lazy (value_enclosing_type (arg1));
else
- memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
- TYPE_LENGTH (value_enclosing_type (arg1)));
+ {
+ v = allocate_value (value_enclosing_type (arg1));
+ memcpy (value_contents_all_raw (v), value_contents_all_raw (arg1),
+ TYPE_LENGTH (value_enclosing_type (arg1)));
+ }
+ v->type = type;
v->offset = value_offset (arg1);
- VALUE_EMBEDDED_OFFSET (v)
- = offset +
- VALUE_EMBEDDED_OFFSET (arg1) +
- TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
+ v->embedded_offset = (offset + value_embedded_offset (arg1)
+ + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8);
}
else
{
/* Plain old data member */
offset += TYPE_FIELD_BITPOS (arg_type, fieldno) / 8;
- v = allocate_value (type);
+
+ /* Lazy register values with offsets are not supported. */
+ if (VALUE_LVAL (arg1) == lval_register && value_lazy (arg1))
+ value_fetch_lazy (arg1);
+
if (value_lazy (arg1))
- VALUE_LAZY (v) = 1;
+ v = allocate_value_lazy (type);
else
- memcpy (value_contents_raw (v),
- value_contents_raw (arg1) + offset,
- TYPE_LENGTH (type));
+ {
+ v = allocate_value (type);
+ memcpy (value_contents_raw (v),
+ value_contents_raw (arg1) + offset,
+ TYPE_LENGTH (type));
+ }
v->offset = (value_offset (arg1) + offset
- + VALUE_EMBEDDED_OFFSET (arg1));
+ + value_embedded_offset (arg1));
}
- VALUE_LVAL (v) = VALUE_LVAL (arg1);
- if (VALUE_LVAL (arg1) == lval_internalvar)
- VALUE_LVAL (v) = lval_internalvar_component;
- VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
+ set_value_component_location (v, arg1);
VALUE_REGNUM (v) = VALUE_REGNUM (arg1);
VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1);
-/* VALUE_OFFSET (v) = VALUE_OFFSET (arg1) + offset
- + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8; */
return v;
}
@@ -1057,7 +1827,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
struct symbol *sym;
struct minimal_symbol *msym;
- sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0, NULL);
+ sym = lookup_symbol (physname, 0, VAR_DOMAIN, 0);
if (sym != NULL)
{
msym = NULL;
@@ -1073,11 +1843,18 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
v = allocate_value (ftype);
if (sym)
{
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+ set_value_address (v, BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
}
else
{
- VALUE_ADDRESS (v) = SYMBOL_VALUE_ADDRESS (msym);
+ /* The minimal symbol might point to a function descriptor;
+ resolve it to the actual code address instead. */
+ struct objfile *objfile = msymbol_objfile (msym);
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
+ set_value_address (v,
+ gdbarch_convert_from_func_ptr_addr
+ (gdbarch, SYMBOL_VALUE_ADDRESS (msym), ¤t_target));
}
if (arg1p)
@@ -1110,7 +1887,7 @@ value_fn_field (struct value **arg1p, struct fn_field *f, int j, struct type *ty
If the field is signed, we also do sign extension. */
LONGEST
-unpack_field_as_long (struct type *type, const char *valaddr, int fieldno)
+unpack_field_as_long (struct type *type, const gdb_byte *valaddr, int fieldno)
{
ULONGEST val;
ULONGEST valmask;
@@ -1125,7 +1902,7 @@ unpack_field_as_long (struct type *type, const char *valaddr, int fieldno)
/* Extract bits. See comment above. */
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
lsbcount = (sizeof val * 8 - bitpos % 8 - bitsize);
else
lsbcount = (bitpos % 8);
@@ -1157,7 +1934,7 @@ unpack_field_as_long (struct type *type, const char *valaddr, int fieldno)
0 <= BITPOS, where lbits is the size of a LONGEST in bits. */
void
-modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
+modify_field (gdb_byte *addr, LONGEST fieldval, int bitpos, int bitsize)
{
ULONGEST oword;
ULONGEST mask = (ULONGEST) -1 >> (8 * sizeof (ULONGEST) - bitsize);
@@ -1172,7 +1949,7 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
{
/* FIXME: would like to include fieldval in the message, but
we don't have a sprintf_longest. */
- warning ("Value does not fit in %d bits.", bitsize);
+ warning (_("Value does not fit in %d bits."), bitsize);
/* Truncate it, otherwise adjoining fields may be corrupted. */
fieldval &= mask;
@@ -1181,7 +1958,7 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
oword = extract_unsigned_integer (addr, sizeof oword);
/* Shifting for bit field depends on endianness of the target machine. */
- if (BITS_BIG_ENDIAN)
+ if (gdbarch_bits_big_endian (current_gdbarch))
bitpos = sizeof (oword) * 8 - bitpos - bitsize;
oword &= ~(mask << bitpos);
@@ -1190,39 +1967,49 @@ modify_field (char *addr, LONGEST fieldval, int bitpos, int bitsize)
store_unsigned_integer (addr, sizeof oword, oword);
}
-/* Convert C numbers into newly allocated values */
+/* Pack NUM into BUF using a target format of TYPE. */
-struct value *
-value_from_longest (struct type *type, LONGEST num)
+void
+pack_long (gdb_byte *buf, struct type *type, LONGEST num)
{
- struct value *val = allocate_value (type);
- enum type_code code;
int len;
-retry:
- code = TYPE_CODE (type);
+
+ type = check_typedef (type);
len = TYPE_LENGTH (type);
- switch (code)
+ switch (TYPE_CODE (type))
{
- case TYPE_CODE_TYPEDEF:
- type = check_typedef (type);
- goto retry;
case TYPE_CODE_INT:
case TYPE_CODE_CHAR:
case TYPE_CODE_ENUM:
+ case TYPE_CODE_FLAGS:
case TYPE_CODE_BOOL:
case TYPE_CODE_RANGE:
- store_signed_integer (value_contents_raw (val), len, num);
+ case TYPE_CODE_MEMBERPTR:
+ store_signed_integer (buf, len, num);
break;
case TYPE_CODE_REF:
case TYPE_CODE_PTR:
- store_typed_address (value_contents_raw (val), type, (CORE_ADDR) num);
+ store_typed_address (buf, type, (CORE_ADDR) num);
break;
default:
- error ("Unexpected type (%d) encountered for integer constant.", code);
+ error (_("Unexpected type (%d) encountered for integer constant."),
+ TYPE_CODE (type));
}
+}
+
+
+/* Convert C numbers into newly allocated values. */
+
+struct value *
+value_from_longest (struct type *type, LONGEST num)
+{
+ struct value *val = allocate_value (type);
+
+ pack_long (value_contents_raw (val), type, num);
+
return val;
}
@@ -1238,32 +2025,23 @@ value_from_pointer (struct type *type, CORE_ADDR addr)
}
-/* Create a value for a string constant to be stored locally
- (not in the inferior's memory space, but in GDB memory).
- This is analogous to value_from_longest, which also does not
- use inferior memory. String shall NOT contain embedded nulls. */
+/* Create a value of type TYPE whose contents come from VALADDR, if it
+ is non-null, and whose memory address (in the inferior) is
+ ADDRESS. */
struct value *
-value_from_string (char *ptr)
+value_from_contents_and_address (struct type *type,
+ const gdb_byte *valaddr,
+ CORE_ADDR address)
{
- struct value *val;
- int len = strlen (ptr);
- int lowbound = current_language->string_lower_bound;
- struct type *string_char_type;
- struct type *rangetype;
- struct type *stringtype;
-
- rangetype = create_range_type ((struct type *) NULL,
- builtin_type_int,
- lowbound, len + lowbound - 1);
- string_char_type = language_string_char_type (current_language,
- current_gdbarch);
- stringtype = create_array_type ((struct type *) NULL,
- string_char_type,
- rangetype);
- val = allocate_value (stringtype);
- memcpy (value_contents_raw (val), ptr, len);
- return val;
+ struct value *v = allocate_value (type);
+ if (valaddr == NULL)
+ set_value_lazy (v, 1);
+ else
+ memcpy (value_contents_raw (v), valaddr, TYPE_LENGTH (type));
+ set_value_address (v, address);
+ VALUE_LVAL (v) = lval_memory;
+ return v;
}
struct value *
@@ -1279,7 +2057,17 @@ value_from_double (struct type *type, DOUBLEST num)
store_typed_floating (value_contents_raw (val), base_type, num);
}
else
- error ("Unexpected type encountered for floating constant.");
+ error (_("Unexpected type encountered for floating constant."));
+
+ return val;
+}
+
+struct value *
+value_from_decfloat (struct type *type, const gdb_byte *dec)
+{
+ struct value *val = allocate_value (type);
+
+ memcpy (value_contents_raw (val), dec, TYPE_LENGTH (type));
return val;
}
@@ -1298,70 +2086,37 @@ coerce_ref (struct value *arg)
struct value *
coerce_array (struct value *arg)
{
- arg = coerce_ref (arg);
- if (current_language->c_style_arrays
- && TYPE_CODE (value_type (arg)) == TYPE_CODE_ARRAY)
- arg = value_coerce_array (arg);
- if (TYPE_CODE (value_type (arg)) == TYPE_CODE_FUNC)
- arg = value_coerce_function (arg);
- return arg;
-}
+ struct type *type;
-struct value *
-coerce_number (struct value *arg)
-{
- arg = coerce_array (arg);
- arg = coerce_enum (arg);
- return arg;
-}
+ arg = coerce_ref (arg);
+ type = check_typedef (value_type (arg));
-struct value *
-coerce_enum (struct value *arg)
-{
- if (TYPE_CODE (check_typedef (value_type (arg))) == TYPE_CODE_ENUM)
- arg = value_cast (builtin_type_unsigned_int, arg);
+ switch (TYPE_CODE (type))
+ {
+ case TYPE_CODE_ARRAY:
+ if (current_language->c_style_arrays)
+ arg = value_coerce_array (arg);
+ break;
+ case TYPE_CODE_FUNC:
+ arg = value_coerce_function (arg);
+ break;
+ }
return arg;
}
-/* Should we use DEPRECATED_EXTRACT_STRUCT_VALUE_ADDRESS instead of
- EXTRACT_RETURN_VALUE? GCC_P is true if compiled with gcc and TYPE
- is the type (which is known to be struct, union or array).
-
- On most machines, the struct convention is used unless we are
- using gcc and the type is of a special size. */
-/* As of about 31 Mar 93, GCC was changed to be compatible with the
- native compiler. GCC 2.3.3 was the last release that did it the
- old way. Since gcc2_compiled was not changed, we have no
- way to correctly win in all cases, so we just do the right thing
- for gcc1 and for gcc2 after this change. Thus it loses for gcc
- 2.0-2.3.3. This is somewhat unfortunate, but changing gcc2_compiled
- would cause more chaos than dealing with some struct returns being
- handled wrong. */
-/* NOTE: cagney/2004-06-13: Deleted check for "gcc_p". GCC 1.x is
- dead. */
-
-int
-generic_use_struct_convention (int gcc_p, struct type *value_type)
-{
- return !(TYPE_LENGTH (value_type) == 1
- || TYPE_LENGTH (value_type) == 2
- || TYPE_LENGTH (value_type) == 4
- || TYPE_LENGTH (value_type) == 8);
-}
-
/* Return true if the function returning the specified type is using
the convention of returning structures in memory (passing in the
- address as a hidden first parameter). GCC_P is nonzero if compiled
- with GCC. */
+ address as a hidden first parameter). */
int
-using_struct_return (struct type *value_type, int gcc_p)
+using_struct_return (struct gdbarch *gdbarch,
+ struct type *func_type, struct type *value_type)
{
enum type_code code = TYPE_CODE (value_type);
if (code == TYPE_CODE_ERROR)
- error ("Function return type unknown.");
+ error (_("Function return type unknown."));
if (code == TYPE_CODE_VOID)
/* A void return value is never in memory. See also corresponding
@@ -1369,24 +2124,56 @@ using_struct_return (struct type *value_type, int gcc_p)
return 0;
/* Probe the architecture for the return-value convention. */
- return (gdbarch_return_value (current_gdbarch, value_type,
+ return (gdbarch_return_value (gdbarch, func_type, value_type,
NULL, NULL, NULL)
!= RETURN_VALUE_REGISTER_CONVENTION);
}
+/* Set the initialized field in a value struct. */
+
+void
+set_value_initialized (struct value *val, int status)
+{
+ val->initialized = status;
+}
+
+/* Return the initialized field in a value struct. */
+
+int
+value_initialized (struct value *val)
+{
+ return val->initialized;
+}
+
void
_initialize_values (void)
{
- add_cmd ("convenience", no_class, show_convenience,
- "Debugger convenience (\"$foo\") variables.\n\
+ add_cmd ("convenience", no_class, show_convenience, _("\
+Debugger convenience (\"$foo\") variables.\n\
These variables are created when you assign them values;\n\
-thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\n\
+thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\
+\n\
A few convenience variables are given values automatically:\n\
\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
-\"$__\" holds the contents of the last address examined with \"x\".",
+\"$__\" holds the contents of the last address examined with \"x\"."),
&showlist);
add_cmd ("values", no_class, show_values,
- "Elements of value history around item number IDX (or last ten).",
+ _("Elements of value history around item number IDX (or last ten)."),
&showlist);
+
+ add_com ("init-if-undefined", class_vars, init_if_undefined_command, _("\
+Initialize a convenience variable if necessary.\n\
+init-if-undefined VARIABLE = EXPRESSION\n\
+Set an internal VARIABLE to the result of the EXPRESSION if it does not\n\
+exist or does not contain a value. The EXPRESSION is not evaluated if the\n\
+VARIABLE is already initialized."));
+
+ add_prefix_cmd ("function", no_class, function_command, _("\
+Placeholder command for showing help on convenience functions."),
+ &functionlist, "function ", 0, &cmdlist);
+
+ internal_fn_type = alloc_type (NULL);
+ TYPE_CODE (internal_fn_type) = TYPE_CODE_INTERNAL_FUNCTION;
+ TYPE_NAME (internal_fn_type) = "";
}