Message ID | 50A608C6.1080804@redhat.com |
---|---|
State | New |
Headers | show |
Am 16.11.2012 10:35, schrieb Paolo Bonzini: > Il 15/11/2012 23:18, Stefan Weil ha scritto: >> Am 15.11.2012 21:52, schrieb Paolo Bonzini: >>> Il 15/11/2012 19:01, Stefan Weil ha scritto: >>>> Hi Paolo, >>>> >>>> this patch breaks QEMU on 32 and 64 bit hosts, native and with Wine. >>>> It's easy to reproduce the SIGSEGV crash: just add a -snapshot option. >>>> Obviously the critical code is executed only when this option was used. >>> >>> I cannot reproduce this, so it must be an assembler or linker bug. >>> >>> Can you try the alternative code that is used for Mac OS X? >> >> The code which is used for Mac OS X also compiles and >> results in the same run-time bug with Wine: > > Ok, I reproduced the original binutils bug, and found a typo in the > weakrefs implementation. Does this work for you? > > diff --git a/compiler.h b/compiler.h > index 55d7d74..d552757 100644 > --- a/compiler.h > +++ b/compiler.h > @@ -50,11 +50,12 @@ > # define __printf__ __gnu_printf__ > # endif > # endif > -# if defined(__APPLE__) > +# if defined(__APPLE__) || defined(_WIN32) > # define QEMU_WEAK_ALIAS(newname, oldname) \ > - static typeof(oldname) weak_##newname __attribute__((unused, weakref(#oldname))) > + static typeof(oldname) weak_##newname __attribute__((unused, weakref(#newname))) > # define QEMU_WEAK_REF(newname, oldname) (weak_##newname ? weak_##newname : oldname) > # else > +#error > # define QEMU_WEAK_ALIAS(newname, oldname) \ > typeof(oldname) newname __attribute__((weak, alias (#oldname))) > # define QEMU_WEAK_REF(newname, oldname) newname > > > If it still doesn't work, let's make sure that this reduced testcase works > for you: Tested-by: Stefan Weil <sw@weilnetz.de> Great, the above patch fixes w32/w64 (native and with Wine). Is this modification needed / does it work with MacOS X, too? With the reduced testcase, I get the same results as in your test. Regards Stefan > > g1.c: > #include<stdio.h> > int f() { printf("strong"); return 82; } > int g() { printf("strong"); return 83; } > > g2.c: > #include<stdio.h> > static int weak_f() { return 42; } > static int weak_g() { return 43; } > typeof(weak_f) f __attribute__((__weak__, __alias__("weak_f"))); > typeof(weak_g) g __attribute__((__weak__, __alias__("weak_g"))); > int main() { printf("%d/%d\n", f(), g()); } > > g3.c: > #include<stdio.h> > static int default_f() { return 42; } > static int default_g() { return 43; } > static typeof(default_f) weak_f __attribute__((__weakref__("f"))); > static typeof(default_g) weak_g __attribute__((__weakref__("g"))); > int main() { printf("%d/%d\n", (weak_f?:default_f)(), (weak_g?:default_g)()); } > > Output should be: > - 42/43 for "gcc g2.c" > - 42/43 for "gcc g3.c" > - strongstrong82/83 for "gcc g1.c g2.c" > - strongstrong82/83 for "gcc g1.c g3.c" > > Output on Windows is: > - 42/42 for "gcc g2.c" > - 42/43 for "gcc g3.c" > - segfault for "gcc g1.c g2.c" > - strongstrong82/83 for "gcc g1.c g3.c" > > So, indeed "normal" weak symbols are broken, but weakrefs seem to work. > > If the above patch doesn't work, and/or the reduced testcase fails, > please send to me: > > - the .exe for "gcc g1.c g3.c" > - the .s file for g3.s > - the .o file for osdep.o > - the linked .exe (I assume both the windows and console versions fail) > - perhaps the .s file for osdep too; add --save-temps to the compiler command line to get it > > Paolo
Il 16/11/2012 18:15, Stefan Weil ha scritto: > > Tested-by: Stefan Weil <sw@weilnetz.de> > > Great, the above patch fixes w32/w64 (native and with Wine). > Is this modification needed / does it work with MacOS X, too? Yes, but I found a way to get rid of weak references completely. The testing is still precious---thanks very much. > With the reduced testcase, I get the same results as in your test. Good to know, too. :) llvm-gcc totally botches it on Mac OS X, by the way (while clang works there). Paolo
On 16 November 2012 09:35, Paolo Bonzini <pbonzini@redhat.com> wrote: > Ok, I reproduced the original binutils bug, and found a typo in the > weakrefs implementation. Does this work for you? > > diff --git a/compiler.h b/compiler.h > index 55d7d74..d552757 100644 > --- a/compiler.h > +++ b/compiler.h > @@ -50,11 +50,12 @@ > # define __printf__ __gnu_printf__ > # endif > # endif > -# if defined(__APPLE__) > +# if defined(__APPLE__) || defined(_WIN32) > # define QEMU_WEAK_ALIAS(newname, oldname) \ > - static typeof(oldname) weak_##newname __attribute__((unused, weakref(#oldname))) > + static typeof(oldname) weak_##newname __attribute__((unused, weakref(#newname))) > # define QEMU_WEAK_REF(newname, oldname) (weak_##newname ? weak_##newname : oldname) > # else > +#error > # define QEMU_WEAK_ALIAS(newname, oldname) \ > typeof(oldname) newname __attribute__((weak, alias (#oldname))) > # define QEMU_WEAK_REF(newname, oldname) newname This change makes compilation fail with clang: LINK qemu-ga Undefined symbols for architecture x86_64: "_monitor_fdset_dup_fd_add", referenced from: _qemu_open in osdep.o "_monitor_fdset_dup_fd_remove", referenced from: _qemu_close in osdep.o "_monitor_fdset_get_fd", referenced from: _qemu_open in osdep.o "_monitor_get_fd", referenced from: _socket_connect in qemu-sockets.o _socket_listen in qemu-sockets.o "_qemu_set_fd_handler2", referenced from: _inet_connect_addr in qemu-sockets.o _unix_connect_opts in qemu-sockets.o _wait_for_connect in qemu-sockets.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) (clang builds OK with current git master.) -- PMM
Il 16/11/2012 18:52, Peter Maydell ha scritto: > clang: error: linker command failed with exit code 1 (use -v to see invocation) > > (clang builds OK with current git master.) But I have no idea why, or whether the generated code is correct... Looks like the safest bet is to go with the good old static library. Paolo
diff --git a/compiler.h b/compiler.h index 55d7d74..d552757 100644 --- a/compiler.h +++ b/compiler.h @@ -50,11 +50,12 @@ # define __printf__ __gnu_printf__ # endif # endif -# if defined(__APPLE__) +# if defined(__APPLE__) || defined(_WIN32) # define QEMU_WEAK_ALIAS(newname, oldname) \ - static typeof(oldname) weak_##newname __attribute__((unused, weakref(#oldname))) + static typeof(oldname) weak_##newname __attribute__((unused, weakref(#newname))) # define QEMU_WEAK_REF(newname, oldname) (weak_##newname ? weak_##newname : oldname) # else +#error # define QEMU_WEAK_ALIAS(newname, oldname) \ typeof(oldname) newname __attribute__((weak, alias (#oldname))) # define QEMU_WEAK_REF(newname, oldname) newname