[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] Building qemu on UltraSparc
From: |
Juergen Keil |
Subject: |
Re: [Qemu-devel] Building qemu on UltraSparc |
Date: |
Tue, 24 May 2005 14:20:46 +0200 (CEST) |
Heiko.Nardmann wrote:
> On Montag 23 Mai 2005 10:38, Juergen Keil wrote:
> [snip]
> > All of the above changes are part of bigger Solaris x86 / Solaris SPARC
> > / FreeBSD / NetBSD patch that I'll attach below.
> >
> >
> > This patch won't immediately fix the issues that you've got on
> > linux/sparc, but it should give you some ideas where to start fixing
> > the build issues.
>
> You probably did your diff against CVS? I have tried it using with clean
> 0.7.0
> distribution (gpatch -p0 < ../qemu-solaris-freebsd-netbsd--patch) and got the
> following:
>
> patching file Makefile
> patching file Makefile.target
> patching file block.c
> Hunk #1 succeeded at 528 (offset -3 lines).
> ...
Yes, the patch was against current qemu cvs sources.
> This has not been a problem. I have done the following configure call then:
>
> ./configure --prefix=$HOME/qemu-0.7.0.installed --target-list="i386-softmmu"
> --cc=gcc-3.4.2 --interp-prefix=$HOME/qemu-0.7.0.installed
>
> Fine, too. Also compilation works fine. But linking fails with the following
> error message:
>
> ld: fatal: relocation error: R_SPARC_WDISP22: file libqemu.a(op.o): symbol
> __op_gen_label1: value 0x34c21f does not fit
> ...
> ld: fatal: relocation error: R_SPARC_WDISP22: file libqemu.a(op.o): symbol
> __op_gen_label1: value 0x34a0d3 does not fit
>
> collect2: ld returned 1 exit status
>
> Any idea what is happening here?
Part of the problem is my GOTO_LABEL_PARAM macro for sparc, in dyngen-exec.h:
#define GOTO_LABEL_PARAM(n) asm volatile ("ba " ASM_NAME(__op_gen_label) #n
";nop")
We have 22 bits in the branch instruction to encode a signed 32-bit word
offset, relative to the current PC. The target address is always a
multiple of 4, so the offset encoded in the branch instruction is an
offset measured in 32-bit words.
The sparc branch instructions cannot jump forward / backward more than
8 mbytes (2^21 * 4 = 8mbyte).
What appears to be happening on your system is that the opcode
templates from the code section for "target-i386/op.c" (these contain
the "ba" branch instruction from the GOTO_LABEL_PARAM macro) jump to an
integer variable that is allocated somewhere in the data or bss section
(the "int __op_gen_label1" variable defined in dyngen.h), and the code
& data section on your system are more than 8 mbytes apart.
Apparently I had luck upto now, because on my solaris 10 sparc box there
have been no such issues with R_SPARC_WDISP22 relocation errors.
> ld: fatal: relocation error: R_SPARC_WDISP22: file libqemu.a(op.o): symbol
> __op_gen_label1: value 0x34c21f does not fit
--> 0x34c21f * 4 = 13830268 = 13.8 mbytes
I guess this can be fixed by moving the branch target "__op_gen_label1"
from the data section to the code section. A "size" on my sparc qemu
binary reports a total code size of ~ 1 mbyte, so that there should be
no issues with R_SPARC_WDISP22 overflows when both the branch instruction
and the branch target are both in the code (.text) section.
A fix would be:
Index: dyngen.h
===================================================================
RCS file: /cvsroot/qemu/qemu/dyngen.h,v
retrieving revision 1.8
diff -u -B -r1.8 dyngen.h
--- dyngen.h 7 Apr 2005 22:20:28 -0000 1.8
+++ dyngen.h 24 May 2005 12:03:11 -0000
@@ -19,7 +19,13 @@
*/
int __op_param1, __op_param2, __op_param3;
+#ifdef __sparc__
+void __op_gen_label1(){}
+void __op_gen_label2(){}
+void __op_gen_label3(){}
+#else
int __op_gen_label1, __op_gen_label2, __op_gen_label3;
+#endif
int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
#ifdef __i386__