llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: aokblast

<details>
<summary>Changes</summary>

In clang-repl, R_*_32 relocations are emitted as direct 32-bit PC-relative 
references. A normal static linker can resolve distant symbols through PLT or 
copy relocations, but clang-repl directly mmap shared objects into memory and 
bypasses static linker.

As a result, relocations may become out of range when a symbol is more than 2GB 
away from the JIT allocation, which can happen on FreeBSD.

Use the large code model to avoid generating such relocations. The x86-64 JIT 
Target Machine already defaults to the large code model, but LLJIT overrides an 
unset code model with CodeModel::Small.

---
Full diff: https://github.com/llvm/llvm-project/pull/201286.diff


1 Files Affected:

- (modified) clang/lib/Interpreter/IncrementalExecutor.cpp (+24-5) 


``````````diff
diff --git a/clang/lib/Interpreter/IncrementalExecutor.cpp 
b/clang/lib/Interpreter/IncrementalExecutor.cpp
index 65cb29a2f441a..9ff1bb6bb92b2 100644
--- a/clang/lib/Interpreter/IncrementalExecutor.cpp
+++ b/clang/lib/Interpreter/IncrementalExecutor.cpp
@@ -65,12 +65,31 @@ IncrementalExecutorBuilder::~IncrementalExecutorBuilder() = 
default;
 
 static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
 createJITTargetMachineBuilder(const llvm::Triple &TT) {
-  if (TT.getTriple() == llvm::sys::getProcessTriple())
-    // This fails immediately if the target backend is not registered
-    return llvm::orc::JITTargetMachineBuilder::detectHost();
+  auto JTMB = [&]() -> llvm::Expected<llvm::orc::JITTargetMachineBuilder> {
+    if (TT.getTriple() == llvm::sys::getProcessTriple())
+      // This fails immediately if the target backend is not registered
+      return llvm::orc::JITTargetMachineBuilder::detectHost();
+
+    // If the target backend is not registered, LLJITBuilder::create() will 
fail
+    return llvm::orc::JITTargetMachineBuilder(TT);
+  }();
+  if (!JTMB)
+    return JTMB.takeError();
 
-  // If the target backend is not registered, LLJITBuilder::create() will fail
-  return llvm::orc::JITTargetMachineBuilder(TT);
+  // Use the large code model. Some external symbols used by exception
+  // handling (e.g. _ZTIPKc) can end up more than 2GB away from the JIT
+  // allocation on FreeBSD. With the small code model, LLVM may emit
+  // Delta32/PC32 relocations that cannot reach those symbols.
+  //
+  // The x86-64 JIT TargetMachine already defaults to the large code model,
+  // but LLJIT overrides an unset code model with CodeModel::Small. Set it
+  // explicitly here to avoid that override.
+  //
+  // Unlike -fPIC, this only affects code generation. It does not change
+  // the __PIC__ preprocessor state, so PCH files remain compatible.
+  if (!JTMB->getCodeModel())
+    JTMB->setCodeModel(llvm::CodeModel::Large);
+  return JTMB;
 }
 
 static llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>

``````````

</details>


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