[clang] [flang] [llvm] [flang] Add runtime trampoline pool for W^X compliance (PR #183108)
Sairudra More via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 26 22:48:41 PST 2026
================
@@ -0,0 +1,69 @@
+//===-- flang-rt/runtime/trampoline.h ----------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Internal declarations for the W^X-compliant trampoline pool.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FLANG_RT_RUNTIME_TRAMPOLINE_H_
+#define FLANG_RT_RUNTIME_TRAMPOLINE_H_
+
+#include <cstddef>
+#include <cstdint>
+
+namespace Fortran::runtime::trampoline {
+
+/// Per-trampoline data entry. Stored in a writable (non-executable) region.
+/// Each entry is paired with a trampoline code stub in the executable region.
+struct TrampolineData {
+ const void *calleeAddress;
+ const void *staticChainAddress;
+};
+
+/// Default number of trampoline slots in the pool.
+/// Can be overridden via FLANG_TRAMPOLINE_POOL_SIZE environment variable.
+constexpr std::size_t kDefaultPoolSize = 1024;
+
+/// Size of each trampoline code stub in bytes (platform-specific).
+#if defined(__x86_64__) || defined(_M_X64)
+// x86-64 trampoline stub:
+// movq TDATA_OFFSET(%rip), %r10 # load static chain from TDATA
+// movabsq $0, %r11 # placeholder for callee address
+// jmpq *%r11
+// Actually we use an indirect approach through the TDATA pointer:
+// movq (%r10), %r10 # load static chain (8 bytes)
+// -- but we need the TDATA pointer first
+// Simplified approach for x86-64:
+// leaq tdata_entry(%rip), %r11 # get TDATA entry address
+// movq 8(%r11), %r10 # load static chain
+// jmpq *(%r11) # jump to callee
+constexpr std::size_t kTrampolineStubSize = 32;
+constexpr int kNestRegister = 10; // %r10 is the nest/static chain register
+#elif defined(__aarch64__) || defined(_M_ARM64)
+// AArch64 trampoline stub:
+// adr x17, tdata_entry # get TDATA entry address
+// ldr x18, [x17, #8] # load static chain
+// ldr x17, [x17] # load callee address
+// br x17
+constexpr std::size_t kTrampolineStubSize = 32;
+constexpr int kNestRegister = 18; // x18 is the platform register
+#elif defined(__powerpc64__) || defined(__ppc64__)
+constexpr std::size_t kTrampolineStubSize = 48;
+constexpr int kNestRegister = 11; // r11
+#else
+// Fallback: generous size
+constexpr std::size_t kTrampolineStubSize = 64;
+constexpr int kNestRegister = 0;
+#endif
+
+/// Alignment requirement for trampoline code stubs.
+constexpr std::size_t kTrampolineAlignment = 16;
----------------
Saieiei wrote:
Removed — it was unused. If we need it later we can add it back.
https://github.com/llvm/llvm-project/pull/183108
More information about the cfe-commits
mailing list