Skip to content

Commit b1bd737

Browse files
committed
[ORC] Add missing files from d6524c8.
1 parent d6524c8 commit b1bd737

File tree

7 files changed

+1343
-0
lines changed

7 files changed

+1343
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %clangxx -c -o %t %s
2+
// RUN: %llvm_jitlink -slab-allocate=20Mb %t
3+
//
4+
// REQUIRES: system-darwin && host-arch-compatible
5+
6+
int main(int argc, char *argv[]) {
7+
try {
8+
throw 42;
9+
} catch (int E) {
10+
return 42 - E;
11+
}
12+
return 1;
13+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//===--- UnwindInfoManager.h -- Register unwind info sections ---*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Utilities for managing eh-frame and compact-unwind registration and lookup
10+
// through libunwind's find_dynamic_unwind_sections mechanism.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
15+
#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
16+
17+
#include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
18+
#include "llvm/ExecutionEngine/Orc/TargetProcess/ExecutorBootstrapService.h"
19+
#include "llvm/Support/Error.h"
20+
#include <map>
21+
#include <mutex>
22+
23+
namespace llvm::orc {
24+
25+
class UnwindInfoManager : public ExecutorBootstrapService {
26+
public:
27+
// This struct's layout should match the unw_dynamic_unwind_sections struct
28+
// from libunwind/src/libunwid_ext.h.
29+
struct UnwindSections {
30+
uintptr_t dso_base;
31+
uintptr_t dwarf_section;
32+
size_t dwarf_section_length;
33+
uintptr_t compact_unwind_section;
34+
size_t compact_unwind_section_length;
35+
};
36+
37+
/// If the libunwind find-dynamic-unwind-info callback registration APIs are
38+
/// available then this method will return an UnwindInfoManager instance,
39+
/// otherwise it will return nullptr.
40+
static std::unique_ptr<UnwindInfoManager> TryCreate();
41+
42+
Error shutdown() override;
43+
void addBootstrapSymbols(StringMap<ExecutorAddr> &M) override;
44+
45+
Error enable(void *FindDynamicUnwindSections);
46+
Error disable(void);
47+
48+
Error registerSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges,
49+
orc::ExecutorAddr DSOBase,
50+
orc::ExecutorAddrRange DWARFEHFrame,
51+
orc::ExecutorAddrRange CompactUnwind);
52+
53+
Error deregisterSections(ArrayRef<orc::ExecutorAddrRange> CodeRanges);
54+
55+
int findSections(uintptr_t Addr, UnwindSections *Info);
56+
57+
private:
58+
UnwindInfoManager(int (*AddFindDynamicUnwindSections)(void *),
59+
int (*RemoveFindDynamicUnwindSections)(void *))
60+
: AddFindDynamicUnwindSections(AddFindDynamicUnwindSections),
61+
RemoveFindDynamicUnwindSections(RemoveFindDynamicUnwindSections) {}
62+
63+
static int findSectionsHelper(UnwindInfoManager *Instance, uintptr_t Addr,
64+
UnwindSections *Info);
65+
66+
std::mutex M;
67+
std::map<uintptr_t, UnwindSections> UWSecs;
68+
69+
int (*AddFindDynamicUnwindSections)(void *) = nullptr;
70+
int (*RemoveFindDynamicUnwindSections)(void *) = nullptr;
71+
void *FindDynamicUnwindSections = nullptr;
72+
73+
static const char *AddFnName, *RemoveFnName;
74+
};
75+
76+
} // namespace llvm::orc
77+
78+
#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_UNWINDINFOMANAGER_H
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
//===- UnwindInfoRegistrationPlugin.h -- libunwind registration -*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Register eh-frame and compact-unwind sections with libunwind
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H
14+
#define LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H
15+
16+
#include "llvm/ExecutionEngine/Orc/LinkGraphLinkingLayer.h"
17+
18+
namespace llvm::orc {
19+
20+
class UnwindInfoRegistrationPlugin : public LinkGraphLinkingLayer::Plugin {
21+
public:
22+
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
23+
Create(IRLayer &IRL, JITDylib &PlatformJD, ExecutorAddr Instance,
24+
ExecutorAddr FindHelper, ExecutorAddr Enable, ExecutorAddr Disable,
25+
ExecutorAddr Register, ExecutorAddr Deregister);
26+
27+
static Expected<std::shared_ptr<UnwindInfoRegistrationPlugin>>
28+
Create(IRLayer &IRL, JITDylib &PlatformJD);
29+
30+
~UnwindInfoRegistrationPlugin();
31+
32+
void modifyPassConfig(MaterializationResponsibility &MR,
33+
jitlink::LinkGraph &G,
34+
jitlink::PassConfiguration &PassConfig) override;
35+
36+
Error notifyEmitted(MaterializationResponsibility &MR) override {
37+
return Error::success();
38+
}
39+
40+
Error notifyFailed(MaterializationResponsibility &MR) override {
41+
return Error::success();
42+
}
43+
44+
Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override {
45+
return Error::success();
46+
}
47+
48+
void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey,
49+
ResourceKey SrcKey) override {}
50+
51+
private:
52+
UnwindInfoRegistrationPlugin(ExecutionSession &ES, ExecutorAddr Instance,
53+
ExecutorAddr Disable, ExecutorAddr Register,
54+
ExecutorAddr Deregister)
55+
: ES(ES), Instance(Instance), Disable(Disable), Register(Register),
56+
Deregister(Deregister) {
57+
DSOBaseName = ES.intern("__jitlink$libunwind_dso_base");
58+
}
59+
60+
static Expected<ThreadSafeModule> makeBouncerModule(ExecutionSession &ES);
61+
Error addUnwindInfoRegistrationActions(jitlink::LinkGraph &G);
62+
63+
ExecutionSession &ES;
64+
SymbolStringPtr DSOBaseName;
65+
ExecutorAddr Instance, Disable, Register, Deregister;
66+
};
67+
68+
} // namespace llvm::orc
69+
70+
#endif // LLVM_EXECUTIONENGINE_ORC_UNWINDINFOREGISTRATIONPLUGIN_H
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//=------- CompactUnwindSupport.cpp - Compact Unwind format support -------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Compact Unwind support.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "CompactUnwindSupport.h"
14+
15+
#include "llvm/ADT/Sequence.h"
16+
17+
#define DEBUG_TYPE "jitlink"
18+
19+
namespace llvm {
20+
namespace jitlink {
21+
22+
Error splitCompactUnwindBlocks(LinkGraph &G, Section &CompactUnwindSection,
23+
size_t RecordSize) {
24+
25+
std::vector<Block *> OriginalBlocks(CompactUnwindSection.blocks().begin(),
26+
CompactUnwindSection.blocks().end());
27+
LLVM_DEBUG({
28+
dbgs() << "In " << G.getName() << " splitting compact unwind section "
29+
<< CompactUnwindSection.getName() << " containing "
30+
<< OriginalBlocks.size() << " initial blocks...\n";
31+
});
32+
33+
while (!OriginalBlocks.empty()) {
34+
auto *B = OriginalBlocks.back();
35+
OriginalBlocks.pop_back();
36+
37+
if (B->getSize() == 0) {
38+
LLVM_DEBUG({
39+
dbgs() << " Skipping empty block at "
40+
<< formatv("{0:x16}", B->getAddress()) << "\n";
41+
});
42+
continue;
43+
}
44+
45+
unsigned NumBlocks = B->getSize() / RecordSize;
46+
47+
LLVM_DEBUG({
48+
dbgs() << " Splitting block at " << formatv("{0:x16}", B->getAddress())
49+
<< " into " << NumBlocks << " compact unwind record(s)\n";
50+
});
51+
52+
if (B->getSize() % RecordSize)
53+
return make_error<JITLinkError>(
54+
"Error splitting compact unwind record in " + G.getName() +
55+
": block at " + formatv("{0:x}", B->getAddress()) + " has size " +
56+
formatv("{0:x}", B->getSize()) +
57+
" (not a multiple of CU record size of " +
58+
formatv("{0:x}", RecordSize) + ")");
59+
60+
auto Blocks =
61+
G.splitBlock(*B, map_range(seq(1U, NumBlocks), [=](Edge::OffsetT Idx) {
62+
return Idx * RecordSize;
63+
}));
64+
65+
for (auto *CURec : Blocks) {
66+
bool AddedKeepAlive = false;
67+
68+
for (auto &E : CURec->edges()) {
69+
if (E.getOffset() == 0) {
70+
LLVM_DEBUG({
71+
dbgs() << " Updating compact unwind record at "
72+
<< CURec->getAddress() << " to point to "
73+
<< (E.getTarget().hasName() ? *E.getTarget().getName()
74+
: StringRef())
75+
<< " (at " << E.getTarget().getAddress() << ")\n";
76+
});
77+
78+
if (E.getTarget().isExternal())
79+
return make_error<JITLinkError>(
80+
"Error adding keep-alive edge for compact unwind record at " +
81+
formatv("{0:x}", CURec->getAddress()) + ": target " +
82+
*E.getTarget().getName() + " is an external symbol");
83+
auto &TgtBlock = E.getTarget().getBlock();
84+
auto &CURecSym =
85+
G.addAnonymousSymbol(*CURec, 0, RecordSize, false, false);
86+
TgtBlock.addEdge(Edge::KeepAlive, 0, CURecSym, 0);
87+
AddedKeepAlive = true;
88+
}
89+
}
90+
91+
if (!AddedKeepAlive)
92+
return make_error<JITLinkError>(
93+
"Error adding keep-alive edge for compact unwind record at " +
94+
formatv("{0:x}", CURec->getAddress()) +
95+
": no outgoing target edge at offset 0");
96+
}
97+
}
98+
99+
return Error::success();
100+
}
101+
102+
} // end namespace jitlink
103+
} // end namespace llvm

0 commit comments

Comments
 (0)