$ cat const_data.c
int main() { printf("%d\n", *(int*) 0); }
$ objdump -dr const_data.o 0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 81 ec 00 00 00 00 sub $0x0,%rsp
b: 8b 05 fc ff ff ff mov -0x4(%rip),%eax
^^^^^^^^^^^ Not reloc'd
11: 48 89 c6 mov %rax,%rsi 14: 48 8d 05 00 00 00 00 lea 0x0(%rip),%rax
17: R_X86_64_PC32 L.0-0x4
1b: 48 89 c7 mov %rax,%rdi
1e: b8 00 00 00 00 mov $0x0,%eax
23: e8 00 00 00 00 callq 28 <main+0x28>
24: R_X86_64_PLT32 printf-0x4
28: c9 leaveq
29: c3 retq
This should SEGV but prints -4 instead since the ref is pc-relative.
A simple fix is to change gen_addrpc32() to add a dummy relocation,
but I believe it should be fixed in gen_modrm_impl().
There's a similar bug when compiling calls to functions at absolute
addresses. The code works as expected when compiling to memory but
tcc refuses to load .o file with ABS relocation.
$ cat const_code.c
int main() { ((void(*)()) 0x7ffe02f8)(); }
$ objdump -dr const_code.o
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 48 81 ec 00 00 00 00 sub $0x0,%rsp
b: b8 00 00 00 00 mov $0x0,%eax
10: e8 00 00 00 00 callq 15 <main+0x15>
11: R_X86_64_PC32 *ABS*+0x7ffe02f4
15: c9 leaveq
16: c3 retq
$ tcc t.o
t.o: error: Invalid relocation entry [ 6] '.rela.text' @ 00000011