[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 4 22:35:01 PDT 2026
aokblast wrote:
Hi, thanks for your reply.
My experiment from yesterday was correct: GOT entries are only emitted for relocatable objects when compiling with `-fPIC`. I also discovered that Linux enables PIC by default (I believe this is related to supporting full ASLR), while FreeBSD does not.
There are some experiment outputs from both FreeBSD and Linux below. The problematic symbol is `_ZTIPKc`, which may be `mmap`'d outside the 2GB range from the JIT'd code:
```text
Relocation section '.rela.gcc_except_table' at offset 0x4e0 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 000000080000000a R_X86_64_32 0000000000000000 _ZTIPKc + 0
```
On FreeBSD, compiling without `-fPIC` emits an `R_X86_64_32` relocation directly against `_ZTIPKc`. Compiling with `-fPIC` instead routes the reference through the GOT (`R_X86_64_REX_GOTPCRELX`) and stores the typeinfo pointer in `.data`, avoiding the problematic 32-bit relocation.
```
blast at pve-freebsd-dev ~/P/cpp> cat test.cpp
#include <stdio.h>
#include <typeinfo>
int f() { throw "Simple exception"; return 0; }
int checkException() { try { printf("Running f()\n"); f(); } catch (const char *e) { printf("%s\n", e); } return 0; }
blast at pve-freebsd-dev ~/P/cpp> clang -c test.cpp -o test.o
blast at pve-freebsd-dev ~/P/cpp> llvm-readelf --relocs test.o
Relocation section '.rela.text' at offset 0x3a8 contains 13 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
000000000000000a 0000000700000004 R_X86_64_PLT32 0000000000000000 __cxa_allocate_exception - 4
0000000000000013 0000000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 0
0000000000000020 0000000800000001 R_X86_64_64 0000000000000000 _ZTIPKc + 0
000000000000002d 0000000900000004 R_X86_64_PLT32 0000000000000000 __cxa_throw - 4
0000000000000049 000000050000000a R_X86_64_32 0000000000000000 .rodata.str1.1 + 11
0000000000000050 0000000b00000004 R_X86_64_PLT32 0000000000000000 printf - 4
0000000000000057 0000000600000004 R_X86_64_PLT32 0000000000000000 _Z1fv - 4
000000000000007c 0000000c00000004 R_X86_64_PLT32 0000000000000000 __cxa_begin_catch - 4
0000000000000089 000000050000000a R_X86_64_32 0000000000000000 .rodata.str1.1 + 1e
0000000000000090 0000000b00000004 R_X86_64_PLT32 0000000000000000 printf - 4
0000000000000097 0000000d00000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000b0 0000000d00000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000b9 0000000e00000004 R_X86_64_PLT32 0000000000000000 _Unwind_Resume - 4
Relocation section '.rela.gcc_except_table' at offset 0x4e0 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 000000080000000a R_X86_64_32 0000000000000000 _ZTIPKc + 0
Relocation section '.rela.eh_frame' at offset 0x4f8 contains 4 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0
0000000000000047 0000000f0000000a R_X86_64_32 0000000000000000 __gxx_personality_v0 + 0
000000000000005c 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 40
0000000000000065 000000030000000a R_X86_64_32 0000000000000000 .gcc_except_table + 0
blast at pve-freebsd-dev ~/P/cpp> clang -fPIC -c test.cpp -o test.o
blast at pve-freebsd-dev ~/P/cpp> llvm-readelf --relocs test.o
Relocation section '.rela.text' at offset 0x420 contains 13 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
000000000000000a 0000000a00000004 R_X86_64_PLT32 0000000000000000 __cxa_allocate_exception - 4
0000000000000014 0000000300000002 R_X86_64_PC32 0000000000000000 .L.str - 4
000000000000001e 0000000b0000002a R_X86_64_REX_GOTPCRELX 0000000000000000 _ZTIPKc - 4
0000000000000027 0000000c00000004 R_X86_64_PLT32 0000000000000000 __cxa_throw - 4
000000000000003b 0000000400000002 R_X86_64_PC32 0000000000000011 .L.str.1 - 4
0000000000000042 0000000e00000004 R_X86_64_PLT32 0000000000000000 printf - 4
0000000000000049 0000000900000004 R_X86_64_PLT32 0000000000000000 _Z1fv - 4
000000000000006e 0000000f00000004 R_X86_64_PLT32 0000000000000000 __cxa_begin_catch - 4
000000000000007d 0000000500000002 R_X86_64_PC32 000000000000001e .L.str.2 - 4
0000000000000084 0000000e00000004 R_X86_64_PLT32 0000000000000000 printf - 4
000000000000008b 0000001000000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000a4 0000001000000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000ad 0000001100000004 R_X86_64_PLT32 0000000000000000 _Unwind_Resume - 4
Relocation section '.rela.gcc_except_table' at offset 0x558 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 0000000800000002 R_X86_64_PC32 0000000000000000 .data + 0
Relocation section '.rela.data' at offset 0x570 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000b00000001 R_X86_64_64 0000000000000000 _ZTIPKc + 0
Relocation section '.rela.data.DW.ref.__gxx_personality_v0' at offset 0x588 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000001300000001 R_X86_64_64 0000000000000000 __gxx_personality_v0 + 0
Relocation section '.rela.eh_frame' at offset 0x5a0 contains 4 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0
0000000000000047 0000001200000002 R_X86_64_PC32 0000000000000000 DW.ref.__gxx_personality_v0 + 0
000000000000005c 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 30
0000000000000065 0000000600000002 R_X86_64_PC32 0000000000000000 .gcc_except_table + 0
blast at pve-freebsd-dev ~/P/cpp>
```
Linux shows the same behavior. By default, Clang emits GOT-based accesses because PIC is enabled, but compiling with `-fno-pic` produces the same `R_X86_64_32` relocation as FreeBSD:
```text
Relocation section '.rela.gcc_except_table' at offset 0x4b0 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 000000080000000a R_X86_64_32 0000000000000000 _ZTIPKc + 0
```
```
blast at linux-dev ~/p/cpp> cat test.cpp
extern "C" int printf(const char *, ...);
int f() { throw "Simple exception"; return 0; }
int checkException() { try { printf("Running f()\n"); f(); } catch (const char *e) { printf("%s\n", e); } return 0; }
blast at linux-dev ~/p/cpp> clang -c test.cpp -o test.o
blast at linux-dev ~/p/cpp> llvm-readelf --relocs ./test.o
Relocation section '.rela.text' at offset 0x3f0 contains 13 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
000000000000000a 0000000a00000004 R_X86_64_PLT32 0000000000000000 __cxa_allocate_exception - 4
0000000000000014 0000000300000002 R_X86_64_PC32 0000000000000000 .L.str - 4
000000000000001e 0000000b0000002a R_X86_64_REX_GOTPCRELX 0000000000000000 _ZTIPKc - 4
0000000000000027 0000000c00000004 R_X86_64_PLT32 0000000000000000 __cxa_throw - 4
000000000000003b 0000000400000002 R_X86_64_PC32 0000000000000011 .L.str.1 - 4
0000000000000042 0000000e00000004 R_X86_64_PLT32 0000000000000000 printf - 4
000000000000004c 0000000900000004 R_X86_64_PLT32 0000000000000000 _Z1fv - 4
000000000000007b 0000000f00000004 R_X86_64_PLT32 0000000000000000 __cxa_begin_catch - 4
000000000000008a 0000000500000002 R_X86_64_PC32 000000000000001e .L.str.2 - 4
0000000000000091 0000000e00000004 R_X86_64_PLT32 0000000000000000 printf - 4
000000000000009b 0000001000000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000b4 0000001000000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000bd 0000001100000004 R_X86_64_PLT32 0000000000000000 _Unwind_Resume - 4
Relocation section '.rela.gcc_except_table' at offset 0x528 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 0000000800000002 R_X86_64_PC32 0000000000000000 .data + 0
Relocation section '.rela.data' at offset 0x540 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000000b00000001 R_X86_64_64 0000000000000000 _ZTIPKc + 0
Relocation section '.rela.data.DW.ref.__gxx_personality_v0' at offset 0x558 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000000 0000001300000001 R_X86_64_64 0000000000000000 __gxx_personality_v0 + 0
Relocation section '.rela.eh_frame' at offset 0x570 contains 4 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0
0000000000000047 0000001200000002 R_X86_64_PC32 0000000000000000 DW.ref.__gxx_personality_v0 + 0
000000000000005c 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 30
0000000000000065 0000000600000002 R_X86_64_PC32 0000000000000000 .gcc_except_table + 0
blast at linux-dev ~/p/cpp> clang -fno-pic -c test.cpp -o test.o
blast at linux-dev ~/p/cpp> llvm-readelf --relocs ./test.o
Relocation section '.rela.text' at offset 0x378 contains 13 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
000000000000000a 0000000700000004 R_X86_64_PLT32 0000000000000000 __cxa_allocate_exception - 4
0000000000000013 0000000500000001 R_X86_64_64 0000000000000000 .rodata.str1.1 + 0
0000000000000020 0000000800000001 R_X86_64_64 0000000000000000 _ZTIPKc + 0
000000000000002d 0000000900000004 R_X86_64_PLT32 0000000000000000 __cxa_throw - 4
0000000000000049 000000050000000a R_X86_64_32 0000000000000000 .rodata.str1.1 + 11
0000000000000050 0000000b00000004 R_X86_64_PLT32 0000000000000000 printf - 4
000000000000005a 0000000600000004 R_X86_64_PLT32 0000000000000000 _Z1fv - 4
0000000000000089 0000000c00000004 R_X86_64_PLT32 0000000000000000 __cxa_begin_catch - 4
0000000000000096 000000050000000a R_X86_64_32 0000000000000000 .rodata.str1.1 + 1e
000000000000009d 0000000b00000004 R_X86_64_PLT32 0000000000000000 printf - 4
00000000000000a7 0000000d00000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000c0 0000000d00000004 R_X86_64_PLT32 0000000000000000 __cxa_end_catch - 4
00000000000000c9 0000000e00000004 R_X86_64_PLT32 0000000000000000 _Unwind_Resume - 4
Relocation section '.rela.gcc_except_table' at offset 0x4b0 contains 1 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000018 000000080000000a R_X86_64_32 0000000000000000 _ZTIPKc + 0
Relocation section '.rela.eh_frame' at offset 0x4c8 contains 4 entries:
Offset Info Type Symbol's Value Symbol's Name + Addend
0000000000000020 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 0
0000000000000047 0000000f0000000a R_X86_64_32 0000000000000000 __gxx_personality_v0 + 0
000000000000005c 0000000200000002 R_X86_64_PC32 0000000000000000 .text + 40
0000000000000065 000000030000000a R_X86_64_32 0000000000000000 .gcc_except_table + 0
```
This suggests that Linux should encounter the same failure if `_ZTIPKc` ends up more than 2GB away from the generated code. Unfortunately, I do not currently have access to a machine powerful enough to build LLVM and verify the testcase.
I also do not think we can simply force PIC mode in clang-repl. clang-repl can consume PCH files, and those PCHs may have been generated with a different PIC level than the REPL session. Enforcing PIC unconditionally in the REPL could therefore introduce compatibility issues between the PCH and the generated code.
https://github.com/llvm/llvm-project/pull/201286
More information about the cfe-commits
mailing list