Не линкуется динамическая библиотека из смеси C и ASM

Ошибка /usr/bin/ld: func.o: relocation R_X86_64_PC32 against symbol 'tab' can not be used when making a shared object; recompile with -fPIC, в любом случае. gcc 9.2.1

func.asm, as:

.global func
.text
func:
lea tab+8(%rip), %rax
mov (%rax), %rax
ret

0000 488D0500 000000    lea tab+8(%rip), %rax
0007 488B00             mov (%rax), %rax
000a C3                 ret

func.asm, nasm:

default rel
extern tab
global func
section .text
func:
lea rax, [tab+8]
mov rax, [rax]
ret

00000000 488D05(08000000)        lea rax, [tab+8]
00000007 488B00                  mov rax, [rax]
0000000A C3                      ret

lib.c:

#include <stdint.h>
uint64_t tab[4] = { 0, 1, 2, 3 };
//uint64_t func();
uint64_t lib()
{
    return -1;//func();
}

exe.c:

#include <stdint.h>
#include <stdio.h>
uint64_t lib();
int main()
{
    printf("%lx\n", lib());
    return 0;
}

as --64 -o func.o func.asm
nasm -f elf64 func.asm
gcc -fPIC -c lib.c
gcc -shared -o lib.so lib.o func.o
gcc exe.c -L. -l:lib.so -o exe

// Исправил ошибки и добавил саму программу, без ассемблерной функции работает.
// Такой код работает, только это неправильно как-то. Должно быть 7 байт rip + offset, или на Linux не получится так?

0000 488B0500 000000    mov tab@GOTPCREL(%rip), %rax
0007 488B4008           mov 8(%rax), %rax
000b C3                 ret

Ответы (1 шт):

Автор решения: J. Doe

func.asm:

default rel
extern tab
global func
section .text
func:
lea rax, [tab+8]
mov rax, [rax]
ret

lib.c:

#include <stdint.h>
__attribute__((visibility("hidden"))) uint64_t tab[4] = { 0, 1, 2, 3 };
uint64_t func();
uint64_t lib()
{
    return func();
}

The precondition when writing 64-bit assembly is that the symbol must be "local" to the library (i.e. not global)

→ Ссылка