xref: /freebsd/contrib/llvm-project/lld/MachO/SyntheticSections.h (revision cfd6422a5217410fbd66f7a7a8a64d9d85e61229)
1 //===- SyntheticSections.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 #ifndef LLD_MACHO_SYNTHETIC_SECTIONS_H
10 #define LLD_MACHO_SYNTHETIC_SECTIONS_H
11 
12 #include "Config.h"
13 #include "ExportTrie.h"
14 #include "InputSection.h"
15 #include "OutputSection.h"
16 #include "Target.h"
17 
18 #include "llvm/ADT/SetVector.h"
19 #include "llvm/Support/raw_ostream.h"
20 
21 namespace lld {
22 namespace macho {
23 
24 namespace section_names {
25 
26 constexpr const char pageZero[] = "__pagezero";
27 constexpr const char header[] = "__mach_header";
28 constexpr const char binding[] = "__binding";
29 constexpr const char lazyBinding[] = "__lazy_binding";
30 constexpr const char export_[] = "__export";
31 constexpr const char symbolTable[] = "__symbol_table";
32 constexpr const char stringTable[] = "__string_table";
33 constexpr const char got[] = "__got";
34 
35 } // namespace section_names
36 
37 class DylibSymbol;
38 class LoadCommand;
39 
40 class SyntheticSection : public OutputSection {
41 public:
42   SyntheticSection(const char *segname, const char *name);
43   virtual ~SyntheticSection() = default;
44 
45   static bool classof(const OutputSection *sec) {
46     return sec->kind() == SyntheticKind;
47   }
48 
49   const StringRef segname;
50 };
51 
52 // The header of the Mach-O file, which must have a file offset of zero.
53 class MachHeaderSection : public SyntheticSection {
54 public:
55   MachHeaderSection();
56   void addLoadCommand(LoadCommand *);
57   bool isHidden() const override { return true; }
58   uint64_t getSize() const override;
59   void writeTo(uint8_t *buf) const override;
60 
61 private:
62   std::vector<LoadCommand *> loadCommands;
63   uint32_t sizeOfCmds = 0;
64 };
65 
66 // A hidden section that exists solely for the purpose of creating the
67 // __PAGEZERO segment, which is used to catch null pointer dereferences.
68 class PageZeroSection : public SyntheticSection {
69 public:
70   PageZeroSection();
71   bool isHidden() const override { return true; }
72   uint64_t getSize() const override { return PageZeroSize; }
73   uint64_t getFileSize() const override { return 0; }
74   void writeTo(uint8_t *buf) const override {}
75 };
76 
77 // This section will be populated by dyld with addresses to non-lazily-loaded
78 // dylib symbols.
79 class GotSection : public SyntheticSection {
80 public:
81   GotSection();
82 
83   const llvm::SetVector<const Symbol *> &getEntries() const { return entries; }
84 
85   bool isNeeded() const override { return !entries.empty(); }
86 
87   uint64_t getSize() const override { return entries.size() * WordSize; }
88 
89   void writeTo(uint8_t *buf) const override;
90 
91   void addEntry(Symbol &sym);
92 
93 private:
94   llvm::SetVector<const Symbol *> entries;
95 };
96 
97 struct BindingEntry {
98   const DylibSymbol *dysym;
99   const InputSection *isec;
100   uint64_t offset;
101   int64_t addend;
102   BindingEntry(const DylibSymbol *dysym, const InputSection *isec,
103                uint64_t offset, int64_t addend)
104       : dysym(dysym), isec(isec), offset(offset), addend(addend) {}
105 };
106 
107 // Stores bind opcodes for telling dyld which symbols to load non-lazily.
108 class BindingSection : public SyntheticSection {
109 public:
110   BindingSection();
111   void finalizeContents();
112   uint64_t getSize() const override { return contents.size(); }
113   // Like other sections in __LINKEDIT, the binding section is special: its
114   // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
115   // section headers.
116   bool isHidden() const override { return true; }
117   bool isNeeded() const override;
118   void writeTo(uint8_t *buf) const override;
119 
120   void addEntry(const DylibSymbol *dysym, const InputSection *isec,
121                 uint64_t offset, int64_t addend) {
122     bindings.emplace_back(dysym, isec, offset, addend);
123   }
124 
125 private:
126   std::vector<BindingEntry> bindings;
127   SmallVector<char, 128> contents;
128 };
129 
130 // The following sections implement lazy symbol binding -- very similar to the
131 // PLT mechanism in ELF.
132 //
133 // ELF's .plt section is broken up into two sections in Mach-O: StubsSection and
134 // StubHelperSection. Calls to functions in dylibs will end up calling into
135 // StubsSection, which contains indirect jumps to addresses stored in the
136 // LazyPointerSection (the counterpart to ELF's .plt.got).
137 //
138 // Initially, the LazyPointerSection contains addresses that point into one of
139 // the entry points in the middle of the StubHelperSection. The code in
140 // StubHelperSection will push on the stack an offset into the
141 // LazyBindingSection. The push is followed by a jump to the beginning of the
142 // StubHelperSection (similar to PLT0), which then calls into dyld_stub_binder.
143 // dyld_stub_binder is a non-lazily-bound symbol, so this call looks it up in
144 // the GOT.
145 //
146 // The stub binder will look up the bind opcodes in the LazyBindingSection at
147 // the given offset. The bind opcodes will tell the binder to update the address
148 // in the LazyPointerSection to point to the symbol, so that subsequent calls
149 // don't have to redo the symbol resolution. The binder will then jump to the
150 // resolved symbol.
151 
152 class StubsSection : public SyntheticSection {
153 public:
154   StubsSection();
155   uint64_t getSize() const override;
156   bool isNeeded() const override { return !entries.empty(); }
157   void writeTo(uint8_t *buf) const override;
158 
159   const llvm::SetVector<DylibSymbol *> &getEntries() const { return entries; }
160 
161   void addEntry(DylibSymbol &sym);
162 
163 private:
164   llvm::SetVector<DylibSymbol *> entries;
165 };
166 
167 class StubHelperSection : public SyntheticSection {
168 public:
169   StubHelperSection();
170   uint64_t getSize() const override;
171   bool isNeeded() const override;
172   void writeTo(uint8_t *buf) const override;
173 
174   void setup();
175 
176   DylibSymbol *stubBinder = nullptr;
177 };
178 
179 // This section contains space for just a single word, and will be used by dyld
180 // to cache an address to the image loader it uses. Note that unlike the other
181 // synthetic sections, which are OutputSections, the ImageLoaderCacheSection is
182 // an InputSection that gets merged into the __data OutputSection.
183 class ImageLoaderCacheSection : public InputSection {
184 public:
185   ImageLoaderCacheSection();
186   uint64_t getSize() const override { return WordSize; }
187 };
188 
189 class LazyPointerSection : public SyntheticSection {
190 public:
191   LazyPointerSection();
192   uint64_t getSize() const override;
193   bool isNeeded() const override;
194   void writeTo(uint8_t *buf) const override;
195 };
196 
197 class LazyBindingSection : public SyntheticSection {
198 public:
199   LazyBindingSection();
200   void finalizeContents();
201   uint64_t getSize() const override { return contents.size(); }
202   uint32_t encode(const DylibSymbol &);
203   // Like other sections in __LINKEDIT, the lazy binding section is special: its
204   // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
205   // section headers.
206   bool isHidden() const override { return true; }
207   bool isNeeded() const override;
208   void writeTo(uint8_t *buf) const override;
209 
210 private:
211   SmallVector<char, 128> contents;
212   llvm::raw_svector_ostream os{contents};
213 };
214 
215 // Stores a trie that describes the set of exported symbols.
216 class ExportSection : public SyntheticSection {
217 public:
218   ExportSection();
219   void finalizeContents();
220   uint64_t getSize() const override { return size; }
221   // Like other sections in __LINKEDIT, the export section is special: its
222   // offsets are recorded in the LC_DYLD_INFO_ONLY load command, instead of in
223   // section headers.
224   bool isHidden() const override { return true; }
225   void writeTo(uint8_t *buf) const override;
226 
227 private:
228   TrieBuilder trieBuilder;
229   size_t size = 0;
230 };
231 
232 // Stores the strings referenced by the symbol table.
233 class StringTableSection : public SyntheticSection {
234 public:
235   StringTableSection();
236   // Returns the start offset of the added string.
237   uint32_t addString(StringRef);
238   uint64_t getSize() const override { return size; }
239   // Like other sections in __LINKEDIT, the string table section is special: its
240   // offsets are recorded in the LC_SYMTAB load command, instead of in section
241   // headers.
242   bool isHidden() const override { return true; }
243   void writeTo(uint8_t *buf) const override;
244 
245 private:
246   // An n_strx value of 0 always indicates the empty string, so we must locate
247   // our non-empty string values at positive offsets in the string table.
248   // Therefore we insert a dummy value at position zero.
249   std::vector<StringRef> strings{"\0"};
250   size_t size = 1;
251 };
252 
253 struct SymtabEntry {
254   Symbol *sym;
255   size_t strx;
256 };
257 
258 class SymtabSection : public SyntheticSection {
259 public:
260   SymtabSection(StringTableSection &);
261   void finalizeContents();
262   size_t getNumSymbols() const { return symbols.size(); }
263   uint64_t getSize() const override;
264   // Like other sections in __LINKEDIT, the symtab section is special: its
265   // offsets are recorded in the LC_SYMTAB load command, instead of in section
266   // headers.
267   bool isHidden() const override { return true; }
268   void writeTo(uint8_t *buf) const override;
269 
270 private:
271   StringTableSection &stringTableSection;
272   std::vector<SymtabEntry> symbols;
273 };
274 
275 struct InStruct {
276   BindingSection *binding = nullptr;
277   GotSection *got = nullptr;
278   LazyPointerSection *lazyPointers = nullptr;
279   StubsSection *stubs = nullptr;
280   StubHelperSection *stubHelper = nullptr;
281   ImageLoaderCacheSection *imageLoaderCache = nullptr;
282 };
283 
284 extern InStruct in;
285 extern std::vector<SyntheticSection *> syntheticSections;
286 
287 } // namespace macho
288 } // namespace lld
289 
290 #endif
291