Unable to printf floating point numbers from executable shared library

后端 未结 1 444
花落未央
花落未央 2021-02-08 12:06

I\'m developing a shared library which can be executed independently to print it\'s own version number.

I\'ve defined a custom entry point as:

const char         


        
1条回答
  •  北恋
    北恋 (楼主)
    2021-02-08 12:29

    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.

    0 讨论(0)
提交回复
热议问题