Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
296a6d1
apply msys2 patches, correct plugin windows.h header
ikappaki May 13, 2026
2019be5
[ORC] Enable JITLink by default for x86_64 COFF targets
ikappaki May 13, 2026
8fcef75
[JITLink][COFF] Resolve __ImageBase before ADDR32NB lowering
ikappaki May 15, 2026
5bb9763
[JITLink][COFF] Add GOT/PLT stub support for ext calls in COFFx86_64
ikappaki May 16, 2026
f9f8a22
[JITLink][COFF] Add ADDR32NB stubs for image rel refs to externals
ikappaki May 17, 2026
aa807e6
fixup! [JITLink][COFF] Resolve __ImageBase before ADDR32NB lowering
ikappaki May 17, 2026
59c2bca
[JITLink][COFF] Fix missing symbol reg for COMDAT sect def symbols
ikappaki May 17, 2026
f226c46
[ORC] Set OverrideObjectFlags for JITLink on COFF
ikappaki May 18, 2026
8327fd8
[ORC] Add SEHFrameRegistrationPlugin for Windows COFF x86_64
ikappaki May 18, 2026
905aef3
[ORC] Add filterd DLLImportDefinitionGenerator for COFF gen platform
ikappaki May 19, 2026
4198c16
[JITLink][ORC] Extend SEHFrameKeepAlivePass and registration for COMD…
ikappaki May 20, 2026
1b574b0
[JITLink][COFF] Remove dead findDefinedSymbolByName call from GetImag…
ikappaki May 21, 2026
13c2f43
[ORC] Add end-to-end SEH integration tests for COFF x86_64
ikappaki May 21, 2026
137a555
[JITLink][COFF] Add GOT/Stubs optimizer pass for COFF x86_64
ikappaki May 30, 2026
45b892f
[ORC] Fix crash in SEHFrameRegistrationPlugin on dead-stripped COMDAT…
ikappaki Jun 6, 2026
713a692
[JITLink][COFF] Migrate COFF x86_64 edge kinds to generic EdgeKind_x8…
ikappaki Jul 27, 2026
5b0d332
[JITLink][COFF] Synthesize __imp_ IAT entries (#203906)
mkovacevic99 Jun 19, 2026
0022615
[ORC] Remove DLLImportDefinitionGenerator filter, superseded by JITLi…
ikappaki Aug 8, 2026
ba9c711
[JITLink][COFF] Declare buildTables and synthesizeIATEntries in COFF_…
ikappaki Aug 8, 2026
9405b95
Revert MSYS2 distro patches (out of scope for upstream)
ikappaki Aug 14, 2026
8b79c2b
[JITLink][COFF] Move __ImageBase resolution to PostAllocationPass
ikappaki Aug 22, 2026
4f138de
[ORC] Add release note for JITLink default on COFF x86_64
ikappaki Aug 22, 2026
ea9e72f
[JITLink][COFF][test] Replace IR imagebase test with assembly jitlink…
ikappaki Aug 22, 2026
f098c39
[JITLink][COFF] Remove SectionIdx16 edge kind, emit Pointer16 directly
ikappaki Aug 22, 2026
b2d3965
[JITLink][COFF] Define COFFIATSectionName constant in COFF.h
ikappaki Aug 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion llvm/docs/ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ point (e.g. maybe you would like to give an example of the
functionality, or simply have a lot to talk about), see the comment below
for adding a new subsection. -->

* ...
* LLJIT now uses JITLink by default for x86_64 COFF targets (Windows).
This enables SEH exception handling in JIT'd code on Windows.

<!-- If you would like to document a larger change, then you can add a
subsection about it right here. You can copy the following boilerplate:
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/COFF.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
namespace llvm {
namespace jitlink {

/// Section name for the synthesized Import Address Table.
constexpr StringRef COFFIATSectionName = "$__IAT";

/// Create a LinkGraph from an COFF relocatable object.
///
/// Note: The graph does not take ownership of the underlying buffer, nor copy
Expand Down
7 changes: 7 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/COFF_x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ namespace jitlink {
Expected<std::unique_ptr<LinkGraph>> createLinkGraphFromCOFFObject_x86_64(
MemoryBufferRef ObjectBuffer, std::shared_ptr<orc::SymbolStringPool> SSP);

/// Create stubs in G for external references: PLT stubs for calls (PCRel32)
/// and ADDR32NB stubs for image-relative pointers (Pointer32NB). Always succeeds.
Error buildTables_COFF_x86_64(LinkGraph &G);

/// Synthesize IAT entries for undefined __imp_X externals in G. Always succeeds.
Error synthesizeIATEntries_COFF_x86_64(LinkGraph &G);

Comment on lines +29 to +35

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, but we should try to share the logic here with COFFAutoImportGenerator.cpp if possible (CC @mkovacevic99, who wrote that class).

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What did you have in mind to merge here? The only possibility I see here is to create a shared function that will create and IAT pointer slot and call it instead of CreatePointer(*G, Sec, &Target, 0)/createAnonymousPointer(G, IATSec, Target).
This pattern is also called inside DLLImportDefinitionGenerator (I have added a FIXME comment for COFFAutoImportGenerator)

/// jit-link the given object buffer, which must be a COFF x86-64 object file.
void link_COFF_x86_64(std::unique_ptr<LinkGraph> G,
std::unique_ptr<JITLinkContext> Ctx);
Expand Down
21 changes: 21 additions & 0 deletions llvm/include/llvm/ExecutionEngine/JITLink/x86_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,16 @@ enum EdgeKind_x86_64 : Edge::Kind {
///
Pointer32,

/// A 32-bit image-relative pointer value relocation.
///
/// The value written is the target's offset from a base address (typically
/// the lowest allocated address in the link graph).
///
/// Fixup expression:
/// Fixup <- Target + Addend : uint32
///
Pointer32NB,

/// A signed 32-bit pointer value relocation
///
/// Fixup expression:
Expand Down Expand Up @@ -427,6 +437,17 @@ enum EdgeKind_x86_64 : Edge::Kind {
/// phase will result in an assert/unreachable during the fixup phase.
///
RequestTLVPAndTransformToPCRel32TLVPLoadREXRelaxable,

/// A 32-bit section-relative relocation.
///
/// The value written is the target's offset from the start of its
/// containing section.
///
/// Fixup expression:
/// Fixup <- Target + Addend : uint32
///
SecRel32,

// First platform specific relocation.
FirstPlatformRelocation
};
Expand Down
52 changes: 52 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/SEHFrameRegistrationPlugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===- SEHFrameRegistrationPlugin.h - Register COFF EH info in-process -*- 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
//
//===----------------------------------------------------------------------===//
//
// Register and deregister .pdata sections in-process using RtlAddFunctionTable
// and RtlDeleteFunctionTable.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_SEHFRAMEREGISTRATIONPLUGIN_H
#define LLVM_EXECUTIONENGINE_ORC_SEHFRAMEREGISTRATIONPLUGIN_H

#include "llvm/ExecutionEngine/Orc/LinkGraphLinkingLayer.h"

namespace llvm::orc {

/// Registers .pdata sections with the Windows unwinder via RtlAddFunctionTable.
///
/// This plugin enables SEH-based stack unwinding for JIT'd code on Windows
/// by registering unwind metadata at finalization and deregistering it on
/// deallocation.
class LLVM_ABI SEHFrameRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
public:
/// Adds a pass to PassConfig that registers .pdata sections in LG with the
/// OS unwinder.
void modifyPassConfig(MaterializationResponsibility &MR,
jitlink::LinkGraph &LG,
jitlink::PassConfiguration &PassConfig) override;

Error notifyFailed(MaterializationResponsibility &MR) override {
return Error::success();
}

Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
return Error::success();
}

void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
ResourceKey SrcKey) override {}

/// Registers .pdata sections in G with the OS unwinder.
/// Returns an error if registration setup fails.
Error registerFrameInfo(jitlink::LinkGraph &G);
};

} // namespace llvm::orc

#endif // LLVM_EXECUTIONENGINE_ORC_SEHFRAMEREGISTRATIONPLUGIN_H
6 changes: 2 additions & 4 deletions llvm/lib/ExecutionEngine/JITLink/COFF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,14 +135,12 @@ Symbol *GetImageBaseSymbol::operator()(LinkGraph &G) {
if (ImageBase)
return *ImageBase;

// __ImageBase is only ever external (generic platform) or absolute (COFFPlatform).
auto IBN = G.intern(ImageBaseName);
ImageBase = G.findExternalSymbolByName(IBN);
if (*ImageBase)
return *ImageBase;
ImageBase = G.findAbsoluteSymbolByName(IBN);
if (*ImageBase)
return *ImageBase;
ImageBase = G.findDefinedSymbolByName(IBN);
ImageBase = G.findExternalSymbolByName(IBN);
if (*ImageBase)
return *ImageBase;

Expand Down
27 changes: 24 additions & 3 deletions llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,16 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
return make_error<JITLinkError>(
"COMDAT export request already exists before symbol " +
formatv("{0:d}", SymIndex));
return createCOMDATExportRequest(SymIndex, Symbol, Definition);

if (auto Err = createCOMDATExportRequest(SymIndex, Symbol, Definition).takeError())
return Err;

// Return a local symbol so relocations can resolve against this index.
// COMDAT sections without an export (e.g. .xdata$*) keep this symbol,
// while those with one will get it replaced in exportCOMDATSymbol.
return &G->addDefinedSymbol(
*B, Symbol.getValue(), SymbolName, 0, Linkage::Strong, Scope::Local,
Symbol.getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION, false);
}
return make_error<JITLinkError>("Unsupported storage class " +
formatv("{0:d}", Symbol.getStorageClass()) +
Expand All @@ -550,9 +559,13 @@ Expected<Symbol *> COFFLinkGraphBuilder::createDefinedSymbol(
// Second symbol is COMDAT symbol which usually defines the external name and
// data type.
//
// Since two symbols always come in a specific order, we initiate pending COMDAT
// Since two symbols usually come in a specific order, we initiate pending COMDAT
// export request when we encounter the first symbol and actually exports it
// when we process the second symbol.
// when we process the second symbol. However, some COMDAT sections (e.g.
// .xdata$*, .pdata$*) only have the section definition symbol with no
// export following. The caller SHOULD register a local symbol for the first
// symbol's index unconditionally so that relocations targeting it can
// resolve regardless of whether an export symbol follows.
//
// Process the first symbol of COMDAT sequence.
Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
Expand Down Expand Up @@ -604,6 +617,9 @@ Expected<Symbol *> COFFLinkGraphBuilder::createCOMDATExportRequest(
}

// Process the second symbol of COMDAT sequence.
//
// Replaces the local placeholder registered for the first symbol's
// index.
Expected<Symbol *>
COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
orc::SymbolStringPtr SymbolName,
Expand All @@ -623,6 +639,11 @@ COFFLinkGraphBuilder::exportCOMDATSymbol(COFFSymbolIndex SymIndex,
<< "\" in section " << Symbol.getSectionNumber() << "\n";
dbgs() << " " << *GSym << "\n";
});

// Clear the first symbol's provisional placeholder so
// setGraphSymbol can replace it.
GraphSymbols[PendingComdatExport->SymbolIndex] = nullptr;

setGraphSymbol(Symbol.getSectionNumber(), PendingComdatExport->SymbolIndex,
*GSym);
DefinedSymbols[SymbolName] = GSym;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/ExecutionEngine/JITLink/COFFLinkGraphBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class COFFLinkGraphBuilder {
}

Symbol &addImageBaseSymbol(StringRef Name = "__ImageBase") {
auto &ImageBase = G->addExternalSymbol(G->intern(Name), 0, true);
auto &ImageBase = G->addAbsoluteSymbol(G->intern(Name), orc::ExecutorAddr(0), 0, Linkage::Strong, Scope::Local, true);
ImageBase.setLive(true);
return ImageBase;
}
Expand Down
Loading