MachOLinkGraphBuilder.h 8.8 KB

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