public inbox for gdb@sourceware.org
 help / color / mirror / Atom feed
* RFC: Available registers as a target property
@ 2005-05-06 16:20 Daniel Jacobowitz
  2005-05-07 10:25 ` Eli Zaretskii
                   ` (5 more replies)
  0 siblings, 6 replies; 26+ messages in thread
From: Daniel Jacobowitz @ 2005-05-06 16:20 UTC (permalink / raw)
  To: gdb

Please bear with me; this is so long-winded I felt the need to give it
section titles.  I'm interested in any and all comments about the problem or
about my solution.  I hope to start implementing within a couple of weeks.

INTRODUCTION
============

Today, the contents of the register cache and the layout of GDB's regnum
space are determined by the gdbarch.  There are several hooks for this,
primarily these three:

	num_regs
	register_name
	register_type

The gdbarch determines what raw registers are available.  But this isn't a
perfect match with what raw registers are _really_ available, because the
gdbarch only has the clues we use to select a gdbarch available: things like
byte order and BFD machine number.  At best, those tell us what registers
the binary we're debugging requires.  The runtime set of registers we can
see are a property of the target, not of the gdbarch.

Here's a couple of examples of existing workarounds for this problem.

From i386_gdbarch_init:
  /* The default settings include the FPU registers, the MMX registers
     and the SSE registers.  This can be overridden for a specific ABI
     by adjusting the members `st0_regnum', `mm0_regnum' and
     `num_xmm_regs' of `struct gdbarch_tdep', otherwise the registers
     will show up in the output of "info all-registers".  Ideally we
     should try to autodetect whether they are available, such that we
     can prevent "info all-registers" from displaying registers that
     aren't available.

     NOTE: kevinb/2003-07-13: ... if it's a choice between printing
     [the SSE registers] always (even when they don't exist) or never
     showing them to the user (even when they do exist), I prefer the
     former over the latter.  */

Currently we always display the SSE registers, and fill them in with dummy
values.  If we knew whether they were available, we could avoid displaying
them entirely.

rs6000-tdep.c:rs6000_gdbarch_init has related problems: registers whose size
and type change depending on the architecture. Here's one I encountered
recently:
  /* For e500 executables, the apuinfo section is of help here.  Such
     section contains the identifier and revision number of each
     Application-specific Processing Unit that is present on the
     chip.  The content of the section is determined by the assembler
     which looks at each instruction and determines which unit (and
     which version of it) can execute it. In our case we just look for
     the existance of the section.  */

There's a number of ways to end up with binaries which will run on an e500
chip but not have an apuinfo section.  The presence of the section is used
to select bfd_mach_ppc_e500, which in turn is used to select registers_e500.
This is one of the many possible PPC register layouts, but it's particularly
interesting because it changes the size of registers 32-63, which moves
register 64 (the PC) to a different offset in the 'g' packet.  Most of the
other "common PPC" layouts are compatible enough that if you get the wrong
one, debugging will still work.  This one isn't.  GDB needs to know whether
it is talking to an e500 stub or not.

The MIPS targets have another variant of the problem; they don't know
whether the target provides 32-bit or 64-bit registers, because code
compiled for 32-bit can run on targets with 64-bit hardware registers - and,
in some cases, be influenced by corruption in the upper halves of the
registers.  So GDB is doing the user a disservice by only displaying 32-bit
registers if it can see the 64-bit registers.

And so on; you get the picture :-)

ONE EXISTING SOLUTION
=====================

On the csl-arm release branch, Paul and I developed a patch specific to the
ARM VFP and Xscale iWMMXt coprocessors.  It uses the xfer_partial interface
to query the target to describe the available registers, and then creates a
new gdbarch based on that information if it does not match the register
layout used by the current gdbarch.  Then there are three additional hooks,
covering native, sim, and remote.  I would like to propose a similar
interface for HEAD - the one on the branch is not suitable as-is.

Here's the branch patches, for reference:
  http://sourceware.org/ml/gdb-patches/2005-03/msg00370.html
  http://sourceware.org/ml/gdb-patches/2005-03/msg00387.html

The interface on the branch is based in ARM-specific code instead of
common code.  There is an inferior_created observer which calls
arm_update_architecture.  That function uses target_read_partial (sloppily)
to fetch a target-specific string.  The currently supported values
of the string are:
	iwmmxt
	iwmmxt:<hex number>
	vfp
	vfp:<hex number>

