Mercurial > hg > CbC > CbC_llvm
comparison lld/MachO/SyntheticSections.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
comparison
equal
deleted
inserted
replaced
173:0572611fdcc8 | 207:2e18cbf3894f |
---|---|
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 // | 6 // |
7 //===----------------------------------------------------------------------===// | 7 //===----------------------------------------------------------------------===// |
8 | 8 |
9 #include "SyntheticSections.h" | 9 #include "SyntheticSections.h" |
10 #include "ConcatOutputSection.h" | |
10 #include "Config.h" | 11 #include "Config.h" |
11 #include "ExportTrie.h" | 12 #include "ExportTrie.h" |
12 #include "InputFiles.h" | 13 #include "InputFiles.h" |
14 #include "MachOStructs.h" | |
13 #include "OutputSegment.h" | 15 #include "OutputSegment.h" |
14 #include "SymbolTable.h" | 16 #include "SymbolTable.h" |
15 #include "Symbols.h" | 17 #include "Symbols.h" |
16 #include "Writer.h" | 18 #include "Writer.h" |
17 | 19 |
18 #include "lld/Common/ErrorHandler.h" | 20 #include "lld/Common/ErrorHandler.h" |
21 #include "lld/Common/Memory.h" | |
22 #include "llvm/ADT/STLExtras.h" | |
23 #include "llvm/Config/llvm-config.h" | |
19 #include "llvm/Support/EndianStream.h" | 24 #include "llvm/Support/EndianStream.h" |
25 #include "llvm/Support/FileSystem.h" | |
20 #include "llvm/Support/LEB128.h" | 26 #include "llvm/Support/LEB128.h" |
27 #include "llvm/Support/Path.h" | |
28 #include "llvm/Support/SHA256.h" | |
29 | |
30 #if defined(__APPLE__) | |
31 #include <sys/mman.h> | |
32 #endif | |
33 | |
34 #ifdef LLVM_HAVE_LIBXAR | |
35 #include <fcntl.h> | |
36 #include <xar/xar.h> | |
37 #endif | |
21 | 38 |
22 using namespace llvm; | 39 using namespace llvm; |
23 using namespace llvm::MachO; | 40 using namespace llvm::MachO; |
24 using namespace llvm::support; | 41 using namespace llvm::support; |
25 using namespace llvm::support::endian; | 42 using namespace llvm::support::endian; |
26 | 43 using namespace lld; |
27 namespace lld { | 44 using namespace lld::macho; |
28 namespace macho { | 45 |
46 InStruct macho::in; | |
47 std::vector<SyntheticSection *> macho::syntheticSections; | |
29 | 48 |
30 SyntheticSection::SyntheticSection(const char *segname, const char *name) | 49 SyntheticSection::SyntheticSection(const char *segname, const char *name) |
31 : OutputSection(SyntheticKind, name) { | 50 : OutputSection(SyntheticKind, name), segname(segname) { |
32 // Synthetic sections always know which segment they belong to so hook | 51 isec = make<InputSection>(); |
33 // them up when they're made | 52 isec->segname = segname; |
34 getOrCreateOutputSegment(segname)->addOutputSection(this); | 53 isec->name = name; |
54 isec->parent = this; | |
55 isec->outSecOff = 0; | |
56 syntheticSections.push_back(this); | |
35 } | 57 } |
36 | 58 |
37 // dyld3's MachOLoaded::getSlide() assumes that the __TEXT segment starts | 59 // dyld3's MachOLoaded::getSlide() assumes that the __TEXT segment starts |
38 // from the beginning of the file (i.e. the header). | 60 // from the beginning of the file (i.e. the header). |
39 MachHeaderSection::MachHeaderSection() | 61 MachHeaderSection::MachHeaderSection() |
40 : SyntheticSection(segment_names::text, section_names::header) {} | 62 : SyntheticSection(segment_names::text, section_names::header) { |
63 // XXX: This is a hack. (See D97007) | |
64 // Setting the index to 1 to pretend that this section is the text | |
65 // section. | |
66 index = 1; | |
67 isec->isFinal = true; | |
68 } | |
41 | 69 |
42 void MachHeaderSection::addLoadCommand(LoadCommand *lc) { | 70 void MachHeaderSection::addLoadCommand(LoadCommand *lc) { |
43 loadCommands.push_back(lc); | 71 loadCommands.push_back(lc); |
44 sizeOfCmds += lc->getSize(); | 72 sizeOfCmds += lc->getSize(); |
45 } | 73 } |
46 | 74 |
47 size_t MachHeaderSection::getSize() const { | 75 uint64_t MachHeaderSection::getSize() const { |
48 return sizeof(mach_header_64) + sizeOfCmds; | 76 uint64_t size = target->headerSize + sizeOfCmds + config->headerPad; |
77 // If we are emitting an encryptable binary, our load commands must have a | |
78 // separate (non-encrypted) page to themselves. | |
79 if (config->emitEncryptionInfo) | |
80 size = alignTo(size, target->getPageSize()); | |
81 return size; | |
82 } | |
83 | |
84 static uint32_t cpuSubtype() { | |
85 uint32_t subtype = target->cpuSubtype; | |
86 | |
87 if (config->outputType == MH_EXECUTE && !config->staticLink && | |
88 target->cpuSubtype == CPU_SUBTYPE_X86_64_ALL && | |
89 config->platform() == PlatformKind::macOS && | |
90 config->platformInfo.minimum >= VersionTuple(10, 5)) | |
91 subtype |= CPU_SUBTYPE_LIB64; | |
92 | |
93 return subtype; | |
49 } | 94 } |
50 | 95 |
51 void MachHeaderSection::writeTo(uint8_t *buf) const { | 96 void MachHeaderSection::writeTo(uint8_t *buf) const { |
52 auto *hdr = reinterpret_cast<mach_header_64 *>(buf); | 97 auto *hdr = reinterpret_cast<mach_header *>(buf); |
53 hdr->magic = MH_MAGIC_64; | 98 hdr->magic = target->magic; |
54 hdr->cputype = CPU_TYPE_X86_64; | 99 hdr->cputype = target->cpuType; |
55 hdr->cpusubtype = CPU_SUBTYPE_X86_64_ALL | CPU_SUBTYPE_LIB64; | 100 hdr->cpusubtype = cpuSubtype(); |
56 hdr->filetype = config->outputType; | 101 hdr->filetype = config->outputType; |
57 hdr->ncmds = loadCommands.size(); | 102 hdr->ncmds = loadCommands.size(); |
58 hdr->sizeofcmds = sizeOfCmds; | 103 hdr->sizeofcmds = sizeOfCmds; |
59 hdr->flags = MH_NOUNDEFS | MH_DYLDLINK | MH_TWOLEVEL; | 104 hdr->flags = MH_DYLDLINK; |
105 | |
106 if (config->namespaceKind == NamespaceKind::twolevel) | |
107 hdr->flags |= MH_NOUNDEFS | MH_TWOLEVEL; | |
108 | |
60 if (config->outputType == MH_DYLIB && !config->hasReexports) | 109 if (config->outputType == MH_DYLIB && !config->hasReexports) |
61 hdr->flags |= MH_NO_REEXPORTED_DYLIBS; | 110 hdr->flags |= MH_NO_REEXPORTED_DYLIBS; |
62 | 111 |
63 uint8_t *p = reinterpret_cast<uint8_t *>(hdr + 1); | 112 if (config->markDeadStrippableDylib) |
64 for (LoadCommand *lc : loadCommands) { | 113 hdr->flags |= MH_DEAD_STRIPPABLE_DYLIB; |
114 | |
115 if (config->outputType == MH_EXECUTE && config->isPic) | |
116 hdr->flags |= MH_PIE; | |
117 | |
118 if (in.exports->hasWeakSymbol || in.weakBinding->hasNonWeakDefinition()) | |
119 hdr->flags |= MH_WEAK_DEFINES; | |
120 | |
121 if (in.exports->hasWeakSymbol || in.weakBinding->hasEntry()) | |
122 hdr->flags |= MH_BINDS_TO_WEAK; | |
123 | |
124 for (const OutputSegment *seg : outputSegments) { | |
125 for (const OutputSection *osec : seg->getSections()) { | |
126 if (isThreadLocalVariables(osec->flags)) { | |
127 hdr->flags |= MH_HAS_TLV_DESCRIPTORS; | |
128 break; | |
129 } | |
130 } | |
131 } | |
132 | |
133 uint8_t *p = reinterpret_cast<uint8_t *>(hdr) + target->headerSize; | |
134 for (const LoadCommand *lc : loadCommands) { | |
65 lc->writeTo(p); | 135 lc->writeTo(p); |
66 p += lc->getSize(); | 136 p += lc->getSize(); |
67 } | 137 } |
68 } | 138 } |
69 | 139 |
70 PageZeroSection::PageZeroSection() | 140 PageZeroSection::PageZeroSection() |
71 : SyntheticSection(segment_names::pageZero, section_names::pageZero) {} | 141 : SyntheticSection(segment_names::pageZero, section_names::pageZero) {} |
72 | 142 |
73 GotSection::GotSection() | 143 RebaseSection::RebaseSection() |
74 : SyntheticSection(segment_names::dataConst, section_names::got) { | 144 : LinkEditSection(segment_names::linkEdit, section_names::rebase) {} |
75 align = 8; | 145 |
146 namespace { | |
147 struct Rebase { | |
148 OutputSegment *segment = nullptr; | |
149 uint64_t offset = 0; | |
150 uint64_t consecutiveCount = 0; | |
151 }; | |
152 } // namespace | |
153 | |
154 // Rebase opcodes allow us to describe a contiguous sequence of rebase location | |
155 // using a single DO_REBASE opcode. To take advantage of it, we delay emitting | |
156 // `DO_REBASE` until we have reached the end of a contiguous sequence. | |
157 static void encodeDoRebase(Rebase &rebase, raw_svector_ostream &os) { | |
158 assert(rebase.consecutiveCount != 0); | |
159 if (rebase.consecutiveCount <= REBASE_IMMEDIATE_MASK) { | |
160 os << static_cast<uint8_t>(REBASE_OPCODE_DO_REBASE_IMM_TIMES | | |
161 rebase.consecutiveCount); | |
162 } else { | |
163 os << static_cast<uint8_t>(REBASE_OPCODE_DO_REBASE_ULEB_TIMES); | |
164 encodeULEB128(rebase.consecutiveCount, os); | |
165 } | |
166 rebase.consecutiveCount = 0; | |
167 } | |
168 | |
169 static void encodeRebase(const OutputSection *osec, uint64_t outSecOff, | |
170 Rebase &lastRebase, raw_svector_ostream &os) { | |
171 OutputSegment *seg = osec->parent; | |
172 uint64_t offset = osec->getSegmentOffset() + outSecOff; | |
173 if (lastRebase.segment != seg || lastRebase.offset != offset) { | |
174 if (lastRebase.consecutiveCount != 0) | |
175 encodeDoRebase(lastRebase, os); | |
176 | |
177 if (lastRebase.segment != seg) { | |
178 os << static_cast<uint8_t>(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | | |
179 seg->index); | |
180 encodeULEB128(offset, os); | |
181 lastRebase.segment = seg; | |
182 lastRebase.offset = offset; | |
183 } else { | |
184 assert(lastRebase.offset != offset); | |
185 os << static_cast<uint8_t>(REBASE_OPCODE_ADD_ADDR_ULEB); | |
186 encodeULEB128(offset - lastRebase.offset, os); | |
187 lastRebase.offset = offset; | |
188 } | |
189 } | |
190 ++lastRebase.consecutiveCount; | |
191 // DO_REBASE causes dyld to both perform the binding and increment the offset | |
192 lastRebase.offset += target->wordSize; | |
193 } | |
194 | |
195 void RebaseSection::finalizeContents() { | |
196 if (locations.empty()) | |
197 return; | |
198 | |
199 raw_svector_ostream os{contents}; | |
200 Rebase lastRebase; | |
201 | |
202 os << static_cast<uint8_t>(REBASE_OPCODE_SET_TYPE_IMM | REBASE_TYPE_POINTER); | |
203 | |
204 llvm::sort(locations, [](const Location &a, const Location &b) { | |
205 return a.isec->getVA() < b.isec->getVA(); | |
206 }); | |
207 for (const Location &loc : locations) | |
208 encodeRebase(loc.isec->parent, loc.isec->outSecOff + loc.offset, lastRebase, | |
209 os); | |
210 if (lastRebase.consecutiveCount != 0) | |
211 encodeDoRebase(lastRebase, os); | |
212 | |
213 os << static_cast<uint8_t>(REBASE_OPCODE_DONE); | |
214 } | |
215 | |
216 void RebaseSection::writeTo(uint8_t *buf) const { | |
217 memcpy(buf, contents.data(), contents.size()); | |
218 } | |
219 | |
220 NonLazyPointerSectionBase::NonLazyPointerSectionBase(const char *segname, | |
221 const char *name) | |
222 : SyntheticSection(segname, name) { | |
223 align = target->wordSize; | |
76 flags = S_NON_LAZY_SYMBOL_POINTERS; | 224 flags = S_NON_LAZY_SYMBOL_POINTERS; |
77 | 225 } |
78 // TODO: section_64::reserved1 should be an index into the indirect symbol | 226 |
79 // table, which we do not currently emit | 227 void macho::addNonLazyBindingEntries(const Symbol *sym, |
80 } | 228 const InputSection *isec, uint64_t offset, |
81 | 229 int64_t addend) { |
82 void GotSection::addEntry(DylibSymbol &sym) { | 230 if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) { |
83 if (entries.insert(&sym)) { | 231 in.binding->addEntry(dysym, isec, offset, addend); |
84 sym.gotIndex = entries.size() - 1; | 232 if (dysym->isWeakDef()) |
85 } | 233 in.weakBinding->addEntry(sym, isec, offset, addend); |
234 } else if (const auto *defined = dyn_cast<Defined>(sym)) { | |
235 in.rebase->addEntry(isec, offset); | |
236 if (defined->isExternalWeakDef()) | |
237 in.weakBinding->addEntry(sym, isec, offset, addend); | |
238 } else { | |
239 // Undefined symbols are filtered out in scanRelocations(); we should never | |
240 // get here | |
241 llvm_unreachable("cannot bind to an undefined symbol"); | |
242 } | |
243 } | |
244 | |
245 void NonLazyPointerSectionBase::addEntry(Symbol *sym) { | |
246 if (entries.insert(sym)) { | |
247 assert(!sym->isInGot()); | |
248 sym->gotIndex = entries.size() - 1; | |
249 | |
250 addNonLazyBindingEntries(sym, isec, sym->gotIndex * target->wordSize); | |
251 } | |
252 } | |
253 | |
254 void NonLazyPointerSectionBase::writeTo(uint8_t *buf) const { | |
255 for (size_t i = 0, n = entries.size(); i < n; ++i) | |
256 if (auto *defined = dyn_cast<Defined>(entries[i])) | |
257 write64le(&buf[i * target->wordSize], defined->getVA()); | |
86 } | 258 } |
87 | 259 |
88 BindingSection::BindingSection() | 260 BindingSection::BindingSection() |
89 : SyntheticSection(segment_names::linkEdit, section_names::binding) {} | 261 : LinkEditSection(segment_names::linkEdit, section_names::binding) {} |
90 | 262 |
91 bool BindingSection::isNeeded() const { return in.got->isNeeded(); } | 263 namespace { |
264 struct Binding { | |
265 OutputSegment *segment = nullptr; | |
266 uint64_t offset = 0; | |
267 int64_t addend = 0; | |
268 int16_t ordinal = 0; | |
269 }; | |
270 } // namespace | |
271 | |
272 // Encode a sequence of opcodes that tell dyld to write the address of symbol + | |
273 // addend at osec->addr + outSecOff. | |
274 // | |
275 // The bind opcode "interpreter" remembers the values of each binding field, so | |
276 // we only need to encode the differences between bindings. Hence the use of | |
277 // lastBinding. | |
278 static void encodeBinding(const Symbol *sym, const OutputSection *osec, | |
279 uint64_t outSecOff, int64_t addend, | |
280 bool isWeakBinding, Binding &lastBinding, | |
281 raw_svector_ostream &os) { | |
282 OutputSegment *seg = osec->parent; | |
283 uint64_t offset = osec->getSegmentOffset() + outSecOff; | |
284 if (lastBinding.segment != seg) { | |
285 os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | | |
286 seg->index); | |
287 encodeULEB128(offset, os); | |
288 lastBinding.segment = seg; | |
289 lastBinding.offset = offset; | |
290 } else if (lastBinding.offset != offset) { | |
291 os << static_cast<uint8_t>(BIND_OPCODE_ADD_ADDR_ULEB); | |
292 encodeULEB128(offset - lastBinding.offset, os); | |
293 lastBinding.offset = offset; | |
294 } | |
295 | |
296 if (lastBinding.addend != addend) { | |
297 os << static_cast<uint8_t>(BIND_OPCODE_SET_ADDEND_SLEB); | |
298 encodeSLEB128(addend, os); | |
299 lastBinding.addend = addend; | |
300 } | |
301 | |
302 uint8_t flags = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM; | |
303 if (!isWeakBinding && sym->isWeakRef()) | |
304 flags |= BIND_SYMBOL_FLAGS_WEAK_IMPORT; | |
305 | |
306 os << flags << sym->getName() << '\0' | |
307 << static_cast<uint8_t>(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER) | |
308 << static_cast<uint8_t>(BIND_OPCODE_DO_BIND); | |
309 // DO_BIND causes dyld to both perform the binding and increment the offset | |
310 lastBinding.offset += target->wordSize; | |
311 } | |
312 | |
313 // Non-weak bindings need to have their dylib ordinal encoded as well. | |
314 static int16_t ordinalForDylibSymbol(const DylibSymbol &dysym) { | |
315 if (config->namespaceKind == NamespaceKind::flat || dysym.isDynamicLookup()) | |
316 return static_cast<int16_t>(BIND_SPECIAL_DYLIB_FLAT_LOOKUP); | |
317 assert(dysym.getFile()->isReferenced()); | |
318 return dysym.getFile()->ordinal; | |
319 } | |
320 | |
321 static void encodeDylibOrdinal(int16_t ordinal, raw_svector_ostream &os) { | |
322 if (ordinal <= 0) { | |
323 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM | | |
324 (ordinal & BIND_IMMEDIATE_MASK)); | |
325 } else if (ordinal <= BIND_IMMEDIATE_MASK) { | |
326 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | ordinal); | |
327 } else { | |
328 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB); | |
329 encodeULEB128(ordinal, os); | |
330 } | |
331 } | |
332 | |
333 static void encodeWeakOverride(const Defined *defined, | |
334 raw_svector_ostream &os) { | |
335 os << static_cast<uint8_t>(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM | | |
336 BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION) | |
337 << defined->getName() << '\0'; | |
338 } | |
92 | 339 |
93 // Emit bind opcodes, which are a stream of byte-sized opcodes that dyld | 340 // Emit bind opcodes, which are a stream of byte-sized opcodes that dyld |
94 // interprets to update a record with the following fields: | 341 // interprets to update a record with the following fields: |
95 // * segment index (of the segment to write the symbol addresses to, typically | 342 // * segment index (of the segment to write the symbol addresses to, typically |
96 // the __DATA_CONST segment which contains the GOT) | 343 // the __DATA_CONST segment which contains the GOT) |
102 // When dyld sees BIND_OPCODE_DO_BIND, it uses the current record state to bind | 349 // When dyld sees BIND_OPCODE_DO_BIND, it uses the current record state to bind |
103 // a symbol in the GOT, and increments the segment offset to point to the next | 350 // a symbol in the GOT, and increments the segment offset to point to the next |
104 // entry. It does *not* clear the record state after doing the bind, so | 351 // entry. It does *not* clear the record state after doing the bind, so |
105 // subsequent opcodes only need to encode the differences between bindings. | 352 // subsequent opcodes only need to encode the differences between bindings. |
106 void BindingSection::finalizeContents() { | 353 void BindingSection::finalizeContents() { |
107 if (!isNeeded()) | |
108 return; | |
109 | |
110 raw_svector_ostream os{contents}; | 354 raw_svector_ostream os{contents}; |
111 os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | | 355 Binding lastBinding; |
112 in.got->parent->index); | 356 |
113 encodeULEB128(in.got->getSegmentOffset(), os); | 357 // Since bindings are delta-encoded, sorting them allows for a more compact |
114 for (const DylibSymbol *sym : in.got->getEntries()) { | 358 // result. Note that sorting by address alone ensures that bindings for the |
115 // TODO: Implement compact encoding -- we only need to encode the | 359 // same segment / section are located together. |
116 // differences between consecutive symbol entries. | 360 llvm::sort(bindings, [](const BindingEntry &a, const BindingEntry &b) { |
117 if (sym->file->ordinal <= BIND_IMMEDIATE_MASK) { | 361 return a.target.getVA() < b.target.getVA(); |
118 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | | 362 }); |
119 sym->file->ordinal); | 363 for (const BindingEntry &b : bindings) { |
120 } else { | 364 int16_t ordinal = ordinalForDylibSymbol(*b.dysym); |
121 error("TODO: Support larger dylib symbol ordinals"); | 365 if (ordinal != lastBinding.ordinal) { |
122 continue; | 366 encodeDylibOrdinal(ordinal, os); |
367 lastBinding.ordinal = ordinal; | |
123 } | 368 } |
124 os << static_cast<uint8_t>(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) | 369 encodeBinding(b.dysym, b.target.isec->parent, |
125 << sym->getName() << '\0' | 370 b.target.isec->outSecOff + b.target.offset, b.addend, |
126 << static_cast<uint8_t>(BIND_OPCODE_SET_TYPE_IMM | BIND_TYPE_POINTER) | 371 /*isWeakBinding=*/false, lastBinding, os); |
127 << static_cast<uint8_t>(BIND_OPCODE_DO_BIND); | 372 } |
128 } | 373 if (!bindings.empty()) |
129 | 374 os << static_cast<uint8_t>(BIND_OPCODE_DONE); |
130 os << static_cast<uint8_t>(BIND_OPCODE_DONE); | |
131 } | 375 } |
132 | 376 |
133 void BindingSection::writeTo(uint8_t *buf) const { | 377 void BindingSection::writeTo(uint8_t *buf) const { |
134 memcpy(buf, contents.data(), contents.size()); | 378 memcpy(buf, contents.data(), contents.size()); |
135 } | 379 } |
136 | 380 |
381 WeakBindingSection::WeakBindingSection() | |
382 : LinkEditSection(segment_names::linkEdit, section_names::weakBinding) {} | |
383 | |
384 void WeakBindingSection::finalizeContents() { | |
385 raw_svector_ostream os{contents}; | |
386 Binding lastBinding; | |
387 | |
388 for (const Defined *defined : definitions) | |
389 encodeWeakOverride(defined, os); | |
390 | |
391 // Since bindings are delta-encoded, sorting them allows for a more compact | |
392 // result. | |
393 llvm::sort(bindings, | |
394 [](const WeakBindingEntry &a, const WeakBindingEntry &b) { | |
395 return a.target.getVA() < b.target.getVA(); | |
396 }); | |
397 for (const WeakBindingEntry &b : bindings) | |
398 encodeBinding(b.symbol, b.target.isec->parent, | |
399 b.target.isec->outSecOff + b.target.offset, b.addend, | |
400 /*isWeakBinding=*/true, lastBinding, os); | |
401 if (!bindings.empty() || !definitions.empty()) | |
402 os << static_cast<uint8_t>(BIND_OPCODE_DONE); | |
403 } | |
404 | |
405 void WeakBindingSection::writeTo(uint8_t *buf) const { | |
406 memcpy(buf, contents.data(), contents.size()); | |
407 } | |
408 | |
137 StubsSection::StubsSection() | 409 StubsSection::StubsSection() |
138 : SyntheticSection(segment_names::text, "__stubs") {} | 410 : SyntheticSection(segment_names::text, section_names::stubs) { |
139 | 411 flags = S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS; |
140 size_t StubsSection::getSize() const { | 412 // The stubs section comprises machine instructions, which are aligned to |
413 // 4 bytes on the archs we care about. | |
414 align = 4; | |
415 reserved2 = target->stubSize; | |
416 } | |
417 | |
418 uint64_t StubsSection::getSize() const { | |
141 return entries.size() * target->stubSize; | 419 return entries.size() * target->stubSize; |
142 } | 420 } |
143 | 421 |
144 void StubsSection::writeTo(uint8_t *buf) const { | 422 void StubsSection::writeTo(uint8_t *buf) const { |
145 size_t off = 0; | 423 size_t off = 0; |
146 for (const DylibSymbol *sym : in.stubs->getEntries()) { | 424 for (const Symbol *sym : entries) { |
147 target->writeStub(buf + off, *sym); | 425 target->writeStub(buf + off, *sym); |
148 off += target->stubSize; | 426 off += target->stubSize; |
149 } | 427 } |
150 } | 428 } |
151 | 429 |
152 void StubsSection::addEntry(DylibSymbol &sym) { | 430 void StubsSection::finalize() { isFinal = true; } |
153 if (entries.insert(&sym)) | 431 |
154 sym.stubsIndex = entries.size() - 1; | 432 bool StubsSection::addEntry(Symbol *sym) { |
433 bool inserted = entries.insert(sym); | |
434 if (inserted) | |
435 sym->stubsIndex = entries.size() - 1; | |
436 return inserted; | |
155 } | 437 } |
156 | 438 |
157 StubHelperSection::StubHelperSection() | 439 StubHelperSection::StubHelperSection() |
158 : SyntheticSection(segment_names::text, "__stub_helper") {} | 440 : SyntheticSection(segment_names::text, section_names::stubHelper) { |
159 | 441 flags = S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS; |
160 size_t StubHelperSection::getSize() const { | 442 align = 4; // This section comprises machine instructions |
443 } | |
444 | |
445 uint64_t StubHelperSection::getSize() const { | |
161 return target->stubHelperHeaderSize + | 446 return target->stubHelperHeaderSize + |
162 in.stubs->getEntries().size() * target->stubHelperEntrySize; | 447 in.lazyBinding->getEntries().size() * target->stubHelperEntrySize; |
163 } | 448 } |
164 | 449 |
165 bool StubHelperSection::isNeeded() const { | 450 bool StubHelperSection::isNeeded() const { return in.lazyBinding->isNeeded(); } |
166 return !in.stubs->getEntries().empty(); | |
167 } | |
168 | 451 |
169 void StubHelperSection::writeTo(uint8_t *buf) const { | 452 void StubHelperSection::writeTo(uint8_t *buf) const { |
170 target->writeStubHelperHeader(buf); | 453 target->writeStubHelperHeader(buf); |
171 size_t off = target->stubHelperHeaderSize; | 454 size_t off = target->stubHelperHeaderSize; |
172 for (const DylibSymbol *sym : in.stubs->getEntries()) { | 455 for (const DylibSymbol *sym : in.lazyBinding->getEntries()) { |
173 target->writeStubHelperEntry(buf + off, *sym, addr + off); | 456 target->writeStubHelperEntry(buf + off, *sym, addr + off); |
174 off += target->stubHelperEntrySize; | 457 off += target->stubHelperEntrySize; |
175 } | 458 } |
176 } | 459 } |
177 | 460 |
180 if (stubBinder == nullptr) { | 463 if (stubBinder == nullptr) { |
181 error("symbol dyld_stub_binder not found (normally in libSystem.dylib). " | 464 error("symbol dyld_stub_binder not found (normally in libSystem.dylib). " |
182 "Needed to perform lazy binding."); | 465 "Needed to perform lazy binding."); |
183 return; | 466 return; |
184 } | 467 } |
185 in.got->addEntry(*stubBinder); | 468 stubBinder->reference(RefState::Strong); |
469 in.got->addEntry(stubBinder); | |
186 | 470 |
187 inputSections.push_back(in.imageLoaderCache); | 471 inputSections.push_back(in.imageLoaderCache); |
188 symtab->addDefined("__dyld_private", in.imageLoaderCache, 0); | 472 // Since this isn't in the symbol table or in any input file, the noDeadStrip |
473 // argument doesn't matter. It's kept alive by ImageLoaderCacheSection() | |
474 // setting `live` to true on the backing InputSection. | |
475 dyldPrivate = | |
476 make<Defined>("__dyld_private", nullptr, in.imageLoaderCache, 0, 0, | |
477 /*isWeakDef=*/false, | |
478 /*isExternal=*/false, /*isPrivateExtern=*/false, | |
479 /*isThumb=*/false, /*isReferencedDynamically=*/false, | |
480 /*noDeadStrip=*/false); | |
189 } | 481 } |
190 | 482 |
191 ImageLoaderCacheSection::ImageLoaderCacheSection() { | 483 ImageLoaderCacheSection::ImageLoaderCacheSection() { |
192 segname = segment_names::data; | 484 segname = segment_names::data; |
193 name = "__data"; | 485 name = section_names::data; |
486 uint8_t *arr = bAlloc.Allocate<uint8_t>(target->wordSize); | |
487 memset(arr, 0, target->wordSize); | |
488 data = {arr, target->wordSize}; | |
489 align = target->wordSize; | |
490 live = true; | |
194 } | 491 } |
195 | 492 |
196 LazyPointerSection::LazyPointerSection() | 493 LazyPointerSection::LazyPointerSection() |
197 : SyntheticSection(segment_names::data, "__la_symbol_ptr") { | 494 : SyntheticSection(segment_names::data, section_names::lazySymbolPtr) { |
198 align = 8; | 495 align = target->wordSize; |
199 flags = S_LAZY_SYMBOL_POINTERS; | 496 flags = S_LAZY_SYMBOL_POINTERS; |
200 } | 497 } |
201 | 498 |
202 size_t LazyPointerSection::getSize() const { | 499 uint64_t LazyPointerSection::getSize() const { |
203 return in.stubs->getEntries().size() * WordSize; | 500 return in.stubs->getEntries().size() * target->wordSize; |
204 } | 501 } |
205 | 502 |
206 bool LazyPointerSection::isNeeded() const { | 503 bool LazyPointerSection::isNeeded() const { |
207 return !in.stubs->getEntries().empty(); | 504 return !in.stubs->getEntries().empty(); |
208 } | 505 } |
209 | 506 |
210 void LazyPointerSection::writeTo(uint8_t *buf) const { | 507 void LazyPointerSection::writeTo(uint8_t *buf) const { |
211 size_t off = 0; | 508 size_t off = 0; |
212 for (const DylibSymbol *sym : in.stubs->getEntries()) { | 509 for (const Symbol *sym : in.stubs->getEntries()) { |
213 uint64_t stubHelperOffset = target->stubHelperHeaderSize + | 510 if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) { |
214 sym->stubsIndex * target->stubHelperEntrySize; | 511 if (dysym->hasStubsHelper()) { |
215 write64le(buf + off, in.stubHelper->addr + stubHelperOffset); | 512 uint64_t stubHelperOffset = |
216 off += WordSize; | 513 target->stubHelperHeaderSize + |
514 dysym->stubsHelperIndex * target->stubHelperEntrySize; | |
515 write64le(buf + off, in.stubHelper->addr + stubHelperOffset); | |
516 } | |
517 } else { | |
518 write64le(buf + off, sym->getVA()); | |
519 } | |
520 off += target->wordSize; | |
217 } | 521 } |
218 } | 522 } |
219 | 523 |
220 LazyBindingSection::LazyBindingSection() | 524 LazyBindingSection::LazyBindingSection() |
221 : SyntheticSection(segment_names::linkEdit, section_names::lazyBinding) {} | 525 : LinkEditSection(segment_names::linkEdit, section_names::lazyBinding) {} |
222 | |
223 bool LazyBindingSection::isNeeded() const { return in.stubs->isNeeded(); } | |
224 | 526 |
225 void LazyBindingSection::finalizeContents() { | 527 void LazyBindingSection::finalizeContents() { |
226 // TODO: Just precompute output size here instead of writing to a temporary | 528 // TODO: Just precompute output size here instead of writing to a temporary |
227 // buffer | 529 // buffer |
228 for (DylibSymbol *sym : in.stubs->getEntries()) | 530 for (DylibSymbol *sym : entries) |
229 sym->lazyBindOffset = encode(*sym); | 531 sym->lazyBindOffset = encode(*sym); |
230 } | 532 } |
231 | 533 |
232 void LazyBindingSection::writeTo(uint8_t *buf) const { | 534 void LazyBindingSection::writeTo(uint8_t *buf) const { |
233 memcpy(buf, contents.data(), contents.size()); | 535 memcpy(buf, contents.data(), contents.size()); |
536 } | |
537 | |
538 void LazyBindingSection::addEntry(DylibSymbol *dysym) { | |
539 if (entries.insert(dysym)) { | |
540 dysym->stubsHelperIndex = entries.size() - 1; | |
541 in.rebase->addEntry(in.lazyPointers->isec, | |
542 dysym->stubsIndex * target->wordSize); | |
543 } | |
234 } | 544 } |
235 | 545 |
236 // Unlike the non-lazy binding section, the bind opcodes in this section aren't | 546 // Unlike the non-lazy binding section, the bind opcodes in this section aren't |
237 // interpreted all at once. Rather, dyld will start interpreting opcodes at a | 547 // interpreted all at once. Rather, dyld will start interpreting opcodes at a |
238 // given offset, typically only binding a single symbol before it finds a | 548 // given offset, typically only binding a single symbol before it finds a |
243 uint32_t opstreamOffset = contents.size(); | 553 uint32_t opstreamOffset = contents.size(); |
244 OutputSegment *dataSeg = in.lazyPointers->parent; | 554 OutputSegment *dataSeg = in.lazyPointers->parent; |
245 os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | | 555 os << static_cast<uint8_t>(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB | |
246 dataSeg->index); | 556 dataSeg->index); |
247 uint64_t offset = in.lazyPointers->addr - dataSeg->firstSection()->addr + | 557 uint64_t offset = in.lazyPointers->addr - dataSeg->firstSection()->addr + |
248 sym.stubsIndex * WordSize; | 558 sym.stubsIndex * target->wordSize; |
249 encodeULEB128(offset, os); | 559 encodeULEB128(offset, os); |
250 if (sym.file->ordinal <= BIND_IMMEDIATE_MASK) | 560 encodeDylibOrdinal(ordinalForDylibSymbol(sym), os); |
251 os << static_cast<uint8_t>(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM | | 561 |
252 sym.file->ordinal); | 562 uint8_t flags = BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM; |
253 else | 563 if (sym.isWeakRef()) |
254 fatal("TODO: Support larger dylib symbol ordinals"); | 564 flags |= BIND_SYMBOL_FLAGS_WEAK_IMPORT; |
255 | 565 |
256 os << static_cast<uint8_t>(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM) | 566 os << flags << sym.getName() << '\0' |
257 << sym.getName() << '\0' << static_cast<uint8_t>(BIND_OPCODE_DO_BIND) | 567 << static_cast<uint8_t>(BIND_OPCODE_DO_BIND) |
258 << static_cast<uint8_t>(BIND_OPCODE_DONE); | 568 << static_cast<uint8_t>(BIND_OPCODE_DONE); |
259 return opstreamOffset; | 569 return opstreamOffset; |
260 } | 570 } |
261 | 571 |
262 ExportSection::ExportSection() | 572 ExportSection::ExportSection() |
263 : SyntheticSection(segment_names::linkEdit, section_names::export_) {} | 573 : LinkEditSection(segment_names::linkEdit, section_names::export_) {} |
264 | 574 |
265 void ExportSection::finalizeContents() { | 575 void ExportSection::finalizeContents() { |
266 // TODO: We should check symbol visibility. | 576 trieBuilder.setImageBase(in.header->addr); |
267 for (const Symbol *sym : symtab->getSymbols()) | 577 for (const Symbol *sym : symtab->getSymbols()) { |
268 if (auto *defined = dyn_cast<Defined>(sym)) | 578 if (const auto *defined = dyn_cast<Defined>(sym)) { |
579 if (defined->privateExtern || !defined->isLive()) | |
580 continue; | |
269 trieBuilder.addSymbol(*defined); | 581 trieBuilder.addSymbol(*defined); |
582 hasWeakSymbol = hasWeakSymbol || sym->isWeakDef(); | |
583 } | |
584 } | |
270 size = trieBuilder.build(); | 585 size = trieBuilder.build(); |
271 } | 586 } |
272 | 587 |
273 void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); } | 588 void ExportSection::writeTo(uint8_t *buf) const { trieBuilder.writeTo(buf); } |
274 | 589 |
590 FunctionStartsSection::FunctionStartsSection() | |
591 : LinkEditSection(segment_names::linkEdit, section_names::functionStarts) {} | |
592 | |
593 void FunctionStartsSection::finalizeContents() { | |
594 raw_svector_ostream os{contents}; | |
595 uint64_t addr = in.header->addr; | |
596 for (const Symbol *sym : symtab->getSymbols()) { | |
597 if (const auto *defined = dyn_cast<Defined>(sym)) { | |
598 if (!defined->isec || !isCodeSection(defined->isec) || !defined->isLive()) | |
599 continue; | |
600 // TODO: Add support for thumbs, in that case | |
601 // the lowest bit of nextAddr needs to be set to 1. | |
602 uint64_t nextAddr = defined->getVA(); | |
603 uint64_t delta = nextAddr - addr; | |
604 if (delta == 0) | |
605 continue; | |
606 encodeULEB128(delta, os); | |
607 addr = nextAddr; | |
608 } | |
609 } | |
610 os << '\0'; | |
611 } | |
612 | |
613 void FunctionStartsSection::writeTo(uint8_t *buf) const { | |
614 memcpy(buf, contents.data(), contents.size()); | |
615 } | |
616 | |
275 SymtabSection::SymtabSection(StringTableSection &stringTableSection) | 617 SymtabSection::SymtabSection(StringTableSection &stringTableSection) |
276 : SyntheticSection(segment_names::linkEdit, section_names::symbolTable), | 618 : LinkEditSection(segment_names::linkEdit, section_names::symbolTable), |
277 stringTableSection(stringTableSection) { | 619 stringTableSection(stringTableSection) {} |
278 // TODO: When we introduce the SyntheticSections superclass, we should make | 620 |
279 // all synthetic sections aligned to WordSize by default. | 621 void SymtabSection::emitBeginSourceStab(DWARFUnit *compileUnit) { |
280 align = WordSize; | 622 StabsEntry stab(N_SO); |
281 } | 623 SmallString<261> dir(compileUnit->getCompilationDir()); |
282 | 624 StringRef sep = sys::path::get_separator(); |
283 size_t SymtabSection::getSize() const { | 625 // We don't use `path::append` here because we want an empty `dir` to result |
284 return symbols.size() * sizeof(nlist_64); | 626 // in an absolute path. `append` would give us a relative path for that case. |
627 if (!dir.endswith(sep)) | |
628 dir += sep; | |
629 stab.strx = stringTableSection.addString( | |
630 saver.save(dir + compileUnit->getUnitDIE().getShortName())); | |
631 stabs.emplace_back(std::move(stab)); | |
632 } | |
633 | |
634 void SymtabSection::emitEndSourceStab() { | |
635 StabsEntry stab(N_SO); | |
636 stab.sect = 1; | |
637 stabs.emplace_back(std::move(stab)); | |
638 } | |
639 | |
640 void SymtabSection::emitObjectFileStab(ObjFile *file) { | |
641 StabsEntry stab(N_OSO); | |
642 stab.sect = target->cpuSubtype; | |
643 SmallString<261> path(!file->archiveName.empty() ? file->archiveName | |
644 : file->getName()); | |
645 std::error_code ec = sys::fs::make_absolute(path); | |
646 if (ec) | |
647 fatal("failed to get absolute path for " + path); | |
648 | |
649 if (!file->archiveName.empty()) | |
650 path.append({"(", file->getName(), ")"}); | |
651 | |
652 stab.strx = stringTableSection.addString(saver.save(path.str())); | |
653 stab.desc = 1; | |
654 stab.value = file->modTime; | |
655 stabs.emplace_back(std::move(stab)); | |
656 } | |
657 | |
658 void SymtabSection::emitEndFunStab(Defined *defined) { | |
659 StabsEntry stab(N_FUN); | |
660 stab.value = defined->size; | |
661 stabs.emplace_back(std::move(stab)); | |
662 } | |
663 | |
664 void SymtabSection::emitStabs() { | |
665 for (const std::string &s : config->astPaths) { | |
666 StabsEntry astStab(N_AST); | |
667 astStab.strx = stringTableSection.addString(s); | |
668 stabs.emplace_back(std::move(astStab)); | |
669 } | |
670 | |
671 std::vector<Defined *> symbolsNeedingStabs; | |
672 for (const SymtabEntry &entry : | |
673 concat<SymtabEntry>(localSymbols, externalSymbols)) { | |
674 Symbol *sym = entry.sym; | |
675 assert(sym->isLive() && | |
676 "dead symbols should not be in localSymbols, externalSymbols"); | |
677 if (auto *defined = dyn_cast<Defined>(sym)) { | |
678 if (defined->isAbsolute()) | |
679 continue; | |
680 InputSection *isec = defined->isec; | |
681 ObjFile *file = dyn_cast_or_null<ObjFile>(isec->file); | |
682 if (!file || !file->compileUnit) | |
683 continue; | |
684 symbolsNeedingStabs.push_back(defined); | |
685 } | |
686 } | |
687 | |
688 llvm::stable_sort(symbolsNeedingStabs, [&](Defined *a, Defined *b) { | |
689 return a->isec->file->id < b->isec->file->id; | |
690 }); | |
691 | |
692 // Emit STABS symbols so that dsymutil and/or the debugger can map address | |
693 // regions in the final binary to the source and object files from which they | |
694 // originated. | |
695 InputFile *lastFile = nullptr; | |
696 for (Defined *defined : symbolsNeedingStabs) { | |
697 InputSection *isec = defined->isec; | |
698 ObjFile *file = cast<ObjFile>(isec->file); | |
699 | |
700 if (lastFile == nullptr || lastFile != file) { | |
701 if (lastFile != nullptr) | |
702 emitEndSourceStab(); | |
703 lastFile = file; | |
704 | |
705 emitBeginSourceStab(file->compileUnit); | |
706 emitObjectFileStab(file); | |
707 } | |
708 | |
709 StabsEntry symStab; | |
710 symStab.sect = defined->isec->parent->index; | |
711 symStab.strx = stringTableSection.addString(defined->getName()); | |
712 symStab.value = defined->getVA(); | |
713 | |
714 if (isCodeSection(isec)) { | |
715 symStab.type = N_FUN; | |
716 stabs.emplace_back(std::move(symStab)); | |
717 emitEndFunStab(defined); | |
718 } else { | |
719 symStab.type = defined->isExternal() ? N_GSYM : N_STSYM; | |
720 stabs.emplace_back(std::move(symStab)); | |
721 } | |
722 } | |
723 | |
724 if (!stabs.empty()) | |
725 emitEndSourceStab(); | |
285 } | 726 } |
286 | 727 |
287 void SymtabSection::finalizeContents() { | 728 void SymtabSection::finalizeContents() { |
288 // TODO support other symbol types | 729 auto addSymbol = [&](std::vector<SymtabEntry> &symbols, Symbol *sym) { |
289 for (Symbol *sym : symtab->getSymbols()) | 730 uint32_t strx = stringTableSection.addString(sym->getName()); |
290 if (isa<Defined>(sym)) | 731 symbols.push_back({sym, strx}); |
291 symbols.push_back({sym, stringTableSection.addString(sym->getName())}); | 732 }; |
292 } | 733 |
293 | 734 // Local symbols aren't in the SymbolTable, so we walk the list of object |
294 void SymtabSection::writeTo(uint8_t *buf) const { | 735 // files to gather them. |
295 auto *nList = reinterpret_cast<nlist_64 *>(buf); | 736 for (const InputFile *file : inputFiles) { |
296 for (const SymtabEntry &entry : symbols) { | 737 if (auto *objFile = dyn_cast<ObjFile>(file)) { |
738 for (Symbol *sym : objFile->symbols) { | |
739 if (auto *defined = dyn_cast_or_null<Defined>(sym)) { | |
740 if (!defined->isExternal() && defined->isLive()) { | |
741 StringRef name = defined->getName(); | |
742 if (!name.startswith("l") && !name.startswith("L")) | |
743 addSymbol(localSymbols, sym); | |
744 } | |
745 } | |
746 } | |
747 } | |
748 } | |
749 | |
750 // __dyld_private is a local symbol too. It's linker-created and doesn't | |
751 // exist in any object file. | |
752 if (Defined *dyldPrivate = in.stubHelper->dyldPrivate) | |
753 addSymbol(localSymbols, dyldPrivate); | |
754 | |
755 for (Symbol *sym : symtab->getSymbols()) { | |
756 if (!sym->isLive()) | |
757 continue; | |
758 if (auto *defined = dyn_cast<Defined>(sym)) { | |
759 if (!defined->includeInSymtab) | |
760 continue; | |
761 assert(defined->isExternal()); | |
762 if (defined->privateExtern) | |
763 addSymbol(localSymbols, defined); | |
764 else | |
765 addSymbol(externalSymbols, defined); | |
766 } else if (auto *dysym = dyn_cast<DylibSymbol>(sym)) { | |
767 if (dysym->isReferenced()) | |
768 addSymbol(undefinedSymbols, sym); | |
769 } | |
770 } | |
771 | |
772 emitStabs(); | |
773 uint32_t symtabIndex = stabs.size(); | |
774 for (const SymtabEntry &entry : | |
775 concat<SymtabEntry>(localSymbols, externalSymbols, undefinedSymbols)) { | |
776 entry.sym->symtabIndex = symtabIndex++; | |
777 } | |
778 } | |
779 | |
780 uint32_t SymtabSection::getNumSymbols() const { | |
781 return stabs.size() + localSymbols.size() + externalSymbols.size() + | |
782 undefinedSymbols.size(); | |
783 } | |
784 | |
785 // This serves to hide (type-erase) the template parameter from SymtabSection. | |
786 template <class LP> class SymtabSectionImpl : public SymtabSection { | |
787 public: | |
788 SymtabSectionImpl(StringTableSection &stringTableSection) | |
789 : SymtabSection(stringTableSection) {} | |
790 uint64_t getRawSize() const override; | |
791 void writeTo(uint8_t *buf) const override; | |
792 }; | |
793 | |
794 template <class LP> uint64_t SymtabSectionImpl<LP>::getRawSize() const { | |
795 return getNumSymbols() * sizeof(typename LP::nlist); | |
796 } | |
797 | |
798 template <class LP> void SymtabSectionImpl<LP>::writeTo(uint8_t *buf) const { | |
799 auto *nList = reinterpret_cast<typename LP::nlist *>(buf); | |
800 // Emit the stabs entries before the "real" symbols. We cannot emit them | |
801 // after as that would render Symbol::symtabIndex inaccurate. | |
802 for (const StabsEntry &entry : stabs) { | |
297 nList->n_strx = entry.strx; | 803 nList->n_strx = entry.strx; |
298 // TODO support other symbol types | 804 nList->n_type = entry.type; |
299 // TODO populate n_desc | 805 nList->n_sect = entry.sect; |
806 nList->n_desc = entry.desc; | |
807 nList->n_value = entry.value; | |
808 ++nList; | |
809 } | |
810 | |
811 for (const SymtabEntry &entry : concat<const SymtabEntry>( | |
812 localSymbols, externalSymbols, undefinedSymbols)) { | |
813 nList->n_strx = entry.strx; | |
814 // TODO populate n_desc with more flags | |
300 if (auto *defined = dyn_cast<Defined>(entry.sym)) { | 815 if (auto *defined = dyn_cast<Defined>(entry.sym)) { |
301 nList->n_type = N_EXT | N_SECT; | 816 uint8_t scope = 0; |
302 nList->n_sect = defined->isec->parent->index; | 817 if (defined->privateExtern) { |
303 // For the N_SECT symbol type, n_value is the address of the symbol | 818 // Private external -- dylib scoped symbol. |
304 nList->n_value = defined->value + defined->isec->getVA(); | 819 // Promote to non-external at link time. |
820 scope = N_PEXT; | |
821 } else if (defined->isExternal()) { | |
822 // Normal global symbol. | |
823 scope = N_EXT; | |
824 } else { | |
825 // TU-local symbol from localSymbols. | |
826 scope = 0; | |
827 } | |
828 | |
829 if (defined->isAbsolute()) { | |
830 nList->n_type = scope | N_ABS; | |
831 nList->n_sect = NO_SECT; | |
832 nList->n_value = defined->value; | |
833 } else { | |
834 nList->n_type = scope | N_SECT; | |
835 nList->n_sect = defined->isec->parent->index; | |
836 // For the N_SECT symbol type, n_value is the address of the symbol | |
837 nList->n_value = defined->getVA(); | |
838 } | |
839 nList->n_desc |= defined->thumb ? N_ARM_THUMB_DEF : 0; | |
840 nList->n_desc |= defined->isExternalWeakDef() ? N_WEAK_DEF : 0; | |
841 nList->n_desc |= | |
842 defined->referencedDynamically ? REFERENCED_DYNAMICALLY : 0; | |
843 } else if (auto *dysym = dyn_cast<DylibSymbol>(entry.sym)) { | |
844 uint16_t n_desc = nList->n_desc; | |
845 int16_t ordinal = ordinalForDylibSymbol(*dysym); | |
846 if (ordinal == BIND_SPECIAL_DYLIB_FLAT_LOOKUP) | |
847 SET_LIBRARY_ORDINAL(n_desc, DYNAMIC_LOOKUP_ORDINAL); | |
848 else if (ordinal == BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE) | |
849 SET_LIBRARY_ORDINAL(n_desc, EXECUTABLE_ORDINAL); | |
850 else { | |
851 assert(ordinal > 0); | |
852 SET_LIBRARY_ORDINAL(n_desc, static_cast<uint8_t>(ordinal)); | |
853 } | |
854 | |
855 nList->n_type = N_EXT; | |
856 n_desc |= dysym->isWeakDef() ? N_WEAK_DEF : 0; | |
857 n_desc |= dysym->isWeakRef() ? N_WEAK_REF : 0; | |
858 nList->n_desc = n_desc; | |
305 } | 859 } |
306 ++nList; | 860 ++nList; |
307 } | 861 } |
308 } | 862 } |
309 | 863 |
864 template <class LP> | |
865 SymtabSection * | |
866 macho::makeSymtabSection(StringTableSection &stringTableSection) { | |
867 return make<SymtabSectionImpl<LP>>(stringTableSection); | |
868 } | |
869 | |
870 IndirectSymtabSection::IndirectSymtabSection() | |
871 : LinkEditSection(segment_names::linkEdit, | |
872 section_names::indirectSymbolTable) {} | |
873 | |
874 uint32_t IndirectSymtabSection::getNumSymbols() const { | |
875 return in.got->getEntries().size() + in.tlvPointers->getEntries().size() + | |
876 in.stubs->getEntries().size(); | |
877 } | |
878 | |
879 bool IndirectSymtabSection::isNeeded() const { | |
880 return in.got->isNeeded() || in.tlvPointers->isNeeded() || | |
881 in.stubs->isNeeded(); | |
882 } | |
883 | |
884 void IndirectSymtabSection::finalizeContents() { | |
885 uint32_t off = 0; | |
886 in.got->reserved1 = off; | |
887 off += in.got->getEntries().size(); | |
888 in.tlvPointers->reserved1 = off; | |
889 off += in.tlvPointers->getEntries().size(); | |
890 // There is a 1:1 correspondence between stubs and LazyPointerSection | |
891 // entries, so they can share the same sub-array in the table. | |
892 in.stubs->reserved1 = in.lazyPointers->reserved1 = off; | |
893 } | |
894 | |
895 static uint32_t indirectValue(const Symbol *sym) { | |
896 return sym->symtabIndex != UINT32_MAX ? sym->symtabIndex | |
897 : INDIRECT_SYMBOL_LOCAL; | |
898 } | |
899 | |
900 void IndirectSymtabSection::writeTo(uint8_t *buf) const { | |
901 uint32_t off = 0; | |
902 for (const Symbol *sym : in.got->getEntries()) { | |
903 write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); | |
904 ++off; | |
905 } | |
906 for (const Symbol *sym : in.tlvPointers->getEntries()) { | |
907 write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); | |
908 ++off; | |
909 } | |
910 for (const Symbol *sym : in.stubs->getEntries()) { | |
911 write32le(buf + off * sizeof(uint32_t), indirectValue(sym)); | |
912 ++off; | |
913 } | |
914 } | |
915 | |
310 StringTableSection::StringTableSection() | 916 StringTableSection::StringTableSection() |
311 : SyntheticSection(segment_names::linkEdit, section_names::stringTable) {} | 917 : LinkEditSection(segment_names::linkEdit, section_names::stringTable) {} |
312 | 918 |
313 uint32_t StringTableSection::addString(StringRef str) { | 919 uint32_t StringTableSection::addString(StringRef str) { |
314 uint32_t strx = size; | 920 uint32_t strx = size; |
315 strings.push_back(str); | 921 strings.push_back(str); // TODO: consider deduplicating strings |
316 size += str.size() + 1; // account for null terminator | 922 size += str.size() + 1; // account for null terminator |
317 return strx; | 923 return strx; |
318 } | 924 } |
319 | 925 |
320 void StringTableSection::writeTo(uint8_t *buf) const { | 926 void StringTableSection::writeTo(uint8_t *buf) const { |
323 memcpy(buf + off, str.data(), str.size()); | 929 memcpy(buf + off, str.data(), str.size()); |
324 off += str.size() + 1; // account for null terminator | 930 off += str.size() + 1; // account for null terminator |
325 } | 931 } |
326 } | 932 } |
327 | 933 |
328 InStruct in; | 934 static_assert((CodeSignatureSection::blobHeadersSize % 8) == 0, ""); |
329 | 935 static_assert((CodeSignatureSection::fixedHeadersSize % 8) == 0, ""); |
330 } // namespace macho | 936 |
331 } // namespace lld | 937 CodeSignatureSection::CodeSignatureSection() |
938 : LinkEditSection(segment_names::linkEdit, section_names::codeSignature) { | |
939 align = 16; // required by libstuff | |
940 fileName = config->outputFile; | |
941 size_t slashIndex = fileName.rfind("/"); | |
942 if (slashIndex != std::string::npos) | |
943 fileName = fileName.drop_front(slashIndex + 1); | |
944 allHeadersSize = alignTo<16>(fixedHeadersSize + fileName.size() + 1); | |
945 fileNamePad = allHeadersSize - fixedHeadersSize - fileName.size(); | |
946 } | |
947 | |
948 uint32_t CodeSignatureSection::getBlockCount() const { | |
949 return (fileOff + blockSize - 1) / blockSize; | |
950 } | |
951 | |
952 uint64_t CodeSignatureSection::getRawSize() const { | |
953 return allHeadersSize + getBlockCount() * hashSize; | |
954 } | |
955 | |
956 void CodeSignatureSection::writeHashes(uint8_t *buf) const { | |
957 uint8_t *code = buf; | |
958 uint8_t *codeEnd = buf + fileOff; | |
959 uint8_t *hashes = codeEnd + allHeadersSize; | |
960 while (code < codeEnd) { | |
961 StringRef block(reinterpret_cast<char *>(code), | |
962 std::min(codeEnd - code, static_cast<ssize_t>(blockSize))); | |
963 SHA256 hasher; | |
964 hasher.update(block); | |
965 StringRef hash = hasher.final(); | |
966 assert(hash.size() == hashSize); | |
967 memcpy(hashes, hash.data(), hashSize); | |
968 code += blockSize; | |
969 hashes += hashSize; | |
970 } | |
971 #if defined(__APPLE__) | |
972 // This is macOS-specific work-around and makes no sense for any | |
973 // other host OS. See https://openradar.appspot.com/FB8914231 | |
974 // | |
975 // The macOS kernel maintains a signature-verification cache to | |
976 // quickly validate applications at time of execve(2). The trouble | |
977 // is that for the kernel creates the cache entry at the time of the | |
978 // mmap(2) call, before we have a chance to write either the code to | |
979 // sign or the signature header+hashes. The fix is to invalidate | |
980 // all cached data associated with the output file, thus discarding | |
981 // the bogus prematurely-cached signature. | |
982 msync(buf, fileOff + getSize(), MS_INVALIDATE); | |
983 #endif | |
984 } | |
985 | |
986 void CodeSignatureSection::writeTo(uint8_t *buf) const { | |
987 uint32_t signatureSize = static_cast<uint32_t>(getSize()); | |
988 auto *superBlob = reinterpret_cast<CS_SuperBlob *>(buf); | |
989 write32be(&superBlob->magic, CSMAGIC_EMBEDDED_SIGNATURE); | |
990 write32be(&superBlob->length, signatureSize); | |
991 write32be(&superBlob->count, 1); | |
992 auto *blobIndex = reinterpret_cast<CS_BlobIndex *>(&superBlob[1]); | |
993 write32be(&blobIndex->type, CSSLOT_CODEDIRECTORY); | |
994 write32be(&blobIndex->offset, blobHeadersSize); | |
995 auto *codeDirectory = | |
996 reinterpret_cast<CS_CodeDirectory *>(buf + blobHeadersSize); | |
997 write32be(&codeDirectory->magic, CSMAGIC_CODEDIRECTORY); | |
998 write32be(&codeDirectory->length, signatureSize - blobHeadersSize); | |
999 write32be(&codeDirectory->version, CS_SUPPORTSEXECSEG); | |
1000 write32be(&codeDirectory->flags, CS_ADHOC | CS_LINKER_SIGNED); | |
1001 write32be(&codeDirectory->hashOffset, | |
1002 sizeof(CS_CodeDirectory) + fileName.size() + fileNamePad); | |
1003 write32be(&codeDirectory->identOffset, sizeof(CS_CodeDirectory)); | |
1004 codeDirectory->nSpecialSlots = 0; | |
1005 write32be(&codeDirectory->nCodeSlots, getBlockCount()); | |
1006 write32be(&codeDirectory->codeLimit, fileOff); | |
1007 codeDirectory->hashSize = static_cast<uint8_t>(hashSize); | |
1008 codeDirectory->hashType = kSecCodeSignatureHashSHA256; | |
1009 codeDirectory->platform = 0; | |
1010 codeDirectory->pageSize = blockSizeShift; | |
1011 codeDirectory->spare2 = 0; | |
1012 codeDirectory->scatterOffset = 0; | |
1013 codeDirectory->teamOffset = 0; | |
1014 codeDirectory->spare3 = 0; | |
1015 codeDirectory->codeLimit64 = 0; | |
1016 OutputSegment *textSeg = getOrCreateOutputSegment(segment_names::text); | |
1017 write64be(&codeDirectory->execSegBase, textSeg->fileOff); | |
1018 write64be(&codeDirectory->execSegLimit, textSeg->fileSize); | |
1019 write64be(&codeDirectory->execSegFlags, | |
1020 config->outputType == MH_EXECUTE ? CS_EXECSEG_MAIN_BINARY : 0); | |
1021 auto *id = reinterpret_cast<char *>(&codeDirectory[1]); | |
1022 memcpy(id, fileName.begin(), fileName.size()); | |
1023 memset(id + fileName.size(), 0, fileNamePad); | |
1024 } | |
1025 | |
1026 BitcodeBundleSection::BitcodeBundleSection() | |
1027 : SyntheticSection(segment_names::llvm, section_names::bitcodeBundle) {} | |
1028 | |
1029 class ErrorCodeWrapper { | |
1030 public: | |
1031 explicit ErrorCodeWrapper(std::error_code ec) : errorCode(ec.value()) {} | |
1032 explicit ErrorCodeWrapper(int ec) : errorCode(ec) {} | |
1033 operator int() const { return errorCode; } | |
1034 | |
1035 private: | |
1036 int errorCode; | |
1037 }; | |
1038 | |
1039 #define CHECK_EC(exp) \ | |
1040 do { \ | |
1041 ErrorCodeWrapper ec(exp); \ | |
1042 if (ec) \ | |
1043 fatal(Twine("operation failed with error code ") + Twine(ec) + ": " + \ | |
1044 #exp); \ | |
1045 } while (0); | |
1046 | |
1047 void BitcodeBundleSection::finalize() { | |
1048 #ifdef LLVM_HAVE_LIBXAR | |
1049 using namespace llvm::sys::fs; | |
1050 CHECK_EC(createTemporaryFile("bitcode-bundle", "xar", xarPath)); | |
1051 | |
1052 xar_t xar(xar_open(xarPath.data(), O_RDWR)); | |
1053 if (!xar) | |
1054 fatal("failed to open XAR temporary file at " + xarPath); | |
1055 CHECK_EC(xar_opt_set(xar, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE)); | |
1056 // FIXME: add more data to XAR | |
1057 CHECK_EC(xar_close(xar)); | |
1058 | |
1059 file_size(xarPath, xarSize); | |
1060 #endif // defined(LLVM_HAVE_LIBXAR) | |
1061 } | |
1062 | |
1063 void BitcodeBundleSection::writeTo(uint8_t *buf) const { | |
1064 using namespace llvm::sys::fs; | |
1065 file_t handle = | |
1066 CHECK(openNativeFile(xarPath, CD_OpenExisting, FA_Read, OF_None), | |
1067 "failed to open XAR file"); | |
1068 std::error_code ec; | |
1069 mapped_file_region xarMap(handle, mapped_file_region::mapmode::readonly, | |
1070 xarSize, 0, ec); | |
1071 if (ec) | |
1072 fatal("failed to map XAR file"); | |
1073 memcpy(buf, xarMap.const_data(), xarSize); | |
1074 | |
1075 closeFile(handle); | |
1076 remove(xarPath); | |
1077 } | |
1078 | |
1079 void macho::createSyntheticSymbols() { | |
1080 auto addHeaderSymbol = [](const char *name) { | |
1081 symtab->addSynthetic(name, in.header->isec, /*value=*/0, | |
1082 /*privateExtern=*/true, /*includeInSymtab=*/false, | |
1083 /*referencedDynamically=*/false); | |
1084 }; | |
1085 | |
1086 switch (config->outputType) { | |
1087 // FIXME: Assign the right address value for these symbols | |
1088 // (rather than 0). But we need to do that after assignAddresses(). | |
1089 case MH_EXECUTE: | |
1090 // If linking PIE, __mh_execute_header is a defined symbol in | |
1091 // __TEXT, __text) | |
1092 // Otherwise, it's an absolute symbol. | |
1093 if (config->isPic) | |
1094 symtab->addSynthetic("__mh_execute_header", in.header->isec, /*value=*/0, | |
1095 /*privateExtern=*/false, /*includeInSymtab=*/true, | |
1096 /*referencedDynamically=*/true); | |
1097 else | |
1098 symtab->addSynthetic("__mh_execute_header", /*isec=*/nullptr, /*value=*/0, | |
1099 /*privateExtern=*/false, /*includeInSymtab=*/true, | |
1100 /*referencedDynamically=*/true); | |
1101 break; | |
1102 | |
1103 // The following symbols are N_SECT symbols, even though the header is not | |
1104 // part of any section and that they are private to the bundle/dylib/object | |
1105 // they are part of. | |
1106 case MH_BUNDLE: | |
1107 addHeaderSymbol("__mh_bundle_header"); | |
1108 break; | |
1109 case MH_DYLIB: | |
1110 addHeaderSymbol("__mh_dylib_header"); | |
1111 break; | |
1112 case MH_DYLINKER: | |
1113 addHeaderSymbol("__mh_dylinker_header"); | |
1114 break; | |
1115 case MH_OBJECT: | |
1116 addHeaderSymbol("__mh_object_header"); | |
1117 break; | |
1118 default: | |
1119 llvm_unreachable("unexpected outputType"); | |
1120 break; | |
1121 } | |
1122 | |
1123 // The Itanium C++ ABI requires dylibs to pass a pointer to __cxa_atexit | |
1124 // which does e.g. cleanup of static global variables. The ABI document | |
1125 // says that the pointer can point to any address in one of the dylib's | |
1126 // segments, but in practice ld64 seems to set it to point to the header, | |
1127 // so that's what's implemented here. | |
1128 addHeaderSymbol("___dso_handle"); | |
1129 } | |
1130 | |
1131 template SymtabSection *macho::makeSymtabSection<LP64>(StringTableSection &); | |
1132 template SymtabSection *macho::makeSymtabSection<ILP32>(StringTableSection &); |