From: Daniel Berlin Date: Sat, 19 May 2001 15:20:14 +0000 (+0000) Subject: 2001-05-07 Daniel Berlin X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b127877435ec6b5f994e5e8e1ea0edc11094a59;p=binutils-gdb.git 2001-05-07 Daniel Berlin Changes by Jim Ingham: * values.c (value_change_enclosing_type): New function. If the new enclosing type is larger than the old one, we need to allocate more space. * value.h: Add value_change_enclosing_type prototype. * valops.c (value_cast): Use it. (value_assign): Use it. (value_addr): Use it. (value_ind): Use it. (value_full_object): Use it. 2001-05-07 Daniel Berlin * values.c (value_static_field): Handle static fields that have a constant value. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 76dba305265..57df488468d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,21 @@ +2001-05-07 Daniel Berlin + + Changes by Jim Ingham: + + * values.c (value_change_enclosing_type): New function. If the + new enclosing type is larger than the old one, we need to allocate + more space. + * value.h: Add value_change_enclosing_type prototype. + * valops.c (value_cast): Use it. + (value_assign): Use it. + (value_addr): Use it. + (value_ind): Use it. + (value_full_object): Use it. + +2001-05-07 Daniel Berlin + + * values.c (value_static_field): Handle static fields that have a constant value. + 2001-05-17 Michael Snyder * blockframe.c (create_new_frame): Zero all the fields via memset, diff --git a/gdb/valops.c b/gdb/valops.c index 0e7e7e14056..7cc025d4eff 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -365,7 +365,7 @@ value_cast (struct type *type, register value_ptr arg2) /* No superclass found, just fall through to change ptr type. */ } VALUE_TYPE (arg2) = type; - VALUE_ENCLOSING_TYPE (arg2) = type; /* pai: chk_val */ + arg2 = value_change_enclosing_type (arg2, type); VALUE_POINTED_TO_OFFSET (arg2) = 0; /* pai: chk_val */ return arg2; } @@ -609,7 +609,7 @@ value_assign (register value_ptr toval, register value_ptr fromval) case lval_internalvar: set_internalvar (VALUE_INTERNALVAR (toval), fromval); val = value_copy (VALUE_INTERNALVAR (toval)->value); - VALUE_ENCLOSING_TYPE (val) = VALUE_ENCLOSING_TYPE (fromval); + val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval)); VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval); VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval); return val; @@ -823,7 +823,7 @@ value_assign (register value_ptr toval, register value_ptr fromval) memcpy (VALUE_CONTENTS_RAW (val), VALUE_CONTENTS (fromval), TYPE_LENGTH (type)); VALUE_TYPE (val) = type; - VALUE_ENCLOSING_TYPE (val) = VALUE_ENCLOSING_TYPE (fromval); + val = value_change_enclosing_type (val, VALUE_ENCLOSING_TYPE (fromval)); VALUE_EMBEDDED_OFFSET (val) = VALUE_EMBEDDED_OFFSET (fromval); VALUE_POINTED_TO_OFFSET (val) = VALUE_POINTED_TO_OFFSET (fromval); @@ -965,7 +965,7 @@ value_addr (value_ptr arg1) /* This may be a pointer to a base subobject; so remember the full derived object's type ... */ - VALUE_ENCLOSING_TYPE (arg2) = lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1)); + arg2 = value_change_enclosing_type (arg2, lookup_pointer_type (VALUE_ENCLOSING_TYPE (arg1))); /* ... and also the relative position of the subobject in the full object */ VALUE_POINTED_TO_OFFSET (arg2) = VALUE_EMBEDDED_OFFSET (arg1); VALUE_BFD_SECTION (arg2) = VALUE_BFD_SECTION (arg1); @@ -1009,7 +1009,7 @@ value_ind (value_ptr arg1) /* Re-adjust type */ VALUE_TYPE (arg2) = TYPE_TARGET_TYPE (base_type); /* Add embedding info */ - VALUE_ENCLOSING_TYPE (arg2) = enc_type; + arg2 = value_change_enclosing_type (arg2, enc_type); VALUE_EMBEDDED_OFFSET (arg2) = VALUE_POINTED_TO_OFFSET (arg1); /* We may be pointing to an object of some derived type */ @@ -3165,7 +3165,7 @@ value_full_object (value_ptr argp, struct type *rtype, int xfull, int xtop, type is wrong, set it *//* pai: FIXME -- sounds iffy */ if (full) { - VALUE_ENCLOSING_TYPE (argp) = real_type; + argp = value_change_enclosing_type (argp, real_type); return argp; } diff --git a/gdb/value.h b/gdb/value.h index 50abe0ebfe7..cc1d90f221a 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -307,6 +307,8 @@ extern value_ptr allocate_value (struct type *type); extern value_ptr allocate_repeat_value (struct type *type, int count); +extern value_ptr value_change_enclosing_type (value_ptr val, struct type *new_type); + extern value_ptr value_mark (void); extern void value_free_to_mark (value_ptr mark); diff --git a/gdb/values.c b/gdb/values.c index 8a93be9f1f7..8336233dab0 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -762,14 +762,65 @@ value_static_field (struct type *type, int fieldno) } else { - addr = SYMBOL_VALUE_ADDRESS (sym); - sect = SYMBOL_BFD_SECTION (sym); - } + /* Anything static that isn't a constant, has an address */ + if (SYMBOL_CLASS (sym) != LOC_CONST) + { + addr = SYMBOL_VALUE_ADDRESS (sym); + sect = SYMBOL_BFD_SECTION (sym); + } + /* However, static const's do not, the value is already known. */ + else + { + return value_from_longest (TYPE_FIELD_TYPE (type, fieldno), SYMBOL_VALUE (sym)); + } + } SET_FIELD_PHYSADDR (TYPE_FIELD (type, fieldno), addr); } return value_at (TYPE_FIELD_TYPE (type, fieldno), addr, sect); } +/* Change the enclosing type of a value object VAL to NEW_ENCL_TYPE. + You have to be careful here, since the size of the data area for the value + is set by the length of the enclosing type. So if NEW_ENCL_TYPE is bigger + than the old enclosing type, you have to allocate more space for the data. + The return value is a pointer to the new version of this value structure. */ + +value_ptr +value_change_enclosing_type (value_ptr val, struct type *new_encl_type) +{ + if (TYPE_LENGTH (new_encl_type) <= TYPE_LENGTH (VALUE_ENCLOSING_TYPE (val))) + { + VALUE_ENCLOSING_TYPE (val) = new_encl_type; + return val; + } + else + { + value_ptr new_val; + register value_ptr prev; + + new_val = (value_ptr) xrealloc (val, sizeof (struct value) + TYPE_LENGTH (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; + } +} + /* Given a value ARG1 (offset by OFFSET bytes) of a struct or union type ARG_TYPE, extract and return the value of one of its (non-static) fields.