From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Cagney To: GDB Discussion Subject: A better register interface Date: Wed, 14 Feb 2001 20:39:00 -0000 Message-id: <3A8B5C60.92EEABA3@cygnus.com> X-SW-Source: 2001-02/msg00165.html Hello, As many people will tell you GDB's current register interface/model is so large you can comfortably drive a road train through it. Right now there are roughly the following interfaces: On the target side: o supply_register() o register_buffer() (nee register_buffer[]) While on the GDB side, there are a number of ways of getting at the cache and all are used randomly. o read_register() o write_register() o get_saved_register() o find_saved_register() but quickly decays into: o {read,write}_register_pid() o read_register_bytes() o register_buffer() o {read,write}_register_gen() Accompanying this there is the split of GDB's registers into virtual, raw, normal? and pseudo. Pseudo registers are significant as, in theory at least, they are not backed by real bytes but instead constructed on the fly using bits and bytes from other registers. Well nice theory :-/ Associated with this are a number of bugs. The most common are: o you can't get a complex pseudo register from a saved frame o you can't modify a complex pseudo o you can only print complex psuedos by a hack - have it backed by a read only buffer. o the RAW_REGISTER_BYTE() macro determines everything including the format of the remote G packet. (a complex pseudo is one that is constructed from random bits from the register cache or stack). I'd like to bite the bullet and see GDB rid of this mess. As a starting point, I'd like to propose the following as the minimal interface and try to cut things down so that there is only a minimal number of calls into the register cache. Hopefully this proposal would also help better clarify the register interfaces. In this I've borrowed from several recent postings (Steven Johnson and Nick Duffek) along with too many bad experiences with the existing model. -- While eventually, I'd like to see a clear separation between the two sides of the register cache - the target side which supplies raw bytes and the gdb/core side which uses values and register names, it won't be possible for some time. Instead, I'd like to see the existing REGNUM space structured as: core gdb | target side 0 . . raw register space . NUM_RAW_REGISTERS . . any additional non raw registers . NUM_COOKED_REGISTERS There are 0..NUM_RAW_REGISTERS raw registers that contain raw register bytes supplied by the target. The target side is only allowed to access 0..NUM_RAW_REGISTERS using functions like: supply_raw_register(RAWNUM, buf, sizeof buf) set_raw_register_state (RAWNUM, that register valid stuff); fetch_raw_register(RAWNUM, buf, sizeof buf) something for value changed? raw_register_size(RAWNUM) raw_register_name(RAWNUM) raw_register_name() is significant as it is new. It is there for two reasons: o it allows the implementation of a simple but meanginful ``info raw-registers'' command that would just dump the raw buffer o it provides abstract names to each target side register. remote.c would then be able to describe its G packet in terms of ``target names'' rather than magic numbers and mysterious offsets. (eg set G-packet-format r0:4,4;r1:12,8;...) There are 0..NUM_COOKED_REGISTERS cooked/pseudo registers that supply register values to core-gdb. gdb-core would be allowd to access cooked registers. Cooked register methods would have frame associated with them (NULL implies no frame but must be handled). cooked_register_name(frame, REGNUM) cooked_register_type(frame, REGNUM) provides the size implicitly read_cooked_register(frame, REGNUM, buf, sizeof buf) write_cooked_register(frame, REGNUM, buf, sizeof buf) along with a few others such as: cooked_register_attrib_p (frame, REGNUM, some attribute - is FP?) thoughts. The key thing is that, the interface is minimized. This would mean that chunks of GDB would need re-implemented. But as they say, no pain, no gain. Andrew