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
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.