qemu-devel
[Top][All Lists]
Advanced

[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__





reply via email to

[Prev in Thread] Current Thread [Next in Thread]