The word refers to an optional register set which is present on the target.
The hex number, if present, is a target-specific number used as a base for
the register set.  For instance, iwmmxt:30 means that the iWMMXt registers
are present, and wr0 (the first register) is number 0x30.  The number gets
saved away in the tdep structure, and a new hook for p/P packet support uses
this if the target we are connected to uses the remote protocol.  The sim
and native targets don't have separate numbering so they ignore this value.

Some shortcomings in the branch implementation:
  - I never implemented support for multiple responses.  It wasn't necessary
    since only two register sets were implemented; there exists today no
    ARM core with both extensions.
  - It uses an observer.  While I do like this sort of use of observers in
    general, it's not appropriate here; this should happen ASAP after
    connecting to the target, because until it does we may not be able to
    read registers reliably.
  - There's no common code infrastructure for this, which I consider a must.
    I don't want targets to reinvent more than necessary.

Also, it operates at an "optional feature" level rather than an "optional
register" level.  The ARM RDI protocol has a nifty feature called
Self-Describing Modules, which allows coprocessors to describe themselves to
the debugger, including describing their register sets.  It includes both
user-level information (name and type - along with a complicated type
description language) and implementation information (like the ARM mode in
which the register is accessible, for banked registers).  I would like
the GDB solution to this problem to be sufficiently flexible to work with
SDM - both because it's a nice model and because that way we can be
compatible with ARM debug servers, given an adequate RDI proxy.

A PROPOSAL
==========

Here's my current idea for an improved interface.  I have not implemented
any of this yet, only the older interface I described above.  It does borrow
heavily from that implementation.

After connecting to a target, GDB checks the current gdbarch for a new
method, gdbarch_set_available_registers.  If the architecture does not
provide this method, the rest of the process is skipped.

GDB then reads the TARGET_OBJECT_AVAILABLE_REGISTERS object from the target,
parses it, and hands it to the gdbarch for final processing.  This means
that the object must have a target-independent format, although it will
have target-dependent content also.

The target calls gdbarch_update_p with an appropriately filled in argument,
which calls its gdbarch_init routine, which can then do the real work of
updating gdbarch_num_regs et cetera.  This means that the gdbarch_init
routine must correctly handle filling in defaults based on the last
architecture.  That code is a bit fragile because it's undertested; I
recently updated ARM to do this robustly.

DETAILS
=======

First of all, the target object.  It can describe either individual
registers or register sets known to the target (for brevity).  Each
component is an ASCII string.  Colon is used as a field delimiter and
semicolon as a component delimiter.  A register set would look like:

	set:<NAME>:<PROTOCOL NUMBER>

No more information is necessary; the register set is an abbreviation of a
well-defined group of registers that both the stub and GDB have external
knowledge of.  GDB will already know the order, types, and sizes of
registers, and potentially other details (such as how to pass them as
arguments to functions).  If GDB does not recognize the register set, it can
safely ignore it, but should issue a warning to the user recommending use of
a later GDB.  If the protocol does not require numbers, they will be
ignored, but they are non-optional in the syntax.

I have spent less time thinking about how to specify individual registers.
This should suffice, but if anyone can see cause for another standard field,
please speak up.

	reg:<NAME>:<PROTOCOL NUMBER>:<BITSIZE>:<TYPE>:<TARGET DATA>...

Types unknown to GDB would default to integral display; common types such as
integral, floating point (native byte order), integral vector, fp vector, et
cetera would be documented in the manual with fixed names.



The remote protocol would use a qPart packet to implement this.  That means
the data would go over the wire hex encoded.  I would probably end up adding
some more intelligent decoding to "set debug remote" so that I could see the
hex-decoded form of this data, since it would be printable.  I've wanted
that before (for qSymbol debugging).

The optional register sets would generally not appear in the remote protocol
'g' packet.  Instead they would be handled using p/P packets.  This is
somewhat less efficient; if someone wants to come up with a g/G-like way to
transfer known register sets in bulk, be my guest.  That's a separate
problem.  The optional registers would not be blocked from appearing in the
g packet, however.  For instance, if MIPS used this feature to expect 32-bit
vs 64-bit GPRs, it would be desirable to continue using a g/G packet for
those.

The architecture would have to register the remote protocol <-> gdb regcache
number mapping.



Simulator targets could implement this mechanism in the simulator.  For now
I created a gdbarch hook which returns a string describing the capabilities
of the simulator, and used it to implement target_xfer_partial for the
common simulator target.  Native targets should override
to_xfer_partial.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: RFC: Available registers as a target property
@ 2005-05-09 22:39 Paul Schlie
  0 siblings, 0 replies; 26+ messages in thread
