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

Reply via email to