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) = ""; }