1//===- Writer.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 "Writer.h"
10#include "COFFLinkerContext.h"
11#include "CallGraphSort.h"
12#include "Config.h"
13#include "DLL.h"
14#include "InputFiles.h"
15#include "LLDMapFile.h"
16#include "MapFile.h"
17#include "PDB.h"
18#include "SymbolTable.h"
19#include "Symbols.h"
20#include "lld/Common/ErrorHandler.h"
21#include "lld/Common/Memory.h"
22#include "lld/Common/Timer.h"
23#include "llvm/ADT/DenseMap.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/StringSet.h"
26#include "llvm/BinaryFormat/COFF.h"
27#include "llvm/Support/BinaryStreamReader.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/Endian.h"
30#include "llvm/Support/FileOutputBuffer.h"
31#include "llvm/Support/Parallel.h"
32#include "llvm/Support/Path.h"
33#include "llvm/Support/RandomNumberGenerator.h"
34#include "llvm/Support/TimeProfiler.h"
35#include "llvm/Support/xxhash.h"
36#include <algorithm>
37#include <cstdio>
38#include <map>
39#include <memory>
40#include <utility>
41
42using namespace llvm;
43using namespace llvm::COFF;
44using namespace llvm::object;
45using namespace llvm::support;
46using namespace llvm::support::endian;
47using namespace lld;
48using namespace lld::coff;
49
50/* To re-generate DOSProgram:
51$ cat > /tmp/DOSProgram.asm
52org 0
53 ; Copy cs to ds.
54 push cs
55 pop ds
56 ; Point ds:dx at the $-terminated string.
57 mov dx, str
58 ; Int 21/AH=09h: Write string to standard output.
59 mov ah, 0x9
60 int 0x21
61 ; Int 21/AH=4Ch: Exit with return code (in AL).
62 mov ax, 0x4C01
63 int 0x21
64str:
65 db 'This program cannot be run in DOS mode.$'
66align 8, db 0
67$ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
68$ xxd -i /tmp/DOSProgram.bin
69*/
70static unsigned char dosProgram[] = {
71 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, 0x21, 0xb8, 0x01, 0x4c,
72 0xcd, 0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72,
73 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65,
74 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20,
75 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x24, 0x00, 0x00
76};
77static_assert(sizeof(dosProgram) % 8 == 0,
78 "DOSProgram size must be multiple of 8");
79
80static const int dosStubSize = sizeof(dos_header) + sizeof(dosProgram);
81static_assert(dosStubSize % 8 == 0, "DOSStub size must be multiple of 8");
82
83static const int numberOfDataDirectory = 16;
84
85namespace {
86
87class DebugDirectoryChunk : public NonSectionChunk {
88public:
89 DebugDirectoryChunk(const COFFLinkerContext &c,
90 const std::vector<std::pair<COFF::DebugType, Chunk *>> &r,
91 bool writeRepro)
92 : records(r), writeRepro(writeRepro), ctx(c) {}
93
94 size_t getSize() const override {
95 return (records.size() + int(writeRepro)) * sizeof(debug_directory);
96 }
97
98 void writeTo(uint8_t *b) const override {
99 auto *d = reinterpret_cast<debug_directory *>(b);
100
101 for (const std::pair<COFF::DebugType, Chunk *>& record : records) {
102 Chunk *c = record.second;
103 const OutputSection *os = ctx.getOutputSection(c);
104 uint64_t offs = os->getFileOff() + (c->getRVA() - os->getRVA());
105 fillEntry(d, debugType: record.first, size: c->getSize(), rva: c->getRVA(), offs);
106 ++d;
107 }
108
109 if (writeRepro) {
110 // FIXME: The COFF spec allows either a 0-sized entry to just say
111 // "the timestamp field is really a hash", or a 4-byte size field
112 // followed by that many bytes containing a longer hash (with the
113 // lowest 4 bytes usually being the timestamp in little-endian order).
114 // Consider storing the full 8 bytes computed by xxh3_64bits here.
115 fillEntry(d, debugType: COFF::IMAGE_DEBUG_TYPE_REPRO, size: 0, rva: 0, offs: 0);
116 }
117 }
118
119 void setTimeDateStamp(uint32_t timeDateStamp) {
120 for (support::ulittle32_t *tds : timeDateStamps)
121 *tds = timeDateStamp;
122 }
123
124private:
125 void fillEntry(debug_directory *d, COFF::DebugType debugType, size_t size,
126 uint64_t rva, uint64_t offs) const {
127 d->Characteristics = 0;
128 d->TimeDateStamp = 0;
129 d->MajorVersion = 0;
130 d->MinorVersion = 0;
131 d->Type = debugType;
132 d->SizeOfData = size;
133 d->AddressOfRawData = rva;
134 d->PointerToRawData = offs;
135
136 timeDateStamps.push_back(x: &d->TimeDateStamp);
137 }
138
139 mutable std::vector<support::ulittle32_t *> timeDateStamps;
140 const std::vector<std::pair<COFF::DebugType, Chunk *>> &records;
141 bool writeRepro;
142 const COFFLinkerContext &ctx;
143};
144
145class CVDebugRecordChunk : public NonSectionChunk {
146public:
147 CVDebugRecordChunk(const COFFLinkerContext &c) : ctx(c) {}
148
149 size_t getSize() const override {
150 return sizeof(codeview::DebugInfo) + ctx.config.pdbAltPath.size() + 1;
151 }
152
153 void writeTo(uint8_t *b) const override {
154 // Save off the DebugInfo entry to backfill the file signature (build id)
155 // in Writer::writeBuildId
156 buildId = reinterpret_cast<codeview::DebugInfo *>(b);
157
158 // variable sized field (PDB Path)
159 char *p = reinterpret_cast<char *>(b + sizeof(*buildId));
160 if (!ctx.config.pdbAltPath.empty())
161 memcpy(dest: p, src: ctx.config.pdbAltPath.data(), n: ctx.config.pdbAltPath.size());
162 p[ctx.config.pdbAltPath.size()] = '\0';
163 }
164
165 mutable codeview::DebugInfo *buildId = nullptr;
166
167private:
168 const COFFLinkerContext &ctx;
169};
170
171class ExtendedDllCharacteristicsChunk : public NonSectionChunk {
172public:
173 ExtendedDllCharacteristicsChunk(uint32_t c) : characteristics(c) {}
174
175 size_t getSize() const override { return 4; }
176
177 void writeTo(uint8_t *buf) const override { write32le(P: buf, V: characteristics); }
178
179 uint32_t characteristics = 0;
180};
181
182// PartialSection represents a group of chunks that contribute to an
183// OutputSection. Collating a collection of PartialSections of same name and
184// characteristics constitutes the OutputSection.
185class PartialSectionKey {
186public:
187 StringRef name;
188 unsigned characteristics;
189
190 bool operator<(const PartialSectionKey &other) const {
191 int c = name.compare(RHS: other.name);
192 if (c > 0)
193 return false;
194 if (c == 0)
195 return characteristics < other.characteristics;
196 return true;
197 }
198};
199
200struct ChunkRange {
201 Chunk *first = nullptr, *last;
202};
203
204// The writer writes a SymbolTable result to a file.
205class Writer {
206public:
207 Writer(COFFLinkerContext &c)
208 : buffer(errorHandler().outputBuffer), delayIdata(c), edata(c), ctx(c) {}
209 void run();
210
211private:
212 void createSections();
213 void createMiscChunks();
214 void createImportTables();
215 void appendImportThunks();
216 void locateImportTables();
217 void createExportTable();
218 void mergeSections();
219 void sortECChunks();
220 void removeUnusedSections();
221 void assignAddresses();
222 bool isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin);
223 std::pair<Defined *, bool> getThunk(DenseMap<uint64_t, Defined *> &lastThunks,
224 Defined *target, uint64_t p,
225 uint16_t type, int margin);
226 bool createThunks(OutputSection *os, int margin);
227 bool verifyRanges(const std::vector<Chunk *> chunks);
228 void createECCodeMap();
229 void finalizeAddresses();
230 void removeEmptySections();
231 void assignOutputSectionIndices();
232 void createSymbolAndStringTable();
233 void openFile(StringRef outputPath);
234 template <typename PEHeaderTy> void writeHeader();
235 void createSEHTable();
236 void createRuntimePseudoRelocs();
237 void createECChunks();
238 void insertCtorDtorSymbols();
239 void markSymbolsWithRelocations(ObjFile *file, SymbolRVASet &usedSymbols);
240 void createGuardCFTables();
241 void markSymbolsForRVATable(ObjFile *file,
242 ArrayRef<SectionChunk *> symIdxChunks,
243 SymbolRVASet &tableSymbols);
244 void getSymbolsFromSections(ObjFile *file,
245 ArrayRef<SectionChunk *> symIdxChunks,
246 std::vector<Symbol *> &symbols);
247 void maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym,
248 StringRef countSym, bool hasFlag=false);
249 void setSectionPermissions();
250 void setECSymbols();
251 void writeSections();
252 void writeBuildId();
253 void writePEChecksum();
254 void sortSections();
255 template <typename T> void sortExceptionTable(ChunkRange &exceptionTable);
256 void sortExceptionTables();
257 void sortCRTSectionChunks(std::vector<Chunk *> &chunks);
258 void addSyntheticIdata();
259 void sortBySectionOrder(std::vector<Chunk *> &chunks);
260 void fixPartialSectionChars(StringRef name, uint32_t chars);
261 bool fixGnuImportChunks();
262 void fixTlsAlignment();
263 PartialSection *createPartialSection(StringRef name, uint32_t outChars);
264 PartialSection *findPartialSection(StringRef name, uint32_t outChars);
265
266 std::optional<coff_symbol16> createSymbol(Defined *d);
267 size_t addEntryToStringTable(StringRef str);
268
269 OutputSection *findSection(StringRef name);
270 void addBaserels();
271 void addBaserelBlocks(std::vector<Baserel> &v);
272
273 uint32_t getSizeOfInitializedData();
274
275 void prepareLoadConfig();
276 template <typename T> void prepareLoadConfig(T *loadConfig);
277 template <typename T> void checkLoadConfigGuardData(const T *loadConfig);
278
279 std::unique_ptr<FileOutputBuffer> &buffer;
280 std::map<PartialSectionKey, PartialSection *> partialSections;
281 std::vector<char> strtab;
282 std::vector<llvm::object::coff_symbol16> outputSymtab;
283 std::vector<ECCodeMapEntry> codeMap;
284 IdataContents idata;
285 Chunk *importTableStart = nullptr;
286 uint64_t importTableSize = 0;
287 Chunk *edataStart = nullptr;
288 Chunk *edataEnd = nullptr;
289 Chunk *iatStart = nullptr;
290 uint64_t iatSize = 0;
291 DelayLoadContents delayIdata;
292 EdataContents edata;
293 bool setNoSEHCharacteristic = false;
294 uint32_t tlsAlignment = 0;
295
296 DebugDirectoryChunk *debugDirectory = nullptr;
297 std::vector<std::pair<COFF::DebugType, Chunk *>> debugRecords;
298 CVDebugRecordChunk *buildId = nullptr;
299 ArrayRef<uint8_t> sectionTable;
300
301 uint64_t fileSize;
302 uint32_t pointerToSymbolTable = 0;
303 uint64_t sizeOfImage;
304 uint64_t sizeOfHeaders;
305
306 OutputSection *textSec;
307 OutputSection *rdataSec;
308 OutputSection *buildidSec;
309 OutputSection *dataSec;
310 OutputSection *pdataSec;
311 OutputSection *idataSec;
312 OutputSection *edataSec;
313 OutputSection *didatSec;
314 OutputSection *rsrcSec;
315 OutputSection *relocSec;
316 OutputSection *ctorsSec;
317 OutputSection *dtorsSec;
318 // Either .rdata section or .buildid section.
319 OutputSection *debugInfoSec;
320
321 // The range of .pdata sections in the output file.
322 //
323 // We need to keep track of the location of .pdata in whichever section it
324 // gets merged into so that we can sort its contents and emit a correct data
325 // directory entry for the exception table. This is also the case for some
326 // other sections (such as .edata) but because the contents of those sections
327 // are entirely linker-generated we can keep track of their locations using
328 // the chunks that the linker creates. All .pdata chunks come from input
329 // files, so we need to keep track of them separately.
330 ChunkRange pdata;
331
332 // x86_64 .pdata sections on ARM64EC/ARM64X targets.
333 ChunkRange hybridPdata;
334
335 COFFLinkerContext &ctx;
336};
337} // anonymous namespace
338
339void lld::coff::writeResult(COFFLinkerContext &ctx) {
340 llvm::TimeTraceScope timeScope("Write output(s)");
341 Writer(ctx).run();
342}
343
344void OutputSection::addChunk(Chunk *c) {
345 chunks.push_back(x: c);
346}
347
348void OutputSection::insertChunkAtStart(Chunk *c) {
349 chunks.insert(position: chunks.begin(), x: c);
350}
351
352void OutputSection::setPermissions(uint32_t c) {
353 header.Characteristics &= ~permMask;
354 header.Characteristics |= c;
355}
356
357void OutputSection::merge(OutputSection *other) {
358 chunks.insert(position: chunks.end(), first: other->chunks.begin(), last: other->chunks.end());
359 other->chunks.clear();
360 contribSections.insert(position: contribSections.end(), first: other->contribSections.begin(),
361 last: other->contribSections.end());
362 other->contribSections.clear();
363
364 // MS link.exe compatibility: when merging a code section into a data section,
365 // mark the target section as a code section.
366 if (other->header.Characteristics & IMAGE_SCN_CNT_CODE) {
367 header.Characteristics |= IMAGE_SCN_CNT_CODE;
368 header.Characteristics &=
369 ~(IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA);
370 }
371}
372
373// Write the section header to a given buffer.
374void OutputSection::writeHeaderTo(uint8_t *buf, bool isDebug) {
375 auto *hdr = reinterpret_cast<coff_section *>(buf);
376 *hdr = header;
377 if (stringTableOff) {
378 // If name is too long, write offset into the string table as a name.
379 encodeSectionName(Out: hdr->Name, Offset: stringTableOff);
380 } else {
381 assert(!isDebug || name.size() <= COFF::NameSize ||
382 (hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0);
383 strncpy(dest: hdr->Name, src: name.data(),
384 n: std::min(a: name.size(), b: (size_t)COFF::NameSize));
385 }
386}
387
388void OutputSection::addContributingPartialSection(PartialSection *sec) {
389 contribSections.push_back(x: sec);
390}
391
392// Check whether the target address S is in range from a relocation
393// of type relType at address P.
394bool Writer::isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin) {
395 if (ctx.config.machine == ARMNT) {
396 int64_t diff = AbsoluteDifference(X: s, Y: p + 4) + margin;
397 switch (relType) {
398 case IMAGE_REL_ARM_BRANCH20T:
399 return isInt<21>(x: diff);
400 case IMAGE_REL_ARM_BRANCH24T:
401 case IMAGE_REL_ARM_BLX23T:
402 return isInt<25>(x: diff);
403 default:
404 return true;
405 }
406 } else if (ctx.config.machine == ARM64) {
407 int64_t diff = AbsoluteDifference(X: s, Y: p) + margin;
408 switch (relType) {
409 case IMAGE_REL_ARM64_BRANCH26:
410 return isInt<28>(x: diff);
411 case IMAGE_REL_ARM64_BRANCH19:
412 return isInt<21>(x: diff);
413 case IMAGE_REL_ARM64_BRANCH14:
414 return isInt<16>(x: diff);
415 default:
416 return true;
417 }
418 } else {
419 llvm_unreachable("Unexpected architecture");
420 }
421}
422
423// Return the last thunk for the given target if it is in range,
424// or create a new one.
425std::pair<Defined *, bool>
426Writer::getThunk(DenseMap<uint64_t, Defined *> &lastThunks, Defined *target,
427 uint64_t p, uint16_t type, int margin) {
428 Defined *&lastThunk = lastThunks[target->getRVA()];
429 if (lastThunk && isInRange(relType: type, s: lastThunk->getRVA(), p, margin))
430 return {lastThunk, false};
431 Chunk *c;
432 switch (ctx.config.machine) {
433 case ARMNT:
434 c = make<RangeExtensionThunkARM>(args&: ctx, args&: target);
435 break;
436 case ARM64:
437 c = make<RangeExtensionThunkARM64>(args&: ctx, args&: target);
438 break;
439 default:
440 llvm_unreachable("Unexpected architecture");
441 }
442 Defined *d = make<DefinedSynthetic>(args: "range_extension_thunk", args&: c);
443 lastThunk = d;
444 return {d, true};
445}
446
447// This checks all relocations, and for any relocation which isn't in range
448// it adds a thunk after the section chunk that contains the relocation.
449// If the latest thunk for the specific target is in range, that is used
450// instead of creating a new thunk. All range checks are done with the
451// specified margin, to make sure that relocations that originally are in
452// range, but only barely, also get thunks - in case other added thunks makes
453// the target go out of range.
454//
455// After adding thunks, we verify that all relocations are in range (with
456// no extra margin requirements). If this failed, we restart (throwing away
457// the previously created thunks) and retry with a wider margin.
458bool Writer::createThunks(OutputSection *os, int margin) {
459 bool addressesChanged = false;
460 DenseMap<uint64_t, Defined *> lastThunks;
461 DenseMap<std::pair<ObjFile *, Defined *>, uint32_t> thunkSymtabIndices;
462 size_t thunksSize = 0;
463 // Recheck Chunks.size() each iteration, since we can insert more
464 // elements into it.
465 for (size_t i = 0; i != os->chunks.size(); ++i) {
466 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(Val: os->chunks[i]);
467 if (!sc)
468 continue;
469 size_t thunkInsertionSpot = i + 1;
470
471 // Try to get a good enough estimate of where new thunks will be placed.
472 // Offset this by the size of the new thunks added so far, to make the
473 // estimate slightly better.
474 size_t thunkInsertionRVA = sc->getRVA() + sc->getSize() + thunksSize;
475 ObjFile *file = sc->file;
476 std::vector<std::pair<uint32_t, uint32_t>> relocReplacements;
477 ArrayRef<coff_relocation> originalRelocs =
478 file->getCOFFObj()->getRelocations(Sec: sc->header);
479 for (size_t j = 0, e = originalRelocs.size(); j < e; ++j) {
480 const coff_relocation &rel = originalRelocs[j];
481 Symbol *relocTarget = file->getSymbol(symbolIndex: rel.SymbolTableIndex);
482
483 // The estimate of the source address P should be pretty accurate,
484 // but we don't know whether the target Symbol address should be
485 // offset by thunksSize or not (or by some of thunksSize but not all of
486 // it), giving us some uncertainty once we have added one thunk.
487 uint64_t p = sc->getRVA() + rel.VirtualAddress + thunksSize;
488
489 Defined *sym = dyn_cast_or_null<Defined>(Val: relocTarget);
490 if (!sym)
491 continue;
492
493 uint64_t s = sym->getRVA();
494
495 if (isInRange(relType: rel.Type, s, p, margin))
496 continue;
497
498 // If the target isn't in range, hook it up to an existing or new thunk.
499 auto [thunk, wasNew] = getThunk(lastThunks, target: sym, p, type: rel.Type, margin);
500 if (wasNew) {
501 Chunk *thunkChunk = thunk->getChunk();
502 thunkChunk->setRVA(
503 thunkInsertionRVA); // Estimate of where it will be located.
504 os->chunks.insert(position: os->chunks.begin() + thunkInsertionSpot, x: thunkChunk);
505 thunkInsertionSpot++;
506 thunksSize += thunkChunk->getSize();
507 thunkInsertionRVA += thunkChunk->getSize();
508 addressesChanged = true;
509 }
510
511 // To redirect the relocation, add a symbol to the parent object file's
512 // symbol table, and replace the relocation symbol table index with the
513 // new index.
514 auto insertion = thunkSymtabIndices.insert(KV: {{file, thunk}, ~0U});
515 uint32_t &thunkSymbolIndex = insertion.first->second;
516 if (insertion.second)
517 thunkSymbolIndex = file->addRangeThunkSymbol(thunk);
518 relocReplacements.emplace_back(args&: j, args&: thunkSymbolIndex);
519 }
520
521 // Get a writable copy of this section's relocations so they can be
522 // modified. If the relocations point into the object file, allocate new
523 // memory. Otherwise, this must be previously allocated memory that can be
524 // modified in place.
525 ArrayRef<coff_relocation> curRelocs = sc->getRelocs();
526 MutableArrayRef<coff_relocation> newRelocs;
527 if (originalRelocs.data() == curRelocs.data()) {
528 newRelocs = MutableArrayRef(
529 bAlloc().Allocate<coff_relocation>(Num: originalRelocs.size()),
530 originalRelocs.size());
531 } else {
532 newRelocs = MutableArrayRef(
533 const_cast<coff_relocation *>(curRelocs.data()), curRelocs.size());
534 }
535
536 // Copy each relocation, but replace the symbol table indices which need
537 // thunks.
538 auto nextReplacement = relocReplacements.begin();
539 auto endReplacement = relocReplacements.end();
540 for (size_t i = 0, e = originalRelocs.size(); i != e; ++i) {
541 newRelocs[i] = originalRelocs[i];
542 if (nextReplacement != endReplacement && nextReplacement->first == i) {
543 newRelocs[i].SymbolTableIndex = nextReplacement->second;
544 ++nextReplacement;
545 }
546 }
547
548 sc->setRelocs(newRelocs);
549 }
550 return addressesChanged;
551}
552
553// Create a code map for CHPE metadata.
554void Writer::createECCodeMap() {
555 if (!isArm64EC(Machine: ctx.config.machine))
556 return;
557
558 // Clear the map in case we were're recomputing the map after adding
559 // a range extension thunk.
560 codeMap.clear();
561
562 std::optional<chpe_range_type> lastType;
563 Chunk *first, *last;
564
565 auto closeRange = [&]() {
566 if (lastType) {
567 codeMap.push_back(x: {first, last, *lastType});
568 lastType.reset();
569 }
570 };
571
572 for (OutputSection *sec : ctx.outputSections) {
573 for (Chunk *c : sec->chunks) {
574 // Skip empty section chunks. MS link.exe does not seem to do that and
575 // generates empty code ranges in some cases.
576 if (isa<SectionChunk>(Val: c) && !c->getSize())
577 continue;
578
579 std::optional<chpe_range_type> chunkType = c->getArm64ECRangeType();
580 if (chunkType != lastType) {
581 closeRange();
582 first = c;
583 lastType = chunkType;
584 }
585 last = c;
586 }
587 }
588
589 closeRange();
590
591 Symbol *tableCountSym = ctx.symtab.findUnderscore(name: "__hybrid_code_map_count");
592 cast<DefinedAbsolute>(Val: tableCountSym)->setVA(codeMap.size());
593}
594
595// Verify that all relocations are in range, with no extra margin requirements.
596bool Writer::verifyRanges(const std::vector<Chunk *> chunks) {
597 for (Chunk *c : chunks) {
598 SectionChunk *sc = dyn_cast_or_null<SectionChunk>(Val: c);
599 if (!sc)
600 continue;
601
602 ArrayRef<coff_relocation> relocs = sc->getRelocs();
603 for (const coff_relocation &rel : relocs) {
604 Symbol *relocTarget = sc->file->getSymbol(symbolIndex: rel.SymbolTableIndex);
605
606 Defined *sym = dyn_cast_or_null<Defined>(Val: relocTarget);
607 if (!sym)
608 continue;
609
610 uint64_t p = sc->getRVA() + rel.VirtualAddress;
611 uint64_t s = sym->getRVA();
612
613 if (!isInRange(relType: rel.Type, s, p, margin: 0))
614 return false;
615 }
616 }
617 return true;
618}
619
620// Assign addresses and add thunks if necessary.
621void Writer::finalizeAddresses() {
622 assignAddresses();
623 if (ctx.config.machine != ARMNT && ctx.config.machine != ARM64)
624 return;
625
626 size_t origNumChunks = 0;
627 for (OutputSection *sec : ctx.outputSections) {
628 sec->origChunks = sec->chunks;
629 origNumChunks += sec->chunks.size();
630 }
631
632 int pass = 0;
633 int margin = 1024 * 100;
634 while (true) {
635 llvm::TimeTraceScope timeScope2("Add thunks pass");
636
637 // First check whether we need thunks at all, or if the previous pass of
638 // adding them turned out ok.
639 bool rangesOk = true;
640 size_t numChunks = 0;
641 {
642 llvm::TimeTraceScope timeScope3("Verify ranges");
643 for (OutputSection *sec : ctx.outputSections) {
644 if (!verifyRanges(chunks: sec->chunks)) {
645 rangesOk = false;
646 break;
647 }
648 numChunks += sec->chunks.size();
649 }
650 }
651 if (rangesOk) {
652 if (pass > 0)
653 log(msg: "Added " + Twine(numChunks - origNumChunks) + " thunks with " +
654 "margin " + Twine(margin) + " in " + Twine(pass) + " passes");
655 return;
656 }
657
658 if (pass >= 10)
659 fatal(msg: "adding thunks hasn't converged after " + Twine(pass) + " passes");
660
661 if (pass > 0) {
662 // If the previous pass didn't work out, reset everything back to the
663 // original conditions before retrying with a wider margin. This should
664 // ideally never happen under real circumstances.
665 for (OutputSection *sec : ctx.outputSections)
666 sec->chunks = sec->origChunks;
667 margin *= 2;
668 }
669
670 // Try adding thunks everywhere where it is needed, with a margin
671 // to avoid things going out of range due to the added thunks.
672 bool addressesChanged = false;
673 {
674 llvm::TimeTraceScope timeScope3("Create thunks");
675 for (OutputSection *sec : ctx.outputSections)
676 addressesChanged |= createThunks(os: sec, margin);
677 }
678 // If the verification above thought we needed thunks, we should have
679 // added some.
680 assert(addressesChanged);
681 (void)addressesChanged;
682
683 // Recalculate the layout for the whole image (and verify the ranges at
684 // the start of the next round).
685 assignAddresses();
686
687 pass++;
688 }
689}
690
691void Writer::writePEChecksum() {
692 if (!ctx.config.writeCheckSum) {
693 return;
694 }
695
696 llvm::TimeTraceScope timeScope("PE checksum");
697
698 // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#checksum
699 uint32_t *buf = (uint32_t *)buffer->getBufferStart();
700 uint32_t size = (uint32_t)(buffer->getBufferSize());
701
702 coff_file_header *coffHeader =
703 (coff_file_header *)((uint8_t *)buf + dosStubSize + sizeof(PEMagic));
704 pe32_header *peHeader =
705 (pe32_header *)((uint8_t *)coffHeader + sizeof(coff_file_header));
706
707 uint64_t sum = 0;
708 uint32_t count = size;
709 ulittle16_t *addr = (ulittle16_t *)buf;
710
711 // The PE checksum algorithm, implemented as suggested in RFC1071
712 while (count > 1) {
713 sum += *addr++;
714 count -= 2;
715 }
716
717 // Add left-over byte, if any
718 if (count > 0)
719 sum += *(unsigned char *)addr;
720
721 // Fold 32-bit sum to 16 bits
722 while (sum >> 16) {
723 sum = (sum & 0xffff) + (sum >> 16);
724 }
725
726 sum += size;
727 peHeader->CheckSum = sum;
728}
729
730// The main function of the writer.
731void Writer::run() {
732 {
733 llvm::TimeTraceScope timeScope("Write PE");
734 ScopedTimer t1(ctx.codeLayoutTimer);
735
736 createImportTables();
737 createSections();
738 appendImportThunks();
739 // Import thunks must be added before the Control Flow Guard tables are
740 // added.
741 createMiscChunks();
742 createExportTable();
743 mergeSections();
744 sortECChunks();
745 removeUnusedSections();
746 finalizeAddresses();
747 removeEmptySections();
748 assignOutputSectionIndices();
749 setSectionPermissions();
750 setECSymbols();
751 createSymbolAndStringTable();
752
753 if (fileSize > UINT32_MAX)
754 fatal(msg: "image size (" + Twine(fileSize) + ") " +
755 "exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
756
757 openFile(outputPath: ctx.config.outputFile);
758 if (ctx.config.is64()) {
759 writeHeader<pe32plus_header>();
760 } else {
761 writeHeader<pe32_header>();
762 }
763 writeSections();
764 prepareLoadConfig();
765 sortExceptionTables();
766
767 // Fix up the alignment in the TLS Directory's characteristic field,
768 // if a specific alignment value is needed
769 if (tlsAlignment)
770 fixTlsAlignment();
771 }
772
773 if (!ctx.config.pdbPath.empty() && ctx.config.debug) {
774 assert(buildId);
775 createPDB(ctx, sectionTable, buildId: buildId->buildId);
776 }
777 writeBuildId();
778
779 writeLLDMapFile(ctx);
780 writeMapFile(ctx);
781
782 writePEChecksum();
783
784 if (errorCount())
785 return;
786
787 llvm::TimeTraceScope timeScope("Commit PE to disk");
788 ScopedTimer t2(ctx.outputCommitTimer);
789 if (auto e = buffer->commit())
790 fatal(msg: "failed to write output '" + buffer->getPath() +
791 "': " + toString(E: std::move(e)));
792}
793
794static StringRef getOutputSectionName(StringRef name) {
795 StringRef s = name.split(Separator: '$').first;
796
797 // Treat a later period as a separator for MinGW, for sections like
798 // ".ctors.01234".
799 return s.substr(Start: 0, N: s.find(C: '.', From: 1));
800}
801
802// For /order.
803void Writer::sortBySectionOrder(std::vector<Chunk *> &chunks) {
804 auto getPriority = [&ctx = ctx](const Chunk *c) {
805 if (auto *sec = dyn_cast<SectionChunk>(Val: c))
806 if (sec->sym)
807 return ctx.config.order.lookup(Key: sec->sym->getName());
808 return 0;
809 };
810
811 llvm::stable_sort(Range&: chunks, C: [=](const Chunk *a, const Chunk *b) {
812 return getPriority(a) < getPriority(b);
813 });
814}
815
816// Change the characteristics of existing PartialSections that belong to the
817// section Name to Chars.
818void Writer::fixPartialSectionChars(StringRef name, uint32_t chars) {
819 for (auto it : partialSections) {
820 PartialSection *pSec = it.second;
821 StringRef curName = pSec->name;
822 if (!curName.consume_front(Prefix: name) ||
823 (!curName.empty() && !curName.starts_with(Prefix: "$")))
824 continue;
825 if (pSec->characteristics == chars)
826 continue;
827 PartialSection *destSec = createPartialSection(name: pSec->name, outChars: chars);
828 destSec->chunks.insert(position: destSec->chunks.end(), first: pSec->chunks.begin(),
829 last: pSec->chunks.end());
830 pSec->chunks.clear();
831 }
832}
833
834// Sort concrete section chunks from GNU import libraries.
835//
836// GNU binutils doesn't use short import files, but instead produces import
837// libraries that consist of object files, with section chunks for the .idata$*
838// sections. These are linked just as regular static libraries. Each import
839// library consists of one header object, one object file for every imported
840// symbol, and one trailer object. In order for the .idata tables/lists to
841// be formed correctly, the section chunks within each .idata$* section need
842// to be grouped by library, and sorted alphabetically within each library
843// (which makes sure the header comes first and the trailer last).
844bool Writer::fixGnuImportChunks() {
845 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
846
847 // Make sure all .idata$* section chunks are mapped as RDATA in order to
848 // be sorted into the same sections as our own synthesized .idata chunks.
849 fixPartialSectionChars(name: ".idata", chars: rdata);
850
851 bool hasIdata = false;
852 // Sort all .idata$* chunks, grouping chunks from the same library,
853 // with alphabetical ordering of the object files within a library.
854 for (auto it : partialSections) {
855 PartialSection *pSec = it.second;
856 if (!pSec->name.starts_with(Prefix: ".idata"))
857 continue;
858
859 if (!pSec->chunks.empty())
860 hasIdata = true;
861 llvm::stable_sort(Range&: pSec->chunks, C: [&](Chunk *s, Chunk *t) {
862 SectionChunk *sc1 = dyn_cast_or_null<SectionChunk>(Val: s);
863 SectionChunk *sc2 = dyn_cast_or_null<SectionChunk>(Val: t);
864 if (!sc1 || !sc2) {
865 // if SC1, order them ascending. If SC2 or both null,
866 // S is not less than T.
867 return sc1 != nullptr;
868 }
869 // Make a string with "libraryname/objectfile" for sorting, achieving
870 // both grouping by library and sorting of objects within a library,
871 // at once.
872 std::string key1 =
873 (sc1->file->parentName + "/" + sc1->file->getName()).str();
874 std::string key2 =
875 (sc2->file->parentName + "/" + sc2->file->getName()).str();
876 return key1 < key2;
877 });
878 }
879 return hasIdata;
880}
881
882// Add generated idata chunks, for imported symbols and DLLs, and a
883// terminator in .idata$2.
884void Writer::addSyntheticIdata() {
885 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
886 idata.create(ctx);
887
888 // Add the .idata content in the right section groups, to allow
889 // chunks from other linked in object files to be grouped together.
890 // See Microsoft PE/COFF spec 5.4 for details.
891 auto add = [&](StringRef n, std::vector<Chunk *> &v) {
892 PartialSection *pSec = createPartialSection(name: n, outChars: rdata);
893 pSec->chunks.insert(position: pSec->chunks.end(), first: v.begin(), last: v.end());
894 };
895
896 // The loader assumes a specific order of data.
897 // Add each type in the correct order.
898 add(".idata$2", idata.dirs);
899 add(".idata$4", idata.lookups);
900 add(".idata$5", idata.addresses);
901 if (!idata.hints.empty())
902 add(".idata$6", idata.hints);
903 add(".idata$7", idata.dllNames);
904}
905
906// Locate the first Chunk and size of the import directory list and the
907// IAT.
908void Writer::locateImportTables() {
909 uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
910
911 if (PartialSection *importDirs = findPartialSection(name: ".idata$2", outChars: rdata)) {
912 if (!importDirs->chunks.empty())
913 importTableStart = importDirs->chunks.front();
914 for (Chunk *c : importDirs->chunks)
915 importTableSize += c->getSize();
916 }
917
918 if (PartialSection *importAddresses = findPartialSection(name: ".idata$5", outChars: rdata)) {
919 if (!importAddresses->chunks.empty())
920 iatStart = importAddresses->chunks.front();
921 for (Chunk *c : importAddresses->chunks)
922 iatSize += c->getSize();
923 }
924}
925
926// Return whether a SectionChunk's suffix (the dollar and any trailing
927// suffix) should be removed and sorted into the main suffixless
928// PartialSection.
929static bool shouldStripSectionSuffix(SectionChunk *sc, StringRef name,
930 bool isMinGW) {
931 // On MinGW, comdat groups are formed by putting the comdat group name
932 // after the '$' in the section name. For .eh_frame$<symbol>, that must
933 // still be sorted before the .eh_frame trailer from crtend.o, thus just
934 // strip the section name trailer. For other sections, such as
935 // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
936 // ".tls$"), they must be strictly sorted after .tls. And for the
937 // hypothetical case of comdat .CRT$XCU, we definitely need to keep the
938 // suffix for sorting. Thus, to play it safe, only strip the suffix for
939 // the standard sections.
940 if (!isMinGW)
941 return false;
942 if (!sc || !sc->isCOMDAT())
943 return false;
944 return name.starts_with(Prefix: ".text$") || name.starts_with(Prefix: ".data$") ||
945 name.starts_with(Prefix: ".rdata$") || name.starts_with(Prefix: ".pdata$") ||
946 name.starts_with(Prefix: ".xdata$") || name.starts_with(Prefix: ".eh_frame$");
947}
948
949void Writer::sortSections() {
950 if (!ctx.config.callGraphProfile.empty()) {
951 DenseMap<const SectionChunk *, int> order =
952 computeCallGraphProfileOrder(ctx);
953 for (auto it : order) {
954 if (DefinedRegular *sym = it.first->sym)
955 ctx.config.order[sym->getName()] = it.second;
956 }
957 }
958 if (!ctx.config.order.empty())
959 for (auto it : partialSections)
960 sortBySectionOrder(chunks&: it.second->chunks);
961}
962
963// Create output section objects and add them to OutputSections.
964void Writer::createSections() {
965 llvm::TimeTraceScope timeScope("Output sections");
966 // First, create the builtin sections.
967 const uint32_t data = IMAGE_SCN_CNT_INITIALIZED_DATA;
968 const uint32_t bss = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
969 const uint32_t code = IMAGE_SCN_CNT_CODE;
970 const uint32_t discardable = IMAGE_SCN_MEM_DISCARDABLE;
971 const uint32_t r = IMAGE_SCN_MEM_READ;
972 const uint32_t w = IMAGE_SCN_MEM_WRITE;
973 const uint32_t x = IMAGE_SCN_MEM_EXECUTE;
974
975 SmallDenseMap<std::pair<StringRef, uint32_t>, OutputSection *> sections;
976 auto createSection = [&](StringRef name, uint32_t outChars) {
977 OutputSection *&sec = sections[{name, outChars}];
978 if (!sec) {
979 sec = make<OutputSection>(args&: name, args&: outChars);
980 ctx.outputSections.push_back(x: sec);
981 }
982 return sec;
983 };
984
985 // Try to match the section order used by link.exe.
986 textSec = createSection(".text", code | r | x);
987 createSection(".bss", bss | r | w);
988 rdataSec = createSection(".rdata", data | r);
989 buildidSec = createSection(".buildid", data | r);
990 dataSec = createSection(".data", data | r | w);
991 pdataSec = createSection(".pdata", data | r);
992 idataSec = createSection(".idata", data | r);
993 edataSec = createSection(".edata", data | r);
994 didatSec = createSection(".didat", data | r);
995 rsrcSec = createSection(".rsrc", data | r);
996 relocSec = createSection(".reloc", data | discardable | r);
997 ctorsSec = createSection(".ctors", data | r | w);
998 dtorsSec = createSection(".dtors", data | r | w);
999
1000 // Then bin chunks by name and output characteristics.
1001 for (Chunk *c : ctx.symtab.getChunks()) {
1002 auto *sc = dyn_cast<SectionChunk>(Val: c);
1003 if (sc && !sc->live) {
1004 if (ctx.config.verbose)
1005 sc->printDiscardedMessage();
1006 continue;
1007 }
1008 StringRef name = c->getSectionName();
1009 if (shouldStripSectionSuffix(sc, name, isMinGW: ctx.config.mingw))
1010 name = name.split(Separator: '$').first;
1011
1012 if (name.starts_with(Prefix: ".tls"))
1013 tlsAlignment = std::max(a: tlsAlignment, b: c->getAlignment());
1014
1015 PartialSection *pSec = createPartialSection(name,
1016 outChars: c->getOutputCharacteristics());
1017 pSec->chunks.push_back(x: c);
1018 }
1019
1020 fixPartialSectionChars(name: ".rsrc", chars: data | r);
1021 fixPartialSectionChars(name: ".edata", chars: data | r);
1022 // Even in non MinGW cases, we might need to link against GNU import
1023 // libraries.
1024 bool hasIdata = fixGnuImportChunks();
1025 if (!idata.empty())
1026 hasIdata = true;
1027
1028 if (hasIdata)
1029 addSyntheticIdata();
1030
1031 sortSections();
1032
1033 if (hasIdata)
1034 locateImportTables();
1035
1036 // Then create an OutputSection for each section.
1037 // '$' and all following characters in input section names are
1038 // discarded when determining output section. So, .text$foo
1039 // contributes to .text, for example. See PE/COFF spec 3.2.
1040 for (auto it : partialSections) {
1041 PartialSection *pSec = it.second;
1042 StringRef name = getOutputSectionName(name: pSec->name);
1043 uint32_t outChars = pSec->characteristics;
1044
1045 if (name == ".CRT") {
1046 // In link.exe, there is a special case for the I386 target where .CRT
1047 // sections are treated as if they have output characteristics DATA | R if
1048 // their characteristics are DATA | R | W. This implements the same
1049 // special case for all architectures.
1050 outChars = data | r;
1051
1052 log(msg: "Processing section " + pSec->name + " -> " + name);
1053
1054 sortCRTSectionChunks(chunks&: pSec->chunks);
1055 }
1056
1057 OutputSection *sec = createSection(name, outChars);
1058 for (Chunk *c : pSec->chunks)
1059 sec->addChunk(c);
1060
1061 sec->addContributingPartialSection(sec: pSec);
1062 }
1063
1064 // Finally, move some output sections to the end.
1065 auto sectionOrder = [&](const OutputSection *s) {
1066 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file
1067 // because the loader cannot handle holes. Stripping can remove other
1068 // discardable ones than .reloc, which is first of them (created early).
1069 if (s->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) {
1070 // Move discardable sections named .debug_ to the end, after other
1071 // discardable sections. Stripping only removes the sections named
1072 // .debug_* - thus try to avoid leaving holes after stripping.
1073 if (s->name.starts_with(Prefix: ".debug_"))
1074 return 3;
1075 return 2;
1076 }
1077 // .rsrc should come at the end of the non-discardable sections because its
1078 // size may change by the Win32 UpdateResources() function, causing
1079 // subsequent sections to move (see https://crbug.com/827082).
1080 if (s == rsrcSec)
1081 return 1;
1082 return 0;
1083 };
1084 llvm::stable_sort(Range&: ctx.outputSections,
1085 C: [&](const OutputSection *s, const OutputSection *t) {
1086 return sectionOrder(s) < sectionOrder(t);
1087 });
1088}
1089
1090void Writer::createMiscChunks() {
1091 llvm::TimeTraceScope timeScope("Misc chunks");
1092 Configuration *config = &ctx.config;
1093
1094 for (MergeChunk *p : ctx.mergeChunkInstances) {
1095 if (p) {
1096 p->finalizeContents();
1097 rdataSec->addChunk(c: p);
1098 }
1099 }
1100
1101 // Create thunks for locally-dllimported symbols.
1102 if (!ctx.symtab.localImportChunks.empty()) {
1103 for (Chunk *c : ctx.symtab.localImportChunks)
1104 rdataSec->addChunk(c);
1105 }
1106
1107 // Create Debug Information Chunks
1108 debugInfoSec = config->mingw ? buildidSec : rdataSec;
1109 if (config->buildIDHash != BuildIDHash::None || config->debug ||
1110 config->repro || config->cetCompat) {
1111 debugDirectory =
1112 make<DebugDirectoryChunk>(args&: ctx, args&: debugRecords, args&: config->repro);
1113 debugDirectory->setAlignment(4);
1114 debugInfoSec->addChunk(c: debugDirectory);
1115 }
1116
1117 if (config->debug || config->buildIDHash != BuildIDHash::None) {
1118 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
1119 // output a PDB no matter what, and this chunk provides the only means of
1120 // allowing a debugger to match a PDB and an executable. So we need it even
1121 // if we're ultimately not going to write CodeView data to the PDB.
1122 buildId = make<CVDebugRecordChunk>(args&: ctx);
1123 debugRecords.emplace_back(args: COFF::IMAGE_DEBUG_TYPE_CODEVIEW, args&: buildId);
1124 if (Symbol *buildidSym = ctx.symtab.findUnderscore(name: "__buildid"))
1125 replaceSymbol<DefinedSynthetic>(s: buildidSym, arg: buildidSym->getName(),
1126 arg&: buildId, arg: 4);
1127 }
1128
1129 if (config->cetCompat) {
1130 debugRecords.emplace_back(args: COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS,
1131 args: make<ExtendedDllCharacteristicsChunk>(
1132 args: IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT));
1133 }
1134
1135 // Align and add each chunk referenced by the debug data directory.
1136 for (std::pair<COFF::DebugType, Chunk *> r : debugRecords) {
1137 r.second->setAlignment(4);
1138 debugInfoSec->addChunk(c: r.second);
1139 }
1140
1141 // Create SEH table. x86-only.
1142 if (config->safeSEH)
1143 createSEHTable();
1144
1145 // Create /guard:cf tables if requested.
1146 if (config->guardCF != GuardCFLevel::Off)
1147 createGuardCFTables();
1148
1149 if (isArm64EC(Machine: config->machine))
1150 createECChunks();
1151
1152 if (config->autoImport)
1153 createRuntimePseudoRelocs();
1154
1155 if (config->mingw)
1156 insertCtorDtorSymbols();
1157}
1158
1159// Create .idata section for the DLL-imported symbol table.
1160// The format of this section is inherently Windows-specific.
1161// IdataContents class abstracted away the details for us,
1162// so we just let it create chunks and add them to the section.
1163void Writer::createImportTables() {
1164 llvm::TimeTraceScope timeScope("Import tables");
1165 // Initialize DLLOrder so that import entries are ordered in
1166 // the same order as in the command line. (That affects DLL
1167 // initialization order, and this ordering is MSVC-compatible.)
1168 for (ImportFile *file : ctx.importFileInstances) {
1169 if (!file->live)
1170 continue;
1171
1172 std::string dll = StringRef(file->dllName).lower();
1173 if (ctx.config.dllOrder.count(x: dll) == 0)
1174 ctx.config.dllOrder[dll] = ctx.config.dllOrder.size();
1175
1176 if (file->impSym && !isa<DefinedImportData>(Val: file->impSym))
1177 fatal(msg: toString(ctx, b&: *file->impSym) + " was replaced");
1178 DefinedImportData *impSym = cast_or_null<DefinedImportData>(Val: file->impSym);
1179 if (ctx.config.delayLoads.count(x: StringRef(file->dllName).lower())) {
1180 if (!file->thunkSym)
1181 fatal(msg: "cannot delay-load " + toString(file) +
1182 " due to import of data: " + toString(ctx, b&: *impSym));
1183 delayIdata.add(sym: impSym);
1184 } else {
1185 idata.add(sym: impSym);
1186 }
1187 }
1188}
1189
1190void Writer::appendImportThunks() {
1191 if (ctx.importFileInstances.empty())
1192 return;
1193
1194 llvm::TimeTraceScope timeScope("Import thunks");
1195 for (ImportFile *file : ctx.importFileInstances) {
1196 if (!file->live)
1197 continue;
1198
1199 if (!file->thunkSym)
1200 continue;
1201
1202 if (!isa<DefinedImportThunk>(Val: file->thunkSym))
1203 fatal(msg: toString(ctx, b&: *file->thunkSym) + " was replaced");
1204 DefinedImportThunk *thunk = cast<DefinedImportThunk>(Val: file->thunkSym);
1205 if (file->thunkLive)
1206 textSec->addChunk(c: thunk->getChunk());
1207 }
1208
1209 if (!delayIdata.empty()) {
1210 Defined *helper = cast<Defined>(Val: ctx.config.delayLoadHelper);
1211 delayIdata.create(helper);
1212 for (Chunk *c : delayIdata.getChunks())
1213 didatSec->addChunk(c);
1214 for (Chunk *c : delayIdata.getDataChunks())
1215 dataSec->addChunk(c);
1216 for (Chunk *c : delayIdata.getCodeChunks())
1217 textSec->addChunk(c);
1218 for (Chunk *c : delayIdata.getCodePData())
1219 pdataSec->addChunk(c);
1220 for (Chunk *c : delayIdata.getCodeUnwindInfo())
1221 rdataSec->addChunk(c);
1222 }
1223}
1224
1225void Writer::createExportTable() {
1226 llvm::TimeTraceScope timeScope("Export table");
1227 if (!edataSec->chunks.empty()) {
1228 // Allow using a custom built export table from input object files, instead
1229 // of having the linker synthesize the tables.
1230 if (ctx.config.hadExplicitExports)
1231 warn(msg: "literal .edata sections override exports");
1232 } else if (!ctx.config.exports.empty()) {
1233 for (Chunk *c : edata.chunks)
1234 edataSec->addChunk(c);
1235 }
1236 if (!edataSec->chunks.empty()) {
1237 edataStart = edataSec->chunks.front();
1238 edataEnd = edataSec->chunks.back();
1239 }
1240 // Warn on exported deleting destructor.
1241 for (auto e : ctx.config.exports)
1242 if (e.sym && e.sym->getName().starts_with(Prefix: "??_G"))
1243 warn(msg: "export of deleting dtor: " + toString(ctx, b&: *e.sym));
1244}
1245
1246void Writer::removeUnusedSections() {
1247 llvm::TimeTraceScope timeScope("Remove unused sections");
1248 // Remove sections that we can be sure won't get content, to avoid
1249 // allocating space for their section headers.
1250 auto isUnused = [this](OutputSection *s) {
1251 if (s == relocSec)
1252 return false; // This section is populated later.
1253 // MergeChunks have zero size at this point, as their size is finalized
1254 // later. Only remove sections that have no Chunks at all.
1255 return s->chunks.empty();
1256 };
1257 llvm::erase_if(C&: ctx.outputSections, P: isUnused);
1258}
1259
1260// The Windows loader doesn't seem to like empty sections,
1261// so we remove them if any.
1262void Writer::removeEmptySections() {
1263 llvm::TimeTraceScope timeScope("Remove empty sections");
1264 auto isEmpty = [](OutputSection *s) { return s->getVirtualSize() == 0; };
1265 llvm::erase_if(C&: ctx.outputSections, P: isEmpty);
1266}
1267
1268void Writer::assignOutputSectionIndices() {
1269 llvm::TimeTraceScope timeScope("Output sections indices");
1270 // Assign final output section indices, and assign each chunk to its output
1271 // section.
1272 uint32_t idx = 1;
1273 for (OutputSection *os : ctx.outputSections) {
1274 os->sectionIndex = idx;
1275 for (Chunk *c : os->chunks)
1276 c->setOutputSectionIdx(idx);
1277 ++idx;
1278 }
1279
1280 // Merge chunks are containers of chunks, so assign those an output section
1281 // too.
1282 for (MergeChunk *mc : ctx.mergeChunkInstances)
1283 if (mc)
1284 for (SectionChunk *sc : mc->sections)
1285 if (sc && sc->live)
1286 sc->setOutputSectionIdx(mc->getOutputSectionIdx());
1287}
1288
1289size_t Writer::addEntryToStringTable(StringRef str) {
1290 assert(str.size() > COFF::NameSize);
1291 size_t offsetOfEntry = strtab.size() + 4; // +4 for the size field
1292 strtab.insert(position: strtab.end(), first: str.begin(), last: str.end());
1293 strtab.push_back(x: '\0');
1294 return offsetOfEntry;
1295}
1296
1297std::optional<coff_symbol16> Writer::createSymbol(Defined *def) {
1298 coff_symbol16 sym;
1299 switch (def->kind()) {
1300 case Symbol::DefinedAbsoluteKind: {
1301 auto *da = dyn_cast<DefinedAbsolute>(Val: def);
1302 // Note: COFF symbol can only store 32-bit values, so 64-bit absolute
1303 // values will be truncated.
1304 sym.Value = da->getVA();
1305 sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
1306 break;
1307 }
1308 default: {
1309 // Don't write symbols that won't be written to the output to the symbol
1310 // table.
1311 // We also try to write DefinedSynthetic as a normal symbol. Some of these
1312 // symbols do point to an actual chunk, like __safe_se_handler_table. Others
1313 // like __ImageBase are outside of sections and thus cannot be represented.
1314 Chunk *c = def->getChunk();
1315 if (!c)
1316 return std::nullopt;
1317 OutputSection *os = ctx.getOutputSection(c);
1318 if (!os)
1319 return std::nullopt;
1320
1321 sym.Value = def->getRVA() - os->getRVA();
1322 sym.SectionNumber = os->sectionIndex;
1323 break;
1324 }
1325 }
1326
1327 // Symbols that are runtime pseudo relocations don't point to the actual
1328 // symbol data itself (as they are imported), but points to the IAT entry
1329 // instead. Avoid emitting them to the symbol table, as they can confuse
1330 // debuggers.
1331 if (def->isRuntimePseudoReloc)
1332 return std::nullopt;
1333
1334 StringRef name = def->getName();
1335 if (name.size() > COFF::NameSize) {
1336 sym.Name.Offset.Zeroes = 0;
1337 sym.Name.Offset.Offset = addEntryToStringTable(str: name);
1338 } else {
1339 memset(s: sym.Name.ShortName, c: 0, n: COFF::NameSize);
1340 memcpy(dest: sym.Name.ShortName, src: name.data(), n: name.size());
1341 }
1342
1343 if (auto *d = dyn_cast<DefinedCOFF>(Val: def)) {
1344 COFFSymbolRef ref = d->getCOFFSymbol();
1345 sym.Type = ref.getType();
1346 sym.StorageClass = ref.getStorageClass();
1347 } else if (def->kind() == Symbol::DefinedImportThunkKind) {
1348 sym.Type = (IMAGE_SYM_DTYPE_FUNCTION << SCT_COMPLEX_TYPE_SHIFT) |
1349 IMAGE_SYM_TYPE_NULL;
1350 sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
1351 } else {
1352 sym.Type = IMAGE_SYM_TYPE_NULL;
1353 sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
1354 }
1355 sym.NumberOfAuxSymbols = 0;
1356 return sym;
1357}
1358
1359void Writer::createSymbolAndStringTable() {
1360 llvm::TimeTraceScope timeScope("Symbol and string table");
1361 // PE/COFF images are limited to 8 byte section names. Longer names can be
1362 // supported by writing a non-standard string table, but this string table is
1363 // not mapped at runtime and the long names will therefore be inaccessible.
1364 // link.exe always truncates section names to 8 bytes, whereas binutils always
1365 // preserves long section names via the string table. LLD adopts a hybrid
1366 // solution where discardable sections have long names preserved and
1367 // non-discardable sections have their names truncated, to ensure that any
1368 // section which is mapped at runtime also has its name mapped at runtime.
1369 for (OutputSection *sec : ctx.outputSections) {
1370 if (sec->name.size() <= COFF::NameSize)
1371 continue;
1372 if ((sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0)
1373 continue;
1374 if (ctx.config.warnLongSectionNames) {
1375 warn(msg: "section name " + sec->name +
1376 " is longer than 8 characters and will use a non-standard string "
1377 "table");
1378 }
1379 sec->setStringTableOff(addEntryToStringTable(str: sec->name));
1380 }
1381
1382 if (ctx.config.writeSymtab) {
1383 for (ObjFile *file : ctx.objFileInstances) {
1384 for (Symbol *b : file->getSymbols()) {
1385 auto *d = dyn_cast_or_null<Defined>(Val: b);
1386 if (!d || d->writtenToSymtab)
1387 continue;
1388 d->writtenToSymtab = true;
1389 if (auto *dc = dyn_cast_or_null<DefinedCOFF>(Val: d)) {
1390 COFFSymbolRef symRef = dc->getCOFFSymbol();
1391 if (symRef.isSectionDefinition() ||
1392 symRef.getStorageClass() == COFF::IMAGE_SYM_CLASS_LABEL)
1393 continue;
1394 }
1395
1396 if (std::optional<coff_symbol16> sym = createSymbol(def: d))
1397 outputSymtab.push_back(x: *sym);
1398
1399 if (auto *dthunk = dyn_cast<DefinedImportThunk>(Val: d)) {
1400 if (!dthunk->wrappedSym->writtenToSymtab) {
1401 dthunk->wrappedSym->writtenToSymtab = true;
1402 if (std::optional<coff_symbol16> sym =
1403 createSymbol(def: dthunk->wrappedSym))
1404 outputSymtab.push_back(x: *sym);
1405 }
1406 }
1407 }
1408 }
1409 }
1410
1411 if (outputSymtab.empty() && strtab.empty())
1412 return;
1413
1414 // We position the symbol table to be adjacent to the end of the last section.
1415 uint64_t fileOff = fileSize;
1416 pointerToSymbolTable = fileOff;
1417 fileOff += outputSymtab.size() * sizeof(coff_symbol16);
1418 fileOff += 4 + strtab.size();
1419 fileSize = alignTo(Value: fileOff, Align: ctx.config.fileAlign);
1420}
1421
1422void Writer::mergeSections() {
1423 llvm::TimeTraceScope timeScope("Merge sections");
1424 if (!pdataSec->chunks.empty()) {
1425 if (isArm64EC(Machine: ctx.config.machine)) {
1426 // On ARM64EC .pdata may contain both ARM64 and X64 data. Split them by
1427 // sorting and store their regions separately.
1428 llvm::stable_sort(Range&: pdataSec->chunks, C: [=](const Chunk *a, const Chunk *b) {
1429 return (a->getMachine() == AMD64) < (b->getMachine() == AMD64);
1430 });
1431
1432 for (auto chunk : pdataSec->chunks) {
1433 if (chunk->getMachine() == AMD64) {
1434 hybridPdata.first = chunk;
1435 hybridPdata.last = pdataSec->chunks.back();
1436 break;
1437 }
1438
1439 if (!pdata.first)
1440 pdata.first = chunk;
1441 pdata.last = chunk;
1442 }
1443 } else {
1444 pdata.first = pdataSec->chunks.front();
1445 pdata.last = pdataSec->chunks.back();
1446 }
1447 }
1448
1449 for (auto &p : ctx.config.merge) {
1450 StringRef toName = p.second;
1451 if (p.first == toName)
1452 continue;
1453 StringSet<> names;
1454 while (true) {
1455 if (!names.insert(key: toName).second)
1456 fatal(msg: "/merge: cycle found for section '" + p.first + "'");
1457 auto i = ctx.config.merge.find(x: toName);
1458 if (i == ctx.config.merge.end())
1459 break;
1460 toName = i->second;
1461 }
1462 OutputSection *from = findSection(name: p.first);
1463 OutputSection *to = findSection(name: toName);
1464 if (!from)
1465 continue;
1466 if (!to) {
1467 from->name = toName;
1468 continue;
1469 }
1470 to->merge(other: from);
1471 }
1472}
1473
1474// EC targets may have chunks of various architectures mixed together at this
1475// point. Group code chunks of the same architecture together by sorting chunks
1476// by their EC range type.
1477void Writer::sortECChunks() {
1478 if (!isArm64EC(Machine: ctx.config.machine))
1479 return;
1480
1481 for (OutputSection *sec : ctx.outputSections) {
1482 if (sec->isCodeSection())
1483 llvm::stable_sort(Range&: sec->chunks, C: [=](const Chunk *a, const Chunk *b) {
1484 std::optional<chpe_range_type> aType = a->getArm64ECRangeType(),
1485 bType = b->getArm64ECRangeType();
1486 return bType && (!aType || *aType < *bType);
1487 });
1488 }
1489}
1490
1491// Visits all sections to assign incremental, non-overlapping RVAs and
1492// file offsets.
1493void Writer::assignAddresses() {
1494 llvm::TimeTraceScope timeScope("Assign addresses");
1495 Configuration *config = &ctx.config;
1496
1497 // We need to create EC code map so that ECCodeMapChunk knows its size.
1498 // We do it here to make sure that we account for range extension chunks.
1499 createECCodeMap();
1500
1501 sizeOfHeaders = dosStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
1502 sizeof(data_directory) * numberOfDataDirectory +
1503 sizeof(coff_section) * ctx.outputSections.size();
1504 sizeOfHeaders +=
1505 config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
1506 sizeOfHeaders = alignTo(Value: sizeOfHeaders, Align: config->fileAlign);
1507 fileSize = sizeOfHeaders;
1508
1509 // The first page is kept unmapped.
1510 uint64_t rva = alignTo(Value: sizeOfHeaders, Align: config->align);
1511
1512 for (OutputSection *sec : ctx.outputSections) {
1513 llvm::TimeTraceScope timeScope("Section: ", sec->name);
1514 if (sec == relocSec)
1515 addBaserels();
1516 uint64_t rawSize = 0, virtualSize = 0;
1517 sec->header.VirtualAddress = rva;
1518
1519 // If /FUNCTIONPADMIN is used, functions are padded in order to create a
1520 // hotpatchable image.
1521 uint32_t padding = sec->isCodeSection() ? config->functionPadMin : 0;
1522 std::optional<chpe_range_type> prevECRange;
1523
1524 for (Chunk *c : sec->chunks) {
1525 // Alignment EC code range baudaries.
1526 if (isArm64EC(Machine: ctx.config.machine) && sec->isCodeSection()) {
1527 std::optional<chpe_range_type> rangeType = c->getArm64ECRangeType();
1528 if (rangeType != prevECRange) {
1529 virtualSize = alignTo(Value: virtualSize, Align: 4096);
1530 prevECRange = rangeType;
1531 }
1532 }
1533 if (padding && c->isHotPatchable())
1534 virtualSize += padding;
1535 // If chunk has EC entry thunk, reserve a space for an offset to the
1536 // thunk.
1537 if (c->getEntryThunk())
1538 virtualSize += sizeof(uint32_t);
1539 virtualSize = alignTo(Value: virtualSize, Align: c->getAlignment());
1540 c->setRVA(rva + virtualSize);
1541 virtualSize += c->getSize();
1542 if (c->hasData)
1543 rawSize = alignTo(Value: virtualSize, Align: config->fileAlign);
1544 }
1545 if (virtualSize > UINT32_MAX)
1546 error(msg: "section larger than 4 GiB: " + sec->name);
1547 sec->header.VirtualSize = virtualSize;
1548 sec->header.SizeOfRawData = rawSize;
1549 if (rawSize != 0)
1550 sec->header.PointerToRawData = fileSize;
1551 rva += alignTo(Value: virtualSize, Align: config->align);
1552 fileSize += alignTo(Value: rawSize, Align: config->fileAlign);
1553 }
1554 sizeOfImage = alignTo(Value: rva, Align: config->align);
1555
1556 // Assign addresses to sections in MergeChunks.
1557 for (MergeChunk *mc : ctx.mergeChunkInstances)
1558 if (mc)
1559 mc->assignSubsectionRVAs();
1560}
1561
1562template <typename PEHeaderTy> void Writer::writeHeader() {
1563 // Write DOS header. For backwards compatibility, the first part of a PE/COFF
1564 // executable consists of an MS-DOS MZ executable. If the executable is run
1565 // under DOS, that program gets run (usually to just print an error message).
1566 // When run under Windows, the loader looks at AddressOfNewExeHeader and uses
1567 // the PE header instead.
1568 Configuration *config = &ctx.config;
1569 uint8_t *buf = buffer->getBufferStart();
1570 auto *dos = reinterpret_cast<dos_header *>(buf);
1571 buf += sizeof(dos_header);
1572 dos->Magic[0] = 'M';
1573 dos->Magic[1] = 'Z';
1574 dos->UsedBytesInTheLastPage = dosStubSize % 512;
1575 dos->FileSizeInPages = divideCeil(Numerator: dosStubSize, Denominator: 512);
1576 dos->HeaderSizeInParagraphs = sizeof(dos_header) / 16;
1577
1578 dos->AddressOfRelocationTable = sizeof(dos_header);
1579 dos->AddressOfNewExeHeader = dosStubSize;
1580
1581 // Write DOS program.
1582 memcpy(dest: buf, src: dosProgram, n: sizeof(dosProgram));
1583 buf += sizeof(dosProgram);
1584
1585 // Write PE magic
1586 memcpy(dest: buf, src: PEMagic, n: sizeof(PEMagic));
1587 buf += sizeof(PEMagic);
1588
1589 // Write COFF header
1590 auto *coff = reinterpret_cast<coff_file_header *>(buf);
1591 buf += sizeof(*coff);
1592 switch (config->machine) {
1593 case ARM64EC:
1594 coff->Machine = AMD64;
1595 break;
1596 case ARM64X:
1597 coff->Machine = ARM64;
1598 break;
1599 default:
1600 coff->Machine = config->machine;
1601 }
1602 coff->NumberOfSections = ctx.outputSections.size();
1603 coff->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
1604 if (config->largeAddressAware)
1605 coff->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
1606 if (!config->is64())
1607 coff->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
1608 if (config->dll)
1609 coff->Characteristics |= IMAGE_FILE_DLL;
1610 if (config->driverUponly)
1611 coff->Characteristics |= IMAGE_FILE_UP_SYSTEM_ONLY;
1612 if (!config->relocatable)
1613 coff->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
1614 if (config->swaprunCD)
1615 coff->Characteristics |= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP;
1616 if (config->swaprunNet)
1617 coff->Characteristics |= IMAGE_FILE_NET_RUN_FROM_SWAP;
1618 coff->SizeOfOptionalHeader =
1619 sizeof(PEHeaderTy) + sizeof(data_directory) * numberOfDataDirectory;
1620
1621 // Write PE header
1622 auto *pe = reinterpret_cast<PEHeaderTy *>(buf);
1623 buf += sizeof(*pe);
1624 pe->Magic = config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
1625
1626 // If {Major,Minor}LinkerVersion is left at 0.0, then for some
1627 // reason signing the resulting PE file with Authenticode produces a
1628 // signature that fails to validate on Windows 7 (but is OK on 10).
1629 // Set it to 14.0, which is what VS2015 outputs, and which avoids
1630 // that problem.
1631 pe->MajorLinkerVersion = 14;
1632 pe->MinorLinkerVersion = 0;
1633
1634 pe->ImageBase = config->imageBase;
1635 pe->SectionAlignment = config->align;
1636 pe->FileAlignment = config->fileAlign;
1637 pe->MajorImageVersion = config->majorImageVersion;
1638 pe->MinorImageVersion = config->minorImageVersion;
1639 pe->MajorOperatingSystemVersion = config->majorOSVersion;
1640 pe->MinorOperatingSystemVersion = config->minorOSVersion;
1641 pe->MajorSubsystemVersion = config->majorSubsystemVersion;
1642 pe->MinorSubsystemVersion = config->minorSubsystemVersion;
1643 pe->Subsystem = config->subsystem;
1644 pe->SizeOfImage = sizeOfImage;
1645 pe->SizeOfHeaders = sizeOfHeaders;
1646 if (!config->noEntry) {
1647 Defined *entry = cast<Defined>(Val: config->entry);
1648 pe->AddressOfEntryPoint = entry->getRVA();
1649 // Pointer to thumb code must have the LSB set, so adjust it.
1650 if (config->machine == ARMNT)
1651 pe->AddressOfEntryPoint |= 1;
1652 }
1653 pe->SizeOfStackReserve = config->stackReserve;
1654 pe->SizeOfStackCommit = config->stackCommit;
1655 pe->SizeOfHeapReserve = config->heapReserve;
1656 pe->SizeOfHeapCommit = config->heapCommit;
1657 if (config->appContainer)
1658 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
1659 if (config->driverWdm)
1660 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER;
1661 if (config->dynamicBase)
1662 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
1663 if (config->highEntropyVA)
1664 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
1665 if (!config->allowBind)
1666 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND;
1667 if (config->nxCompat)
1668 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
1669 if (!config->allowIsolation)
1670 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
1671 if (config->guardCF != GuardCFLevel::Off)
1672 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_GUARD_CF;
1673 if (config->integrityCheck)
1674 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY;
1675 if (setNoSEHCharacteristic || config->noSEH)
1676 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_SEH;
1677 if (config->terminalServerAware)
1678 pe->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
1679 pe->NumberOfRvaAndSize = numberOfDataDirectory;
1680 if (textSec->getVirtualSize()) {
1681 pe->BaseOfCode = textSec->getRVA();
1682 pe->SizeOfCode = textSec->getRawSize();
1683 }
1684 pe->SizeOfInitializedData = getSizeOfInitializedData();
1685
1686 // Write data directory
1687 auto *dir = reinterpret_cast<data_directory *>(buf);
1688 buf += sizeof(*dir) * numberOfDataDirectory;
1689 if (edataStart) {
1690 dir[EXPORT_TABLE].RelativeVirtualAddress = edataStart->getRVA();
1691 dir[EXPORT_TABLE].Size =
1692 edataEnd->getRVA() + edataEnd->getSize() - edataStart->getRVA();
1693 }
1694 if (importTableStart) {
1695 dir[IMPORT_TABLE].RelativeVirtualAddress = importTableStart->getRVA();
1696 dir[IMPORT_TABLE].Size = importTableSize;
1697 }
1698 if (iatStart) {
1699 dir[IAT].RelativeVirtualAddress = iatStart->getRVA();
1700 dir[IAT].Size = iatSize;
1701 }
1702 if (rsrcSec->getVirtualSize()) {
1703 dir[RESOURCE_TABLE].RelativeVirtualAddress = rsrcSec->getRVA();
1704 dir[RESOURCE_TABLE].Size = rsrcSec->getVirtualSize();
1705 }
1706 // ARM64EC (but not ARM64X) contains x86_64 exception table in data directory.
1707 ChunkRange &exceptionTable =
1708 ctx.config.machine == ARM64EC ? hybridPdata : pdata;
1709 if (exceptionTable.first) {
1710 dir[EXCEPTION_TABLE].RelativeVirtualAddress =
1711 exceptionTable.first->getRVA();
1712 dir[EXCEPTION_TABLE].Size = exceptionTable.last->getRVA() +
1713 exceptionTable.last->getSize() -
1714 exceptionTable.first->getRVA();
1715 }
1716 if (relocSec->getVirtualSize()) {
1717 dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = relocSec->getRVA();
1718 dir[BASE_RELOCATION_TABLE].Size = relocSec->getVirtualSize();
1719 }
1720 if (Symbol *sym = ctx.symtab.findUnderscore(name: "_tls_used")) {
1721 if (Defined *b = dyn_cast<Defined>(Val: sym)) {
1722 dir[TLS_TABLE].RelativeVirtualAddress = b->getRVA();
1723 dir[TLS_TABLE].Size = config->is64()
1724 ? sizeof(object::coff_tls_directory64)
1725 : sizeof(object::coff_tls_directory32);
1726 }
1727 }
1728 if (debugDirectory) {
1729 dir[DEBUG_DIRECTORY].RelativeVirtualAddress = debugDirectory->getRVA();
1730 dir[DEBUG_DIRECTORY].Size = debugDirectory->getSize();
1731 }
1732 if (Symbol *sym = ctx.symtab.findUnderscore(name: "_load_config_used")) {
1733 if (auto *b = dyn_cast<DefinedRegular>(Val: sym)) {
1734 SectionChunk *sc = b->getChunk();
1735 assert(b->getRVA() >= sc->getRVA());
1736 uint64_t offsetInChunk = b->getRVA() - sc->getRVA();
1737 if (!sc->hasData || offsetInChunk + 4 > sc->getSize())
1738 fatal(msg: "_load_config_used is malformed");
1739
1740 ArrayRef<uint8_t> secContents = sc->getContents();
1741 uint32_t loadConfigSize =
1742 *reinterpret_cast<const ulittle32_t *>(&secContents[offsetInChunk]);
1743 if (offsetInChunk + loadConfigSize > sc->getSize())
1744 fatal(msg: "_load_config_used is too large");
1745 dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = b->getRVA();
1746 dir[LOAD_CONFIG_TABLE].Size = loadConfigSize;
1747 }
1748 }
1749 if (!delayIdata.empty()) {
1750 dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress =
1751 delayIdata.getDirRVA();
1752 dir[DELAY_IMPORT_DESCRIPTOR].Size = delayIdata.getDirSize();
1753 }
1754
1755 // Write section table
1756 for (OutputSection *sec : ctx.outputSections) {
1757 sec->writeHeaderTo(buf, isDebug: config->debug);
1758 buf += sizeof(coff_section);
1759 }
1760 sectionTable = ArrayRef<uint8_t>(
1761 buf - ctx.outputSections.size() * sizeof(coff_section), buf);
1762
1763 if (outputSymtab.empty() && strtab.empty())
1764 return;
1765
1766 coff->PointerToSymbolTable = pointerToSymbolTable;
1767 uint32_t numberOfSymbols = outputSymtab.size();
1768 coff->NumberOfSymbols = numberOfSymbols;
1769 auto *symbolTable = reinterpret_cast<coff_symbol16 *>(
1770 buffer->getBufferStart() + coff->PointerToSymbolTable);
1771 for (size_t i = 0; i != numberOfSymbols; ++i)
1772 symbolTable[i] = outputSymtab[i];
1773 // Create the string table, it follows immediately after the symbol table.
1774 // The first 4 bytes is length including itself.
1775 buf = reinterpret_cast<uint8_t *>(&symbolTable[numberOfSymbols]);
1776 write32le(P: buf, V: strtab.size() + 4);
1777 if (!strtab.empty())
1778 memcpy(dest: buf + 4, src: strtab.data(), n: strtab.size());
1779}
1780
1781void Writer::openFile(StringRef path) {
1782 buffer = CHECK(
1783 FileOutputBuffer::create(path, fileSize, FileOutputBuffer::F_executable),
1784 "failed to open " + path);
1785}
1786
1787void Writer::createSEHTable() {
1788 SymbolRVASet handlers;
1789 for (ObjFile *file : ctx.objFileInstances) {
1790 if (!file->hasSafeSEH())
1791 error(msg: "/safeseh: " + file->getName() + " is not compatible with SEH");
1792 markSymbolsForRVATable(file, symIdxChunks: file->getSXDataChunks(), tableSymbols&: handlers);
1793 }
1794
1795 // Set the "no SEH" characteristic if there really were no handlers, or if
1796 // there is no load config object to point to the table of handlers.
1797 setNoSEHCharacteristic =
1798 handlers.empty() || !ctx.symtab.findUnderscore(name: "_load_config_used");
1799
1800 maybeAddRVATable(tableSymbols: std::move(handlers), tableSym: "__safe_se_handler_table",
1801 countSym: "__safe_se_handler_count");
1802}
1803
1804// Add a symbol to an RVA set. Two symbols may have the same RVA, but an RVA set
1805// cannot contain duplicates. Therefore, the set is uniqued by Chunk and the
1806// symbol's offset into that Chunk.
1807static void addSymbolToRVASet(SymbolRVASet &rvaSet, Defined *s) {
1808 Chunk *c = s->getChunk();
1809 if (!c)
1810 return;
1811 if (auto *sc = dyn_cast<SectionChunk>(Val: c))
1812 c = sc->repl; // Look through ICF replacement.
1813 uint32_t off = s->getRVA() - (c ? c->getRVA() : 0);
1814 rvaSet.insert(V: {.inputChunk: c, .offset: off});
1815}
1816
1817// Given a symbol, add it to the GFIDs table if it is a live, defined, function
1818// symbol in an executable section.
1819static void maybeAddAddressTakenFunction(SymbolRVASet &addressTakenSyms,
1820 Symbol *s) {
1821 if (!s)
1822 return;
1823
1824 switch (s->kind()) {
1825 case Symbol::DefinedLocalImportKind:
1826 case Symbol::DefinedImportDataKind:
1827 // Defines an __imp_ pointer, so it is data, so it is ignored.
1828 break;
1829 case Symbol::DefinedCommonKind:
1830 // Common is always data, so it is ignored.
1831 break;
1832 case Symbol::DefinedAbsoluteKind:
1833 case Symbol::DefinedSyntheticKind:
1834 // Absolute is never code, synthetic generally isn't and usually isn't
1835 // determinable.
1836 break;
1837 case Symbol::LazyArchiveKind:
1838 case Symbol::LazyObjectKind:
1839 case Symbol::LazyDLLSymbolKind:
1840 case Symbol::UndefinedKind:
1841 // Undefined symbols resolve to zero, so they don't have an RVA. Lazy
1842 // symbols shouldn't have relocations.
1843 break;
1844
1845 case Symbol::DefinedImportThunkKind:
1846 // Thunks are always code, include them.
1847 addSymbolToRVASet(rvaSet&: addressTakenSyms, s: cast<Defined>(Val: s));
1848 break;
1849
1850 case Symbol::DefinedRegularKind: {
1851 // This is a regular, defined, symbol from a COFF file. Mark the symbol as
1852 // address taken if the symbol type is function and it's in an executable
1853 // section.
1854 auto *d = cast<DefinedRegular>(Val: s);
1855 if (d->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
1856 SectionChunk *sc = dyn_cast<SectionChunk>(Val: d->getChunk());
1857 if (sc && sc->live &&
1858 sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)
1859 addSymbolToRVASet(rvaSet&: addressTakenSyms, s: d);
1860 }
1861 break;
1862 }
1863 }
1864}
1865
1866// Visit all relocations from all section contributions of this object file and
1867// mark the relocation target as address-taken.
1868void Writer::markSymbolsWithRelocations(ObjFile *file,
1869 SymbolRVASet &usedSymbols) {
1870 for (Chunk *c : file->getChunks()) {
1871 // We only care about live section chunks. Common chunks and other chunks
1872 // don't generally contain relocations.
1873 SectionChunk *sc = dyn_cast<SectionChunk>(Val: c);
1874 if (!sc || !sc->live)
1875 continue;
1876
1877 for (const coff_relocation &reloc : sc->getRelocs()) {
1878 if (ctx.config.machine == I386 &&
1879 reloc.Type == COFF::IMAGE_REL_I386_REL32)
1880 // Ignore relative relocations on x86. On x86_64 they can't be ignored
1881 // since they're also used to compute absolute addresses.
1882 continue;
1883
1884 Symbol *ref = sc->file->getSymbol(symbolIndex: reloc.SymbolTableIndex);
1885 maybeAddAddressTakenFunction(addressTakenSyms&: usedSymbols, s: ref);
1886 }
1887 }
1888}
1889
1890// Create the guard function id table. This is a table of RVAs of all
1891// address-taken functions. It is sorted and uniqued, just like the safe SEH
1892// table.
1893void Writer::createGuardCFTables() {
1894 Configuration *config = &ctx.config;
1895
1896 SymbolRVASet addressTakenSyms;
1897 SymbolRVASet giatsRVASet;
1898 std::vector<Symbol *> giatsSymbols;
1899 SymbolRVASet longJmpTargets;
1900 SymbolRVASet ehContTargets;
1901 for (ObjFile *file : ctx.objFileInstances) {
1902 // If the object was compiled with /guard:cf, the address taken symbols
1903 // are in .gfids$y sections, and the longjmp targets are in .gljmp$y
1904 // sections. If the object was not compiled with /guard:cf, we assume there
1905 // were no setjmp targets, and that all code symbols with relocations are
1906 // possibly address-taken.
1907 if (file->hasGuardCF()) {
1908 markSymbolsForRVATable(file, symIdxChunks: file->getGuardFidChunks(), tableSymbols&: addressTakenSyms);
1909 markSymbolsForRVATable(file, symIdxChunks: file->getGuardIATChunks(), tableSymbols&: giatsRVASet);
1910 getSymbolsFromSections(file, symIdxChunks: file->getGuardIATChunks(), symbols&: giatsSymbols);
1911 markSymbolsForRVATable(file, symIdxChunks: file->getGuardLJmpChunks(), tableSymbols&: longJmpTargets);
1912 } else {
1913 markSymbolsWithRelocations(file, usedSymbols&: addressTakenSyms);
1914 }
1915 // If the object was compiled with /guard:ehcont, the ehcont targets are in
1916 // .gehcont$y sections.
1917 if (file->hasGuardEHCont())
1918 markSymbolsForRVATable(file, symIdxChunks: file->getGuardEHContChunks(), tableSymbols&: ehContTargets);
1919 }
1920
1921 // Mark the image entry as address-taken.
1922 if (config->entry)
1923 maybeAddAddressTakenFunction(addressTakenSyms, s: config->entry);
1924
1925 // Mark exported symbols in executable sections as address-taken.
1926 for (Export &e : config->exports)
1927 maybeAddAddressTakenFunction(addressTakenSyms, s: e.sym);
1928
1929 // For each entry in the .giats table, check if it has a corresponding load
1930 // thunk (e.g. because the DLL that defines it will be delay-loaded) and, if
1931 // so, add the load thunk to the address taken (.gfids) table.
1932 for (Symbol *s : giatsSymbols) {
1933 if (auto *di = dyn_cast<DefinedImportData>(Val: s)) {
1934 if (di->loadThunkSym)
1935 addSymbolToRVASet(rvaSet&: addressTakenSyms, s: di->loadThunkSym);
1936 }
1937 }
1938
1939 // Ensure sections referenced in the gfid table are 16-byte aligned.
1940 for (const ChunkAndOffset &c : addressTakenSyms)
1941 if (c.inputChunk->getAlignment() < 16)
1942 c.inputChunk->setAlignment(16);
1943
1944 maybeAddRVATable(tableSymbols: std::move(addressTakenSyms), tableSym: "__guard_fids_table",
1945 countSym: "__guard_fids_count");
1946
1947 // Add the Guard Address Taken IAT Entry Table (.giats).
1948 maybeAddRVATable(tableSymbols: std::move(giatsRVASet), tableSym: "__guard_iat_table",
1949 countSym: "__guard_iat_count");
1950
1951 // Add the longjmp target table unless the user told us not to.
1952 if (config->guardCF & GuardCFLevel::LongJmp)
1953 maybeAddRVATable(tableSymbols: std::move(longJmpTargets), tableSym: "__guard_longjmp_table",
1954 countSym: "__guard_longjmp_count");
1955
1956 // Add the ehcont target table unless the user told us not to.
1957 if (config->guardCF & GuardCFLevel::EHCont)
1958 maybeAddRVATable(tableSymbols: std::move(ehContTargets), tableSym: "__guard_eh_cont_table",
1959 countSym: "__guard_eh_cont_count");
1960
1961 // Set __guard_flags, which will be used in the load config to indicate that
1962 // /guard:cf was enabled.
1963 uint32_t guardFlags = uint32_t(GuardFlags::CF_INSTRUMENTED) |
1964 uint32_t(GuardFlags::CF_FUNCTION_TABLE_PRESENT);
1965 if (config->guardCF & GuardCFLevel::LongJmp)
1966 guardFlags |= uint32_t(GuardFlags::CF_LONGJUMP_TABLE_PRESENT);
1967 if (config->guardCF & GuardCFLevel::EHCont)
1968 guardFlags |= uint32_t(GuardFlags::EH_CONTINUATION_TABLE_PRESENT);
1969 Symbol *flagSym = ctx.symtab.findUnderscore(name: "__guard_flags");
1970 cast<DefinedAbsolute>(Val: flagSym)->setVA(guardFlags);
1971}
1972
1973// Take a list of input sections containing symbol table indices and add those
1974// symbols to a vector. The challenge is that symbol RVAs are not known and
1975// depend on the table size, so we can't directly build a set of integers.
1976void Writer::getSymbolsFromSections(ObjFile *file,
1977 ArrayRef<SectionChunk *> symIdxChunks,
1978 std::vector<Symbol *> &symbols) {
1979 for (SectionChunk *c : symIdxChunks) {
1980 // Skip sections discarded by linker GC. This comes up when a .gfids section
1981 // is associated with something like a vtable and the vtable is discarded.
1982 // In this case, the associated gfids section is discarded, and we don't
1983 // mark the virtual member functions as address-taken by the vtable.
1984 if (!c->live)
1985 continue;
1986
1987 // Validate that the contents look like symbol table indices.
1988 ArrayRef<uint8_t> data = c->getContents();
1989 if (data.size() % 4 != 0) {
1990 warn(msg: "ignoring " + c->getSectionName() +
1991 " symbol table index section in object " + toString(file));
1992 continue;
1993 }
1994
1995 // Read each symbol table index and check if that symbol was included in the
1996 // final link. If so, add it to the vector of symbols.
1997 ArrayRef<ulittle32_t> symIndices(
1998 reinterpret_cast<const ulittle32_t *>(data.data()), data.size() / 4);
1999 ArrayRef<Symbol *> objSymbols = file->getSymbols();
2000 for (uint32_t symIndex : symIndices) {
2001 if (symIndex >= objSymbols.size()) {
2002 warn(msg: "ignoring invalid symbol table index in section " +
2003 c->getSectionName() + " in object " + toString(file));
2004 continue;
2005 }
2006 if (Symbol *s = objSymbols[symIndex]) {
2007 if (s->isLive())
2008 symbols.push_back(x: cast<Symbol>(Val: s));
2009 }
2010 }
2011 }
2012}
2013
2014// Take a list of input sections containing symbol table indices and add those
2015// symbols to an RVA table.
2016void Writer::markSymbolsForRVATable(ObjFile *file,
2017 ArrayRef<SectionChunk *> symIdxChunks,
2018 SymbolRVASet &tableSymbols) {
2019 std::vector<Symbol *> syms;
2020 getSymbolsFromSections(file, symIdxChunks, symbols&: syms);
2021
2022 for (Symbol *s : syms)
2023 addSymbolToRVASet(rvaSet&: tableSymbols, s: cast<Defined>(Val: s));
2024}
2025
2026// Replace the absolute table symbol with a synthetic symbol pointing to
2027// tableChunk so that we can emit base relocations for it and resolve section
2028// relative relocations.
2029void Writer::maybeAddRVATable(SymbolRVASet tableSymbols, StringRef tableSym,
2030 StringRef countSym, bool hasFlag) {
2031 if (tableSymbols.empty())
2032 return;
2033
2034 NonSectionChunk *tableChunk;
2035 if (hasFlag)
2036 tableChunk = make<RVAFlagTableChunk>(args: std::move(tableSymbols));
2037 else
2038 tableChunk = make<RVATableChunk>(args: std::move(tableSymbols));
2039 rdataSec->addChunk(c: tableChunk);
2040
2041 Symbol *t = ctx.symtab.findUnderscore(name: tableSym);
2042 Symbol *c = ctx.symtab.findUnderscore(name: countSym);
2043 replaceSymbol<DefinedSynthetic>(s: t, arg: t->getName(), arg&: tableChunk);
2044 cast<DefinedAbsolute>(Val: c)->setVA(tableChunk->getSize() / (hasFlag ? 5 : 4));
2045}
2046
2047// Create CHPE metadata chunks.
2048void Writer::createECChunks() {
2049 auto codeMapChunk = make<ECCodeMapChunk>(args&: codeMap);
2050 rdataSec->addChunk(c: codeMapChunk);
2051 Symbol *codeMapSym = ctx.symtab.findUnderscore(name: "__hybrid_code_map");
2052 replaceSymbol<DefinedSynthetic>(s: codeMapSym, arg: codeMapSym->getName(),
2053 arg&: codeMapChunk);
2054}
2055
2056// MinGW specific. Gather all relocations that are imported from a DLL even
2057// though the code didn't expect it to, produce the table that the runtime
2058// uses for fixing them up, and provide the synthetic symbols that the
2059// runtime uses for finding the table.
2060void Writer::createRuntimePseudoRelocs() {
2061 std::vector<RuntimePseudoReloc> rels;
2062
2063 for (Chunk *c : ctx.symtab.getChunks()) {
2064 auto *sc = dyn_cast<SectionChunk>(Val: c);
2065 if (!sc || !sc->live)
2066 continue;
2067 // Don't create pseudo relocations for sections that won't be
2068 // mapped at runtime.
2069 if (sc->header->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2070 continue;
2071 sc->getRuntimePseudoRelocs(res&: rels);
2072 }
2073
2074 if (!ctx.config.pseudoRelocs) {
2075 // Not writing any pseudo relocs; if some were needed, error out and
2076 // indicate what required them.
2077 for (const RuntimePseudoReloc &rpr : rels)
2078 error(msg: "automatic dllimport of " + rpr.sym->getName() + " in " +
2079 toString(file: rpr.target->file) + " requires pseudo relocations");
2080 return;
2081 }
2082
2083 if (!rels.empty()) {
2084 log(msg: "Writing " + Twine(rels.size()) + " runtime pseudo relocations");
2085 const char *symbolName = "_pei386_runtime_relocator";
2086 Symbol *relocator = ctx.symtab.findUnderscore(name: symbolName);
2087 if (!relocator)
2088 error(msg: "output image has runtime pseudo relocations, but the function " +
2089 Twine(symbolName) +
2090 " is missing; it is needed for fixing the relocations at runtime");
2091 }
2092
2093 PseudoRelocTableChunk *table = make<PseudoRelocTableChunk>(args&: rels);
2094 rdataSec->addChunk(c: table);
2095 EmptyChunk *endOfList = make<EmptyChunk>();
2096 rdataSec->addChunk(c: endOfList);
2097
2098 Symbol *headSym = ctx.symtab.findUnderscore(name: "__RUNTIME_PSEUDO_RELOC_LIST__");
2099 Symbol *endSym =
2100 ctx.symtab.findUnderscore(name: "__RUNTIME_PSEUDO_RELOC_LIST_END__");
2101 replaceSymbol<DefinedSynthetic>(s: headSym, arg: headSym->getName(), arg&: table);
2102 replaceSymbol<DefinedSynthetic>(s: endSym, arg: endSym->getName(), arg&: endOfList);
2103}
2104
2105// MinGW specific.
2106// The MinGW .ctors and .dtors lists have sentinels at each end;
2107// a (uintptr_t)-1 at the start and a (uintptr_t)0 at the end.
2108// There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
2109// and __DTOR_LIST__ respectively.
2110void Writer::insertCtorDtorSymbols() {
2111 AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(args&: ctx, args: -1);
2112 AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(args&: ctx, args: 0);
2113 AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(args&: ctx, args: -1);
2114 AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(args&: ctx, args: 0);
2115 ctorsSec->insertChunkAtStart(c: ctorListHead);
2116 ctorsSec->addChunk(c: ctorListEnd);
2117 dtorsSec->insertChunkAtStart(c: dtorListHead);
2118 dtorsSec->addChunk(c: dtorListEnd);
2119
2120 Symbol *ctorListSym = ctx.symtab.findUnderscore(name: "__CTOR_LIST__");
2121 Symbol *dtorListSym = ctx.symtab.findUnderscore(name: "__DTOR_LIST__");
2122 replaceSymbol<DefinedSynthetic>(s: ctorListSym, arg: ctorListSym->getName(),
2123 arg&: ctorListHead);
2124 replaceSymbol<DefinedSynthetic>(s: dtorListSym, arg: dtorListSym->getName(),
2125 arg&: dtorListHead);
2126}
2127
2128// Handles /section options to allow users to overwrite
2129// section attributes.
2130void Writer::setSectionPermissions() {
2131 llvm::TimeTraceScope timeScope("Sections permissions");
2132 for (auto &p : ctx.config.section) {
2133 StringRef name = p.first;
2134 uint32_t perm = p.second;
2135 for (OutputSection *sec : ctx.outputSections)
2136 if (sec->name == name)
2137 sec->setPermissions(perm);
2138 }
2139}
2140
2141// Set symbols used by ARM64EC metadata.
2142void Writer::setECSymbols() {
2143 if (!isArm64EC(Machine: ctx.config.machine))
2144 return;
2145
2146 Symbol *rfeTableSym = ctx.symtab.findUnderscore(name: "__arm64x_extra_rfe_table");
2147 replaceSymbol<DefinedSynthetic>(s: rfeTableSym, arg: "__arm64x_extra_rfe_table",
2148 arg&: pdata.first);
2149
2150 if (pdata.first) {
2151 Symbol *rfeSizeSym =
2152 ctx.symtab.findUnderscore(name: "__arm64x_extra_rfe_table_size");
2153 cast<DefinedAbsolute>(Val: rfeSizeSym)
2154 ->setVA(pdata.last->getRVA() + pdata.last->getSize() -
2155 pdata.first->getRVA());
2156 }
2157}
2158
2159// Write section contents to a mmap'ed file.
2160void Writer::writeSections() {
2161 llvm::TimeTraceScope timeScope("Write sections");
2162 uint8_t *buf = buffer->getBufferStart();
2163 for (OutputSection *sec : ctx.outputSections) {
2164 uint8_t *secBuf = buf + sec->getFileOff();
2165 // Fill gaps between functions in .text with INT3 instructions
2166 // instead of leaving as NUL bytes (which can be interpreted as
2167 // ADD instructions). Only fill the gaps between chunks. Most
2168 // chunks overwrite it anyway, but uninitialized data chunks
2169 // merged into a code section don't.
2170 if ((sec->header.Characteristics & IMAGE_SCN_CNT_CODE) &&
2171 (ctx.config.machine == AMD64 || ctx.config.machine == I386)) {
2172 uint32_t prevEnd = 0;
2173 for (Chunk *c : sec->chunks) {
2174 uint32_t off = c->getRVA() - sec->getRVA();
2175 memset(s: secBuf + prevEnd, c: 0xCC, n: off - prevEnd);
2176 prevEnd = off + c->getSize();
2177 }
2178 memset(s: secBuf + prevEnd, c: 0xCC, n: sec->getRawSize() - prevEnd);
2179 }
2180
2181 parallelForEach(R&: sec->chunks, Fn: [&](Chunk *c) {
2182 c->writeTo(buf: secBuf + c->getRVA() - sec->getRVA());
2183 });
2184 }
2185}
2186
2187void Writer::writeBuildId() {
2188 llvm::TimeTraceScope timeScope("Write build ID");
2189
2190 // There are two important parts to the build ID.
2191 // 1) If building with debug info, the COFF debug directory contains a
2192 // timestamp as well as a Guid and Age of the PDB.
2193 // 2) In all cases, the PE COFF file header also contains a timestamp.
2194 // For reproducibility, instead of a timestamp we want to use a hash of the
2195 // PE contents.
2196 Configuration *config = &ctx.config;
2197 bool generateSyntheticBuildId = config->buildIDHash == BuildIDHash::Binary;
2198 if (generateSyntheticBuildId) {
2199 assert(buildId && "BuildId is not set!");
2200 // BuildId->BuildId was filled in when the PDB was written.
2201 }
2202
2203 // At this point the only fields in the COFF file which remain unset are the
2204 // "timestamp" in the COFF file header, and the ones in the coff debug
2205 // directory. Now we can hash the file and write that hash to the various
2206 // timestamp fields in the file.
2207 StringRef outputFileData(
2208 reinterpret_cast<const char *>(buffer->getBufferStart()),
2209 buffer->getBufferSize());
2210
2211 uint32_t timestamp = config->timestamp;
2212 uint64_t hash = 0;
2213
2214 if (config->repro || generateSyntheticBuildId)
2215 hash = xxh3_64bits(data: outputFileData);
2216
2217 if (config->repro)
2218 timestamp = static_cast<uint32_t>(hash);
2219
2220 if (generateSyntheticBuildId) {
2221 buildId->buildId->PDB70.CVSignature = OMF::Signature::PDB70;
2222 buildId->buildId->PDB70.Age = 1;
2223 memcpy(dest: buildId->buildId->PDB70.Signature, src: &hash, n: 8);
2224 // xxhash only gives us 8 bytes, so put some fixed data in the other half.
2225 memcpy(dest: &buildId->buildId->PDB70.Signature[8], src: "LLD PDB.", n: 8);
2226 }
2227
2228 if (debugDirectory)
2229 debugDirectory->setTimeDateStamp(timestamp);
2230
2231 uint8_t *buf = buffer->getBufferStart();
2232 buf += dosStubSize + sizeof(PEMagic);
2233 object::coff_file_header *coffHeader =
2234 reinterpret_cast<coff_file_header *>(buf);
2235 coffHeader->TimeDateStamp = timestamp;
2236}
2237
2238// Sort .pdata section contents according to PE/COFF spec 5.5.
2239template <typename T>
2240void Writer::sortExceptionTable(ChunkRange &exceptionTable) {
2241 if (!exceptionTable.first)
2242 return;
2243
2244 // We assume .pdata contains function table entries only.
2245 auto bufAddr = [&](Chunk *c) {
2246 OutputSection *os = ctx.getOutputSection(c);
2247 return buffer->getBufferStart() + os->getFileOff() + c->getRVA() -
2248 os->getRVA();
2249 };
2250 uint8_t *begin = bufAddr(exceptionTable.first);
2251 uint8_t *end = bufAddr(exceptionTable.last) + exceptionTable.last->getSize();
2252 if ((end - begin) % sizeof(T) != 0) {
2253 fatal(msg: "unexpected .pdata size: " + Twine(end - begin) +
2254 " is not a multiple of " + Twine(sizeof(T)));
2255 }
2256
2257 parallelSort(MutableArrayRef<T>(reinterpret_cast<T *>(begin),
2258 reinterpret_cast<T *>(end)),
2259 [](const T &a, const T &b) { return a.begin < b.begin; });
2260}
2261
2262// Sort .pdata section contents according to PE/COFF spec 5.5.
2263void Writer::sortExceptionTables() {
2264 llvm::TimeTraceScope timeScope("Sort exception table");
2265
2266 struct EntryX64 {
2267 ulittle32_t begin, end, unwind;
2268 };
2269 struct EntryArm {
2270 ulittle32_t begin, unwind;
2271 };
2272
2273 switch (ctx.config.machine) {
2274 case AMD64:
2275 sortExceptionTable<EntryX64>(exceptionTable&: pdata);
2276 break;
2277 case ARM64EC:
2278 case ARM64X:
2279 sortExceptionTable<EntryX64>(exceptionTable&: hybridPdata);
2280 [[fallthrough]];
2281 case ARMNT:
2282 case ARM64:
2283 sortExceptionTable<EntryArm>(exceptionTable&: pdata);
2284 break;
2285 default:
2286 if (pdata.first)
2287 lld::errs() << "warning: don't know how to handle .pdata.\n";
2288 break;
2289 }
2290}
2291
2292// The CRT section contains, among other things, the array of function
2293// pointers that initialize every global variable that is not trivially
2294// constructed. The CRT calls them one after the other prior to invoking
2295// main().
2296//
2297// As per C++ spec, 3.6.2/2.3,
2298// "Variables with ordered initialization defined within a single
2299// translation unit shall be initialized in the order of their definitions
2300// in the translation unit"
2301//
2302// It is therefore critical to sort the chunks containing the function
2303// pointers in the order that they are listed in the object file (top to
2304// bottom), otherwise global objects might not be initialized in the
2305// correct order.
2306void Writer::sortCRTSectionChunks(std::vector<Chunk *> &chunks) {
2307 auto sectionChunkOrder = [](const Chunk *a, const Chunk *b) {
2308 auto sa = dyn_cast<SectionChunk>(Val: a);
2309 auto sb = dyn_cast<SectionChunk>(Val: b);
2310 assert(sa && sb && "Non-section chunks in CRT section!");
2311
2312 StringRef sAObj = sa->file->mb.getBufferIdentifier();
2313 StringRef sBObj = sb->file->mb.getBufferIdentifier();
2314
2315 return sAObj == sBObj && sa->getSectionNumber() < sb->getSectionNumber();
2316 };
2317 llvm::stable_sort(Range&: chunks, C: sectionChunkOrder);
2318
2319 if (ctx.config.verbose) {
2320 for (auto &c : chunks) {
2321 auto sc = dyn_cast<SectionChunk>(Val: c);
2322 log(msg: " " + sc->file->mb.getBufferIdentifier().str() +
2323 ", SectionID: " + Twine(sc->getSectionNumber()));
2324 }
2325 }
2326}
2327
2328OutputSection *Writer::findSection(StringRef name) {
2329 for (OutputSection *sec : ctx.outputSections)
2330 if (sec->name == name)
2331 return sec;
2332 return nullptr;
2333}
2334
2335uint32_t Writer::getSizeOfInitializedData() {
2336 uint32_t res = 0;
2337 for (OutputSection *s : ctx.outputSections)
2338 if (s->header.Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
2339 res += s->getRawSize();
2340 return res;
2341}
2342
2343// Add base relocations to .reloc section.
2344void Writer::addBaserels() {
2345 if (!ctx.config.relocatable)
2346 return;
2347 relocSec->chunks.clear();
2348 std::vector<Baserel> v;
2349 for (OutputSection *sec : ctx.outputSections) {
2350 if (sec->header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
2351 continue;
2352 llvm::TimeTraceScope timeScope("Base relocations: ", sec->name);
2353 // Collect all locations for base relocations.
2354 for (Chunk *c : sec->chunks)
2355 c->getBaserels(res: &v);
2356 // Add the addresses to .reloc section.
2357 if (!v.empty())
2358 addBaserelBlocks(v);
2359 v.clear();
2360 }
2361}
2362
2363// Add addresses to .reloc section. Note that addresses are grouped by page.
2364void Writer::addBaserelBlocks(std::vector<Baserel> &v) {
2365 const uint32_t mask = ~uint32_t(pageSize - 1);
2366 uint32_t page = v[0].rva & mask;
2367 size_t i = 0, j = 1;
2368 for (size_t e = v.size(); j < e; ++j) {
2369 uint32_t p = v[j].rva & mask;
2370 if (p == page)
2371 continue;
2372 relocSec->addChunk(c: make<BaserelChunk>(args&: page, args: &v[i], args: &v[0] + j));
2373 i = j;
2374 page = p;
2375 }
2376 if (i == j)
2377 return;
2378 relocSec->addChunk(c: make<BaserelChunk>(args&: page, args: &v[i], args: &v[0] + j));
2379}
2380
2381PartialSection *Writer::createPartialSection(StringRef name,
2382 uint32_t outChars) {
2383 PartialSection *&pSec = partialSections[{.name: name, .characteristics: outChars}];
2384 if (pSec)
2385 return pSec;
2386 pSec = make<PartialSection>(args&: name, args&: outChars);
2387 return pSec;
2388}
2389
2390PartialSection *Writer::findPartialSection(StringRef name, uint32_t outChars) {
2391 auto it = partialSections.find(x: {.name: name, .characteristics: outChars});
2392 if (it != partialSections.end())
2393 return it->second;
2394 return nullptr;
2395}
2396
2397void Writer::fixTlsAlignment() {
2398 Defined *tlsSym =
2399 dyn_cast_or_null<Defined>(Val: ctx.symtab.findUnderscore(name: "_tls_used"));
2400 if (!tlsSym)
2401 return;
2402
2403 OutputSection *sec = ctx.getOutputSection(c: tlsSym->getChunk());
2404 assert(sec && tlsSym->getRVA() >= sec->getRVA() &&
2405 "no output section for _tls_used");
2406
2407 uint8_t *secBuf = buffer->getBufferStart() + sec->getFileOff();
2408 uint64_t tlsOffset = tlsSym->getRVA() - sec->getRVA();
2409 uint64_t directorySize = ctx.config.is64()
2410 ? sizeof(object::coff_tls_directory64)
2411 : sizeof(object::coff_tls_directory32);
2412
2413 if (tlsOffset + directorySize > sec->getRawSize())
2414 fatal(msg: "_tls_used sym is malformed");
2415
2416 if (ctx.config.is64()) {
2417 object::coff_tls_directory64 *tlsDir =
2418 reinterpret_cast<object::coff_tls_directory64 *>(&secBuf[tlsOffset]);
2419 tlsDir->setAlignment(tlsAlignment);
2420 } else {
2421 object::coff_tls_directory32 *tlsDir =
2422 reinterpret_cast<object::coff_tls_directory32 *>(&secBuf[tlsOffset]);
2423 tlsDir->setAlignment(tlsAlignment);
2424 }
2425}
2426
2427void Writer::prepareLoadConfig() {
2428 Symbol *sym = ctx.symtab.findUnderscore(name: "_load_config_used");
2429 auto *b = cast_if_present<DefinedRegular>(Val: sym);
2430 if (!b) {
2431 if (ctx.config.guardCF != GuardCFLevel::Off)
2432 warn(msg: "Control Flow Guard is enabled but '_load_config_used' is missing");
2433 return;
2434 }
2435
2436 OutputSection *sec = ctx.getOutputSection(c: b->getChunk());
2437 uint8_t *buf = buffer->getBufferStart();
2438 uint8_t *secBuf = buf + sec->getFileOff();
2439 uint8_t *symBuf = secBuf + (b->getRVA() - sec->getRVA());
2440 uint32_t expectedAlign = ctx.config.is64() ? 8 : 4;
2441 if (b->getChunk()->getAlignment() < expectedAlign)
2442 warn(msg: "'_load_config_used' is misaligned (expected alignment to be " +
2443 Twine(expectedAlign) + " bytes, got " +
2444 Twine(b->getChunk()->getAlignment()) + " instead)");
2445 else if (!isAligned(Lhs: Align(expectedAlign), SizeInBytes: b->getRVA()))
2446 warn(msg: "'_load_config_used' is misaligned (RVA is 0x" +
2447 Twine::utohexstr(Val: b->getRVA()) + " not aligned to " +
2448 Twine(expectedAlign) + " bytes)");
2449
2450 if (ctx.config.is64())
2451 prepareLoadConfig(loadConfig: reinterpret_cast<coff_load_configuration64 *>(symBuf));
2452 else
2453 prepareLoadConfig(loadConfig: reinterpret_cast<coff_load_configuration32 *>(symBuf));
2454}
2455
2456template <typename T> void Writer::prepareLoadConfig(T *loadConfig) {
2457 if (ctx.config.dependentLoadFlags)
2458 loadConfig->DependentLoadFlags = ctx.config.dependentLoadFlags;
2459
2460 checkLoadConfigGuardData(loadConfig);
2461}
2462
2463template <typename T>
2464void Writer::checkLoadConfigGuardData(const T *loadConfig) {
2465 size_t loadConfigSize = loadConfig->Size;
2466
2467#define RETURN_IF_NOT_CONTAINS(field) \
2468 if (loadConfigSize < offsetof(T, field) + sizeof(T::field)) { \
2469 warn("'_load_config_used' structure too small to include " #field); \
2470 return; \
2471 }
2472
2473#define IF_CONTAINS(field) \
2474 if (loadConfigSize >= offsetof(T, field) + sizeof(T::field))
2475
2476#define CHECK_VA(field, sym) \
2477 if (auto *s = dyn_cast<DefinedSynthetic>(ctx.symtab.findUnderscore(sym))) \
2478 if (loadConfig->field != ctx.config.imageBase + s->getRVA()) \
2479 warn(#field " not set correctly in '_load_config_used'");
2480
2481#define CHECK_ABSOLUTE(field, sym) \
2482 if (auto *s = dyn_cast<DefinedAbsolute>(ctx.symtab.findUnderscore(sym))) \
2483 if (loadConfig->field != s->getVA()) \
2484 warn(#field " not set correctly in '_load_config_used'");
2485
2486 if (ctx.config.guardCF == GuardCFLevel::Off)
2487 return;
2488 RETURN_IF_NOT_CONTAINS(GuardFlags)
2489 CHECK_VA(GuardCFFunctionTable, "__guard_fids_table")
2490 CHECK_ABSOLUTE(GuardCFFunctionCount, "__guard_fids_count")
2491 CHECK_ABSOLUTE(GuardFlags, "__guard_flags")
2492 IF_CONTAINS(GuardAddressTakenIatEntryCount) {
2493 CHECK_VA(GuardAddressTakenIatEntryTable, "__guard_iat_table")
2494 CHECK_ABSOLUTE(GuardAddressTakenIatEntryCount, "__guard_iat_count")
2495 }
2496
2497 if (!(ctx.config.guardCF & GuardCFLevel::LongJmp))
2498 return;
2499 RETURN_IF_NOT_CONTAINS(GuardLongJumpTargetCount)
2500 CHECK_VA(GuardLongJumpTargetTable, "__guard_longjmp_table")
2501 CHECK_ABSOLUTE(GuardLongJumpTargetCount, "__guard_longjmp_count")
2502
2503 if (!(ctx.config.guardCF & GuardCFLevel::EHCont))
2504 return;
2505 RETURN_IF_NOT_CONTAINS(GuardEHContinuationCount)
2506 CHECK_VA(GuardEHContinuationTable, "__guard_eh_cont_table")
2507 CHECK_ABSOLUTE(GuardEHContinuationCount, "__guard_eh_cont_count")
2508
2509#undef RETURN_IF_NOT_CONTAINS
2510#undef IF_CONTAINS
2511#undef CHECK_VA
2512#undef CHECK_ABSOLUTE
2513}
2514