1 //===- SyntheticSections.cpp ---------------------------------------------===// 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 #include "SyntheticSections.h" 10 #include "Config.h" 11 #include "ExportTrie.h" 12 #include "InputFiles.h" 13 #include "MachOStructs.h" 14 #include "MergedOutputSection.h" 15 #include "OutputSegment.h" 16 #include "SymbolTable.h" 17 #include "Symbols.h" 18 #include "Writer.h" 19 20 #include "lld/Common/ErrorHandler.h" 21 #include "lld/Common/Memory.h" 22 #include "llvm/Support/EndianStream.h" 23 #include "llvm/Support/LEB128.h" 24 25 using namespace llvm; 26 using namespace llvm::support; 27 using namespace llvm::support::endian; 28 using namespace lld; 29 using namespace lld::macho; 30 31 InStruct macho::in; 32 std::vector<SyntheticSection *> macho::syntheticSections; 33 34 SyntheticSection::SyntheticSection(const char *segname, const char *name) 35 : OutputSection(SyntheticKind, name), segname(segname) { 36 syntheticSections.push_back(this); 37 } 38 39 // dyld3's MachOLoaded::getSlide() assumes that the __TEXT segment starts 40 // from the beginning of the file (i.e. the header). 41 MachHeaderSection::MachHeaderSection() 42 : SyntheticSection(segment_names::text, section_names::header) {} 43 44 void MachHeaderSection::addLoadCommand(LoadCommand *lc) { 45 loadCommands.push_back(lc); 46 sizeOfCmds += lc->getSize(); 47 } 48 49 uint64_t MachHeaderSection::getSize() const { 50 return sizeof(MachO::mach_header_64) + sizeOfCmds + config->headerPad; 51 } 52 53 void MachHeaderSection::writeTo(uint8_t *buf) const { 54 auto *hdr = reinterpret_cast<MachO::mach_header_64 *>(buf); 55 hdr->magic = MachO::MH_MAGIC_64; 56 hdr->cputype = MachO::CPU_TYPE_X86_64; 57 hdr->cpusubtype = MachO::CPU_SUBTYPE_X86_64_ALL | MachO::CPU_SUBTYPE_LIB64; 58 hdr->filetype = config->outputType; 59 hdr->ncmds = loadCommands.size(); 60 hdr->sizeofcmds = sizeOfCmds; 61 hdr->flags = MachO::MH_NOUNDEFS | MachO::MH_DYLDLINK | MachO::MH_TWOLEVEL; 62 63 if (config->outputType == MachO::MH_DYLIB && !config->hasReexports) 64 hdr->flags |= MachO::MH_NO_REEXPORTED_DYLIBS; 65 66 for (OutputSegment *seg : outputSegments) { 67 for (OutputSection *osec : seg->getSections()) { 68 if (isThreadLocalVariables(osec->flags)) { 69 hdr->flags |= MachO::MH_HAS_TLV_DESCRIPTORS; 70 break; 71 } 72 } 73 } 74 75 uint8_t *p = reinterpret_cast<uint8_t *>(hdr + 1); 76 for (LoadCommand *lc : loadCommands) { 77 lc->writeTo(p); 78 p += lc->getSize(); 79 } 80 } 81 82 PageZeroSection::PageZeroSection() 83 : SyntheticSection(segment_names::pageZero, section_names::pageZero) {} 84 85 NonLazyPointerSectionBase::NonLazyPointerSectionBase(const char *segname, 86 const char *name) 87 : SyntheticSection(segname, name) { 88 align = 8; 89 flags = MachO::S_NON_LAZY_SYMBOL_POINTERS; 90 } 91 92 void NonLazyPointerSectionBase::addEntry(Symbol &sym) { 93 if (entries.insert(&sym)) { 94 assert(sym.gotIndex == UINT32_MAX); 95 sym.gotIndex = entries.size() - 1; 96 } 97 } 98 99 void NonLazyPointerSectionBase::writeTo(uint8_t *buf) const { 100 for (size_t i = 0, n = entries.size(); i < n; ++i) 101 if (auto *defined = dyn_cast<Defined>(entries[i])) 102 write64le(&buf[i * WordSize], defined->getVA()); 103 } 104 105 BindingSection::BindingSection() 106 : LinkEditSection(segment_names::linkEdit, section_names::binding) {} 107 108 bool BindingSection::isNeeded() const { 109 return bindings.size() != 0 || in.got->isNeeded() || 110 in.tlvPointers->isNeeded(); 111 } 112 113 namespace { 114 struct Binding { 115 OutputSegment *segment = nullptr; 116 uint64_t offset = 0; 117 int64_t addend = 0; 118 uint8_t ordinal = 0; 119 }; 120 } // namespace 121 122 // Encode a sequence of opcodes that tell dyld to write the address of dysym + 123 // addend at osec->addr + outSecOff. 124 // 125 // The bind opcode "interpreter" remembers the values of each binding field, so 126 // we only need to encode the differences between bindings. Hence the use of 127 // lastBinding. 128 static void encodeBinding(const DylibSymbol &dysym, const OutputSection *osec, 129 uint64_t outSecOff, int64_t addend, 130 Binding &lastBinding, raw_svector_ostream &os) { 131 using namespace llvm::MachO; 132 OutputSegment *seg = osec->parent; 133 uint64_t offset = osec->getSegmentOffset() + outSecOff; 134 if (lastBinding.segment != seg) { 135 os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | 136 seg->index); 137 encodeULEB128(offset, os); 138 lastBinding.segment = seg; 139 lastBinding.offset = offset; 140 } else if (lastBinding.offset != offset) { 141 os << static_cast<uint8_t>(BIND_OPCODE_ADD_ADDR_ULEB); 142 encodeULEB128(offset - lastBinding.offset, os); 143 lastBinding.offset = offset; 144 } 145 146 if (lastBinding.ordinal != dysym.file->ordinal) { 147 if (dysym.file->ordinal <= BIND_IMMEDIATE_MASK) { 148 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | 149 dysym.file->ordinal); 150 } else { 151 os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB); 152 encodeULEB128(dysym.file->ordinal, os); 153 } 154 lastBinding.ordinal = dysym.file->ordinal; 155 } 156 157 if (lastBinding.addend != addend) { 158 os << static_cast<uint8_t>(BIND_OPCODE_SET_ADDEND_SLEB); 159 encodeSLEB128(addend, os); 160 lastBinding.addend = addend; 161 } 162 163 os << static_cast<uint8_t>(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) 164 << dysym.getName() << '\0' 165 << static_cast<uint8_t>(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER) 166 << static_cast<uint8_t>(BIND_OPCODE_DO_BIND); 167 // DO_BIND causes dyld to both perform the binding and increment the offset 168 lastBinding.offset += WordSize; 169 } 170 171 static bool encodeNonLazyPointerSection(NonLazyPointerSectionBase *osec, 172 Binding &lastBinding, 173 raw_svector_ostream &os) { 174 bool didEncode = false; 175 size_t idx = 0; 176 for (const Symbol *sym : osec->getEntries()) { 177 if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) { 178 didEncode = true; 179 encodeBinding(*dysym, osec, idx * WordSize, /*addend=*/0, lastBinding, 180 os); 181 } 182 ++idx; 183 } 184 return didEncode; 185 } 186 187 // Emit bind opcodes, which are a stream of byte-sized opcodes that dyld 188 // interprets to update a record with the following fields: 189 // * segment index (of the segment to write the symbol addresses to, typically 190 // the __DATA_CONST segment which contains the GOT) 191 // * offset within the segment, indicating the next location to write a binding 192 // * symbol type 193 // * symbol library ordinal (the index of its library's LC_LOAD_DYLIB command) 194 // * symbol name 195 // * addend 196 // When dyld sees BIND_OPCODE_DO_BIND, it uses the current record state to bind 197 // a symbol in the GOT, and increments the segment offset to point to the next 198 // entry. It does *not* clear the record state after doing the bind, so 199 // subsequent opcodes only need to encode the differences between bindings. 200 void BindingSection::finalizeContents() { 201 raw_svector_ostream os{contents}; 202 Binding lastBinding; 203 bool didEncode = encodeNonLazyPointerSection(in.got, lastBinding, os); 204 didEncode |= encodeNonLazyPointerSection(in.tlvPointers, lastBinding, os); 205 206 // Sorting the relocations by segment and address allows us to encode them 207 // more compactly. 208 llvm::sort(bindings, [](const BindingEntry &a, const BindingEntry &b) { 209 OutputSegment *segA = a.isec->parent->parent; 210 OutputSegment *segB = b.isec->parent->parent; 211 if (segA != segB) 212 return segA->fileOff < segB->fileOff; 213 OutputSection *osecA = a.isec->parent; 214 OutputSection *osecB = b.isec->parent; 215 if (osecA != osecB) 216 return osecA->addr < osecB->addr; 217 if (a.isec != b.isec) 218 return a.isec->outSecOff < b.isec->outSecOff; 219 return a.offset < b.offset; 220 }); 221 for (const BindingEntry &b : bindings) { 222 didEncode = true; 223 encodeBinding(*b.dysym, b.isec->parent, b.isec->outSecOff + b.offset, 224 b.addend, lastBinding, os); 225 } 226 if (didEncode) 227 os << static_cast<uint8_t>(MachO::BIND_OPCODE_DONE); 228 } 229 230 void BindingSection::writeTo(uint8_t *buf) const { 231 memcpy(buf, contents.data(), contents.size()); 232 } 233 234 StubsSection::StubsSection() 235 : SyntheticSection(segment_names::text, "__stubs") {} 236 237 uint64_t StubsSection::getSize() const { 238 return entries.size() * target->stubSize; 239 } 240 241 void StubsSection::writeTo(uint8_t *buf) const { 242 size_t off = 0; 243 for (const DylibSymbol *sym : in.stubs->getEntries()) { 244 target->writeStub(buf + off, *sym); 245 off += target->stubSize; 246 } 247 } 248 249 void StubsSection::addEntry(DylibSymbol &sym) { 250 if (entries.insert(&sym)) 251 sym.stubsIndex = entries.size() - 1; 252 } 253 254 StubHelperSection::StubHelperSection() 255 : SyntheticSection(segment_names::text, "__stub_helper") {} 256 257 uint64_t StubHelperSection::getSize() const { 258 return target->stubHelperHeaderSize + 259 in.stubs->getEntries().size() * target->stubHelperEntrySize; 260 } 261 262 bool StubHelperSection::isNeeded() const { 263 return !in.stubs->getEntries().empty(); 264 } 265 266 void StubHelperSection::writeTo(uint8_t *buf) const { 267 target->writeStubHelperHeader(buf); 268 size_t off = target->stubHelperHeaderSize; 269 for (const DylibSymbol *sym : in.stubs->getEntries()) { 270 target->writeStubHelperEntry(buf + off, *sym, addr + off); 271 off += target->stubHelperEntrySize; 272 } 273 } 274 275 void StubHelperSection::setup() { 276 stubBinder = dyn_cast_or_null<DylibSymbol>(symtab->find("dyld_stub_binder")); 277 if (stubBinder == nullptr) { 278 error("symbol dyld_stub_binder not found (normally in libSystem.dylib). " 279 "Needed to perform lazy binding."); 280 return; 281 } 282 in.got->addEntry(*stubBinder); 283 284 inputSections.push_back(in.imageLoaderCache); 285 symtab->addDefined("__dyld_private", in.imageLoaderCache, 0, 286 /*isWeakDef=*/false); 287 } 288 289 ImageLoaderCacheSection::ImageLoaderCacheSection() { 290 segname = segment_names::data; 291 name = "__data"; 292 uint8_t *arr = bAlloc.Allocate<uint8_t>(WordSize); 293 memset(arr, 0, WordSize); 294 data = {arr, WordSize}; 295 } 296 297 LazyPointerSection::LazyPointerSection() 298 : SyntheticSection(segment_names::data, "__la_symbol_ptr") { 299 align = 8; 300 flags = MachO::S_LAZY_SYMBOL_POINTERS; 301 } 302 303 uint64_t LazyPointerSection::getSize() const { 304 return in.stubs->getEntries().size() * WordSize; 305 } 306 307 bool LazyPointerSection::isNeeded() const { 308 return !in.stubs->getEntries().empty(); 309 } 310 311 void LazyPointerSection::writeTo(uint8_t *buf) const { 312 size_t off = 0; 313 for (const DylibSymbol *sym : in.stubs->getEntries()) { 314 uint64_t stubHelperOffset = target->stubHelperHeaderSize + 315 sym->stubsIndex * target->stubHelperEntrySize; 316 write64le(buf + off, in.stubHelper->addr + stubHelperOffset); 317 off += WordSize; 318 } 319 } 320 321 LazyBindingSection::LazyBindingSection() 322 : LinkEditSection(segment_names::linkEdit, section_names::lazyBinding) {} 323 324 bool LazyBindingSection::isNeeded() const { return in.stubs->isNeeded(); } 325 326 void LazyBindingSection::finalizeContents() { 327 // TODO: Just precompute output size here instead of writing to a temporary 328 // buffer 329 for (DylibSymbol *sym : in.stubs->getEntries()) 330 sym->lazyBindOffset = encode(*sym); 331 } 332 333 void LazyBindingSection::writeTo(uint8_t *buf) const { 334 memcpy(buf, contents.data(), contents.size()); 335 } 336 337 // Unlike the non-lazy binding section, the bind opcodes in this section aren't 338 // interpreted all at once. Rather, dyld will start interpreting opcodes at a 339 // given offset, typically only binding a single symbol before it finds a 340 // BIND_OPCODE_DONE terminator. As such, unlike in the non-lazy-binding case, 341 // we cannot encode just the differences between symbols; we have to emit the 342 // complete bind information for each symbol. 343 uint32_t LazyBindingSection::encode(const DylibSymbol &sym) { 344 uint32_t opstreamOffset = contents.size(); 345 OutputSegment *dataSeg = in.lazyPointers->parent; 346 os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | 347 dataSeg->index); 348 uint64_t offset = in.lazyPointers->addr - dataSeg->firstSection()->addr + 349 sym.stubsIndex * WordSize; 350 encodeULEB128(offset, os); 351 if (sym.file->ordinal <= MachO::BIND_IMMEDIATE_MASK) { 352 os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | 353 sym.file->ordinal); 354 } else { 355 os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB); 356 encodeULEB128(sym.file->ordinal, os); 357 } 358 359 os << static_cast<uint8_t>(MachO::BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) 360 << sym.getName() << '\0' 361 << static_cast<uint8_t>(MachO::BIND_OPCODE_DO_BIND) 362 << static_cast<uint8_t>(MachO::BIND_OPCODE_DONE); 363 return opstreamOffset; 364 } 365 366 ExportSection::ExportSection() 367 : LinkEditSection(segment_names::linkEdit, section_names::export_) {} 368 369 void ExportSection::finalizeContents() { 370 // TODO: We should check symbol visibility. 371 for (const Symbol *sym : symtab->getSymbols()) 372 if (auto *defined = dyn_cast<Defined>(sym)) 373 trieBuilder.addSymbol(*defined); 374 size = trieBuilder.build(); 375 } 376 377 void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); } 378 379 SymtabSection::SymtabSection(StringTableSection &stringTableSection) 380 : SyntheticSection(segment_names::linkEdit, section_names::symbolTable), 381 stringTableSection(stringTableSection) {} 382 383 uint64_t SymtabSection::getSize() const { 384 return symbols.size() * sizeof(structs::nlist_64); 385 } 386 387 void SymtabSection::finalizeContents() { 388 // TODO support other symbol types 389 for (Symbol *sym : symtab->getSymbols()) 390 if (isa<Defined>(sym)) 391 symbols.push_back({sym, stringTableSection.addString(sym->getName())}); 392 } 393 394 void SymtabSection::writeTo(uint8_t *buf) const { 395 auto *nList = reinterpret_cast<structs::nlist_64 *>(buf); 396 for (const SymtabEntry &entry : symbols) { 397 nList->n_strx = entry.strx; 398 // TODO support other symbol types 399 // TODO populate n_desc 400 if (auto *defined = dyn_cast<Defined>(entry.sym)) { 401 nList->n_type = MachO::N_EXT | MachO::N_SECT; 402 nList->n_sect = defined->isec->parent->index; 403 // For the N_SECT symbol type, n_value is the address of the symbol 404 nList->n_value = defined->value + defined->isec->getVA(); 405 } 406 ++nList; 407 } 408 } 409 410 StringTableSection::StringTableSection() 411 : LinkEditSection(segment_names::linkEdit, section_names::stringTable) {} 412 413 uint32_t StringTableSection::addString(StringRef str) { 414 uint32_t strx = size; 415 strings.push_back(str); 416 size += str.size() + 1; // account for null terminator 417 return strx; 418 } 419 420 void StringTableSection::writeTo(uint8_t *buf) const { 421 uint32_t off = 0; 422 for (StringRef str : strings) { 423 memcpy(buf + off, str.data(), str.size()); 424 off += str.size() + 1; // account for null terminator 425 } 426 } 427