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