From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20267 invoked by alias); 20 Feb 2002 18:50:19 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 18896 invoked from network); 20 Feb 2002 18:49:12 -0000 Received: from unknown (HELO localhost.redhat.com) (24.112.135.44) by sources.redhat.com with SMTP; 20 Feb 2002 18:49:12 -0000 Received: from cygnus.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 095C73D12; Wed, 20 Feb 2002 13:49:07 -0500 (EST) Message-ID: <3C73EFA3.6050805@cygnus.com> Date: Wed, 20 Feb 2002 10:50:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:0.9.8) Gecko/20020210 X-Accept-Language: en-us MIME-Version: 1.0 To: Richard.Earnshaw@arm.com Cc: gdb@sources.redhat.com Subject: Re: The regcache abstraction (Was Re: PATCH ARM initial support for different floating-point models) References: <200202201644.QAA09255@cam-mail2.cambridge.arm.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2002-02/txt/msg00255.txt.bz2 Richard what follows is the short obscure answer (sorry). I'll try to do the long (add to documentation answer, in about a week - this really does need to be documented. > retrieving revision 1.47 >> > diff -p -r1.47 arm-tdep.c >> > *** arm-tdep.c 2002/02/19 13:57:35 1.47 >> > --- arm-tdep.c 2002/02/19 19:14:40 >> > *************** arm_extract_return_value (struct type *t >> > *** 2139,2145 **** >> > char *valbuf) >> > { >> > if (TYPE_CODE_FLT == TYPE_CODE (type)) >> > ! convert_from_extended (®buf[REGISTER_BYTE (ARM_F0_REGNUM)], valbuf); >> > else >> > memcpy (valbuf, ®buf[REGISTER_BYTE (ARM_A1_REGNUM)], >> > TYPE_LENGTH (type)); > >> >> Here, unfortunatly, directly pokeing around the regcache buffer (a >> parameter) is still the only way to do this. > > > Yep, this is awful, but that's what it has always done there (you quote > the old code). Yes, I figured you're intended modifications were just re-aranging the existing code. For the above case it isn't possible to do any better. Fixing the problem requires further changes to the regcache interface - perhaphs a mechanism for saving/restoring the regcache or better the ``target register state''. > And you quote the old code again here. > > >> Need to be careful though. If the code is assuming a floating point >> value should be stored across multiple adjacent registers then the code >> will need to be broken down into separate explicit writes. > > > I desperately need a high-level overview of how the regcache interface is > *supposed* to work in the brave new world (ie without all the legacy > interfaces lying around). Let me start by trying to draw a little diagram > to explain how I think it might work; then we can expand on that, or > re-draw it as appropriate. > > Lets start the model with four main units. The inferior, the regcache, > the MI routines and the tdep support. The interfaces are then as follows: > > +--------------------------------+ > | Inferior | > +--------------------------------+ > ^ | > | | A > | v > +--------------------------------+ > | Regcache | > +--------------------------------+ > ^ | ^ | > | | B | | C > | v | v > +-------------+ +-------------+ > | MI |<==>| Tdep | > +-------------+ D +-------------+ > > That gives us three potential interfaces to the regcache, A, B and C. In > addition, there is an interface D, which is effectively the gdbarch vector. > > Now, as I understand it, interface A is quite straight-forward and > consists of three functions: > > supply_register() > collect_register() > set_register_cached() > > [The last of these is needed because a target may be unable to recover > some registers at certain times, and may need to tell the regcache that.] Yes. In a ``pure'' new model the regcache only contains raw values. > This interface is used by the 'nat' code or anything else that talks to a > target machine (ie it lies at the callee side of a target_ops vector). > > However, after that it starts to become fuzzy. The first problem is that > it isn't completely clear whether the regcache should contain a raw cache > of the physical registers, or some munged view of them. > > I'd be inclined to argue the regcache should be pretty much a raw cache of > the machine registers, and that interface B is therefore bogus (since it > can't know how to interpret the information); therefore all accesses to > the regcache by MI code should be, at least conceptually, via the tdep > code using interface D. > > Of course, it may be that many targets will have near identical routines > for mapping D<->C and there's no reason why that shouldn't be extracted > out so that the gdbarch vector can handle it cleanly. > > So my questions are: Do we have interface B? If so, why? what functions > comprise C? and what functions comprise D? (core gdb is safer than MI, although core GDB still has problems). In theory the call pattern is: core-gdb -> read_register_gen -> gdbarch_register_read() -> regcache_read() OR -> memory_read() -> get value from raw regcache. All accesses to the regcache are ment to go via gdbarch_register_read() which your architecture controls. If a register is really in memory, register_read() can fetch it from memory. If a register is a composite of several raw registers, register_read() can compose it (on the fly) from the sub registers. Conversely for writes. gdbarch_register_write() can scatter the register's value to the correct raw register and memory locations. The theory breaks down on two fronts: Core code still uses read_register_bytes() to do things like extract struct values from two or more registers assuming they are adjacent. That code is broken since, for instance, when a 64 bit architecture is executing 32 bit compat code - structs are across 32 and not 64 bit registers. Core code still uses read_register_bytes() to save the register cache and to apply operations on a saved register set (eg extract return value). That code is broken since it saves/restores all registers and not just the registers (and memory) relevant to the ABI. Andrew