From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cagney To: GDB Discussion Subject: [multi-arch] The frame as the global parameter (long, important) Date: Fri, 23 Feb 2001 16:34:00 -0000 Message-id: <3A970102.68681EB2@cygnus.com> X-SW-Source: 2001-02/msg00335.html Hello, (For all two of you that haven't figured it out, I'm back at working on multi-arch :-) This e-mail first discusses multi-arch and some of its requirements. It then goes on to propose a number of significant but related structural changes to GDB that help it take a step closer to being multi-arch. ---- Multi-arch is the grand plan that one day GDB will be able to do things like debug a target that contains several different architectures. The classic embedded example would be the Play Station 2 while the UNIX example is for platforms like Solaris where both 32 and 64 bit binaries are present. Several steps in this plan were identified (with any long term project, the more distant the work, the more vague the details :-): o Replace hardwired macros with run-time tests/calls to an architecture vector. o Modify GDB's configury so that different architectures could be incorporated into a single GDB. o Modify GDB so that it can debug a system that contains several different architectures. This was identified as the tricky bit. Right now, I think things are about ready for step two (hopefully fairly straight forward) so it is time to plan for step three. Hmm. ---- When multi-arch was first discussed it was fairly clear that GDB was going to need to be parameterize with something. At the time, it was thought that during stage three everything would be parameterized with either a large architecture vector or an even larger merged architecture / target vector. Hmm. ---- In the mean time, Kevin B has been looking at TPID, that global integer which is used to identify the current thread. A pretty logical chain of thought leads to the conclusion that, since each thread can have a different architecture, each thread should have an arcitecture bound to it. So rather than parameterize everything with the architecture, why not instead parameterize everything with a thread object. Hmm. ---- One of the very long term goals of GDB is to be able to debug RPC code. Looking at what appears to be a simple debugging example: (gdb) step 10 do_rpc_to_machine_foo(); (gdb) step do_rpc_to_machine_foo() at foo.c:50 50 printf ("Hello world\n"); (gdb) Examing the stack frame, and remembering the idea is that this is RPC code: (gdb) where #0 do_rpc_to_machine_foo() at foo::foo.c:50 #1 0x804883d in main () at blah::blah.c:10 (gdb) info architecture The architecture is foo. (gdb) up #1 0x804883d in main () at blah::blah.c:10 10 do_rpc_to_machine_foo(); (gdb) info architecture The architecture is blah The architecture is clearly bound to the frame rather than the thread. A thread has a frame, a frame has an architecture. So why not pass the frame around everywhere? Hmm. ---- Looking at the existing code base,I think it is clear that much it isn't worried about threads or architectures. Rather it is worried about frames. To do a stack backtrack, you need a frame. To list the current source, you (often - PIC) need a frame. To examine variables you need a frame. To do an inferior function call, you need a frame. In fact, when the target stops, the second thing GDB does (after checking that the stop is for real) is to create a frame. On a target that doesn't have a frame, GDB fakes it. If GDB can't fake a frame, things get pretty sick. In a way, this shouldn't be unexpected. GDB is a debugger designed for debugging procedural languages that, in some way resemble C. Much of a procedural language revolves around the stack frame. Hmm. ---- A number of GDB's existing targets have limited runtime support for architecture variants (THUMB/ARM and MIPS16/MIPS). For these targets the ISA may change between stack frames. At present this is implemented by wrapping all architecture specific code in ``if (ISA_A) ... else ...;''. Such code would clearly immediatly benefit from a change that bound the architecture to the frame. Hmm. ---- Given all this, I'd like to propose the following structural changes to GDB. o The frame have an architecture attached to it. As an intermediate hack, current architecture and current frame would remain as globals. o All the functions that apply to the frame be parameterized with a frame argument and modified to use the frame's architecture. o (Per previous e-mail) The frame and its registers be more clearly separated from the target (in particular the regcache). Most calls that go directly to the regcache will instead go via the current frame. A consequence of this is that the current need for the RAW / PSEUDO / NATURAL register mess will be eliminated. Yessss! While looking simple, these changes are certainly everything but. Every frame / regcache / memcache access will need to be examined / modified. Fortunately, most of these uses can be examined independently so the work can be carried out incrementally. Clearly this change, on its own, won't be sufficient to make GDB multi-arch. I would argue, however, that like the initial multi-arch work, it is a clear step in the right direction. With that in mind, I'm looking for comments, questions and suggestions. ---- Finally. I'd like to thank Jim Blandy, David Taylor, Fernando Nasser, Kevin Buettner, Elena Zannoni and Michael Snyder (who else? Red Hat) for providing the support and suggestions needed to develop this idea. Andrew