Date: Wed, 30 Aug 1995 20:36:53 +0200
From: Andreas Busse <email@example.com>
Question is: Would it hurt to change the struct pt_regs plus the
the macros SAVE_ALL, RESTORE_ALL and everything related so that
all required registers are saved, or shall I write my own
SAVE_ALL_GDB and RESTORE_ALL_GDB macros and a new struct containing
the regs ?
Agh, Andy take a look at the sparc-stub.c file, on the Sparc all the
registers are just thrown on the stack at trap time with down and
dirty offsets plain and simple. There is no fundamental reason for
you to rewrite pt_regs at all. In fact what I did was add a header
called include/asm-sparc/kgdb.h and on the mips you could put your
Mips KGDB specific register layout in there. Personally I only keep
an extern or two for people to call breakpoint() etc.
$0 ... $31 ($0 isn't worth to store, I know :-))
Most of them are availabe thru pt_regs. Only zero ($0),
k0 ($26) and k1 ($27) are missing.
So we have a couple of choices:
a) change struct pt_regs and all associated macros and functions
ugh don't do this...
b) fake the values of zero (always 0 anyway) and k0,k1
this neither. ;)
c) change GDB
this especially not ;)
d) Give gdb stub the registers in the layout that it does expect them
in and just leave it at that.
No one except the gdb-stub handle_exception() will ever see this stuff,
it's private to the debugger.
Changing GDB isn't a good idea, I believe.
True, when I got it such that anyone with a stock SunOS4.1.3 gdb user
level binary could kgdb with it, I was definately pleased. Strive for
this in your implementation and then you can keep up with the latest
gdb releases as new features specific to MIPS support are added more
easily than if you change code. Although I would like to add some
Sparc MMU/cache specific debugging features I learned this is a
non-sensical goal because one can call any arbitrary function in the
kernel at any point in time, and get a return value etc, while under
kgdb. For instance, I can easily do:
(gdb) print find_empty_task()
(gdb) print show_free_areas()
(gdb) print show_regs()
for instance ;-) And then happily continue kernel execution where the
origional breakpoint happened, as if nothing ever occurred ;)
Oh and be real careful about two things with KGDB
1) Make sure you *absolutely* can flush the instruction and/or
virtually addressed caches before returning from kgdb. If
multiple cache types can be found on the machine you must
know which one is present before you can kgdb.
2) On the Sparc I quickly got very frustrated when I could not set
breakpoints in what seemed like very innocent places in the kernel
and sometimes stepping would fail for what seemed like no reason
at all. Well, seems gdb tries to be overly smart about branch
prediction and tried to set breakpoint in the ROM boot monitor
to which I was making calls to for probing of devices etc. Try
to catch this in the hex2mem() routine somehow and return 0 if
kgdb is trying to write to bogon addresses.
As a solution to problem number 2, I have adjusted my mm code on the
Sparc to make all Boot Monitor pages COW, and Linux will copy the ROM
pages into physical RAM when kgdb tries to set breakpoints in this
area and yet preserve the mappings. Pretty krufty eh? ;-)
David S. Miller