On Sat, Oct 23, 2010 at 8:51 AM, Mark Cave-Ayland mark.cave-ayland@siriusit.co.uk wrote:
Blue Swirl wrote:
The only thing I can think of is that this simple example fails because of something related to the return address, but I'm not 100% sure.
'call' instruction writes the return address to %o7, clobbering previous %o7 from the OS. That's why 'save' and 'restore' are needed.
In this case, alternatively changing just 'call' to 'jmp' and deleting the rest should also work.
Also what are the rules about how much information you can push onto the stack of the previous frame, i.e. the frame pointer? My current thoughts are that I can either i) push arguments onto the %fp and not save into a new window or ii) push arguments onto the %sp after a save (in which case I need additional code to copy the i registers into the o registers before calling the C function). Does this sound correct?
I'd go for ii) or 'jmp'.
Okay. I tried using jmp but I got an "out of range" error on compilation so I started working on something based on disassembling the output of a GCC wrapper function. The attached patch works well my Solaris 8 ISO, although now after some twirly batons we appear to be sat in an infinite loop:
The address of jmp target needs be in a register. Alternatively 'b' should work.
The offsets to %sp are too low, the area you are using is used by window trap handlers. They should be %sp+0x60 etc, but usually the addressing is %fp-0x20 etc which should yield the same address. Maybe this was the problem?
This document describes the usual stack frame layout: http://www.sparc.com/standards/psABI3rd.pdf
Other nitpicks: The usual practice is to use 'ret' followed by 'restore' in the delay slot (which can also perform 'mov %o0, %i0'). 'extern' is not needed with function declarations. obp_fortheval_v2_handler2() is not used AFAICT. init_openprom() declaration should be moved to romvec.h so all romvec stuff is in one place.
build@zeno:~/src/openbios/openbios-devel$ sparc64-linux-gdb GNU gdb 6.8 Copyright (C) 2008 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=sparc64-linux". (gdb) file obj-sparc32/openbios-builtin.elf.nostrip Reading symbols from /home/build/src/openbios/openbios-devel/obj-sparc32/openbios-builtin.elf.nostrip...done. (gdb) target remote :1234 Remote debugging using :1234 [New Thread 1] 0x00000000 in ?? () (gdb) cont Continuing. ^C Program received signal SIGINT, Interrupt. 0x00106190 in ?? () (gdb) stepi 0x00106194 in ?? () (gdb) 0x00106190 in ?? () (gdb) disas 0x106190 0x106194 Dump of assembler code from 0x106190 to 0x106194: 0x00106190: call 0x106190 End of assembler dump. (gdb)
From the addresses and the twirly baton beforehand, I'd say we're actually now in the Solaris kernel. The interesting part of this is the fact that we get stuck in an infinite loop as shown above - I wonder if this is just the Solaris way of handling errors? Or perhaps maybe OpenBIOS doesn't have a romvec entry to enable diagnostic messages to be output to the console?
We don't implement pv_putstr (not used by Linux) and pv_printf calls printk directly without your wrappers.
While there is no notable regression when building with -Os, my NetBSD and Debian test ISO images crash out when compiled with -O0 (as set in this patch) - anyone have any ideas on this one?
Probably related to low %sp offset: unoptimized functions always use save/restore and they are not inlined, so the call chain is longer and window spills more likely to happen.