DefineExternalSectionStartAndEndSymbols.h 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. //===--------- DefineExternalSectionStartAndEndSymbols.h --------*- 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. // 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.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
  15. #define LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H
  16. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  17. #include "llvm/Support/Debug.h"
  18. #define DEBUG_TYPE "jitlink"
  19. namespace llvm {
  20. namespace jitlink {
  21. struct SectionRangeSymbolDesc {
  22. SectionRangeSymbolDesc() = default;
  23. SectionRangeSymbolDesc(Section &Sec, bool IsStart)
  24. : Sec(&Sec), IsStart(IsStart) {}
  25. Section *Sec = nullptr;
  26. bool IsStart = false;
  27. };
  28. /// Pass implementation for the createDefineExternalSectionStartAndEndSymbols
  29. /// function.
  30. template <typename SymbolIdentifierFunction>
  31. class DefineExternalSectionStartAndEndSymbols {
  32. public:
  33. DefineExternalSectionStartAndEndSymbols(SymbolIdentifierFunction F)
  34. : F(std::move(F)) {}
  35. Error operator()(LinkGraph &G) {
  36. // This pass will affect the external symbols set, so copy them out into a
  37. // vector and iterate over that.
  38. std::vector<Symbol *> Externals(G.external_symbols().begin(),
  39. G.external_symbols().end());
  40. for (auto *Sym : Externals) {
  41. SectionRangeSymbolDesc D = F(G, *Sym);
  42. if (D.Sec) {
  43. auto &SR = getSectionRange(*D.Sec);
  44. if (D.IsStart) {
  45. if (SR.empty())
  46. G.makeAbsolute(*Sym, orc::ExecutorAddr());
  47. else
  48. G.makeDefined(*Sym, *SR.getFirstBlock(), 0, 0, Linkage::Strong,
  49. Scope::Local, false);
  50. } else {
  51. if (SR.empty())
  52. G.makeAbsolute(*Sym, orc::ExecutorAddr());
  53. else
  54. G.makeDefined(*Sym, *SR.getLastBlock(),
  55. SR.getLastBlock()->getSize(), 0, Linkage::Strong,
  56. Scope::Local, false);
  57. }
  58. }
  59. }
  60. return Error::success();
  61. }
  62. private:
  63. SectionRange &getSectionRange(Section &Sec) {
  64. auto I = SectionRanges.find(&Sec);
  65. if (I == SectionRanges.end())
  66. I = SectionRanges.insert(std::make_pair(&Sec, SectionRange(Sec))).first;
  67. return I->second;
  68. }
  69. DenseMap<Section *, SectionRange> SectionRanges;
  70. SymbolIdentifierFunction F;
  71. };
  72. /// Returns a JITLink pass (as a function class) that uses the given symbol
  73. /// identification function to identify external section start and end symbols
  74. /// (and their associated Section*s) and transform the identified externals
  75. /// into defined symbols pointing to the start of the first block in the
  76. /// section and the end of the last (start and end symbols for empty sections
  77. /// will be transformed into absolute symbols at address 0).
  78. ///
  79. /// The identification function should be callable as
  80. ///
  81. /// SectionRangeSymbolDesc (LinkGraph &G, Symbol &Sym)
  82. ///
  83. /// If Sym is not a section range start or end symbol then a default
  84. /// constructed SectionRangeSymbolDesc should be returned. If Sym is a start
  85. /// symbol then SectionRangeSymbolDesc(Sec, true), where Sec is a reference to
  86. /// the target Section. If Sym is an end symbol then
  87. /// SectionRangeSymbolDesc(Sec, false) should be returned.
  88. ///
  89. /// This pass should be run in the PostAllocationPass pipeline, at which point
  90. /// all blocks should have been assigned their final addresses.
  91. template <typename SymbolIdentifierFunction>
  92. DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>
  93. createDefineExternalSectionStartAndEndSymbolsPass(
  94. SymbolIdentifierFunction &&F) {
  95. return DefineExternalSectionStartAndEndSymbols<SymbolIdentifierFunction>(
  96. std::forward<SymbolIdentifierFunction>(F));
  97. }
  98. } // end namespace jitlink
  99. } // end namespace llvm
  100. #undef DEBUG_TYPE
  101. #endif // LLVM_EXECUTIONENGINE_JITLINK_DEFINEEXTERNALSECTIONSTARTANDENDSYMBOLS_H