LLVM 17.0.0git
MachOLinkGraphBuilder.h
Go to the documentation of this file.
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
13#ifndef LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
14#define LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
15
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/StringMap.h"
19#include "llvm/Object/MachO.h"
20
21#include "EHFrameSupportImpl.h"
22#include "JITLinkGeneric.h"
23
24#include <list>
25
26namespace llvm {
27namespace jitlink {
28
30public:
33
34protected:
35
38
39 private:
40 NormalizedSymbol(std::optional<StringRef> Name, uint64_t Value,
41 uint8_t Type, uint8_t Sect, uint16_t Desc, Linkage L,
42 Scope S)
44 S(S) {
45 assert((!Name || !Name->empty()) && "Name must be none or non-empty");
46 }
47
48 public:
53
54 std::optional<StringRef> Name;
56 uint8_t Type = 0;
57 uint8_t Sect = 0;
61 Symbol *GraphSymbol = nullptr;
62 };
63
64 // Normalized section representation. Section and segment names are guaranteed
65 // to be null-terminated, hence the extra bytes on SegName and SectName.
68
69 private:
70 NormalizedSection() = default;
71
72 public:
73 char SectName[17];
74 char SegName[17];
79 const char *Data = nullptr;
81 std::map<orc::ExecutorAddr, Symbol *> CanonicalSymbols;
82 };
83
84 using SectionParserFunction = std::function<Error(NormalizedSection &S)>;
85
88
89 LinkGraph &getGraph() const { return *G; }
90
91 const object::MachOObjectFile &getObject() const { return Obj; }
92
95
96 virtual Error addRelocations() = 0;
97
98 /// Create a symbol.
99 template <typename... ArgTs>
101 NormalizedSymbol *Sym = reinterpret_cast<NormalizedSymbol *>(
102 Allocator.Allocate<NormalizedSymbol>());
103 new (Sym) NormalizedSymbol(std::forward<ArgTs>(Args)...);
104 return *Sym;
105 }
106
107 /// Index is zero-based (MachO section indexes are usually one-based) and
108 /// assumed to be in-range. Client is responsible for checking.
110 auto I = IndexToSection.find(Index);
111 assert(I != IndexToSection.end() && "No section recorded at index");
112 return I->second;
113 }
114
115 /// Try to get the section at the given index. Will return an error if the
116 /// given index is out of range, or if no section has been added for the given
117 /// index.
119 auto I = IndexToSection.find(Index);
120 if (I == IndexToSection.end())
121 return make_error<JITLinkError>("No section recorded for index " +
122 formatv("{0:d}", Index));
123 return I->second;
124 }
125
126 /// Try to get the symbol at the given index. Will return an error if the
127 /// given index is out of range, or if no symbol has been added for the given
128 /// index.
130 auto I = IndexToSymbol.find(Index);
131 if (I == IndexToSymbol.end())
132 return make_error<JITLinkError>("No symbol at index " +
133 formatv("{0:d}", Index));
134 assert(I->second && "Null symbol at index");
135 return *I->second;
136 }
137
138 /// Returns the symbol with the highest address not greater than the search
139 /// address, or null if no such symbol exists.
142 auto I = NSec.CanonicalSymbols.upper_bound(Address);
143 if (I == NSec.CanonicalSymbols.begin())
144 return nullptr;
145 return std::prev(I)->second;
146 }
147
148 /// Returns the symbol with the highest address not greater than the search
149 /// address, or an error if no such symbol exists.
152 auto *Sym = getSymbolByAddress(NSec, Address);
153 if (Sym)
154 if (Address <= Sym->getAddress() + Sym->getSize())
155 return *Sym;
156 return make_error<JITLinkError>("No symbol covering address " +
157 formatv("{0:x16}", Address));
158 }
159
160 static Linkage getLinkage(uint16_t Desc);
161 static Scope getScope(StringRef Name, uint8_t Type);
162 static bool isAltEntry(const NormalizedSymbol &NSym);
163
164 static bool isDebugSection(const NormalizedSection &NSec);
165 static bool isZeroFillSection(const NormalizedSection &NSec);
166
170 getObject().getRelocation(RelItr->getRawDataRefImpl());
172 RI.r_address = ARI.r_word0;
173 RI.r_symbolnum = ARI.r_word1 & 0xffffff;
174 RI.r_pcrel = (ARI.r_word1 >> 24) & 1;
175 RI.r_length = (ARI.r_word1 >> 25) & 3;
176 RI.r_extern = (ARI.r_word1 >> 27) & 1;
177 RI.r_type = (ARI.r_word1 >> 28);
178 return RI;
179 }
180
181private:
182 static unsigned getPointerSize(const object::MachOObjectFile &Obj);
183 static support::endianness getEndianness(const object::MachOObjectFile &Obj);
184
185 void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
186 auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
187 // There should be no symbol at this address, or, if there is,
188 // it should be a zero-sized symbol from an empty section (which
189 // we can safely override).
190 assert((!CanonicalSymEntry || CanonicalSymEntry->getSize() == 0) &&
191 "Duplicate canonical symbol at address");
192 CanonicalSymEntry = &Sym;
193 }
194
195 Section &getCommonSection();
196 void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
197 orc::ExecutorAddr Address, const char *Data,
199 uint32_t Alignment, bool IsLive);
200
201 Error createNormalizedSections();
202 Error createNormalizedSymbols();
203
204 /// Create graph blocks and symbols for externals, absolutes, commons and
205 /// all defined symbols in sections without custom parsers.
206 Error graphifyRegularSymbols();
207
208 /// Create and return a graph symbol for the given normalized symbol.
209 ///
210 /// NSym's GraphSymbol member will be updated to point at the newly created
211 /// symbol.
212 Symbol &createStandardGraphSymbol(NormalizedSymbol &Sym, Block &B,
213 size_t Size, bool IsText,
214 bool IsNoDeadStrip, bool IsCanonical);
215
216 /// Create graph blocks and symbols for all sections.
217 Error graphifySectionsWithCustomParsers();
218
219 /// Graphify cstring section.
220 Error graphifyCStringSection(NormalizedSection &NSec,
221 std::vector<NormalizedSymbol *> NSyms);
222
223 // Put the BumpPtrAllocator first so that we don't free any of the underlying
224 // memory until the Symbol/Addressable destructors have been run.
226
227 const object::MachOObjectFile &Obj;
228 std::unique_ptr<LinkGraph> G;
229
230 bool SubsectionsViaSymbols = false;
232 Section *CommonSection = nullptr;
233
235 StringMap<SectionParserFunction> CustomSectionParserFunctions;
236};
237
238/// A pass to split up __LD,__compact_unwind sections.
240public:
241 CompactUnwindSplitter(StringRef CompactUnwindSectionName)
242 : CompactUnwindSectionName(CompactUnwindSectionName) {}
244
245private:
246 StringRef CompactUnwindSectionName;
247};
248
249} // end namespace jitlink
250} // end namespace llvm
251
252#endif // LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
This file defines the StringMap class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static uint64_t getPointerSize(const Value *V, const DataLayout &DL, const TargetLibraryInfo &TLI, const Function *F)
This file defines the DenseMap class.
std::string Name
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
Basic Register Allocator
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:66
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Tagged union holding either a T or a Error.
Definition: Error.h:470
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:111
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
MachO::any_relocation_info getRelocation(DataRefImpl Rel) const
Represents an address in the executor process.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>