X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fvalue.c;h=7566921c80f6785295c0ca81a49c2bcb654d02e1;hb=3b7538c0317072d430eca4e808b183dac5bd5e45;hp=7085ec11f75690f3fb4218085119eac9582b3384;hpb=c187492465e6fd60ebf2f4710944fa7b6a679a02;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/value.c b/gdb/value.c index 7085ec11f7..7566921c80 100644 --- a/gdb/value.c +++ b/gdb/value.c @@ -1,8 +1,8 @@ /* Low level packing and unpacking of values for GDB, the GNU Debugger. Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, - 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007 - Free Software Foundation, Inc. + 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + 2009 Free Software Foundation, Inc. This file is part of GDB. @@ -34,11 +34,34 @@ #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 @@ -58,6 +81,15 @@ struct value /* 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. @@ -71,8 +103,8 @@ struct value int bitsize; /* Only used for bitfields; position of start of field. For - BITS_BIG_ENDIAN=0 targets, it is the position of the LSB. For - BITS_BIG_ENDIAN=1 targets, it is the position of the MSB. */ + 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 @@ -128,17 +160,17 @@ struct value /* Values are stored in a chain, so that they can be deleted easily over calls to the inferior. Values assigned to internal - variables or put into the value history are taken off this - list. */ + 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 memory at address in the - location.address field plus the offset field (and the lval field - should be lval_memory). + 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 @@ -158,21 +190,9 @@ struct value /* If value is a variable, is it initialized or not. */ int initialized; - /* Actual contents of the value. For use of this value; setting it - uses the stuff above. Not valid if lazy is nonzero. Target - byte-order. We force it to be aligned properly for any possible - value. Note that a value therefore extends beyond what is - declared here. */ - union - { - gdb_byte contents[1]; - DOUBLEST force_doublest_align; - LONGEST force_longest_align; - CORE_ADDR force_core_addr_align; - void *force_pointer_align; - } aligner; - /* Do not add any new members here -- contents above will trash - them. */ + /* Actual contents of the value. Target byte-order. NULL or not + valid if lazy is nonzero. */ + gdb_byte *contents; }; /* Prototypes for local functions. */ @@ -201,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) @@ -208,27 +232,30 @@ 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; val->embedded_offset = 0; val->pointed_to_offset = 0; @@ -237,8 +264,28 @@ allocate_value (struct type *type) 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) @@ -247,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. */ @@ -255,6 +302,45 @@ 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 * @@ -310,13 +396,15 @@ set_value_bitsize (struct value *value, int bit) 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; } gdb_byte * value_contents_all_raw (struct value *value) { - return value->aligner.contents; + allocate_value_contents (value); + return value->contents; } struct type * @@ -330,7 +418,7 @@ value_contents_all (struct value *value) { if (value->lazy) value_fetch_lazy (value); - return value->aligner.contents; + return value->contents; } int @@ -415,16 +503,52 @@ 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 * -deprecated_value_address_hack (struct value *value) +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) { - return &value->location.address; + gdb_assert (value->lval != lval_internalvar + && value->lval != lval_internalvar_component); + value->location.address = addr; } struct internalvar ** @@ -465,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 @@ -549,7 +691,12 @@ 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); val->location = arg->location; @@ -569,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. */ @@ -663,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; } @@ -679,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); + 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] = '+'; @@ -703,6 +878,32 @@ 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. @@ -731,7 +932,7 @@ init_if_undefined_command (char* args, int from_tty) /* Only evaluate the expression if the lvalue is void. This may still fail if the expresssion is invalid. */ - if (TYPE_CODE (value_type (intvar->value)) == TYPE_CODE_VOID) + if (TYPE_CODE (intvar->type) == TYPE_CODE_VOID) evaluate_expression (expr); do_cleanups (old_chain); @@ -745,7 +946,7 @@ init_if_undefined_command (char* args, int from_tty) the return value is NULL. */ struct internalvar * -lookup_only_internalvar (char *name) +lookup_only_internalvar (const char *name) { struct internalvar *var; @@ -761,19 +962,31 @@ lookup_only_internalvar (char *name) NAME should not normally include a dollar sign. */ struct internalvar * -create_internalvar (char *name) +create_internalvar (const char *name) { struct internalvar *var; var = (struct internalvar *) xmalloc (sizeof (struct internalvar)); var->name = concat (name, (char *)NULL); - var->value = allocate_value (builtin_type_void); - var->endian = gdbarch_byte_order (current_gdbarch); - release_value (var->value); + 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. @@ -782,7 +995,7 @@ create_internalvar (char *name) one is created, with a void value. */ struct internalvar * -lookup_internalvar (char *name) +lookup_internalvar (const char *name) { struct internalvar *var; @@ -797,95 +1010,291 @@ struct value * value_of_internalvar (struct internalvar *var) { struct value *val; - int i, j; - gdb_byte temp; - - val = value_copy (var->value); - if (value_lazy (val)) - value_fetch_lazy (val); - VALUE_LVAL (val) = lval_internalvar; - VALUE_INTERNALVAR (val) = var; - - /* Values are always stored in the target's byte order. When connected to a - target this will most likely always be correct, so there's normally no - need to worry about it. - However, internal variables can be set up before the target endian is - known and so may become out of date. Fix it up before anybody sees. - - Internal variables usually hold simple scalar values, and we can - correct those. More complex values (e.g. structures and floating - point types) are left alone, because they would be too complicated - to correct. */ - - if (var->endian != gdbarch_byte_order (current_gdbarch)) + if (var->make_value != NULL) + val = (*var->make_value) (var); + else { - gdb_byte *array = value_contents_raw (val); - struct type *type = check_typedef (value_enclosing_type (val)); - switch (TYPE_CODE (type)) + 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: - /* Reverse the bytes. */ - for (i = 0, j = TYPE_LENGTH (type) - 1; i < j; i++, j--) - { - temp = array[j]; - array[j] = array[i]; - array[i] = temp; - } + 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) { - gdb_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; - var->endian = gdbarch_byte_order (current_gdbarch); - 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; } +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. */ @@ -914,6 +1323,7 @@ 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 @@ -926,7 +1336,26 @@ preserve_values (struct objfile *objfile) preserve_one_value (cur->values[i], objfile, copied_types); for (var = internalvars; var; var = var->next) - preserve_one_value (var->value, objfile, copied_types); + { + 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); } @@ -936,7 +1365,9 @@ 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) @@ -945,7 +1376,7 @@ show_convenience (char *ignore, int from_tty) } printf_filtered (("$%s = "), var->name); value_print (value_of_internalvar (var), gdb_stdout, - 0, Val_pretty_default); + &opts); printf_filtered (("\n")); } if (!varseen) @@ -981,6 +1412,7 @@ value_as_double (struct value *val) 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. */ @@ -1015,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' @@ -1035,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); @@ -1126,6 +1558,11 @@ unpack_long (struct type *type, const gdb_byte *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 @@ -1183,6 +1620,8 @@ unpack_double (struct type *type, const gdb_byte *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. */ @@ -1226,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)); @@ -1234,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 @@ -1259,7 +1698,7 @@ value_static_field (struct type *type, int fieldno) } if (retval && VALUE_LVAL (retval) == lval_memory) SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), - VALUE_ADDRESS (retval)); + value_address (retval)); } return retval; } @@ -1273,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) @@ -1342,13 +1754,20 @@ 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)) - set_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); v->embedded_offset = (offset + value_embedded_offset (arg1) + TYPE_FIELD_BITPOS (arg_type, fieldno) / 8); @@ -1357,20 +1776,24 @@ value_primitive_field (struct value *arg1, int offset, { /* 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)) - set_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_LVAL (v) = VALUE_LVAL (arg1); - if (VALUE_LVAL (arg1) == lval_internalvar) - VALUE_LVAL (v) = lval_internalvar_component; - v->location = arg1->location; + set_value_component_location (v, arg1); VALUE_REGNUM (v) = VALUE_REGNUM (arg1); VALUE_FRAME_ID (v) = VALUE_FRAME_ID (arg1); return v; @@ -1404,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; @@ -1420,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) @@ -1472,7 +1902,7 @@ unpack_field_as_long (struct type *type, const gdb_byte *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); @@ -1528,7 +1958,7 @@ modify_field (gdb_byte *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); @@ -1595,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 * @@ -1641,6 +2062,16 @@ value_from_double (struct type *type, DOUBLEST num) 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; +} + struct value * coerce_ref (struct value *arg) { @@ -1655,28 +2086,21 @@ 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; } @@ -1686,7 +2110,8 @@ coerce_enum (struct value *arg) address as a hidden first parameter). */ int -using_struct_return (struct type *value_type) +using_struct_return (struct gdbarch *gdbarch, + struct type *func_type, struct type *value_type) { enum type_code code = TYPE_CODE (value_type); @@ -1699,7 +2124,7 @@ using_struct_return (struct type *value_type) 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); } @@ -1743,4 +2168,12 @@ 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) = ""; }