Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lld/COFF/Writer.cpp
34870 views
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
42
using namespace llvm;
43
using namespace llvm::COFF;
44
using namespace llvm::object;
45
using namespace llvm::support;
46
using namespace llvm::support::endian;
47
using namespace lld;
48
using namespace lld::coff;
49
50
/* To re-generate DOSProgram:
51
$ cat > /tmp/DOSProgram.asm
52
org 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
64
str:
65
db 'This program cannot be run in DOS mode.$'
66
align 8, db 0
67
$ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
68
$ xxd -i /tmp/DOSProgram.bin
69
*/
70
static 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
};
77
static_assert(sizeof(dosProgram) % 8 == 0,
78
"DOSProgram size must be multiple of 8");
79
80
static const int dosStubSize = sizeof(dos_header) + sizeof(dosProgram);
81
static_assert(dosStubSize % 8 == 0, "DOSStub size must be multiple of 8");
82
83
static const int numberOfDataDirectory = 16;
84
85
namespace {
86
87
class DebugDirectoryChunk : public NonSectionChunk {
88
public:
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, record.first, c->getSize(), 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, COFF::IMAGE_DEBUG_TYPE_REPRO, 0, 0, 0);
116
}
117
}
118
119
void setTimeDateStamp(uint32_t timeDateStamp) {
120
for (support::ulittle32_t *tds : timeDateStamps)
121
*tds = timeDateStamp;
122
}
123
124
private:
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(&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
145
class CVDebugRecordChunk : public NonSectionChunk {
146
public:
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(p, ctx.config.pdbAltPath.data(), ctx.config.pdbAltPath.size());
162
p[ctx.config.pdbAltPath.size()] = '\0';
163
}
164
165
mutable codeview::DebugInfo *buildId = nullptr;
166
167
private:
168
const COFFLinkerContext &ctx;
169
};
170
171
class ExtendedDllCharacteristicsChunk : public NonSectionChunk {
172
public:
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(buf, 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.
185
class PartialSectionKey {
186
public:
187
StringRef name;
188
unsigned characteristics;
189
190
bool operator<(const PartialSectionKey &other) const {
191
int c = name.compare(other.name);
192
if (c > 0)
193
return false;
194
if (c == 0)
195
return characteristics < other.characteristics;
196
return true;
197
}
198
};
199
200
struct ChunkRange {
201
Chunk *first = nullptr, *last;
202
};
203
204
// The writer writes a SymbolTable result to a file.
205
class Writer {
206
public:
207
Writer(COFFLinkerContext &c)
208
: buffer(errorHandler().outputBuffer), delayIdata(c), edata(c), ctx(c) {}
209
void run();
210
211
private:
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
339
void lld::coff::writeResult(COFFLinkerContext &ctx) {
340
llvm::TimeTraceScope timeScope("Write output(s)");
341
Writer(ctx).run();
342
}
343
344
void OutputSection::addChunk(Chunk *c) {
345
chunks.push_back(c);
346
}
347
348
void OutputSection::insertChunkAtStart(Chunk *c) {
349
chunks.insert(chunks.begin(), c);
350
}
351
352
void OutputSection::setPermissions(uint32_t c) {
353
header.Characteristics &= ~permMask;
354
header.Characteristics |= c;
355
}
356
357
void OutputSection::merge(OutputSection *other) {
358
chunks.insert(chunks.end(), other->chunks.begin(), other->chunks.end());
359
other->chunks.clear();
360
contribSections.insert(contribSections.end(), other->contribSections.begin(),
361
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.
374
void 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(hdr->Name, stringTableOff);
380
} else {
381
assert(!isDebug || name.size() <= COFF::NameSize ||
382
(hdr->Characteristics & IMAGE_SCN_MEM_DISCARDABLE) == 0);
383
strncpy(hdr->Name, name.data(),
384
std::min(name.size(), (size_t)COFF::NameSize));
385
}
386
}
387
388
void OutputSection::addContributingPartialSection(PartialSection *sec) {
389
contribSections.push_back(sec);
390
}
391
392
// Check whether the target address S is in range from a relocation
393
// of type relType at address P.
394
bool Writer::isInRange(uint16_t relType, uint64_t s, uint64_t p, int margin) {
395
if (ctx.config.machine == ARMNT) {
396
int64_t diff = AbsoluteDifference(s, p + 4) + margin;
397
switch (relType) {
398
case IMAGE_REL_ARM_BRANCH20T:
399
return isInt<21>(diff);
400
case IMAGE_REL_ARM_BRANCH24T:
401
case IMAGE_REL_ARM_BLX23T:
402
return isInt<25>(diff);
403
default:
404
return true;
405
}
406
} else if (ctx.config.machine == ARM64) {
407
int64_t diff = AbsoluteDifference(s, p) + margin;
408
switch (relType) {
409
case IMAGE_REL_ARM64_BRANCH26:
410
return isInt<28>(diff);
411
case IMAGE_REL_ARM64_BRANCH19:
412
return isInt<21>(diff);
413
case IMAGE_REL_ARM64_BRANCH14:
414
return isInt<16>(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.
425
std::pair<Defined *, bool>
426
Writer::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(type, lastThunk->getRVA(), p, margin))
430
return {lastThunk, false};
431
Chunk *c;
432
switch (ctx.config.machine) {
433
case ARMNT:
434
c = make<RangeExtensionThunkARM>(ctx, target);
435
break;
436
case ARM64:
437
c = make<RangeExtensionThunkARM64>(ctx, target);
438
break;
439
default:
440
llvm_unreachable("Unexpected architecture");
441
}
442
Defined *d = make<DefinedSynthetic>("range_extension_thunk", 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.
458
bool 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>(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(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(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>(relocTarget);
490
if (!sym)
491
continue;
492
493
uint64_t s = sym->getRVA();
494
495
if (isInRange(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, sym, p, 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(os->chunks.begin() + thunkInsertionSpot, 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({{file, thunk}, ~0U});
515
uint32_t &thunkSymbolIndex = insertion.first->second;
516
if (insertion.second)
517
thunkSymbolIndex = file->addRangeThunkSymbol(thunk);
518
relocReplacements.emplace_back(j, 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>(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.
554
void Writer::createECCodeMap() {
555
if (!isArm64EC(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({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>(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("__hybrid_code_map_count");
592
cast<DefinedAbsolute>(tableCountSym)->setVA(codeMap.size());
593
}
594
595
// Verify that all relocations are in range, with no extra margin requirements.
596
bool Writer::verifyRanges(const std::vector<Chunk *> chunks) {
597
for (Chunk *c : chunks) {
598
SectionChunk *sc = dyn_cast_or_null<SectionChunk>(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(rel.SymbolTableIndex);
605
606
Defined *sym = dyn_cast_or_null<Defined>(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(rel.Type, s, p, 0))
614
return false;
615
}
616
}
617
return true;
618
}
619
620
// Assign addresses and add thunks if necessary.
621
void 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(sec->chunks)) {
645
rangesOk = false;
646
break;
647
}
648
numChunks += sec->chunks.size();
649
}
650
}
651
if (rangesOk) {
652
if (pass > 0)
653
log("Added " + Twine(numChunks - origNumChunks) + " thunks with " +
654
"margin " + Twine(margin) + " in " + Twine(pass) + " passes");
655
return;
656
}
657
658
if (pass >= 10)
659
fatal("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(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
691
void 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.
731
void 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("image size (" + Twine(fileSize) + ") " +
755
"exceeds maximum allowable size (" + Twine(UINT32_MAX) + ")");
756
757
openFile(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);
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("failed to write output '" + buffer->getPath() +
791
"': " + toString(std::move(e)));
792
}
793
794
static StringRef getOutputSectionName(StringRef name) {
795
StringRef s = name.split('$').first;
796
797
// Treat a later period as a separator for MinGW, for sections like
798
// ".ctors.01234".
799
return s.substr(0, s.find('.', 1));
800
}
801
802
// For /order.
803
void Writer::sortBySectionOrder(std::vector<Chunk *> &chunks) {
804
auto getPriority = [&ctx = ctx](const Chunk *c) {
805
if (auto *sec = dyn_cast<SectionChunk>(c))
806
if (sec->sym)
807
return ctx.config.order.lookup(sec->sym->getName());
808
return 0;
809
};
810
811
llvm::stable_sort(chunks, [=](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.
818
void 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(name) ||
823
(!curName.empty() && !curName.starts_with("$")))
824
continue;
825
if (pSec->characteristics == chars)
826
continue;
827
PartialSection *destSec = createPartialSection(pSec->name, chars);
828
destSec->chunks.insert(destSec->chunks.end(), pSec->chunks.begin(),
829
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).
844
bool 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(".idata", 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(".idata"))
857
continue;
858
859
if (!pSec->chunks.empty())
860
hasIdata = true;
861
llvm::stable_sort(pSec->chunks, [&](Chunk *s, Chunk *t) {
862
SectionChunk *sc1 = dyn_cast_or_null<SectionChunk>(s);
863
SectionChunk *sc2 = dyn_cast_or_null<SectionChunk>(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.
884
void 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(n, rdata);
893
pSec->chunks.insert(pSec->chunks.end(), v.begin(), 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.
908
void Writer::locateImportTables() {
909
uint32_t rdata = IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ;
910
911
if (PartialSection *importDirs = findPartialSection(".idata$2", 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(".idata$5", 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.
929
static 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(".text$") || name.starts_with(".data$") ||
945
name.starts_with(".rdata$") || name.starts_with(".pdata$") ||
946
name.starts_with(".xdata$") || name.starts_with(".eh_frame$");
947
}
948
949
void 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(it.second->chunks);
961
}
962
963
// Create output section objects and add them to OutputSections.
964
void 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>(name, outChars);
980
ctx.outputSections.push_back(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>(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, ctx.config.mingw))
1010
name = name.split('$').first;
1011
1012
if (name.starts_with(".tls"))
1013
tlsAlignment = std::max(tlsAlignment, c->getAlignment());
1014
1015
PartialSection *pSec = createPartialSection(name,
1016
c->getOutputCharacteristics());
1017
pSec->chunks.push_back(c);
1018
}
1019
1020
fixPartialSectionChars(".rsrc", data | r);
1021
fixPartialSectionChars(".edata", 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(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("Processing section " + pSec->name + " -> " + name);
1053
1054
sortCRTSectionChunks(pSec->chunks);
1055
}
1056
1057
OutputSection *sec = createSection(name, outChars);
1058
for (Chunk *c : pSec->chunks)
1059
sec->addChunk(c);
1060
1061
sec->addContributingPartialSection(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(".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(ctx.outputSections,
1085
[&](const OutputSection *s, const OutputSection *t) {
1086
return sectionOrder(s) < sectionOrder(t);
1087
});
1088
}
1089
1090
void 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(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>(ctx, debugRecords, config->repro);
1113
debugDirectory->setAlignment(4);
1114
debugInfoSec->addChunk(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>(ctx);
1123
debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_CODEVIEW, buildId);
1124
if (Symbol *buildidSym = ctx.symtab.findUnderscore("__buildid"))
1125
replaceSymbol<DefinedSynthetic>(buildidSym, buildidSym->getName(),
1126
buildId, 4);
1127
}
1128
1129
if (config->cetCompat) {
1130
debugRecords.emplace_back(COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS,
1131
make<ExtendedDllCharacteristicsChunk>(
1132
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(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(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.
1163
void 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(dll) == 0)
1174
ctx.config.dllOrder[dll] = ctx.config.dllOrder.size();
1175
1176
if (file->impSym && !isa<DefinedImportData>(file->impSym))
1177
fatal(toString(ctx, *file->impSym) + " was replaced");
1178
DefinedImportData *impSym = cast_or_null<DefinedImportData>(file->impSym);
1179
if (ctx.config.delayLoads.count(StringRef(file->dllName).lower())) {
1180
if (!file->thunkSym)
1181
fatal("cannot delay-load " + toString(file) +
1182
" due to import of data: " + toString(ctx, *impSym));
1183
delayIdata.add(impSym);
1184
} else {
1185
idata.add(impSym);
1186
}
1187
}
1188
}
1189
1190
void 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>(file->thunkSym))
1203
fatal(toString(ctx, *file->thunkSym) + " was replaced");
1204
DefinedImportThunk *thunk = cast<DefinedImportThunk>(file->thunkSym);
1205
if (file->thunkLive)
1206
textSec->addChunk(thunk->getChunk());
1207
}
1208
1209
if (!delayIdata.empty()) {
1210
Defined *helper = cast<Defined>(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
1225
void 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("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("??_G"))
1243
warn("export of deleting dtor: " + toString(ctx, *e.sym));
1244
}
1245
1246
void 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(ctx.outputSections, isUnused);
1258
}
1259
1260
// The Windows loader doesn't seem to like empty sections,
1261
// so we remove them if any.
1262
void Writer::removeEmptySections() {
1263
llvm::TimeTraceScope timeScope("Remove empty sections");
1264
auto isEmpty = [](OutputSection *s) { return s->getVirtualSize() == 0; };
1265
llvm::erase_if(ctx.outputSections, isEmpty);
1266
}
1267
1268
void 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
1289
size_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(strtab.end(), str.begin(), str.end());
1293
strtab.push_back('\0');
1294
return offsetOfEntry;
1295
}
1296
1297
std::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>(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(name);
1338
} else {
1339
memset(sym.Name.ShortName, 0, COFF::NameSize);
1340
memcpy(sym.Name.ShortName, name.data(), name.size());
1341
}
1342
1343
if (auto *d = dyn_cast<DefinedCOFF>(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
1359
void 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("section name " + sec->name +
1376
" is longer than 8 characters and will use a non-standard string "
1377
"table");
1378
}
1379
sec->setStringTableOff(addEntryToStringTable(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>(b);
1386
if (!d || d->writtenToSymtab)
1387
continue;
1388
d->writtenToSymtab = true;
1389
if (auto *dc = dyn_cast_or_null<DefinedCOFF>(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(d))
1397
outputSymtab.push_back(*sym);
1398
1399
if (auto *dthunk = dyn_cast<DefinedImportThunk>(d)) {
1400
if (!dthunk->wrappedSym->writtenToSymtab) {
1401
dthunk->wrappedSym->writtenToSymtab = true;
1402
if (std::optional<coff_symbol16> sym =
1403
createSymbol(dthunk->wrappedSym))
1404
outputSymtab.push_back(*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(fileOff, ctx.config.fileAlign);
1420
}
1421
1422
void Writer::mergeSections() {
1423
llvm::TimeTraceScope timeScope("Merge sections");
1424
if (!pdataSec->chunks.empty()) {
1425
if (isArm64EC(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(pdataSec->chunks, [=](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(toName).second)
1456
fatal("/merge: cycle found for section '" + p.first + "'");
1457
auto i = ctx.config.merge.find(toName);
1458
if (i == ctx.config.merge.end())
1459
break;
1460
toName = i->second;
1461
}
1462
OutputSection *from = findSection(p.first);
1463
OutputSection *to = findSection(toName);
1464
if (!from)
1465
continue;
1466
if (!to) {
1467
from->name = toName;
1468
continue;
1469
}
1470
to->merge(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.
1477
void Writer::sortECChunks() {
1478
if (!isArm64EC(ctx.config.machine))
1479
return;
1480
1481
for (OutputSection *sec : ctx.outputSections) {
1482
if (sec->isCodeSection())
1483
llvm::stable_sort(sec->chunks, [=](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.
1493
void 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(sizeOfHeaders, config->fileAlign);
1507
fileSize = sizeOfHeaders;
1508
1509
// The first page is kept unmapped.
1510
uint64_t rva = alignTo(sizeOfHeaders, 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(ctx.config.machine) && sec->isCodeSection()) {
1527
std::optional<chpe_range_type> rangeType = c->getArm64ECRangeType();
1528
if (rangeType != prevECRange) {
1529
virtualSize = alignTo(virtualSize, 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(virtualSize, c->getAlignment());
1540
c->setRVA(rva + virtualSize);
1541
virtualSize += c->getSize();
1542
if (c->hasData)
1543
rawSize = alignTo(virtualSize, config->fileAlign);
1544
}
1545
if (virtualSize > UINT32_MAX)
1546
error("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(virtualSize, config->align);
1552
fileSize += alignTo(rawSize, config->fileAlign);
1553
}
1554
sizeOfImage = alignTo(rva, config->align);
1555
1556
// Assign addresses to sections in MergeChunks.
1557
for (MergeChunk *mc : ctx.mergeChunkInstances)
1558
if (mc)
1559
mc->assignSubsectionRVAs();
1560
}
1561
1562
template <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(dosStubSize, 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(buf, dosProgram, sizeof(dosProgram));
1583
buf += sizeof(dosProgram);
1584
1585
// Write PE magic
1586
memcpy(buf, PEMagic, 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>(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("_tls_used")) {
1721
if (Defined *b = dyn_cast<Defined>(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("_load_config_used")) {
1733
if (auto *b = dyn_cast<DefinedRegular>(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("_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("_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, 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(buf, strtab.size() + 4);
1777
if (!strtab.empty())
1778
memcpy(buf + 4, strtab.data(), strtab.size());
1779
}
1780
1781
void Writer::openFile(StringRef path) {
1782
buffer = CHECK(
1783
FileOutputBuffer::create(path, fileSize, FileOutputBuffer::F_executable),
1784
"failed to open " + path);
1785
}
1786
1787
void Writer::createSEHTable() {
1788
SymbolRVASet handlers;
1789
for (ObjFile *file : ctx.objFileInstances) {
1790
if (!file->hasSafeSEH())
1791
error("/safeseh: " + file->getName() + " is not compatible with SEH");
1792
markSymbolsForRVATable(file, file->getSXDataChunks(), 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("_load_config_used");
1799
1800
maybeAddRVATable(std::move(handlers), "__safe_se_handler_table",
1801
"__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.
1807
static void addSymbolToRVASet(SymbolRVASet &rvaSet, Defined *s) {
1808
Chunk *c = s->getChunk();
1809
if (!c)
1810
return;
1811
if (auto *sc = dyn_cast<SectionChunk>(c))
1812
c = sc->repl; // Look through ICF replacement.
1813
uint32_t off = s->getRVA() - (c ? c->getRVA() : 0);
1814
rvaSet.insert({c, 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.
1819
static 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(addressTakenSyms, cast<Defined>(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>(s);
1855
if (d->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION) {
1856
SectionChunk *sc = dyn_cast<SectionChunk>(d->getChunk());
1857
if (sc && sc->live &&
1858
sc->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE)
1859
addSymbolToRVASet(addressTakenSyms, 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.
1868
void 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>(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(reloc.SymbolTableIndex);
1885
maybeAddAddressTakenFunction(usedSymbols, 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.
1893
void 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, file->getGuardFidChunks(), addressTakenSyms);
1909
markSymbolsForRVATable(file, file->getGuardIATChunks(), giatsRVASet);
1910
getSymbolsFromSections(file, file->getGuardIATChunks(), giatsSymbols);
1911
markSymbolsForRVATable(file, file->getGuardLJmpChunks(), longJmpTargets);
1912
} else {
1913
markSymbolsWithRelocations(file, 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, file->getGuardEHContChunks(), ehContTargets);
1919
}
1920
1921
// Mark the image entry as address-taken.
1922
if (config->entry)
1923
maybeAddAddressTakenFunction(addressTakenSyms, config->entry);
1924
1925
// Mark exported symbols in executable sections as address-taken.
1926
for (Export &e : config->exports)
1927
maybeAddAddressTakenFunction(addressTakenSyms, 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>(s)) {
1934
if (di->loadThunkSym)
1935
addSymbolToRVASet(addressTakenSyms, 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(std::move(addressTakenSyms), "__guard_fids_table",
1945
"__guard_fids_count");
1946
1947
// Add the Guard Address Taken IAT Entry Table (.giats).
1948
maybeAddRVATable(std::move(giatsRVASet), "__guard_iat_table",
1949
"__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(std::move(longJmpTargets), "__guard_longjmp_table",
1954
"__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(std::move(ehContTargets), "__guard_eh_cont_table",
1959
"__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("__guard_flags");
1970
cast<DefinedAbsolute>(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.
1976
void 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("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("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(cast<Symbol>(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.
2016
void Writer::markSymbolsForRVATable(ObjFile *file,
2017
ArrayRef<SectionChunk *> symIdxChunks,
2018
SymbolRVASet &tableSymbols) {
2019
std::vector<Symbol *> syms;
2020
getSymbolsFromSections(file, symIdxChunks, syms);
2021
2022
for (Symbol *s : syms)
2023
addSymbolToRVASet(tableSymbols, cast<Defined>(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.
2029
void 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>(std::move(tableSymbols));
2037
else
2038
tableChunk = make<RVATableChunk>(std::move(tableSymbols));
2039
rdataSec->addChunk(tableChunk);
2040
2041
Symbol *t = ctx.symtab.findUnderscore(tableSym);
2042
Symbol *c = ctx.symtab.findUnderscore(countSym);
2043
replaceSymbol<DefinedSynthetic>(t, t->getName(), tableChunk);
2044
cast<DefinedAbsolute>(c)->setVA(tableChunk->getSize() / (hasFlag ? 5 : 4));
2045
}
2046
2047
// Create CHPE metadata chunks.
2048
void Writer::createECChunks() {
2049
auto codeMapChunk = make<ECCodeMapChunk>(codeMap);
2050
rdataSec->addChunk(codeMapChunk);
2051
Symbol *codeMapSym = ctx.symtab.findUnderscore("__hybrid_code_map");
2052
replaceSymbol<DefinedSynthetic>(codeMapSym, codeMapSym->getName(),
2053
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.
2060
void Writer::createRuntimePseudoRelocs() {
2061
std::vector<RuntimePseudoReloc> rels;
2062
2063
for (Chunk *c : ctx.symtab.getChunks()) {
2064
auto *sc = dyn_cast<SectionChunk>(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(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("automatic dllimport of " + rpr.sym->getName() + " in " +
2079
toString(rpr.target->file) + " requires pseudo relocations");
2080
return;
2081
}
2082
2083
if (!rels.empty()) {
2084
log("Writing " + Twine(rels.size()) + " runtime pseudo relocations");
2085
const char *symbolName = "_pei386_runtime_relocator";
2086
Symbol *relocator = ctx.symtab.findUnderscore(symbolName);
2087
if (!relocator)
2088
error("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>(rels);
2094
rdataSec->addChunk(table);
2095
EmptyChunk *endOfList = make<EmptyChunk>();
2096
rdataSec->addChunk(endOfList);
2097
2098
Symbol *headSym = ctx.symtab.findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__");
2099
Symbol *endSym =
2100
ctx.symtab.findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__");
2101
replaceSymbol<DefinedSynthetic>(headSym, headSym->getName(), table);
2102
replaceSymbol<DefinedSynthetic>(endSym, endSym->getName(), 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.
2110
void Writer::insertCtorDtorSymbols() {
2111
AbsolutePointerChunk *ctorListHead = make<AbsolutePointerChunk>(ctx, -1);
2112
AbsolutePointerChunk *ctorListEnd = make<AbsolutePointerChunk>(ctx, 0);
2113
AbsolutePointerChunk *dtorListHead = make<AbsolutePointerChunk>(ctx, -1);
2114
AbsolutePointerChunk *dtorListEnd = make<AbsolutePointerChunk>(ctx, 0);
2115
ctorsSec->insertChunkAtStart(ctorListHead);
2116
ctorsSec->addChunk(ctorListEnd);
2117
dtorsSec->insertChunkAtStart(dtorListHead);
2118
dtorsSec->addChunk(dtorListEnd);
2119
2120
Symbol *ctorListSym = ctx.symtab.findUnderscore("__CTOR_LIST__");
2121
Symbol *dtorListSym = ctx.symtab.findUnderscore("__DTOR_LIST__");
2122
replaceSymbol<DefinedSynthetic>(ctorListSym, ctorListSym->getName(),
2123
ctorListHead);
2124
replaceSymbol<DefinedSynthetic>(dtorListSym, dtorListSym->getName(),
2125
dtorListHead);
2126
}
2127
2128
// Handles /section options to allow users to overwrite
2129
// section attributes.
2130
void 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.
2142
void Writer::setECSymbols() {
2143
if (!isArm64EC(ctx.config.machine))
2144
return;
2145
2146
Symbol *rfeTableSym = ctx.symtab.findUnderscore("__arm64x_extra_rfe_table");
2147
replaceSymbol<DefinedSynthetic>(rfeTableSym, "__arm64x_extra_rfe_table",
2148
pdata.first);
2149
2150
if (pdata.first) {
2151
Symbol *rfeSizeSym =
2152
ctx.symtab.findUnderscore("__arm64x_extra_rfe_table_size");
2153
cast<DefinedAbsolute>(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.
2160
void 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(secBuf + prevEnd, 0xCC, off - prevEnd);
2176
prevEnd = off + c->getSize();
2177
}
2178
memset(secBuf + prevEnd, 0xCC, sec->getRawSize() - prevEnd);
2179
}
2180
2181
parallelForEach(sec->chunks, [&](Chunk *c) {
2182
c->writeTo(secBuf + c->getRVA() - sec->getRVA());
2183
});
2184
}
2185
}
2186
2187
void 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(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(buildId->buildId->PDB70.Signature, &hash, 8);
2224
// xxhash only gives us 8 bytes, so put some fixed data in the other half.
2225
memcpy(&buildId->buildId->PDB70.Signature[8], "LLD PDB.", 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.
2239
template <typename T>
2240
void 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("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.
2263
void 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>(pdata);
2276
break;
2277
case ARM64EC:
2278
case ARM64X:
2279
sortExceptionTable<EntryX64>(hybridPdata);
2280
[[fallthrough]];
2281
case ARMNT:
2282
case ARM64:
2283
sortExceptionTable<EntryArm>(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.
2306
void Writer::sortCRTSectionChunks(std::vector<Chunk *> &chunks) {
2307
auto sectionChunkOrder = [](const Chunk *a, const Chunk *b) {
2308
auto sa = dyn_cast<SectionChunk>(a);
2309
auto sb = dyn_cast<SectionChunk>(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(chunks, sectionChunkOrder);
2318
2319
if (ctx.config.verbose) {
2320
for (auto &c : chunks) {
2321
auto sc = dyn_cast<SectionChunk>(c);
2322
log(" " + sc->file->mb.getBufferIdentifier().str() +
2323
", SectionID: " + Twine(sc->getSectionNumber()));
2324
}
2325
}
2326
}
2327
2328
OutputSection *Writer::findSection(StringRef name) {
2329
for (OutputSection *sec : ctx.outputSections)
2330
if (sec->name == name)
2331
return sec;
2332
return nullptr;
2333
}
2334
2335
uint32_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.
2344
void 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(&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.
2364
void 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(make<BaserelChunk>(page, &v[i], &v[0] + j));
2373
i = j;
2374
page = p;
2375
}
2376
if (i == j)
2377
return;
2378
relocSec->addChunk(make<BaserelChunk>(page, &v[i], &v[0] + j));
2379
}
2380
2381
PartialSection *Writer::createPartialSection(StringRef name,
2382
uint32_t outChars) {
2383
PartialSection *&pSec = partialSections[{name, outChars}];
2384
if (pSec)
2385
return pSec;
2386
pSec = make<PartialSection>(name, outChars);
2387
return pSec;
2388
}
2389
2390
PartialSection *Writer::findPartialSection(StringRef name, uint32_t outChars) {
2391
auto it = partialSections.find({name, outChars});
2392
if (it != partialSections.end())
2393
return it->second;
2394
return nullptr;
2395
}
2396
2397
void Writer::fixTlsAlignment() {
2398
Defined *tlsSym =
2399
dyn_cast_or_null<Defined>(ctx.symtab.findUnderscore("_tls_used"));
2400
if (!tlsSym)
2401
return;
2402
2403
OutputSection *sec = ctx.getOutputSection(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("_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
2427
void Writer::prepareLoadConfig() {
2428
Symbol *sym = ctx.symtab.findUnderscore("_load_config_used");
2429
auto *b = cast_if_present<DefinedRegular>(sym);
2430
if (!b) {
2431
if (ctx.config.guardCF != GuardCFLevel::Off)
2432
warn("Control Flow Guard is enabled but '_load_config_used' is missing");
2433
return;
2434
}
2435
2436
OutputSection *sec = ctx.getOutputSection(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("'_load_config_used' is misaligned (expected alignment to be " +
2443
Twine(expectedAlign) + " bytes, got " +
2444
Twine(b->getChunk()->getAlignment()) + " instead)");
2445
else if (!isAligned(Align(expectedAlign), b->getRVA()))
2446
warn("'_load_config_used' is misaligned (RVA is 0x" +
2447
Twine::utohexstr(b->getRVA()) + " not aligned to " +
2448
Twine(expectedAlign) + " bytes)");
2449
2450
if (ctx.config.is64())
2451
prepareLoadConfig(reinterpret_cast<coff_load_configuration64 *>(symBuf));
2452
else
2453
prepareLoadConfig(reinterpret_cast<coff_load_configuration32 *>(symBuf));
2454
}
2455
2456
template <typename T> void Writer::prepareLoadConfig(T *loadConfig) {
2457
if (ctx.config.dependentLoadFlags)
2458
loadConfig->DependentLoadFlags = ctx.config.dependentLoadFlags;
2459
2460
checkLoadConfigGuardData(loadConfig);
2461
}
2462
2463
template <typename T>
2464
void 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
2515