On Apr 6 20:20, Jean-Pierre Flori wrote: > [...] > The problem we recently encountered was the following: > in gmp-impl.h, mpn_store (which can be either a macro or a function if > efficient assembly is available, and so is always a function on x86_64) > was not marked __declspec(dllexport/dllimport). > (See https://github.com/wbhart/mpir/blob/master/gmp-impl.h#L2419 for the > current version with the __GMP_DECLSPEC, defined in mpir.h (from gmp- > h.in) where this gets defined as __declspec(dllimport) for the user > visible header and use outside of MPIR itself) > It seems that because of this lack, the call to mpn_store from a bunch of > test executables produced the wrong callq instruction. > Once we added the __GMP_DECLSPEC the function got correctly called. > > What I don't really get is that from what I've read e.g. here : https:// > access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/4/ > html/Using_ld_the_GNU_Linker/win32.html > is that the dllimport/export should not be needed anymore.
And in fact it isn't. > So I took a slightly deeper look and played with the definition of > __GMP_DECLSPEC in gmp-h.in/mpir.h to be empty or __declspec(dllexport/ > import). > The library was built with: > ./configure --disable-static --enable-shared > make > make check (-> potential segfaults when testing the mpn dir) > > As far as dllexport is concerned, we pass --export-all-symbols to ld, and > as expected, we don't need the dllexport part when building the library > (we get __imp_ and __nm_ symbols for functions). > > But it seems that the --enable-auto-import counterpart (which should be > ld default) is defeated. > I've had a look at the assembly and objects produced by gcc before linking > and they indeed look different. > With the dllimport magic, I get in t-neg.s: > movq %rax, %rcx > movq __imp___gmpn_store(%rip), %rax > call *%rax > Without it I get: > movq %rax, %rcx > call __gmpn_store > Similar differences in the object file (t-neg.o). > Looking at the exes produced (.libs/t-neg.exe) gives with the dllimport > magic: > 100401115: 48 89 c1 mov %rax,%rcx > 100401118: 48 8b 05 f1 71 00 00 mov 0x71f1(%rip),%rax # > 100408310 <__imp___gmpn_store> > 10040111f: ff d0 callq *%rax > Without it: > 100401111: 48 89 c1 mov %rax,%rcx > 100401114: e8 f7 71 00 00 callq 100408310 > <__imp___gmpn_store> This is ok. Look closely at the address after the callq. It's the start address of the executable (0x1:00400000) plus an offset. If you disassemble the executable you will find a jmp statement at this address. This is the trampoline code which is automatically generated for external references if they are not marked with dllimport. The problem at this point is that I can't reproduce your issue with a simple example. Here's the example: ==== SNIP ==== $ cat > lib.c <<EOF #include <stdio.h> int foo (int a) { printf ("a = %d\n", a); return a; } EOF $ cat > app.c <<EOF #include <stdio.h> extern int foo (int); int main () { int x = foo (42); printf ("x = %d\n", x); return 0; } EOF $ gcc -g -shared -o lib.dll lib.c $ gcc -g -o app app.c lib.dll $ ./app a = 42 x = 42 ==== SNAP ==== Let's have a look into the executable: $ objdump -d app.exe [...] 00000001004010d0 <main>: 1004010d0: 55 push %rbp 1004010d1: 48 89 e5 mov %rsp,%rbp 1004010d4: 48 83 ec 30 sub $0x30,%rsp 1004010d8: e8 93 00 00 00 callq 100401170 <__main> 1004010dd: b9 2a 00 00 00 mov $0x2a,%ecx 1004010e2: e8 59 06 00 00 callq 100401740 <foo> 1004010e7: 89 45 fc mov %eax,-0x4(%rbp) [...] So the call to foo is a call to address 1:00401740. Let's have a look what is at that address: 0000000100401740 <foo>: 100401740: ff 25 1a 5a 00 00 jmpq *0x5a1a(%rip) # 100407160 <__imp_foo> Address 100407160 is somewhere within the IAT which gets relocated at runtime. This is exactly as it's supposed to be. Now, here's the question: Where is your problem different? What exactly makes your code fail? Can you construct your problem from my simple testcase, or can you construct an equally simple testcase which fails? Corinna -- Corinna Vinschen Please, send mails regarding Cygwin to Cygwin Maintainer cygwin AT cygwin DOT com Red Hat
pgpg5F7iECioF.pgp
Description: PGP signature