What is my linker doing?? (x86_64)
Posted: Tue Jun 30, 2015 6:47 am
I thought I'd ask this on those forums, as everyone here has a very detailed grasp of this low-level stuff.
I was writing a compiler for a custom high-level object-oriented language, which produces GNU assembler code, then after assembling, links it with a runtime library written in C, using 'gcc'.
It's all going well, but there is literally one function that would never link. HelloWorld.main() calls System.exit(), which then calls Posix.exit(), and Posix.exit() is written in C. Here's the assembly code for the relevant signature of System.exit():
This code is in a library called "libelecstd.so" (hence the "@PLT"). Posix.exit() is written in C:
Which, in assembly generated by GCC, is:
It all looks good (I understand there is no prologue because exit() never returns), but the program simply crashes. The symbol _Elec_Static_4elec2rt6Posix_4exit_3int in the "callq" instruction resolves the "_Elec_TypeDef_4elec2rt9Exception+48" for some reason, and then once flow jumps to that symbol, the next instruction is a call to some random address without a symbol, and when flow jumps to there, that area is filled with zeroes (which disassembly to some "add" instruction repeatedly).
Does anyone see any reason why this might be happening??
I was writing a compiler for a custom high-level object-oriented language, which produces GNU assembler code, then after assembling, links it with a runtime library written in C, using 'gcc'.
It's all going well, but there is literally one function that would never link. HelloWorld.main() calls System.exit(), which then calls Posix.exit(), and Posix.exit() is written in C. Here's the assembly code for the relevant signature of System.exit():
Code: Select all
.globl _Elec_Static_4elec2rt6System_4exit_3int
_Elec_Static_4elec2rt6System_4exit_3int:
pushq %rbp
movq %rsp, %rbp
subq $48, %rsp
xor %rax, %rax
movq %rax, -48(%rbp)
movq %rax, -40(%rbp)
movq %rax, -32(%rbp)
movq %rbx, -8(%rbp)
movq %r15, -16(%rbp)
movq %r14, -24(%rbp)
movq %r13, -32(%rbp)
movq %r12, -40(%rbp)
movq %rdi, -48(%rbp)
movq -48(%rbp), %rax
pushq %rax
popq %rdi
call _Elec_Static_4elec2rt5Posix_4exit_3int@PLT
addq $0, %rsp
xor %rax, %rax
S_6:
movq %rbp, %rdi
call S_7
movq -16(%rbp), %r15
movq -24(%rbp), %r14
movq -32(%rbp), %r13
movq -40(%rbp), %r12
movq -8(%rbp), %rbx
addq $48, %rsp
popq %rbp
ret
S_7:
// cleanup function
ret
S_8:
.size _Elec_Static_4elec2rt6System_4exit_3int, .-_Elec_Static_4elec2rt6System_4exit_3int
Code: Select all
_ELEC_ABI void _Elec_Static_4elec2rt5Posix_4exit_3int(_Elec_int status)
{
exit((int)status);
};
Code: Select all
.globl _Elec_Static_4elec2rt5Posix_4exit_3int
.type _Elec_Static_4elec2rt5Posix_4exit_3int, @function
_Elec_Static_4elec2rt5Posix_4exit_3int:
.LFB5:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movl %eax, %edi
call exit@PLT
.cfi_endproc
.LFE5:
.size _Elec_Static_4elec2rt5Posix_4exit_3int, .-_Elec_Static_4elec2rt5Posix_4exit_3int
Does anyone see any reason why this might be happening??