From: Paul Schlie @ 2005-05-09 22:39 UTC (permalink / raw)
  To: Chris Zankel, Daniel Jacobowitz, gdb

> Chris Zankel <zankel@tensilica.com> writes:
> I am wondering if it would also make sense to support the other way around and
> let GDB tell the target about the processor/register configuration. A scenario
> for this would be where GDB talks to an OCD daemon (=target) that controls the
> processor via JTAG. The daemon wouldn't need to know everything about the
> processor configuration.

Would seem sensible to consider, especially coming from a company with a
better perspective on the requirements of "configurable" processors than
most?



^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: RFC: Available registers as a target property
@ 2005-05-10  0:03 Paul Schlie
  0 siblings, 0 replies; 26+ messages in thread
From: Paul Schlie @ 2005-05-10  0:03 UTC (permalink / raw)
  To: Daniel Jacobowitz, Chris Zankel, gdb

> The daemon would already have to be updated to understand any new
> protocol extensions, so we're talking about modifying that agent in
> any case.  Given that, can you explain what advantage we would gain
> by having GDB pass configuration information to the daemon, instead of
> having the daemon parse some text file at startup and then communicate
> the configuration information to GDB?

Possibly because it's GDB which needs to know about both the symbolic and
semantics associated with registers and their interpretation, a target
interface only needs to know which and in what order GDB expects to have
their values communicated in, not what they mean, or how logically relate
to the program being debugged.

I.e. a target interface only needs to know how to retrieve/update register
values for a particular physical or simulated target, usually established
by convention, and possibly optionally identify a target more specifically
to GDB by returning a configuration status word typically defined by
configurable processors, or by simply literally specifying to GDB which
configuration to presume when invoked, just as is essentially done today,
as one can't expect to debug a PPC if GDB is configured to presume an x86
target for example.


^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: RFC: Available registers as a target property
@ 2005-05-10 11:12 Paul Schlie
  0 siblings, 0 replies; 26+ messages in thread
From: Paul Schlie @ 2005-05-10 11:12 UTC (permalink / raw)
  To: Chris Zankel, Daniel Jacobowitz, gdb

> I was thinking about an architecture with multiple configurations (registers),
> such as Arc, Tensilica, ARM coprocessors (?), etc.

> Having a single daemon supporting these multiple (arbitrary) configurations
> would probably be easier for JTAG probe vendors. Since GDB certainly needs to
> know about the particular configuration, the daemon wouldn't need to be
> modified for each configuration.
>
>> I don't want to support both directions just for kicks, but there may
>> be value here that I haven't thought of yet.  That's why I asked
>> Tensilica for feedback.
>
> I understand. I was just wondering if this would be useful and actully agree
> that your proposal makes much more sense and that the target should know about
> the configuration.
>
> In our case, the daemon currently doesn't know about a particular
> configuration, and GDB only queries for registers the processor (better) has.
> For example, to read 'special register' <SR>, OCD simply issues a rsr a2,<SR>
> and doesn't know if this <SR> really exists.

It seems that there are two fundamental models which may be adopted:

- refine GDB to be fully architecturally neutral, whereby all target
  specific architectural details are provided by the target; including
  but not limited to binary code encoding format, disassembly definitions,
  type encoding definitions, symbolic and semantic register definition,
  specification logical register names, types, purpose {GP pointer/data,
  SP, FP, PC, SR, etc. including their encoding {endian, signess, fixed/
  floating point encoding}}, logical/physical memory space definition
  address range, address resolution, segmentation, etc.}, not to mention
  potentially countless control registers which may be present to control
  the cache, MMU, FPU, etc. configurations, and/or operating modes; and
  possibly even the target interface protocol specification.

- refine GDB to enable these various potential target specific details to
  be extracted from a target definition/configuration binary specification
  directly, likely as directed by the user and possibly further refined
  after subsequently querying the target. Essentially leaving the target
  interface to be primarily responsible for GDB <=> target protocol
  translation, being essentially analogous to the driver for an I/O device)

 (Although not vastly dissimilar, it likely boils down to where one wants to
 draw the line between the division of responsibility between the debugger
 and the target interface processes; where personally regardless of where,
 I simply believe all target architectural specification information should
 be consolidated for the benefit of other tools, rather than being scattered
 all over the place, or rely on proprietary sources of this information,
 being "hidden" in a "propriety target interface".)


