LLVM 19.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
87 SubtargetFeatures Features,
89
90 LinkGraph &getGraph() const { return *G; }
91
92 const object::MachOObjectFile &getObject() const { return Obj; }
93
96
97 virtual Error addRelocations() = 0;
98
99 /// Create a symbol.
100 template <typename... ArgTs>
102 NormalizedSymbol *Sym = reinterpret_cast<NormalizedSymbol *>(
103 Allocator.Allocate<NormalizedSymbol>());
104 new (Sym) NormalizedSymbol(std::forward<ArgTs>(Args)...);
105 return *Sym;
106 }
107
108 /// Index is zero-based (MachO section indexes are usually one-based) and
109 /// assumed to be in-range. Client is responsible for checking.
111 auto I = IndexToSection.find(Index);
112 assert(I != IndexToSection.end() && "No section recorded at index");
113 return I->second;
114 }
115
116 /// Try to get the section at the given index. Will return an error if the
117 /// given index is out of range, or if no section has been added for the given
118 /// index.
120 auto I = IndexToSection.find(Index);
121 if (I == IndexToSection.end())
122 return make_error<JITLinkError>("No section recorded for index " +
123 formatv("{0:d}", Index));
124 return I->second;
125 }
126
127 /// Try to get the symbol at the given index. Will return an error if the
128 /// given index is out of range, or if no symbol has been added for the given
129 /// index.
131 auto I = IndexToSymbol.find(Index);
132 if (I == IndexToSymbol.end())
133 return make_error<JITLinkError>("No symbol at index " +
134 formatv("{0:d}", Index));
135 assert(I->second && "Null symbol at index");
136 return *I->second;
137 }
138
139 /// Returns the symbol with the highest address not greater than the search
140 /// address, or null if no such symbol exists.
143 auto I = NSec.CanonicalSymbols.upper_bound(Address);
144 if (I == NSec.CanonicalSymbols.begin())
145 return nullptr;
146 return std::prev(I)->second;
147 }
148
149 /// Returns the symbol with the highest address not greater than the search
150 /// address, or an error if no such symbol exists.
153 auto *Sym = getSymbolByAddress(NSec, Address);
154 if (Sym)
155 if (Address <= Sym->getAddress() + Sym->getSize())
156 return *Sym;
157 return make_error<JITLinkError>("No symbol covering address " +
158 formatv("{0:x16}", Address));
159 }
160
162 static Scope getScope(StringRef Name, uint8_t Type);
163 static bool isAltEntry(const NormalizedSymbol &NSym);
164
165 static bool isDebugSection(const NormalizedSection &NSec);
166 static bool isZeroFillSection(const NormalizedSection &NSec);
167
171 getObject().getRelocation(RelItr->getRawDataRefImpl());
173 RI.r_address = ARI.r_word0;
174 RI.r_symbolnum = ARI.r_word1 & 0xffffff;
175 RI.r_pcrel = (ARI.r_word1 >> 24) & 1;
176 RI.r_length = (ARI.r_word1 >> 25) & 3;
177 RI.r_extern = (ARI.r_word1 >> 27) & 1;
178 RI.r_type = (ARI.r_word1 >> 28);
179 return RI;
180 }
181
182private:
183 static unsigned getPointerSize(const object::MachOObjectFile &Obj);
184 static llvm::endianness getEndianness(const object::MachOObjectFile &Obj);
185
186 void setCanonicalSymbol(NormalizedSection &NSec, Symbol &Sym) {
187 auto *&CanonicalSymEntry = NSec.CanonicalSymbols[Sym.getAddress()];
188 // There should be no symbol at this address, or, if there is,
189 // it should be a zero-sized symbol from an empty section (which
190 // we can safely override).
191 assert((!CanonicalSymEntry || CanonicalSymEntry->getSize() == 0) &&
192 "Duplicate canonical symbol at address");
193 CanonicalSymEntry = &Sym;
194 }
195
196 Section &getCommonSection();
197 void addSectionStartSymAndBlock(unsigned SecIndex, Section &GraphSec,
198 orc::ExecutorAddr Address, const char *Data,
200 uint32_t Alignment, bool IsLive);
201
202 Error createNormalizedSections();
203 Error createNormalizedSymbols();
204
205 /// Create graph blocks and symbols for externals, absolutes, commons and
206 /// all defined symbols in sections without custom parsers.
207 Error graphifyRegularSymbols();
208
209 /// Create and return a graph symbol for the given normalized symbol.
210 ///
211 /// NSym's GraphSymbol member will be updated to point at the newly created
212 /// symbol.
213 Symbol &createStandardGraphSymbol(NormalizedSymbol &Sym, Block &B,
214 size_t Size, bool IsText,
215 bool IsNoDeadStrip, bool IsCanonical);
216
217 /// Create graph blocks and symbols for all sections.
218 Error graphifySectionsWithCustomParsers();
219
220 /// Graphify cstring section.
221 Error graphifyCStringSection(NormalizedSection &NSec,
222 std::vector<NormalizedSymbol *> NSyms);
223
224 // Put the BumpPtrAllocator first so that we don't free any of the underlying
225 // memory until the Symbol/Addressable destructors have been run.
227
228 const object::MachOObjectFile &Obj;
229 std::unique_ptr<LinkGraph> G;
230
231 bool SubsectionsViaSymbols = false;
233 Section *CommonSection = nullptr;
234
236 StringMap<SectionParserFunction> CustomSectionParserFunctions;
237};
238
239/// A pass to split up __LD,__compact_unwind sections.
241public:
242 CompactUnwindSplitter(StringRef CompactUnwindSectionName)
243 : CompactUnwindSectionName(CompactUnwindSectionName) {}
245
246private:
247 StringRef CompactUnwindSectionName;
248};
249
250} // end namespace jitlink
251} // end namespace llvm
252
253#endif // LIB_EXECUTIONENGINE_JITLINK_MACHOLINKGRAPHBUILDER_H
This file defines the StringMap class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static std::optional< TypeSize > 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
Symbol * Sym
Definition: ELF_riscv.cpp:479
#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:160
Tagged union holding either a T or a Error.
Definition: Error.h:474
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition: StringMap.h:128
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Manages the enabling and disabling of subtarget specific features.
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))...))>
endianness
Definition: bit.h:70
Description of the encoding of one expression Op.