Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b05e3a7
[ORC] Fix file comment formatting. NFC.
lhames Jan 30, 2025
4abac9f
[ORC] Drop 'Info' from MachOCompactUnwindInfoSectionName.
lhames Feb 3, 2025
1244803
[ORC] Add minimal-throw-catch.ll regression test for lli -jit-mode=orc.
lhames Feb 4, 2025
3a474e7
[ORC] Actually use -jit-kind=orc for the new minimal-throw-catch.ll t…
lhames Feb 4, 2025
c5f8508
[ORC] Rename MachOCompactUnwindSectionName to MachOUnwindInfoSectionN…
lhames Feb 4, 2025
1bcbc68
[ORC] Fix eh-frame record target finding in MachOPlatform.
lhames Feb 4, 2025
74d53f7
[ORC] Moch MachOPlatform unwind-info fixes.
lhames Feb 5, 2025
50c4c2b
Re-reapply "[ORC] Enable JIT support for the compact-unwind..." with …
lhames Feb 4, 2025
7782b83
[ORC-RT] Add a comment explaining the purpose of this testcase. NFC.
lhames Feb 5, 2025
0c23bde
[ORC] Fix buggy calculation of second-level-page offset in unwind-info.
lhames Feb 5, 2025
975fa93
[JITLink] Add a jitlink::Symbol::getSection() convenience method.
lhames Feb 6, 2025
749bebc
[JITLink] Handle compact-unwind records that depend on DWARF FDEs.
lhames Feb 6, 2025
b3876b6
[JITLink] Add missing testcase for compact-unwind-needs-dwarf.
lhames Feb 6, 2025
a9b4976
[ORC-RT] Use templates to express deeply nested function calls in tes…
lhames Feb 6, 2025
1ba8799
[ORC] Add a FIXME. NFC.
lhames Feb 7, 2025
c7e085c
[ORC] Add ExecutionSession convenience methods to access bootstrap va…
lhames Feb 7, 2025
bf2828f
[ORC] Force eh-frame use for older Darwins on x86-64 in MachOPlatform…
lhames Feb 7, 2025
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
4 changes: 2 additions & 2 deletions clang/test/Interpreter/simple-exception.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// clang-format off
// UNSUPPORTED: system-aix
// XFAIL for arm and arm64, or running on Windows.
// XFAIL: target=arm{{.*}}, system-windows
// XFAIL for arm, or running on Windows.
// XFAIL: target=arm-{{.*}}, target=armv{{.*}}, system-windows
// RUN: cat %s | clang-repl | FileCheck %s

// Incompatible with msan. It passes with -O3 but fail -Oz. Interpreter
Expand Down
6 changes: 6 additions & 0 deletions compiler-rt/lib/orc/macho_platform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,12 @@ Error MachOPlatformRuntimeState::registerObjectPlatformSections(
return make_error<StringError>(ErrStream.str());
}

ORC_RT_DEBUG({
printdbg(" UnwindInfo: %s, UseCallbackStyleUnwindInfo: %s\n",
UnwindInfo ? "true" : "false",
UseCallbackStyleUnwindInfo ? "true" : "false");
});

