3

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.

user45698746
  • 305
  • 2
  • 13
  • Change to `lea dune_syscall_handler(%rip), %rax` to make it PIC. – Jester Nov 23 '20 at 02:50
  • @Jester. thank you for the reply. I change the line to `lea dune_syscall_handler(%rip), %rax`. It still shows the same relocation error. But the next line after the relocation error shows `ld: final link failed: Bad value`. Previously this error was `dune.o: error adding symbols: Bad value` – user45698746 Nov 23 '20 at 03:15
  • @MichaelPetch Thanks for the reply. No. I just double-checked. I'm compiling with `gcc -fPIC -c -o dune.o dune.S` – user45698746 Nov 23 '20 at 04:36
  • 6
    What if you use `movabsq $dune_syscall_handler, %rax` – Michael Petch Nov 23 '20 at 04:37
  • @MichaelPetch It compiled. Thank you very much. You are a lifesaver. – user45698746 Nov 23 '20 at 04:43
  • @MichaelPetch, if it's not too much to ask, Can you please briefly explain what was that error about? – user45698746 Nov 23 '20 at 05:09
  • 2
    The error `relocation R_X86_64_32S against 'dune_syscall_handler' can not be used when making a shared object;` suggests that a 32-bit signed number isn't enough to reference `dune_syscall_handler` in a PIC way. The `movabsq` is a way to move the 64-bit address of `dune_syscall_handler` to a register. In PIC code that 64-bit address will be fixed up (relocated) when the program is loaded by a dynamic loader. – Michael Petch Nov 23 '20 at 13:00
  • @MichaelPetch perfect. Thank you. – user45698746 Nov 23 '20 at 17:57
  • @user45698746 Changing `lea dune_syscall_handler, %rax` to use `movabs` allows libdune to compile using -fPIC, but it looks like the dune sandbox app goes into an infinite loop. I wonder whether you got this to work for the sandbox app, if so how? – Ismail Badawi Jul 22 '22 at 17:56

0 Answers0