MachOLinkGraphBuilder.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. //===----- MachOLinkGraphBuilder.h - MachO LinkGraph builder ----*- 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. // Generic MachO LinkGraph building code.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
  13. #define LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
  14. #include "llvm/ADT/DenseMap.h"
  15. #include "llvm/ADT/StringMap.h"
  16. #include "llvm/ExecutionEngine/JITLink/JITLink.h"
  17. #include "llvm/Object/MachO.h"
  18. #include "EHFrameSupportImpl.h"
  19. #include "JITLinkGeneric.h"
  20. #include <list>
  21. namespace llvm {
  22. namespace jitlink {
  23. class MachOLinkGraphBuilder {
  24. public:
  25. virtual ~MachOLinkGraphBuilder();
  26. Expected<std::unique_ptr<LinkGraph>> buildGraph();
  27. protected:
  28. struct NormalizedSymbol {
  29. friend class MachOLinkGraphBuilder;
  30. private:
  31. NormalizedSymbol(std::optional<StringRef> Name, uint64_t Value,
  32. uint8_t Type, uint8_t Sect, uint16_t Desc, Linkage L,
  33. Scope S)
  34. : Name(Name), Value(Value), Type(Type), Sect(Sect), Desc(Desc), L(L),
  35. S(S) {
  36. assert((!Name || !Name->empty()) && "Name must be none or non-empty");
  37. }
  38. public:
  39. NormalizedSymbol(const NormalizedSymbol &) = delete;
  40. NormalizedSymbol &operator=(const NormalizedSymbol &) = delete;
  41. NormalizedSymbol(NormalizedSymbol &&) = delete;
  42. NormalizedSymbol &operator=(NormalizedSymbol &&) = delete;
  43. std::optional<StringRef> Name;
  44. uint64_t Value = 0;
  45. uint8_t Type = 0;
  46. uint8_t Sect = 0;
  47. uint16_t Desc = 0;
  48. Linkage L = Linkage::Strong;
  49. Scope S = Scope::Default;
  50. Symbol *GraphSymbol = nullptr;
  51. };
  52. // Normalized section representation. Section and segment names are guaranteed
  53. // to be null-terminated, hence the extra bytes on SegName and SectName.
  54. class NormalizedSection {
  55. friend class MachOLinkGraphBuilder;
  56. private:
  57. NormalizedSection() = default;
  58. public:
  59. char SectName[17];
  60. char SegName[17];
  61. orc::ExecutorAddr Address;
  62. uint64_t Size = 0;
  63. uint64_t Alignment = 0;
  64. uint32_t Flags = 0;
  65. const char *Data = nullptr;
  66. Section *GraphSection = nullptr;
  67. std::map<orc::ExecutorAddr, Symbol *> CanonicalSymbols;
  68. };
  69. using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
  70. MachOLinkGraphBuilder(const object::MachOObjectFile &Obj, Triple TT,
  71. LinkGraph::GetEdgeKindNameFunction GetEdgeKindName);
  72. LinkGraph &getGraph() const { return *G; }
  73. const object::MachOObjectFile &getObject() const { return Obj; }
  74. void addCustomSectionParser(StringRef SectionName,
  75. SectionParserFunction Parse);
  76. virtual Error addRelocations() = 0;
  77. /// Create a symbol.
  78. template <typename... ArgTs>
  79. NormalizedSymbol &createNormalizedSymbol(ArgTs &&... Args) {
  80. NormalizedSymbol *Sym = reinterpret_cast<NormalizedSymbol *>(
  81. Allocator.Allocate<NormalizedSymbol>());
  82. new (Sym) NormalizedSymbol(std::forward<ArgTs>(Args)...);
  83. return *Sym;
  84. }
  85. /// Index is zero-based (MachO section indexes are usually one-based) and
  86. /// assumed to be in-range. Client is responsible for checking.
  87. NormalizedSection &getSectionByIndex(unsigned Index) {
  88. auto I = IndexToSection.find(Index);
  89. assert(I != IndexToSection.end() && "No section recorded at index");
  90. return I->second;
  91. }
  92. /// Try to get the section at the given index. Will return an error if the
  93. /// given index is out of range, or if no section has been added for the given
  94. /// index.
  95. Expected<NormalizedSection &> findSectionByIndex(unsigned Index) {
  96. auto I = IndexToSection.find(Index);
  97. if (I == IndexToSection.end())
  98. return make_error<JITLinkError>("No section recorded for index " +
  99. formatv("{0:d}", Index));
  100. return I->second;
  101. }
  102. /// Try to get the symbol at the given index. Will return an error if the
  103. /// given index is out of range, or if no symbol has been added for the given
  104. /// index.
  105. Expected<NormalizedSymbol &> findSymbolByIndex(uint64_t Index) {
  106. auto I = IndexToSymbol.find(Index);
  107. if (I == IndexToSymbol.end())
  108. return make_error<JITLinkError>("No symbol at index " +
  109. formatv("{0:d}", Index));
  110. assert(I->second && "Null symbol at index");
  111. return *I->second;
  112. }
  113. /// Returns the symbol with the highest address not greater than the search
  114. /// address, or null if no such symbol exists.
  115. Symbol *getSymbolByAddress(NormalizedSection &NSec,
  116. orc::ExecutorAddr Address) {
  117. auto I = NSec.CanonicalSymbols.upper_bound(Address);
  118. if (I == NSec.CanonicalSymbols.begin())
  119. return nullptr;
  120. return std::prev(I)->second;
  121. }
  122. /// Returns the symbol with the highest address not greater than the search
  123. /// address, or an error if no such symbol exists.
  124. Expected<Symbol &> findSymbolByAddress(NormalizedSection &NSec,
  125. orc::ExecutorAddr Address) {
  126. auto *Sym = getSymbolByAddress(NSec, Address);
  127. if (Sym)
  128. if (Address <= Sym->getAddress() + Sym->getSize())
  129. return *Sym;
  130. return make_error<JITLinkError>("No symbol covering address " +
  131. formatv("{0:x16}", Address));
  132. }
  133. static Linkage getLinkage(uint16_t Desc);
  134. static Scope getScope(StringRef Name, uint8_t Type);
  135. static bool isAltEntry(const NormalizedSymbol &NSym);
  136. static bool isDebugSection(const NormalizedSection &NSec);
  137. static bool isZeroFillSection(const NormalizedSection &NSec);
  138. MachO::relocation_info
  139. getRelocationInfo(const object::relocation_iterator RelItr) {
  140. MachO::any_relocation_info ARI =
  141. getObject().getRelocation(RelItr->getRawDataRefImpl());
  142. MachO::relocation_info RI;
  143. RI.r_address = ARI.r_word0;
  144. RI.r_symbolnum = ARI.r_word1 & 0xffffff;
  145. RI.r_pcrel = (ARI.r_word1 >> 24) & 1;
  146. RI.r_length = (ARI.r_word1 >> 25) & 3;
  147. RI.r_extern = (ARI.r_word1 >> 27) & 1;
  148. RI.r_type = (ARI.r_word1 >> 28);
  149. return RI;
  150. }
  151. private:
  152. static unsigned getPointerSize(const object::MachOObjectFile &Obj);
  153. static support::endianness getEndianness(const object::MachOObjectFile &Obj);
  154. void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
  155. auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
  156. // There should be no symbol at this address, or, if there is,
  157. // it should be a zero-sized symbol from an empty section (which
  158. // we can safely override).
  159. assert((!CanonicalSymEntry || CanonicalSymEntry->getSize() == 0) &&
  160. "Duplicate canonical symbol at address");
  161. CanonicalSymEntry = &Sym;
  162. }
  163. Section &getCommonSection();
  164. void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
  165. orc::ExecutorAddr Address, const char *Data,
  166. orc::ExecutorAddrDiff Size,
  167. uint32_t Alignment, bool IsLive);
  168. Error createNormalizedSections();
  169. Error createNormalizedSymbols();
  170. /// Create graph blocks and symbols for externals, absolutes, commons and
  171. /// all defined symbols in sections without custom parsers.
  172. Error graphifyRegularSymbols();
  173. /// Create and return a graph symbol for the given normalized symbol.
  174. ///
  175. /// NSym's GraphSymbol member will be updated to point at the newly created
  176. /// symbol.
  177. Symbol &createStandardGraphSymbol(NormalizedSymbol &Sym, Block &B,
  178. size_t Size, bool IsText,
  179. bool IsNoDeadStrip, bool IsCanonical);
  180. /// Create graph blocks and symbols for all sections.
  181. Error graphifySectionsWithCustomParsers();
  182. /// Graphify cstring section.
  183. Error graphifyCStringSection(NormalizedSection &NSec,
  184. std::vector<NormalizedSymbol *> NSyms);
  185. // Put the BumpPtrAllocator first so that we don't free any of the underlying
  186. // memory until the Symbol/Addressable destructors have been run.
  187. BumpPtrAllocator Allocator;
  188. const object::MachOObjectFile &Obj;
  189. std::unique_ptr<LinkGraph> G;
  190. bool SubsectionsViaSymbols = false;
  191. DenseMap<unsigned, NormalizedSection> IndexToSection;
  192. Section *CommonSection = nullptr;
  193. DenseMap<uint32_t, NormalizedSymbol *> IndexToSymbol;
  194. StringMap<SectionParserFunction> CustomSectionParserFunctions;
  195. };
  196. /// A pass to split up __LD,__compact_unwind sections.
  197. class CompactUnwindSplitter {
  198. public:
  199. CompactUnwindSplitter(StringRef CompactUnwindSectionName)
  200. : CompactUnwindSectionName(CompactUnwindSectionName) {}
  201. Error operator()(LinkGraph &G);
  202. private:
  203. StringRef CompactUnwindSectionName;
  204. };
  205. } // end namespace jitlink
  206. } // end namespace llvm
  207. #endif // LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H