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@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@pve-freebsd-dev ~/P/cpp> clang -c test.cpp -o test.o
blast@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@pve-freebsd-dev ~/P/cpp> clang -fPIC -c test.cpp -o test.o
blast@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@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@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@linux-dev ~/p/cpp> clang -c test.cpp -o test.o
blast@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@linux-dev ~/p/cpp> clang -fno-pic -c test.cpp -o test.o
blast@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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits