How to call a C function from assembly file?

Viewed 192

I have the source code of a static library. I'm trying to compile it into a dynamic library. The source code has .c files and one .S file. While compiling I'm getting a relocation error from the assembly code. Going through the assembly code, I find out that this error is generated while calling a function from one of the C files. Assembly code segment is,

.extern dune_syscall_handler // I added it 
__dune_syscall:
testq $1, %gs:IN_USERMODE
jnz 1f
pushq   %r11
popfq
vmcall
jmp *%rcx

1:
/* first switch to the kernel stack */
movq    %rsp, %gs:TMP
movq    %gs:TRAP_STACK, %rsp

/* now push the trap frame onto the stack */
subq    $TF_END, %rsp
movq    %rcx, RIP(%rsp)
movq    %r11, RFLAGS(%rsp)
movq    %r10, RCX(%rsp) /* fixup to standard 64-bit calling ABI */
SAVE_REGS 0, 1
movq    %gs:TMP, %rax
movq    %rax, RSP(%rsp)

SET_G0_FS_BASE

/* re-enable interrupts and jump to the handler */
sti
movq    %rsp, %rdi /* argument 0 */
lea dune_syscall_handler, %rax  <-------------------- Causing error
call    *%rax


SET_G3_FS_BASE

RESTORE_REGS 0, 1
movq    RCX(%rsp), %r10
movq    RFLAGS(%rsp), %r11
movq    RIP(%rsp), %rcx

/* switch to the user stack and return to ring 3 */
movq    RSP(%rsp), %rsp
sysretq

Causing the following error,

ld: dune.o: relocation R_X86_64_32S against `dune_syscall_handler' can not be used when 
making a shared object; recompile with -fPIC
dune.o: error adding symbols: Bad value

dune_syscall_handler is defined in a separate C file. I use -fPIC flag while compiling. readelf shows the following,

$readelf -r dune.o

Relocation section '.rela.text' at offset 0x18c8 contains 2 entries:
Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000219  00120000000b R_X86_64_32S      0000000000000000 dune_syscall_handler + 0

I guess Sym. Value suppose to filledup by linker during runtime? That's why it is empty? Listing symbols from the object shows,

$nm dune.o
0000000000000070 t __dune_retry
00000000000002e5 T dune_jump_to_user
000000000000016c T __dune_syscall
000000000000028e T __dune_syscall_end
                 U dune_syscall_handler
0000000000000100 a I
  

I'm new to assembly. My understanding is while trying to load the effective address of the C function dune_syscall_handler, the linker could not find it. I just can't figure out why. Can someone please tell me how can I call a C function from an assembly file? There is a similar post with a same tile How to call a C function from Assembly code. But I guess my problem is different.

0 Answers
Related