Unable to printf floating point numbers from executable shared library

独自空忆成欢 提交于 2019-12-03 06:17:46

Figured it out. :)

The floating point operations on x86_64 use the xmm vector registers. Access to these must be aligned on 16byte boundaries. This explains why 32bit platforms were unaffected and integer and character printing worked.

I've compiled my code to assembly with:

gcc -W list.c -o list.S -shared -Wl,-e,my_main -S -fPIC

then altered the "my_main" function to be have more stack space.

Before:

my_main:
 .LFB6:
 .cfi_startproc
 pushq   %rbp
 .cfi_def_cfa_offset 16
 .cfi_offset 6, -16
 movq    %rsp, %rbp
 .cfi_def_cfa_register 6
 movl    $.LC0, %eax
 movsd   .LC1(%rip), %xmm0
 movq    %rax, %rdi
 movl    $1, %eax
 call    printf
 movl    $0, %edi
 call    _exit
 .cfi_endproc

After:

my_main:
 .LFB6:
 .cfi_startproc
 pushq   %rbp
 .cfi_def_cfa_offset 16
 .cfi_offset 6, -16
 subq    $8, %rsp ;;;;;;;;;;;;;;; ADDED THIS LINE
 movq    %rsp, %rbp
 .cfi_def_cfa_register 6
 movl    $.LC0, %eax
 movsd   .LC1(%rip), %xmm0
 movq    %rax, %rdi
 movl    $1, %eax
 call    printf
 movl    $0, %edi
 call    _exit
 .cfi_endproc

Then I compiled this .S file by:

gcc list.S -o liblist.so -Wl,-e,my_main -shared

This fixes the issue, but I will forward this thread to the GCC and GLIBC mailing lists, as it looks like a bug.

edit1:

According to noshadow in gcc irc, this is a non standard way to do this. He said if one is to use gcc -e option, either initialize the C runtime manually, or don't use libc functions. Makes sense.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!