public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Corinna Vinschen <corinna-cygwin@cygwin.com>
To: cygwin@cygwin.com
Subject: Re: Possibly wrong address passed to callq asm instruction within MPIR test binaries
Date: Mon, 07 Apr 2014 08:43:00 -0000	[thread overview]
Message-ID: <20140407084312.GA2061@calimero.vinschen.de> (raw)
In-Reply-To: <lhsctu$56e$1@ger.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 4688 bytes --]

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

[-- Attachment #2: Type: application/pgp-signature, Size: 819 bytes --]

  parent reply	other threads:[~2014-04-07  8:43 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-01 22:07 Jean-Pierre Flori
2014-04-02  9:07 ` Corinna Vinschen
2014-04-06 20:20   ` Jean-Pierre Flori
2014-04-07  7:52     ` Achim Gratz
2014-04-07  8:43     ` Corinna Vinschen [this message]
2014-04-07  9:14       ` Jean-Pierre Flori
2014-04-07  9:39         ` Corinna Vinschen
2014-04-07  9:55           ` Jean-Pierre Flori
2014-04-07  9:49         ` Jean-Pierre Flori
2014-04-07 10:42           ` Jean-Pierre Flori
2014-04-07 10:45             ` Jean-Pierre Flori
2014-04-07 11:26               ` Jean-Pierre Flori
2014-04-07 11:30                 ` Corinna Vinschen
2014-04-07 11:50                   ` Jean-Pierre Flori
2014-04-07 11:57                     ` Corinna Vinschen
2014-04-07 13:28                       ` Jean-Pierre Flori
2014-04-07 14:03                         ` Jean-Pierre Flori
2014-04-07 14:36                           ` Corinna Vinschen
2014-04-07 14:48                             ` Jean-Pierre Flori
2014-04-07 15:39                               ` Corinna Vinschen
2014-04-03 13:02 ` Jean-Pierre Flori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140407084312.GA2061@calimero.vinschen.de \
    --to=corinna-cygwin@cygwin.com \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).