@@ -73,6 +73,31 @@ struct LLVMInitializer {
7373
7474static LLVMInitializer llvm_initializer;
7575
76+ /* !
77+ * \brief Custom ObjectLinkingLayer plugin for init/fini section handling.
78+ *
79+ * Collects function pointers from init/fini sections (.init_array, .fini_array,
80+ * .ctors, .dtors, .CRT$XC*, .CRT$XT*) and runs them in priority order.
81+ *
82+ * Three-platform init/fini strategy:
83+ *
84+ * - **macOS**: MachOPlatform (via orc_rt) handles __mod_init_func/__mod_term_func
85+ * and __cxa_atexit natively. We delegate to jit_->initialize()/deinitialize().
86+ * No InitFiniPlugin needed.
87+ *
88+ * - **Windows**: COFFPlatform is unusable — it requires MSVC CRT symbols
89+ * (_CxxThrowException, RTTI vtables, etc.) that LLVM's COFF ORC runtime
90+ * cannot provide (stalled for 2+ years). Our plugin handles .CRT$XC*/ .CRT $XT *
91+ * sections instead.
92+ *
93+ * - **Linux**: ELFNixPlatform does not handle .init_array/.fini_array correctly
94+ * prior to https:// github.com/llvm/llvm-project/pull/175981. Once a new LLVM
95+ * release includes that patch, we can switch Linux to ELFNixPlatform and
96+ * remove the plugin for that platform.
97+ *
98+ * The plugin is gated behind `#if defined (__linux__) || defined(_WIN32)` so it
99+ * can be removed per-platform as LLVM's native platform support matures.
100+ */
76101class InitFiniPlugin : public llvm::orc::ObjectLinkingLayer::Plugin {
77102 // Store a raw pointer to avoid a reference cycle:
78103 // Session → LLJIT → ObjectLinkingLayer → Plugin → Session
@@ -565,9 +590,9 @@ ORCJITExecutionSessionObj::ORCJITExecutionSessionObj(const std::string& orc_rt_p
565590 });
566591#endif
567592#if defined(__linux__) || defined(_WIN32)
568- // Linux/Windows: use our custom InitFiniPlugin for init/fini section collection
569- // and priority-ordered execution.
570- // macOS: MachOPlatform handles init/fini natively via jit_->initialize()/deinitialize() .
593+ // Linux/Windows: use our custom InitFiniPlugin for init/fini section
594+ // collection and priority-ordered execution. See InitFiniPlugin class
595+ // documentation for the three-platform init/fini strategy .
571596 auto & objlayer = jit_->getObjLinkingLayer ();
572597 static_cast <llvm::orc::ObjectLinkingLayer&>(objlayer).addPlugin (
573598 std::make_unique<InitFiniPlugin>(this ));
0 commit comments