1 //===--------- DefineExternalSectionStartAndEndSymbols.h --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Utility class for recognizing external section start and end symbols and
10 // transforming them into defined symbols for the start and end blocks of the
11 // associated Section.
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
16 #define LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
18 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
19 #include "llvm/Support/Debug.h"
21 #define DEBUG_TYPE "jitlink"
26 struct SectionRangeSymbolDesc
{
27 SectionRangeSymbolDesc() = default;
28 SectionRangeSymbolDesc(Section
&Sec
, bool IsStart
)
29 : Sec(&Sec
), IsStart(IsStart
) {}
30 Section
*Sec
= nullptr;
34 /// Pass implementation for the createDefineExternalSectionStartAndEndSymbols
36 template <typename SymbolIdentifierFunction
>
37 class DefineExternalSectionStartAndEndSymbols
{
39 DefineExternalSectionStartAndEndSymbols(SymbolIdentifierFunction F
)
42 Error
operator()(LinkGraph
&G
) {
44 // This pass will affect the external symbols set, so copy them out into a
45 // vector and iterate over that.
46 std::vector
<Symbol
*> Externals(G
.external_symbols().begin(),
47 G
.external_symbols().end());
49 for (auto *Sym
: Externals
) {
50 SectionRangeSymbolDesc D
= F(G
, *Sym
);
52 auto &SR
= getSectionRange(*D
.Sec
);
55 G
.makeAbsolute(*Sym
, orc::ExecutorAddr());
57 G
.makeDefined(*Sym
, *SR
.getFirstBlock(), 0, 0, Linkage::Strong
,
61 G
.makeAbsolute(*Sym
, orc::ExecutorAddr());
63 G
.makeDefined(*Sym
, *SR
.getLastBlock(),
64 SR
.getLastBlock()->getSize(), 0, Linkage::Strong
,
69 return Error::success();
73 SectionRange
&getSectionRange(Section
&Sec
) {
74 auto I
= SectionRanges
.find(&Sec
);
75 if (I
== SectionRanges
.end())
76 I
= SectionRanges
.insert(std::make_pair(&Sec
, SectionRange(Sec
))).first
;
80 DenseMap
<Section
*, SectionRange
> SectionRanges
;
81 SymbolIdentifierFunction F
;
84 /// Returns a JITLink pass (as a function class) that uses the given symbol
85 /// identification function to identify external section start and end symbols
86 /// (and their associated Section*s) and transform the identified externals
87 /// into defined symbols pointing to the start of the first block in the
88 /// section and the end of the last (start and end symbols for empty sections
89 /// will be transformed into absolute symbols at address 0).
91 /// The identification function should be callable as
93 /// SectionRangeSymbolDesc (LinkGraph &G, Symbol &Sym)
95 /// If Sym is not a section range start or end symbol then a default
96 /// constructed SectionRangeSymbolDesc should be returned. If Sym is a start
97 /// symbol then SectionRangeSymbolDesc(Sec, true), where Sec is a reference to
98 /// the target Section. If Sym is an end symbol then
99 /// SectionRangeSymbolDesc(Sec, false) should be returned.
101 /// This pass should be run in the PostAllocationPass pipeline, at which point
102 /// all blocks should have been assigned their final addresses.
103 template <typename SymbolIdentifierFunction
>
104 DefineExternalSectionStartAndEndSymbols
<SymbolIdentifierFunction
>
105 createDefineExternalSectionStartAndEndSymbolsPass(
106 SymbolIdentifierFunction
&&F
) {
107 return DefineExternalSectionStartAndEndSymbols
<SymbolIdentifierFunction
>(
108 std::forward
<SymbolIdentifierFunction
>(F
));
111 } // end namespace jitlink
112 } // end namespace llvm
116 #endif // LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H