123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- //===--------- DefineExternalSectionStartAndEndSymbols.h --------*- 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
- //
- //===----------------------------------------------------------------------===//
- //
- // Utility class for recognizing external section start and end symbols and
- // transforming them into defined symbols for the start and end blocks of the
- // associated Section.
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
- #define LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
- #include "llvm/ExecutionEngine/JITLink/JITLink.h"
- #include "llvm/Support/Debug.h"
- #define DEBUG_TYPE "jitlink"
- namespace llvm {
- namespace jitlink {
- struct SectionRangeSymbolDesc {
- SectionRangeSymbolDesc() = default;
- SectionRangeSymbolDesc(Section &Sec, bool IsStart)
- : Sec(&Sec), IsStart(IsStart) {}
- Section *Sec = nullptr;
- bool IsStart = false;
- };
- /// Pass implementation for the createDefineExternalSectionStartAndEndSymbols
- /// function.
- template <typename SymbolIdentifierFunction>
- class DefineExternalSectionStartAndEndSymbols {
- public:
- DefineExternalSectionStartAndEndSymbols(SymbolIdentifierFunction F)
- : F(std::move(F)) {}
- Error operator()(LinkGraph &G) {
- // This pass will affect the external symbols set, so copy them out into a
- // vector and iterate over that.
- std::vector<Symbol *> Externals(G.external_symbols().begin(),
- G.external_symbols().end());
- for (auto *Sym : Externals) {
- SectionRangeSymbolDesc D = F(G, *Sym);
- if (D.Sec) {
- auto &SR = getSectionRange(*D.Sec);
- if (D.IsStart) {
- if (SR.empty())
- G.makeAbsolute(*Sym, orc::ExecutorAddr());
- else
- G.makeDefined(*Sym, *SR.getFirstBlock(), 0, 0, Linkage::Strong,
- Scope::Local, false);
- } else {
- if (SR.empty())
- G.makeAbsolute(*Sym, orc::ExecutorAddr());
- else
- G.makeDefined(*Sym, *SR.getLastBlock(),
- SR.getLastBlock()->getSize(), 0, Linkage::Strong,
- Scope::Local, false);
- }
- }
- }
- return Error::success();
- }
- private:
- SectionRange &getSectionRange(Section &Sec) {
- auto I = SectionRanges.find(&Sec);
- if (I == SectionRanges.end())
- I = SectionRanges.insert(std::make_pair(&Sec, SectionRange(Sec))).first;
- return I->second;
- }
- DenseMap<Section *, SectionRange> SectionRanges;
- SymbolIdentifierFunction F;
- };
- /// Returns a JITLink pass (as a function class) that uses the given symbol
- /// identification function to identify external section start and end symbols
- /// (and their associated Section*s) and transform the identified externals
- /// into defined symbols pointing to the start of the first block in the
- /// section and the end of the last (start and end symbols for empty sections
- /// will be transformed into absolute symbols at address 0).
- ///
- /// The identification function should be callable as
- ///
- /// SectionRangeSymbolDesc (LinkGraph &G, Symbol &Sym)
- ///
- /// If Sym is not a section range start or end symbol then a default
- /// constructed SectionRangeSymbolDesc should be returned. If Sym is a start
- /// symbol then SectionRangeSymbolDesc(Sec, true), where Sec is a reference to
- /// the target Section. If Sym is an end symbol then
- /// SectionRangeSymbolDesc(Sec, false) should be returned.
- ///
- /// This pass should be run in the PostAllocationPass pipeline, at which point
- /// all blocks should have been assigned their final addresses.
- template <typename SymbolIdentifierFunction>
- DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>
- createDefineExternalSectionStartAndEndSymbolsPass(
- SymbolIdentifierFunction &&F) {
- return DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>(
- std::forward<SymbolIdentifierFunction>(F));
- }
- } // end namespace jitlink
- } // end namespace llvm
- #undef DEBUG_TYPE
- #endif // LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
|