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

Corinna Vinschen corinna-cygwin@cygwin.com
Mon Apr 7 14:36:00 GMT 2014


On Apr  7 14:02, Jean-Pierre Flori wrote:
> Le Mon, 07 Apr 2014 13:28:19 +0000, Jean-Pierre Flori a écrit :
> 
> > Le Mon, 07 Apr 2014 13:57:30 +0200, Corinna Vinschen a écrit :
> > 
> >> On Apr  7 11:50, Jean-Pierre Flori wrote:
> >>> Le Mon, 07 Apr 2014 13:30:27 +0200, Corinna Vinschen a écrit :
> >>> > 
> >>> > I'm sorry, but I don't know how this works exactly.  The nm prefix
> >>> > is only added for external references, not for inlined functions,
> >>> > but I don't know the gory details.  You may be better off to ask on
> >>> > the gcc mailing list.
> >>> > 
> >>> No problem, I've already learned tons of stuff thanks to your help.
> >>> I've just posted on gcc-help.
> >>> http://gcc.gnu.org/ml/gcc-help/2014-04/msg00024.html
> >> 
> >> Thanks.  A simple testcase would still be nice, of course.
> >> 
> >> 
> > Sure, but it seems the issue is that I cannot get the __nm_ prefix when
> > I elaborate on a minimal problem like you did.
> > 
> > I'll still try to get something this afternoon.
> I think I got something:
> $ cat > lib.c <<EOF
> #include <stdio.h>
> 
> int
> foo (int a)
> {
>   printf ("a = %d\n", a);
>   return a;
> }
> EOF
> $cat > asm.as <<EOF
> global nothing
> ;export nothing
> nothing:
>   ret
>   end
> EOF
> $ cat > app.c <<EOF
> #include <stdio.h>
> 
> extern int foo (int);
> 
> int
> main ()
> {
>   int x = foo (42);
>   printf ("x = %d\n", x);
>   nothing();
>   return 0;
> }
> EOF
> $ gcc -g -c lib.c -o lib.o
> $ yasm -fx64 asm.as -o asm.o
> $ gcc -shared lib.o ams.o -Wl,--out-implib=lib.dll.a -Wl,--export-all-
> symbols -o lib.dll
> $ gcc -g -o app app.c -L. -llib
> $ ./app
> ...
> <segfault>
> 
> Without the export directive (commented above) I get __nm_ prefix and 
> wrong callq instruction.
> With it, the __nm_prefix disappears and the trampoline correctly used.

I think you must define the export (gas: .def) pseudo op when creating
your own assembler code exporting a symbol from a DLL.  If you look
into the code created by gcc from lib.c:

$ gcc -S lib.c
$ cat lib.s
        .file   "lib.c"
        .section .rdata,"dr"
.LC0:
        .ascii "a = %d\12\0"
        .text
        .globl  foo
        .def    foo;    .scl    2;      .type   32;     .endef
        .seh_proc       foo
foo:
        pushq   %rbp
        .seh_pushreg    %rbp
        movq    %rsp, %rbp
        .seh_setframe   %rbp, 0
        subq    $32, %rsp
        .seh_stackalloc 32
        .seh_endprologue
        movl    %ecx, 16(%rbp)
        movl    16(%rbp), %edx
        leaq    .LC0(%rip), %rcx
        call    printf
        movl    16(%rbp), %eax
        addq    $32, %rsp
        popq    %rbp
        ret
        .seh_endproc
        .ident  "GCC: (GNU) 4.8.2"
        .def    printf; .scl    2;      .type   32;     .endef

At this point gcc doesn't know that foo will get exported from a DLL,
but it generates the .def directive nevertheless.  If I create the
same code in gas:

	.text
	.globl nothing
	.def   nothing; .scl 2; .type 32; .endef
nothing:
	ret

then it works, but crashes if I omit the .def directive.  So it seems
to me you don't have to export the symbol using the dllimport/dllexport
directives, but you have to specify the symbol explicitely for export.


Corinna
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://cygwin.com/pipermail/cygwin/attachments/20140407/8baf5199/attachment.sig>


More information about the Cygwin mailing list