This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Possibly wrong address passed to callq asm instruction within MPIR test binaries


On Apr  7 09:14, Jean-Pierre Flori wrote:
> Le Mon, 07 Apr 2014 10:43:12 +0200, Corinna Vinschen a ÃcritÂ:
> > On Apr  6 20:20, Jean-Pierre Flori wrote:
> >> 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.
> For most functions I indeed see this trampoline trick within the binary.
> > 
> > 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?
> Looking a little further, it seems the problematic functions are those 
> directly assembled from assembly code.
> That was the case of mpn_store on x86_64.

Just for clarity:  mpn_store is an assembler function calling an
external C function, right?

So IIUC, the assembler code in mpn_store contains a fixed callq, like
this:

   callq foo

And this crashes when foo is in an external DLL.  This is no wonder
at all.  x86_64 does not have a callq opcode with 64 bit absolute
addressing.  What you get in the example above is 32 bit PC-relative
addressing, so if foo is not part of the same binary, you're likely
to crash because the offset is just wrong.

AFAICS, what you have to do is to change your asse4mbler code to create
your own jump trampoline, or any other method which evaluates the 
correct 64 bit address in a place which is accessible via callq:

    movq __imp_foo, %rax
    callq *%rax
    [...]
  __imp_foo:
    .quad foo

or

    callq __jmp_foo
    [...]
  __jmp_foo
    jmp foo


HTH,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Maintainer                 cygwin AT cygwin DOT com
Red Hat

Attachment: pgpnYqaKlu0kR.pgp
Description: PGP signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]