[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/aokblast edited https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/aokblast auto_merge_disabled https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
lhames wrote: > @lhames Hi, since you are largely engaging in ORC and clang-repl stuff. I > still want you to take a look whether you have any concern on this? Hi @aokblast. I’m travelling at the moment, but can take a look when I get back on Tuesday. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
MaskRay wrote: Drive-by: the PR description no longer matches the implementation. The PICLevelReader stuff looks strange, but I don't have time to take a closer look. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote: @lhames Hi, since you are largely engaging in ORC and clang-repl stuff. I still want you to take a look whether you have any concern on this? https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
@@ -135,6 +154,32 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
+
+ // clang-repl always compiles position-independent code (it injects -fPIC),
+ // so a PCH that was built with a different PIC level is incompatible: mixing
+ // the two leads to relocations that may be out of range once the JIT maps
+ // code more than 2GB away. PICLevel is a "compatible" language option, so
the
+ // ASTReader would otherwise accept the mismatch silently. Reject it up front
+ // here, before any Interpreter/FrontendAction is constructed.
+ StringRef PCHInclude = Clang->getPreprocessorOpts().ImplicitPCHInclude;
+ if (!PCHInclude.empty()) {
aokblast wrote:
Fix it
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/vgvassilev edited https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/vgvassilev commented: This looks to be heading in a really good direction. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
@@ -135,6 +154,32 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
+
+ // clang-repl always compiles position-independent code (it injects -fPIC),
+ // so a PCH that was built with a different PIC level is incompatible: mixing
+ // the two leads to relocations that may be out of range once the JIT maps
+ // code more than 2GB away. PICLevel is a "compatible" language option, so
the
+ // ASTReader would otherwise accept the mismatch silently. Reject it up front
+ // here, before any Interpreter/FrontendAction is constructed.
+ StringRef PCHInclude = Clang->getPreprocessorOpts().ImplicitPCHInclude;
+ if (!PCHInclude.empty()) {
vgvassilev wrote:
Can we make this condition also work for pcm (C++/Clang modules)? The rest of
the code should be largely the same.
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote: @lhames I add a PIC level checker. It should report error now instead of having a assertion failure. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/aokblast updated
https://github.com/llvm/llvm-project/pull/201286
>From e8b89d39d83b6bcb2894bc2a090b22f7addae659 Mon Sep 17 00:00:00 2001
From: aokblast
Date: Wed, 3 Jun 2026 21:48:20 +0800
Subject: [PATCH 1/4] [Clang][Interpreter] Force GOT access for external data
references
In clang-repl, R_*_32 relocations are emitted as direct 32-bit
PC-relative references. A normal static linker can resolve references to
distinct symbol through the GOT or Copy relocation, but clang-repl
directly mmaps shared objects into memory and bypasses the static
linker.
As a result, relocations may become out of range when a symbol is
located more than 2GB away from the JIT allocation, which can happen on
FreeBSD.
Disable DirectAccessExtraData to force external data accesses through
the GOT, avoiding the generation of direct 32-bit relocations that are
subject to the 2GB addressing limit.
---
clang/lib/Interpreter/Interpreter.cpp | 11 +++
1 file changed, 11 insertions(+)
diff --git a/clang/lib/Interpreter/Interpreter.cpp
b/clang/lib/Interpreter/Interpreter.cpp
index 7586c26235449..70cea2819fb5f 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -133,6 +133,17 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
+ // Clang emits direct PC-relative accesses for external data (e.g. C++
+ // type-info used by exception handling). As clang-repl directly mmap()s
+ // shared objects into memory, the target symbol may be more than 2GB away
+ // from the generated code, resulting in an out-of-range Delta32/PC32
+ // relocation. Force GOT-based access instead so the relocation remains
+ // within range.
+ //
+ // Unlike -fPIC, this does not define __PIC__ and remains compatible with
+ // precompiled headers.
+ Clang->getCodeGenOpts().DirectAccessExternalData = false;
+
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
return std::move(Clang);
>From 53616b351dbdd4c83603f633edad4f4c9344e4bf Mon Sep 17 00:00:00 2001
From: aokblast
Date: Tue, 9 Jun 2026 21:38:20 +0800
Subject: [PATCH 2/4] fixup! [Clang][Interpreter] Force GOT access for external
data references
---
clang/lib/Interpreter/Interpreter.cpp | 22 +++---
clang/test/Interpreter/execute-pch.cpp | 2 +-
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/lib/Interpreter/Interpreter.cpp
b/clang/lib/Interpreter/Interpreter.cpp
index 70cea2819fb5f..34da251b033da 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -133,17 +133,6 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
- // Clang emits direct PC-relative accesses for external data (e.g. C++
- // type-info used by exception handling). As clang-repl directly mmap()s
- // shared objects into memory, the target symbol may be more than 2GB away
- // from the generated code, resulting in an out-of-range Delta32/PC32
- // relocation. Force GOT-based access instead so the relocation remains
- // within range.
- //
- // Unlike -fPIC, this does not define __PIC__ and remains compatible with
- // precompiled headers.
- Clang->getCodeGenOpts().DirectAccessExternalData = false;
-
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
return std::move(Clang);
@@ -164,6 +153,17 @@ IncrementalCompilerBuilder::create(std::string TT,
ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
+ // Compile as position-independent code. This prevents the frontend from
+ // marking external symbols (e.g. C++ type-info such as _ZTIPKc used for
+ // exception handling) as dso_local and emitting direct PC-relative
+ // references. JITLink can place the GOT entry near the JIT'd code, keeping
+ // the relocation in range. Without -fPIC, a direct Delta32 relocation to a
+ // host symbol may be out of range when the JIT memory is mapped more than
+ // 2GB away (as on FreeBSD), breaking tests such as
+ // Interpreter/simple-exception.cpp. Insert before user arguments so it can
+ // still be overridden.
+ ClangArgv.insert(ClangArgv.begin() + 1, "-fPIC");
+
// Prepending -c to force the driver to do something if no action was
// specified. By prepending we allow users to override the default
// action and use other actions in incremental mode.
diff --git a/clang/test/Interpreter/execute-pch.cpp
b/clang/test/Interpreter/execute-pch.cpp
index 8041ee6ac966d..2247cf5583095 100644
--- a/clang/test/Interpreter/execute-pch.cpp
+++ b/clang/test/Interpreter/execute-pch.cpp
@@ -5,7 +5,7 @@
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
-// RUN: %clang -fmax-type-align=16 -Xclang -fdeprecated-macro
-fno-stack-protector -Xclang -fwrapv -Xclang -fblocks -Xclang
-
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote: Hmm, it is really strange that fPIC in clang-repl doesn't break Windows. It seems that clang-repl does not go through the stand argument parsing subroutines in CommonArgs. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
vgvassilev wrote: > @vgvassilev -- Does clang-repl ever consume PCHs in a context where it > couldn't just regenerate them from source with the correct code & relocation > model? It does. But there we can do the opposite -- we can look how to pch was built and start clang-repl with these flags. This is what cling does. cc: @jeaye https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote: > Ahh -- I should have guessed that this would be non-PIC. :) > > If the memory manager can guarantee that code is allocated in the low 4Gb > this should be ok, but in general we can't guarantee that, and clang-repl > probably shouldn't try to support it. > > I think it's reasonable to require PIC for JIT'd code under clang-repl (and > for that to be the default in ORC). Clang should be able to detect when a PCH > assumes an incompatible relocation model and reject the PCH. Thanks for your reply! I think it is ok to enforce PIC by default in clang-repl. However, I need some time to figure out where I can report the error. Currently, it causes an assertion failure in Clang Sema. Here is a version that enables PIC by default. Let's see if the CI passes first. > > @vgvassilev -- Does clang-repl ever consume PCHs in a context where it > couldn't just regenerate them from source with the correct code & relocation > model? https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/aokblast updated
https://github.com/llvm/llvm-project/pull/201286
>From e8b89d39d83b6bcb2894bc2a090b22f7addae659 Mon Sep 17 00:00:00 2001
From: aokblast
Date: Wed, 3 Jun 2026 21:48:20 +0800
Subject: [PATCH 1/2] [Clang][Interpreter] Force GOT access for external data
references
In clang-repl, R_*_32 relocations are emitted as direct 32-bit
PC-relative references. A normal static linker can resolve references to
distinct symbol through the GOT or Copy relocation, but clang-repl
directly mmaps shared objects into memory and bypasses the static
linker.
As a result, relocations may become out of range when a symbol is
located more than 2GB away from the JIT allocation, which can happen on
FreeBSD.
Disable DirectAccessExtraData to force external data accesses through
the GOT, avoiding the generation of direct 32-bit relocations that are
subject to the 2GB addressing limit.
---
clang/lib/Interpreter/Interpreter.cpp | 11 +++
1 file changed, 11 insertions(+)
diff --git a/clang/lib/Interpreter/Interpreter.cpp
b/clang/lib/Interpreter/Interpreter.cpp
index 7586c26235449..70cea2819fb5f 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -133,6 +133,17 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
+ // Clang emits direct PC-relative accesses for external data (e.g. C++
+ // type-info used by exception handling). As clang-repl directly mmap()s
+ // shared objects into memory, the target symbol may be more than 2GB away
+ // from the generated code, resulting in an out-of-range Delta32/PC32
+ // relocation. Force GOT-based access instead so the relocation remains
+ // within range.
+ //
+ // Unlike -fPIC, this does not define __PIC__ and remains compatible with
+ // precompiled headers.
+ Clang->getCodeGenOpts().DirectAccessExternalData = false;
+
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
return std::move(Clang);
>From 53616b351dbdd4c83603f633edad4f4c9344e4bf Mon Sep 17 00:00:00 2001
From: aokblast
Date: Tue, 9 Jun 2026 21:38:20 +0800
Subject: [PATCH 2/2] fixup! [Clang][Interpreter] Force GOT access for external
data references
---
clang/lib/Interpreter/Interpreter.cpp | 22 +++---
clang/test/Interpreter/execute-pch.cpp | 2 +-
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/lib/Interpreter/Interpreter.cpp
b/clang/lib/Interpreter/Interpreter.cpp
index 70cea2819fb5f..34da251b033da 100644
--- a/clang/lib/Interpreter/Interpreter.cpp
+++ b/clang/lib/Interpreter/Interpreter.cpp
@@ -133,17 +133,6 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
- // Clang emits direct PC-relative accesses for external data (e.g. C++
- // type-info used by exception handling). As clang-repl directly mmap()s
- // shared objects into memory, the target symbol may be more than 2GB away
- // from the generated code, resulting in an out-of-range Delta32/PC32
- // relocation. Force GOT-based access instead so the relocation remains
- // within range.
- //
- // Unlike -fPIC, this does not define __PIC__ and remains compatible with
- // precompiled headers.
- Clang->getCodeGenOpts().DirectAccessExternalData = false;
-
Clang->getFrontendOpts().DisableFree = false;
Clang->getCodeGenOpts().DisableFree = false;
return std::move(Clang);
@@ -164,6 +153,17 @@ IncrementalCompilerBuilder::create(std::string TT,
ClangArgv.insert(ClangArgv.begin(), MainExecutableName.c_str());
+ // Compile as position-independent code. This prevents the frontend from
+ // marking external symbols (e.g. C++ type-info such as _ZTIPKc used for
+ // exception handling) as dso_local and emitting direct PC-relative
+ // references. JITLink can place the GOT entry near the JIT'd code, keeping
+ // the relocation in range. Without -fPIC, a direct Delta32 relocation to a
+ // host symbol may be out of range when the JIT memory is mapped more than
+ // 2GB away (as on FreeBSD), breaking tests such as
+ // Interpreter/simple-exception.cpp. Insert before user arguments so it can
+ // still be overridden.
+ ClangArgv.insert(ClangArgv.begin() + 1, "-fPIC");
+
// Prepending -c to force the driver to do something if no action was
// specified. By prepending we allow users to override the default
// action and use other actions in incremental mode.
diff --git a/clang/test/Interpreter/execute-pch.cpp
b/clang/test/Interpreter/execute-pch.cpp
index 8041ee6ac966d..2247cf5583095 100644
--- a/clang/test/Interpreter/execute-pch.cpp
+++ b/clang/test/Interpreter/execute-pch.cpp
@@ -5,7 +5,7 @@
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
-// RUN: %clang -fmax-type-align=16 -Xclang -fdeprecated-macro
-fno-stack-protector -Xclang -fwrapv -Xclang -fblocks -Xclang
-
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
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
0018 0008000a R_X86_64_32
_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
#include
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
000a 00070004 R_X86_64_PLT32
__cxa_allocate_exception - 4
0013 00050001 R_X86_64_64
.rodata.str1.1 + 0
0020 00080001 R_X86_64_64
_ZTIPKc + 0
002d 00090004 R_X86_64_PLT32
__cxa_throw - 4
0049 0005000a R_X86_64_32
.rodata.str1.1 + 11
0050 000b0004 R_X86_64_PLT32
printf - 4
0057 00060004 R_X86_64_PLT32
_Z1fv - 4
007c 000c0004 R_X86_64_PLT32
__cxa_begin_catch - 4
0089 0005000a R_X86_64_32
.rodata.str1.1 + 1e
0090 000b0004 R_X86_64_PLT32
printf - 4
0097 000d0004 R_X86_64_PLT32
__cxa_end_catch - 4
00b0 000d0004 R_X86_64_PLT32
__cxa_end_catch - 4
00b9 000e0004 R_X86_64_PLT32
_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
0018 0008000a R_X86_64_32
_ZTIPKc + 0
Relocation section '.rela.eh_frame' at offset 0x4f8 contains 4 entries:
Offset Info Type Symbol's Value
Symbol's Name + Addend
0020 00020002 R_X86_64_PC32
.text + 0
0047 000f000a R_X86_64_32
__gxx_personality_v0 + 0
005c 00020002 R_X86_64_PC32
.text + 40
0065 0003000a R_X86_64_32
.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
000a 000a0004 R_X86_64_PLT32
__cxa_allocate_exception - 4
0014 00030002 R_X86_64_PC32
.L.str - 4
001e 000b002a R_X86_64_REX_GOTPCRELX
_ZTIPKc - 4
0027 000c0004 R_X86_64_PLT32
__cxa_throw - 4
003b 00040002 R_X86_64_PC32 0011
.L.str.1 - 4
0042 000e0004 R_X86_64_PLT32
printf - 4
0049 00090004 R_X86_64_PLT32
_Z1fv - 4
006e 000f0004 R_X86_64_PLT32
__cxa_begin_catch - 4
007d 00050002 R_X86_64_PC32 001e
.L.str.2 - 4
0084 000e0004 R_X86_64_PLT32
printf - 4
008b 0014 R_X86_64_PLT32
__cxa_end_catch - 4
00a4 0014 R_X86_64_PLT32
__cxa_end_catch - 4
0
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote: > ``` > // Clang emits direct PC-relative accesses for external data (e.g. C++ > // type-info used by exception handling). As clang-repl directly mmap()s > // shared objects into memory, the target symbol may be more than 2GB away > // from the generated code, resulting in an out-of-range Delta32/PC32 > // relocation. Force GOT-based access instead so the relocation remains > // within range. > ``` > > We need to dig into how these accesses are getting generated. Provided that > we configure the memory manager correctly the JIT should be able to handle > arbitrary objects without requiring any special codegen settings. Sorry, please ignore the previous comment. I falsely use GCC instead of clang. I will write some detail on failure case on FreeBSD later. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aokblast wrote:
> > In clang-repl, R_*_32 relocations are emitted as direct 32-bit PC-relative
> > references. A normal static linker can resolve references to distinct
> > symbol through the GOT or Copy relocation, but clang-repl directly mmaps
> > shared objects into memory and bypasses the static linker.
>
> Can you be more specific about the relocations that you're seeing?
>
> CodeGen usually requests a GOT entry (by selecting one of the GOT relocations
> and producing the necessary instruction sequence), and the linker just builds
> the requested GOT entry.
>
> The usual caveat is hidden symbols:
>
> ```c
> extern int __attribute__((visibility("hidden"))) X;
> int getX() { return X; } // <- will typically emit 32-bit PC-relative
> reference
> ```
>
> The problem in this case is that ClangRepl probably isn't doing slab
> allocation by default, in which case switching to a slab-based allocator is
> the best answer.
GOT is only generated for relocatable code when -fPIC is enabled. This is not
the default in ClangRepl. I previously tried building relocatable objects in
ClangRepl with -fPIC, but encountered a test failure.
The issue is that ClangRepl can consume PCH (precompiled headers) where the
headers are compiled normally (i.e., without -fPIC). This leads to a mismatch
in PIC levels between objects, causing assertion failures.
I can share the failing test case that triggered this patch on FreeBSD.
Here is my experiment:
```
blast@linux-dev ~/p/cpp> cvat ^C
blast@linux-dev ~/p/cpp> cat test.cpp
extern int X;
int getX() { return X; }
blast@linux-dev ~/p/cpp> cc test.cpp -c -o test.o
blast@linux-dev ~/p/cpp> readelf --relocs test.o
Relocation section '.rela.text' at offset 0x168 contains 1 entry:
Offset Info Type Sym. ValueSym. Name + Addend
000a 00040002 R_X86_64_PC32 X - 4
Relocation section '.rela.eh_frame' at offset 0x180 contains 1 entry:
Offset Info Type Sym. ValueSym. Name + Addend
0020 00020002 R_X86_64_PC32 .text + 0
blast@linux-dev ~/p/cpp> cc -fPIC test.cpp -c -o test.o
blast@linux-dev ~/p/cpp> readelf --relocs test.o
Relocation section '.rela.text' at offset 0x1a0 contains 1 entry:
Offset Info Type Sym. ValueSym. Name + Addend
000b 0005002a R_X86_64_REX_GOTP X - 4
Relocation section '.rela.eh_frame' at offset 0x1b8 contains 1 entry:
Offset Info Type Sym. ValueSym. Name + Addend
0020 00020002 R_X86_64_PC32 .text + 0
blast@linux-dev ~/p/cpp> uname -a
Linux linux-dev 6.8.12-13-pve #1 SMP PREEMPT_DYNAMIC PMX 6.8.12-13
(2025-07-22T10:00Z) x86_64 x86_64 x86_64 GNU/Linux
```
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/lhames requested changes to this pull request. ``` // Clang emits direct PC-relative accesses for external data (e.g. C++ // type-info used by exception handling). As clang-repl directly mmap()s // shared objects into memory, the target symbol may be more than 2GB away // from the generated code, resulting in an out-of-range Delta32/PC32 // relocation. Force GOT-based access instead so the relocation remains // within range. ``` We need to dig into how these accesses are getting generated. Provided that we configure the memory manager correctly the JIT should be able to handle arbitrary objects without requiring any special codegen settings. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
lhames wrote:
> In clang-repl, R_*_32 relocations are emitted as direct 32-bit PC-relative
> references. A normal static linker can resolve references to distinct symbol
> through the GOT or Copy relocation, but clang-repl directly mmaps shared
> objects into memory and bypasses the static linker.
Can you be more specific about the relocations that you're seeing?
CodeGen usually requests a GOT entry (by selecting one of the GOT relocations
and producing the necessary instruction sequence), and the linker just builds
the requested GOT entry.
The usual caveat is hidden symbols:
```c
extern int __attribute__((visibility("hidden"))) X;
int getX() { return X; } // <- will typically emit 32-bit PC-relative reference
```
The problem in this case is that ClangRepl probably isn't doing slab allocation
by default, in which case switching to a slab-based allocator is the best
answer.
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
https://github.com/aokblast edited https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
@@ -133,6 +133,17 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
+ // Clang emits direct PC-relative accesses for external data (e.g. C++
+ // type-info used by exception handling). As clang-repl directly mmap()s
+ // shared objects into memory, the target symbol may be more than 2GB away
+ // from the generated code, resulting in an out-of-range Delta32/PC32
+ // relocation. Force GOT-based access instead so the relocation remains
+ // within range.
+ //
+ // Unlike -fPIC, this does not define __PIC__ and remains compatible with
+ // precompiled headers.
+ Clang->getCodeGenOpts().DirectAccessExternalData = false;
vgvassilev wrote:
This sounds reasonable to me. Before moving forward I’d hope @lhames to
comment.
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
@@ -133,6 +133,17 @@ CreateCI(const llvm::opt::ArgStringList &Argv) {
// times, reusing the same AST.
Clang->getCodeGenOpts().ClearASTBeforeBackend = false;
+ // Clang emits direct PC-relative accesses for external data (e.g. C++
+ // type-info used by exception handling). As clang-repl directly mmap()s
+ // shared objects into memory, the target symbol may be more than 2GB away
+ // from the generated code, resulting in an out-of-range Delta32/PC32
+ // relocation. Force GOT-based access instead so the relocation remains
+ // within range.
+ //
+ // Unlike -fPIC, this does not define __PIC__ and remains compatible with
+ // precompiled headers.
+ Clang->getCodeGenOpts().DirectAccessExternalData = false;
aokblast wrote:
My understanding is that it uses the following pattern:
```
mov foo@GOTPCREL(%rip), %rax
mov (%rax), %eax
```
The origianl PC relative is:
```
lea foo(%rip), %rax
```
It definitely introduces some performance difference, but it is the correct way
to handle R_*_32 relocations. In a static linker, simple cases are resolved
directly, while others are handled using R_*_COPY or R_*_GLOB_DAT relocations,
which can target symbols beyond the 2GB range.
https://github.com/llvm/llvm-project/pull/201286
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results * 88178 tests passed * 1637 tests skipped * 1 test failed ## Failed Tests (click on a test name to see its output) ### Clang Clang.Driver/hipspv-toolchain.hip ``` Exit Code: 1 Command Output (stdout): -- # RUN: at line 4 /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -### -target x86_64-linux-gnu --offload=spirv64--no-offload-new-driver --hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv -nohipwrapperinc /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip 2>&1 | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck --check-prefixes=CHECK,OLD-DTRIPLE=spirv64 /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang '-###' -target x86_64-linux-gnu --offload=spirv64 --no-offload-new-driver --hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv -nohipwrapperinc /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # note: command had no output on stdout or stderr # executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck --check-prefixes=CHECK,OLD -DTRIPLE=spirv64 /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # note: command had no output on stdout or stderr # RUN: at line 9 /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -### -target x86_64-linux-gnu--offload=spirv64-unknown-chipstar --offload-new-driver --hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv -nohipwrapperinc /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip 2>&1 | /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck --check-prefixes=CHECK,NEW-DTRIPLE=spirv64-unknown-chipstar -DHIP_PATH=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang '-###' -target x86_64-linux-gnu --offload=spirv64-unknown-chipstar --offload-new-driver --hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv -nohipwrapperinc /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # note: command had no output on stdout or stderr # executed command: /home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/FileCheck --check-prefixes=CHECK,NEW -DTRIPLE=spirv64-unknown-chipstar -DHIP_PATH=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip # .---command stderr # | /home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/hipspv-toolchain.hip:41:14: error: NEW-SAME: expected string not found in input # | // NEW-SAME: "--emit-fatbin-only" "--no-lto" "-o" "[[BUNDLE:.*hipfb]]" # | ^ # | :8:236: note: scanning from here # | "/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-linker-wrapper" "--device-compiler=spirv64-unknown-chipstar=--hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv" "--device-linker=spirv64-unknown-chipstar=--allow-partial-linkage" "--device-linker=spirv64-unknown-chipstar=--create-library" "--no-lto" "--host-triple=x86_64-unknown-linux-gnu" "--linker-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-offload-bundler" "--emit-fatbin-only" "-o" "/tmp/lit-tmp-dq0lwyap/hipspv-toolchain-963cc8.hipfb" "/tmp/lit-tmp-dq0lwyap/hipspv-toolchain-a49572.out" # | ^ # | :8:521: note: possible intended match here # | "/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-linker-wrapper" "--device-compiler=spirv64-unknown-chipstar=--hip-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/clang/test/Driver/Inputs/hipspv" "--device-linker=spirv64-unknown-chipstar=--allow-partial-linkage" "--device-linker=spirv64-unknown-chipstar=--create-library" "--no-lto" "--host-triple=x86_64-unknown-linux-gnu" "--linker-path=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-offload-bundler" "--emit-fatb
[clang] [Clang][Interpreter] Force GOT access for external data references (PR #201286)
aengelke wrote: The JIT mode in TargetMachine is for the legacy MCJIT, which cannot generate PLTs/GOTs. This should eventually be removed. https://github.com/llvm/llvm-project/pull/201286 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
