Re: Per-type architecture (Re: [10/15] Basic value access routines)

Ulrich Weigand
2009-06-23T00:41:46Z

Daniel Jacobowitz wrote:

> I think you're simplifying the wrong thing - it probably simplifies
> your patches to remove the global architecture a lot, but I think it
> makes the rest of GDB more complicated in exchange. Why should types
> have an associated architecture, in and of themselves?

Let's start by looking at *values* first. In order to perform just
about any operations on a value, in fact even to understand just what
the contents of a value objects even *mean*, there's a bunch of
information we need:

- for (nearly) every value, the byte order

- for values of bitfield type, the bitfield byte order (as you mention)

- for values of floating point type, the floating point format (which
today is sometimes, but not always, attached to the type)

- for values of pointer/reference type, the architecture-specific semantics
of converting target pointer values to and from GDB internal addresses

- for values of function pointer type, the architecture-specific semantics of
finding the target function (function descriptors etc.)

- for values of C++ specific types (classes, pointers-to-member etc.), how
they are encoded according to the platform ABI

In addition, when printing values, we need additional data on:

- how to format target addresses for printing

- how to interpret requests of printing the value "as something else"
(e.g. as floating point, or as string, or as instruction disassembly)
rather than its base type

All this information today is provided via gdbarch properties accessed
(just about always) from current_gdbarch.

For the second set of properties, one might argue that this is data that
*should* properly be provided as extra information in addition to the
value itself -- you print the value "as something". For example, the
printing routines might carry a gdbarch as print_options.

However, for the *first* set of properties it doesn't seem to make sense
to require this information to be provided apart from the value object;
there is just about nothing you can do with the value if you don't even
understand how to interpret its contents.

If we agree that it should be possible to retrieve those properties from
a value object itself, then the question becomes if they should attach to
single values, or rather types. My initial patch set implemented the
first approach. However, on further thought, I now tend to prefer the
second option. In the end, a "type" is nothing else but a set of rules
how to interpret the contents of uniform classes of values, right? And all
the above properties are of that form ...

Now, those properties could just be attached to the type itself, without
completing the link to a gdbarch object. In a way, this seems to be what
was attempted by TYPE_FLOATFORMAT. However, implementing this looks to
be at least as complex as going all the way to gdbarch -- e.g. if you
make byte order a property of the type, you still need to wait to create
types until you know what target architecture to create them for.

Plus, at this point it isn't actually hard to make that transition; nearly
all types are *already* associated with either an objfile (and thus its
architecture indirectly), or explicitly with an architecture as target-
specific types. There are still a couple of places where we randomly
access builtin_type_int32 or the like, but it seems they can all be
restructured to avoid such accesses *while making the code simpler!*

For example, one class of such uses is to find some random type in order
to construct an index value to pass to value_subscript (or value_ptradd)
or the like. We actually know the *offset* as numerical value, but finding
the *type* to form a value object out of the offset is hard. In this case,
it seems to me the interface of our helper routines is simply ill-defined:
value_subscript does not even *look* at the type of the index operand, the
only thing it does to the value is calling value_as_long! So simply changing
the interface to take a LONGEST instead of value fixes this class of problems
while making the callers simpler.

On the other hand, actually going all the way to ensure every type is
associated with a gdbarch makes several other simplifications possible:

- we can continue to provide a simple lookup_pointer_type interface --
if a type knows its own architecture, it knows the representation of
pointer types to itself!

- we can continue to have architecture-specific properties of *types*
defined via gdbarch callbacks, e.g. address classes

> Maybe we can take a similar approach here. Instead of inventing a new
> ad-hoc representation of types, use types, but make a copy with the
> right architecture when they're accessed. WDYT?

This seems even uglier to me :-) Maybe I'm just looking at this particular
target-description case a bit differently, but for me tdesc_type is not
"inventing a new ad-hoc representation of types", it is simply a 1:1 in-memory
representation of the XML contents without any GDB-specific reinterpretation
-- think something like "DOM tree" structures. In fact, if it weren't that
we want to avoid excessive dependencies on XML libraries, I'd argue we should
just parse XML into a standard DOM tree representation as provided by those.

Looking at this this way, serialization/deserialization of XML into and out
of those "DOM tree" structures *should not* involve too much GDB specifics
like GDB private data structures, but simply follow the self-describing
property of the XML format ...

(Or stating it another way, I think the tdesc_type patch I posted is a good
idea even if we decide in the end to not associate every type with an
architecture.)

Thoughts?

Bye,
Ulrich

--
Dr. Ulrich Weigand
GNU Toolchain for Linux on System z and Cell BE
Ulrich.Weigand@de.ibm.com