^ permalink raw reply	[flat|nested] 26+ messages in thread
* Re: RFC: Available registers as a target property
@ 2005-05-17 23:08 Paul Schlie
  0 siblings, 0 replies; 26+ messages in thread
From: Paul Schlie @ 2005-05-17 23:08 UTC (permalink / raw)
  To: Daniel Jacobowitz, gdb

> Daniel Jacobowitz <drow at false dot org> writes:
> This is a much-revised version of the original proposal, based on all
> the feedback I've gotten and an additional week thinking about the
> problem.  As before, I would appreciate feedback.  Otherwise, I think
> this is just about sufficiently baked to implement.
> ...

Upon also having the opportunity to thing further about this, I agree
that there's value in being able to define logical registers which may
be more target specific than traditionally defined/visible within the
architectural description files; and possibly even more generalized?

- more specifically, although I still believe that any register
  descriptions which are logically part of the machine's core ISA
  belong with and should correspond to that target's architectural
  definitions as would be seemingly necessary to correspond to it's
  disassembler register definitions and presumptions (as any alterative
  doesn't seem to minimally confusing, unless I misunderstand?)

- however as there are often logical registers which are considered
  supplementary to even non-configurable architectures, often representing
  control registers associated with MMU, Cache, or other closely coupled
  CPU subsystems which would be nice to define a "view of" more generally
  (including but not limited to memory mapped I/O registers, etc.).

So wonder if some hybrid mechanism, similar to that which you describe
may be most ideally flexible, and sufficient to meet your goals:

- presume that (by practical necessity) all logical registers which are
  part of a target's core architectural programming model which by
  definition should directly correspond to those definitions presumed
  by it's disassembler are sourced though gdbarch definitions, as seemingly
  required if they are to correspond?

- enable extended logical register views to be defined either by
  extended definitions via gdgarch, or the target (as you've both
  specified), and alternatively simply a configuration file (which
  may potentially scripted to load via an init file script to specify
  extended register views for those which may be memory or I/O space
  mapped.)

- where these extended architectural register definitions merely provide
  a convenient view of the logical state of the machine, which may be
  mapped either to specific registers which the target stub may need to
  be specifically aware of how to access through target specific jtag
  specified scan locations etc. or may simply be memory or I/O space
  mapped, as is often the case for extended control registers, in which
  case only the corresponding address and precision, would seem to need
  to be specified to enable GDB to request updates from the target, which
  would likely be useful for many existing target stubs for example? (where
  targets which must access extended registers through non-generalized means
  may publish there existence directly through their target interface stub).

So in rough summary:

- presume core architectural and disasssembly machine descriptions are
  sourced in some correlated manor (so they hopefully agree)

- non-core hard-registers which need direct specialized access may be
  described through gdbarch, or published via the target stub.
  
- non-core generalized memory/i-o space mapped logical register descriptions
  may be sourced either through gdbarch, the target, or an init file.

Just as a thought, and hope that this slight generalization of your
proposal might be found potentially helpful?




^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2005-05-20 14:54 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-06 16:20 RFC: Available registers as a target property Daniel Jacobowitz
2005-05-07 10:25 ` Eli Zaretskii
2005-05-07 16:19   ` Daniel Jacobowitz
2005-05-07 19:37     ` Eli Zaretskii
2005-05-09 15:37       ` Daniel Jacobowitz
2005-05-09 20:58         ` Eli Zaretskii
2005-05-07 16:04 ` Mark Kettenis
2005-05-09 16:20   ` Daniel Jacobowitz
2005-05-09 15:57 ` Paul Brook
2005-05-09 16:32   ` Daniel Jacobowitz
2005-05-09 21:33 ` Chris Zankel
2005-05-09 23:07   ` Daniel Jacobowitz
2005-05-10  0:23     ` Chris Zankel
2005-05-10 21:08       ` Daniel Jacobowitz
2005-05-12 23:35         ` Chris Zankel
2005-05-17 14:03           ` Daniel Jacobowitz
2005-05-10  0:54 ` Ramana Radhakrishnan
2005-05-10 21:14   ` Daniel Jacobowitz
2005-05-17 19:32 ` Daniel Jacobowitz
2005-05-18  9:29   ` Richard Earnshaw
2005-05-19  1:00     ` Daniel Jacobowitz
2005-05-20 14:54       ` Richard Earnshaw
2005-05-09 22:39 Paul Schlie
2005-05-10  0:03 Paul Schlie
2005-05-10 11:12 Paul Schlie
2005-05-17 23:08 Paul Schlie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).