along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "defs.h"
-#include <string.h>
#include "bfd.h"
#include "symtab.h"
#include "symfile.h"
#include "complaints.h"
#include "gdbcmd.h"
#include "cp-abi.h"
-#include "gdb_assert.h"
#include "hashtab.h"
-#include "exceptions.h"
#include "cp-support.h"
#include "bcache.h"
#include "dwarf2loc.h"
if (top_level && TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
+ /* Types that have a dynamic TYPE_DATA_LOCATION are considered
+ dynamic, even if the type itself is statically defined.
+ From a user's point of view, this may appear counter-intuitive;
+ but it makes sense in this context, because the point is to determine
+ whether any part of the type needs to be resolved before it can
+ be exploited. */
+ if (TYPE_DATA_LOCATION (type) != NULL
+ && (TYPE_DATA_LOCATION_KIND (type) == PROP_LOCEXPR
+ || TYPE_DATA_LOCATION_KIND (type) == PROP_LOCLIST))
+ return 1;
+
switch (TYPE_CODE (type))
{
case TYPE_CODE_RANGE:
CORE_ADDR addr,
int top_level);
-/* Given a dynamic range type (dyn_range_type), return a static version
- of that type. */
+/* Given a dynamic range type (dyn_range_type) and address,
+ return a static version of that type. */
static struct type *
-resolve_dynamic_range (struct type *dyn_range_type)
+resolve_dynamic_range (struct type *dyn_range_type, CORE_ADDR addr)
{
CORE_ADDR value;
struct type *static_range_type;
gdb_assert (TYPE_CODE (dyn_range_type) == TYPE_CODE_RANGE);
prop = &TYPE_RANGE_DATA (dyn_range_type)->low;
- if (dwarf2_evaluate_property (prop, &value))
+ if (dwarf2_evaluate_property (prop, addr, &value))
{
low_bound.kind = PROP_CONST;
low_bound.data.const_val = value;
}
prop = &TYPE_RANGE_DATA (dyn_range_type)->high;
- if (dwarf2_evaluate_property (prop, &value))
+ if (dwarf2_evaluate_property (prop, addr, &value))
{
high_bound.kind = PROP_CONST;
high_bound.data.const_val = value;
of the associated array. */
static struct type *
-resolve_dynamic_array (struct type *type)
+resolve_dynamic_array (struct type *type, CORE_ADDR addr)
{
CORE_ADDR value;
struct type *elt_type;
elt_type = type;
range_type = check_typedef (TYPE_INDEX_TYPE (elt_type));
- range_type = resolve_dynamic_range (range_type);
+ range_type = resolve_dynamic_range (range_type, addr);
ary_dim = check_typedef (TYPE_TARGET_TYPE (elt_type));
if (ary_dim != NULL && TYPE_CODE (ary_dim) == TYPE_CODE_ARRAY)
- elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type));
+ elt_type = resolve_dynamic_array (TYPE_TARGET_TYPE (type), addr);
else
elt_type = TYPE_TARGET_TYPE (type);
{
struct type *resolved_type;
int i;
- int vla_field = TYPE_NFIELDS (type) - 1;
+ unsigned resolved_type_bit_length = 0;
gdb_assert (TYPE_CODE (type) == TYPE_CODE_STRUCT);
gdb_assert (TYPE_NFIELDS (type) > 0);
TYPE_NFIELDS (resolved_type) * sizeof (struct field));
for (i = 0; i < TYPE_NFIELDS (resolved_type); ++i)
{
- struct type *t;
+ unsigned new_bit_length;
if (field_is_static (&TYPE_FIELD (type, i)))
continue;
- t = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
+ TYPE_FIELD_TYPE (resolved_type, i)
+ = resolve_dynamic_type_internal (TYPE_FIELD_TYPE (resolved_type, i),
addr, 0);
- /* This is a bit odd. We do not support a VLA in any position
- of a struct except for the last. GCC does have an extension
- that allows a VLA in the middle of a structure, but the DWARF
- it emits is relatively useless to us, so we can't represent
- such a type properly -- and even if we could, we do not have
- enough information to redo structure layout anyway.
- Nevertheless, we check all the fields in case something odd
- slips through, since it's better to see an error than
- incorrect results. */
- if (t != TYPE_FIELD_TYPE (resolved_type, i)
- && i != vla_field)
- error (_("Attempt to resolve a variably-sized type which appears "
- "in the interior of a structure type"));
-
- TYPE_FIELD_TYPE (resolved_type, i) = t;
+ /* As we know this field is not a static field, the field's
+ field_loc_kind should be FIELD_LOC_KIND_BITPOS. Verify
+ this is the case, but only trigger a simple error rather
+ than an internal error if that fails. While failing
+ that verification indicates a bug in our code, the error
+ is not severe enough to suggest to the user he stops
+ his debugging session because of it. */
+ if (TYPE_FIELD_LOC_KIND (resolved_type, i) != FIELD_LOC_KIND_BITPOS)
+ error (_("Cannot determine struct field location"
+ " (invalid location kind)"));
+ new_bit_length = TYPE_FIELD_BITPOS (resolved_type, i);
+ if (TYPE_FIELD_BITSIZE (resolved_type, i) != 0)
+ new_bit_length += TYPE_FIELD_BITSIZE (resolved_type, i);
+ else
+ new_bit_length += (TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, i))
+ * TARGET_CHAR_BIT);
+
+ /* Normally, we would use the position and size of the last field
+ to determine the size of the enclosing structure. But GCC seems
+ to be encoding the position of some fields incorrectly when
+ the struct contains a dynamic field that is not placed last.
+ So we compute the struct size based on the field that has
+ the highest position + size - probably the best we can do. */
+ if (new_bit_length > resolved_type_bit_length)
+ resolved_type_bit_length = new_bit_length;
}
- /* Due to the above restrictions we can successfully compute
- the size of the resulting structure here, as the offset of
- the final field plus its size. */
TYPE_LENGTH (resolved_type)
- = (TYPE_FIELD_BITPOS (resolved_type, vla_field) / TARGET_CHAR_BIT
- + TYPE_LENGTH (TYPE_FIELD_TYPE (resolved_type, vla_field)));
+ = (resolved_type_bit_length + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT;
+
return resolved_type;
}
{
struct type *real_type = check_typedef (type);
struct type *resolved_type = type;
+ const struct dynamic_prop *prop;
+ CORE_ADDR value;
if (!is_dynamic_type_internal (real_type, top_level))
return type;
}
case TYPE_CODE_ARRAY:
- resolved_type = resolve_dynamic_array (type);
+ resolved_type = resolve_dynamic_array (type, addr);
break;
case TYPE_CODE_RANGE:
- resolved_type = resolve_dynamic_range (type);
+ resolved_type = resolve_dynamic_range (type, addr);
break;
case TYPE_CODE_UNION:
break;
}
+ /* Resolve data_location attribute. */
+ prop = TYPE_DATA_LOCATION (resolved_type);
+ if (dwarf2_evaluate_property (prop, addr, &value))
+ {
+ TYPE_DATA_LOCATION_ADDR (resolved_type) = value;
+ TYPE_DATA_LOCATION_KIND (resolved_type) = PROP_CONST;
+ }
+ else
+ TYPE_DATA_LOCATION (resolved_type) = NULL;
+
return resolved_type;
}
*TYPE_RANGE_DATA (new_type) = *TYPE_RANGE_DATA (type);
}
+ /* Copy the data location information. */
+ if (TYPE_DATA_LOCATION (type) != NULL)
+ {
+ TYPE_DATA_LOCATION (new_type)
+ = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+ memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+ sizeof (struct dynamic_prop));
+ }
+
/* Copy pointers to other types. */
if (TYPE_TARGET_TYPE (type))
TYPE_TARGET_TYPE (new_type) =
TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
memcpy (TYPE_MAIN_TYPE (new_type), TYPE_MAIN_TYPE (type),
sizeof (struct main_type));
+ if (TYPE_DATA_LOCATION (type) != NULL)
+ {
+ TYPE_DATA_LOCATION (new_type)
+ = TYPE_ALLOC (new_type, sizeof (struct dynamic_prop));
+ memcpy (TYPE_DATA_LOCATION (new_type), TYPE_DATA_LOCATION (type),
+ sizeof (struct dynamic_prop));
+ }
return new_type;
}