aboutsummaryrefslogtreecommitdiff
path: root/gdb/values.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/values.c')
-rw-r--r--gdb/values.c78
1 files changed, 72 insertions, 6 deletions
diff --git a/gdb/values.c b/gdb/values.c
index 670ed24..5f41e64 100644
--- a/gdb/values.c
+++ b/gdb/values.c
@@ -532,6 +532,19 @@ value_as_double (val)
error ("Invalid floating value found in program.");
return foo;
}
+/* Extract a value as a C pointer.
+ Does not deallocate the value. */
+CORE_ADDR
+value_as_pointer (val)
+ value val;
+{
+ /* This coerces arrays and functions, which is necessary (e.g.
+ in disassemble_command). It also dereferences references, which
+ I suspect is the most logical thing to do. */
+ if (TYPE_CODE (VALUE_TYPE (val)) != TYPE_CODE_ENUM)
+ COERCE_ARRAY (val);
+ return unpack_pointer (VALUE_TYPE (val), VALUE_CONTENTS (val));
+}
/* Unpack raw data (copied from debugee, target byte order) at VALADDR
as a long, or as a double, assuming the raw data is described
@@ -674,10 +687,13 @@ unpack_long (type, valaddr)
error ("That operation is not possible on an integer of that size.");
}
}
+#if 0
+ /* There is no guarantee that a pointer can fit within a LONGEST.
+ Callers should use unpack_pointer instead. */
else if (code == TYPE_CODE_PTR
|| code == TYPE_CODE_REF)
{
- if (len == sizeof (char *))
+ if (len == sizeof (CORE_ADDR))
{
CORE_ADDR retval;
bcopy (valaddr, &retval, sizeof (retval));
@@ -685,10 +701,15 @@ unpack_long (type, valaddr)
return retval;
}
}
+#endif
else if (code == TYPE_CODE_MEMBER)
error ("not implemented: member types in unpack_long");
+#if 0
error ("Value not integer or pointer.");
+#else
+ error ("Value not integer.");
+#endif
return 0; /* For lint -- never reached */
}
@@ -735,6 +756,7 @@ unpack_double (type, valaddr, invp)
else
{
error ("Unexpected type of floating point number.");
+ return 0; /* Placate lint. */
}
}
else if (nosign) {
@@ -749,6 +771,46 @@ unpack_double (type, valaddr, invp)
return unpack_long (type, valaddr);
}
}
+
+/* Unpack raw data (copied from debugee, target byte order) at VALADDR
+ as a CORE_ADDR, assuming the raw data is described by type TYPE.
+ We don't assume any alignment for the raw data. Return value is in
+ host byte order.
+
+ If you want functions and arrays to be coerced to pointers, and
+ references to be dereferenced, call value_as_pointer() instead.
+
+ C++: It is assumed that the front-end has taken care of
+ all matters concerning pointers to members. A pointer
+ to member which reaches here is considered to be equivalent
+ to an INT (or some size). After all, it is only an offset. */
+
+CORE_ADDR
+unpack_pointer (type, valaddr)
+ struct type *type;
+ char *valaddr;
+{
+ register enum type_code code = TYPE_CODE (type);
+ register int len = TYPE_LENGTH (type);
+
+ if (code == TYPE_CODE_PTR
+ || code == TYPE_CODE_REF)
+ {
+ if (len == sizeof (CORE_ADDR))
+ {
+ CORE_ADDR retval;
+ bcopy (valaddr, &retval, sizeof (retval));
+ SWAP_TARGET_AND_HOST (&retval, sizeof (retval));
+ return retval;
+ }
+ error ("Unrecognized pointer size.");
+ }
+ else if (code == TYPE_CODE_MEMBER)
+ error ("not implemented: member types in unpack_pointer");
+
+ error ("Value is not a pointer.");
+ return 0; /* For lint -- never reached */
+}
/* Given a value ARG1 (offset by OFFSET bytes)
of a struct or union type ARG_TYPE,
@@ -922,6 +984,7 @@ value_headof (arg, btype, dtype)
/* First collect the vtables we must look at for this object. */
/* FIXME-tiemann: right now, just look at top-most vtable. */
value vtbl, entry, best_entry = 0;
+ /* FIXME: entry_type is never used. */
struct type *entry_type;
int i, nelems;
int offset, best_offset = 0;
@@ -954,11 +1017,11 @@ value_headof (arg, btype, dtype)
/* Now search through the virtual function table. */
entry = value_ind (vtbl);
entry_type = VALUE_TYPE (entry);
- nelems = value_as_long (value_field (entry, 2));
+ nelems = longest_to_int (value_as_long (value_field (entry, 2)));
for (i = 1; i <= nelems; i++)
{
entry = value_subscript (vtbl, value_from_long (builtin_type_int, i));
- offset = value_as_long (value_field (entry, 0));
+ offset = longest_to_int (value_as_long (value_field (entry, 0)));
if (offset < best_offset)
{
best_offset = offset;
@@ -970,7 +1033,7 @@ value_headof (arg, btype, dtype)
/* Move the pointer according to BEST_ENTRY's offset, and figure
out what type we should return as the new pointer. */
- pc_for_sym = value_as_long (value_field (best_entry, 2));
+ pc_for_sym = value_as_pointer (value_field (best_entry, 2));
sym = find_pc_function (pc_for_sym);
demangled_name = cplus_demangle (SYMBOL_NAME (sym), -1);
*(strchr (demangled_name, ':')) = '\0';
@@ -1111,7 +1174,8 @@ baseclass_addr (type, index, valaddr, valuep, errp)
CORE_ADDR addr;
int status;
- addr = unpack_long (TYPE_FIELD_TYPE (type, i),
+ addr
+ = unpack_pointer (TYPE_FIELD_TYPE (type, i),
valaddr + (TYPE_FIELD_BITPOS (type, i) / 8));
status = target_read_memory (addr,
@@ -1143,7 +1207,7 @@ baseclass_addr (type, index, valaddr, valuep, errp)
{
char *baddr;
- baddr = baseclass_addr (type, i, valaddr, valuep);
+ baddr = baseclass_addr (type, i, valaddr, valuep, errp);
if (baddr)
return baddr;
}
@@ -1190,6 +1254,8 @@ check_stub_method (type, i, j)
if (OPNAME_PREFIX_P (field_name))
{
char *opname = cplus_mangle_opname (field_name + 3);
+ if (opname == NULL)
+ error ("No mangling for \"%s\"", field_name);
mangled_name_len += strlen (opname);
mangled_name = (char *)xmalloc (mangled_name_len);