if (UnwindInfo && UseCallbackStyleUnwindInfo) {
ORC_RT_DEBUG({
printdbg(" Registering new-style unwind info for:\n"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// RUN: %clangxx -c -o %t %s
// RUN: %llvm_jitlink -slab-allocate=20Mb %t
//
// REQUIRES: system-darwin && host-arch-compatible

// Test that we can throw and catch an exception through a large number of
// stack frames. The number (1022) is chosen to force emission of multiple
// unwind info second-level pages.

template <int N>
void f() { try { f<N - 1>(); } catch (...) { throw; } }

template <>
void f<0>() { throw 42; }

int main(int argc, char *argv[]) {
try {
f<1020>();
} catch (int n) {
return 42 - n;
}
return 1;
}

14 changes: 14 additions & 0 deletions compiler-rt/test/orc/TestCases/Darwin/Generic/exceptions.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// RUN: %clangxx -c -o %t %s
// RUN: %llvm_jitlink -slab-allocate=20Mb %t
//
// REQUIRES: system-darwin && host-arch-compatible

// Test that trivial throw / catch works.
int main(int argc, char *argv[]) {
try {
throw 42;
} catch (int E) {
return 42 - E;
}
return 1;
}
11 changes: 7 additions & 4 deletions llvm/include/llvm/ExecutionEngine/JITLink/JITLink.h
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ class Symbol {
return static_cast<const Block &>(*Base);
}

/// Return the Section for this Symbol (Symbol must be defined).
Section &getSection() const { return getBlock().getSection(); }

/// Returns the offset for this symbol within the underlying addressable.
orc::ExecutorAddrDiff getOffset() const { return Offset; }

Expand Down Expand Up @@ -1460,7 +1463,7 @@ class LinkGraph {
A.setAddress(orc::ExecutorAddr());
} else {
assert(Sym.isDefined() && "Sym is not a defined symbol");
Section &Sec = Sym.getBlock().getSection();
Section &Sec = Sym.getSection();
Sec.removeSymbol(Sym);
Sym.makeExternal(createAddressable(orc::ExecutorAddr(), false));
}
Expand Down Expand Up @@ -1488,7 +1491,7 @@ class LinkGraph {
Sym.setScope(Scope::Local);
} else {
assert(Sym.isDefined() && "Sym is not a defined symbol");
Section &Sec = Sym.getBlock().getSection();
Section &Sec = Sym.getSection();
Sec.removeSymbol(Sym);
Sym.makeAbsolute(createAddressable(Address));
}
Expand Down Expand Up @@ -1534,7 +1537,7 @@ class LinkGraph {
transferDefinedSymbol(Symbol &Sym, Block &DestBlock,
orc::ExecutorAddrDiff NewOffset,
std::optional<orc::ExecutorAddrDiff> ExplicitNewSize) {
auto &OldSection = Sym.getBlock().getSection();
auto &OldSection = Sym.getSection();
Sym.setBlock(DestBlock);
Sym.setOffset(NewOffset);
if (ExplicitNewSize)
Expand Down Expand Up @@ -1622,7 +1625,7 @@ class LinkGraph {
/// Removes defined symbols. Does not remove the underlying block.
void removeDefinedSymbol(Symbol &Sym) {
assert(Sym.isDefined() && "Sym is not a defined symbol");
Sym.getBlock().getSection().removeSymbol(Sym);
Sym.getSection().removeSymbol(Sym);
destroySymbol(Sym);
}

Expand Down
33 changes: 31 additions & 2 deletions llvm/include/llvm/ExecutionEngine/Orc/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -1204,8 +1204,13 @@ class JITDylib : public ThreadSafeRefCountedBase<JITDylib>,

JITDylib(ExecutionSession &ES, std::string Name);

std::pair<AsynchronousSymbolQuerySet, std::shared_ptr<SymbolDependenceMap>>
IL_removeTracker(ResourceTracker &RT);
struct RemoveTrackerResult {
AsynchronousSymbolQuerySet QueriesToFail;
std::shared_ptr<SymbolDependenceMap> FailedSymbols;
std::vector<std::unique_ptr<MaterializationUnit>> DefunctMUs;
};

RemoveTrackerResult IL_removeTracker(ResourceTracker &RT);

void transferTracker(ResourceTracker &DstRT, ResourceTracker &SrcRT);

Expand Down Expand Up @@ -1551,6 +1556,30 @@ class ExecutionSession {
EPC->getDispatcher().dispatch(std::move(T));
}

/// Returns the bootstrap map.
const StringMap<std::vector<char>> &getBootstrapMap() const {
return EPC->getBootstrapMap();
}

/// Look up and SPS-deserialize a bootstrap map value.
template <typename T, typename SPSTagT>
Error getBootstrapMapValue(StringRef Key, std::optional<T> &Val) const {
return EPC->getBootstrapMapValue<T, SPSTagT>(Key, Val);
}

/// Returns the bootstrap symbol map.
const StringMap<ExecutorAddr> &getBootstrapSymbolsMap() const {
return EPC->getBootstrapSymbolsMap();
}

/// For each (ExecutorAddr&, StringRef) pair, looks up the string in the
/// bootstrap symbols map and writes its address to the ExecutorAddr if
/// found. If any symbol is not found then the function returns an error.
Error getBootstrapSymbols(
ArrayRef<std::pair<ExecutorAddr &, StringRef>> Pairs) const {
return EPC->getBootstrapSymbols(Pairs);
}

/// Run a wrapper function in the executor.
///
/// The wrapper function should be callable as:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/UnwindInfoManager.h"
#include "llvm/ExecutionEngine/Orc/TaskDispatch.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
Expand Down Expand Up @@ -507,6 +508,9 @@ class SelfExecutorProcessControl : public ExecutorProcessControl,
SymbolLookupCompleteFn F) override;

std::unique_ptr<jitlink::JITLinkMemoryManager> OwnedMemMgr;
#ifdef __APPLE__
std::unique_ptr<UnwindInfoManager> UnwindInfoMgr;
#endif // __APPLE__
char GlobalManglingPrefix = 0;
};

Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/MachOPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ class MachOPlatform : public Platform {
DenseMap<JITDylib *, SymbolLookupSet> RegisteredInitSymbols;

std::mutex PlatformMutex;
bool ForceEHFrames = false;
BootstrapInfo *Bootstrap = nullptr;
DenseMap<JITDylib *, ExecutorAddr> JITDylibToHeaderAddr;
DenseMap<ExecutorAddr, JITDylib *> HeaderAddrToJITDylib;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace orc {
extern StringRef MachODataCommonSectionName;
extern StringRef MachODataDataSectionName;
extern StringRef MachOEHFrameSectionName;
extern StringRef MachOCompactUnwindInfoSectionName;
extern StringRef MachOCompactUnwindSectionName;
extern StringRef MachOCStringSectionName;
extern StringRef MachOModInitFuncSectionName;
extern StringRef MachOObjCCatListSectionName;
Expand Down Expand Up @@ -53,6 +53,7 @@ extern StringRef MachOTextTextSectionName;
extern StringRef MachOThreadBSSSectionName;
extern StringRef MachOThreadDataSectionName;
extern StringRef MachOThreadVarsSectionName;
extern StringRef MachOUnwindInfoSectionName;

extern StringRef MachOInitSectionNames[22];

Expand Down
9 changes: 9 additions & 0 deletions llvm/include/llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,15 @@ using SPSRunAsMainSignature = int64_t(shared::SPSExecutorAddr,
using SPSRunAsVoidFunctionSignature = int32_t(shared::SPSExecutorAddr);
using SPSRunAsIntFunctionSignature = int32_t(shared::SPSExecutorAddr, int32_t);
} // end namespace rt

namespace rt_alt {
extern const char *UnwindInfoManagerInstanceName;
extern const char *UnwindInfoManagerFindSectionsHelperName;
extern const char *UnwindInfoManagerEnableWrapperName;
extern const char *UnwindInfoManagerDisableWrapperName;
extern const char *UnwindInfoManagerRegisterActionName;
extern const char *UnwindInfoManagerDeregisterActionName;
} // end namespace rt_alt
} // end namespace orc
} // end namespace llvm

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
//===- DefaultHostBootstrapValues.h - Defaults for host 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
//
//===----------------------------------------------------------------------===//
//
// Set sensible default bootstrap values for JIT execution in the host process.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H

#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include <vector>

namespace llvm::orc {

void addDefaultBootstrapValuesForHostProcess(
StringMap<std::vector<char>> &BootstrapMap,
StringMap<ExecutorAddr> &BootstrapSymbols);

} // namespace llvm::orc

#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_DEFAULTHOSTBOOTSTRAPVALUES_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
//===--- UnwindInfoManager.h -- Register unwind info sections ---*- 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
//
//===----------------------------------------------------------------------===//
//
// Utilities for managing eh-frame and compact-unwind registration and lookup
// through libunwind's find_dynamic_unwind_sections mechanism.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H

#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
#include "llvm/Support/Error.h"
#include <map>
#include <mutex>

namespace llvm::orc {

class UnwindInfoManager : public ExecutorBootstrapService {
public:
// This struct's layout should match the unw_dynamic_unwind_sections struct
// from libunwind/src/libunwid_ext.h.
struct UnwindSections {
uintptr_t dso_base;
uintptr_t dwarf_section;
size_t dwarf_section_length;
uintptr_t compact_unwind_section;
size_t compact_unwind_section_length;
};

/// If the libunwind find-dynamic-unwind-info callback registration APIs are
/// available then this method will return an UnwindInfoManager instance,
/// otherwise it will return nullptr.
static std::unique_ptr<UnwindInfoManager> TryCreate();

Error shutdown() override;
void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;

Error enable(void *FindDynamicUnwindSections);
Error disable(void);

Error registerSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges,
orc::ExecutorAddr DSOBase,
orc::ExecutorAddrRange DWARFEHFrame,
orc::ExecutorAddrRange CompactUnwind);

Error deregisterSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges);

int findSections(uintptr_t Addr, UnwindSections *Info);

private:
UnwindInfoManager(int (*AddFindDynamicUnwindSections)(void *),
int (*RemoveFindDynamicUnwindSections)(void *))
: AddFindDynamicUnwindSections(AddFindDynamicUnwindSections),
RemoveFindDynamicUnwindSections(RemoveFindDynamicUnwindSections) {}

static int findSectionsHelper(UnwindInfoManager *Instance, uintptr_t Addr,
UnwindSections *Info);

std::mutex M;
std::map<uintptr_t, UnwindSections> UWSecs;

int (*AddFindDynamicUnwindSections)(void *) = nullptr;
int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;
void *FindDynamicUnwindSections = nullptr;

static const char *AddFnName, *RemoveFnName;
};

} // namespace llvm::orc

#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
//===- UnwindInfoRegistrationPlugin.h -- libunwind registration -*- 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 eh-frame and compact-unwind sections with libunwind
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H
#define LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H

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

namespace llvm::orc {

class UnwindInfoRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
public:
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
Create(IRLayer &IRL, JITDylib &PlatformJD, ExecutorAddr Instance,
ExecutorAddr FindHelper, ExecutorAddr Enable, ExecutorAddr Disable,
ExecutorAddr Register, ExecutorAddr Deregister);

static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
Create(IRLayer &IRL, JITDylib &PlatformJD);

~UnwindInfoRegistrationPlugin();

void modifyPassConfig(MaterializationResponsibility &MR,
jitlink::LinkGraph &G,
jitlink::PassConfiguration &PassConfig) override;

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

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 {}

private:
UnwindInfoRegistrationPlugin(ExecutionSession &ES, ExecutorAddr Instance,
ExecutorAddr Disable, ExecutorAddr Register,
ExecutorAddr Deregister)
: ES(ES), Instance(Instance), Disable(Disable), Register(Register),
Deregister(Deregister) {
DSOBaseName = ES.intern("__jitlink$libunwind_dso_base");
}

static Expected<ThreadSafeModule> makeBouncerModule(ExecutionSession &ES);
Error addUnwindInfoRegistrationActions(jitlink::LinkGraph &G);

ExecutionSession &ES;
SymbolStringPtr DSOBaseName;
ExecutorAddr Instance, Disable, Register, Deregister;
};

} // namespace llvm::orc

#endif // LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H
Loading