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