1 //===- Writer.cpp ---------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
10 #include "COFFLinkerContext.h"
11 #include "CallGraphSort.h"
14 #include "InputFiles.h"
15 #include "LLDMapFile.h"
18 #include "SymbolTable.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"
43 using namespace llvm::COFF
;
44 using namespace llvm::object
;
45 using namespace llvm::support
;
46 using namespace llvm::support::endian
;
48 using namespace lld::coff
;
50 /* To re-generate DOSProgram:
51 $ cat > /tmp/DOSProgram.asm
56 ; Point ds:dx at the $-terminated string.
58 ; Int 21/AH=09h: Write string to standard output.
61 ; Int 21/AH=4Ch: Exit with return code (in AL).
65 db 'This program cannot be run in DOS mode.$'
67 $ nasm -fbin /tmp/DOSProgram.asm -o /tmp/DOSProgram.bin
68 $ xxd -i /tmp/DOSProgram.bin
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
77 static_assert(sizeof(dosProgram
) % 8 == 0,
78 "DOSProgram size must be multiple of 8");
79 static_assert((sizeof(dos_header
) + sizeof(dosProgram
)) % 8 == 0,
80 "DOSStub size must be multiple of 8");
82 static const int numberOfDataDirectory
= 16;
86 class DebugDirectoryChunk
: public NonSectionChunk
{
88 DebugDirectoryChunk(const COFFLinkerContext
&c
,
89 const std::vector
<std::pair
<COFF::DebugType
, Chunk
*>> &r
,
91 : records(r
), writeRepro(writeRepro
), ctx(c
) {}
93 size_t getSize() const override
{
94 return (records
.size() + int(writeRepro
)) * sizeof(debug_directory
);
97 void writeTo(uint8_t *b
) const override
{
98 auto *d
= reinterpret_cast<debug_directory
*>(b
);
100 for (const std::pair
<COFF::DebugType
, Chunk
*>& record
: records
) {
101 Chunk
*c
= record
.second
;
102 const OutputSection
*os
= ctx
.getOutputSection(c
);
103 uint64_t offs
= os
->getFileOff() + (c
->getRVA() - os
->getRVA());
104 fillEntry(d
, record
.first
, c
->getSize(), c
->getRVA(), offs
);
109 // FIXME: The COFF spec allows either a 0-sized entry to just say
110 // "the timestamp field is really a hash", or a 4-byte size field
111 // followed by that many bytes containing a longer hash (with the
112 // lowest 4 bytes usually being the timestamp in little-endian order).
113 // Consider storing the full 8 bytes computed by xxh3_64bits here.
114 fillEntry(d
, COFF::IMAGE_DEBUG_TYPE_REPRO
, 0, 0, 0);
118 void setTimeDateStamp(uint32_t timeDateStamp
) {
119 for (support::ulittle32_t
*tds
: timeDateStamps
)
120 *tds
= timeDateStamp
;
124 void fillEntry(debug_directory
*d
, COFF::DebugType debugType
, size_t size
,
125 uint64_t rva
, uint64_t offs
) const {
126 d
->Characteristics
= 0;
127 d
->TimeDateStamp
= 0;
131 d
->SizeOfData
= size
;
132 d
->AddressOfRawData
= rva
;
133 d
->PointerToRawData
= offs
;
135 timeDateStamps
.push_back(&d
->TimeDateStamp
);
138 mutable std::vector
<support::ulittle32_t
*> timeDateStamps
;
139 const std::vector
<std::pair
<COFF::DebugType
, Chunk
*>> &records
;
141 const COFFLinkerContext
&ctx
;
144 class CVDebugRecordChunk
: public NonSectionChunk
{
146 CVDebugRecordChunk(const COFFLinkerContext
&c
) : ctx(c
) {}
148 size_t getSize() const override
{
149 return sizeof(codeview::DebugInfo
) + ctx
.config
.pdbAltPath
.size() + 1;
152 void writeTo(uint8_t *b
) const override
{
153 // Save off the DebugInfo entry to backfill the file signature (build id)
154 // in Writer::writeBuildId
155 buildId
= reinterpret_cast<codeview::DebugInfo
*>(b
);
157 // variable sized field (PDB Path)
158 char *p
= reinterpret_cast<char *>(b
+ sizeof(*buildId
));
159 if (!ctx
.config
.pdbAltPath
.empty())
160 memcpy(p
, ctx
.config
.pdbAltPath
.data(), ctx
.config
.pdbAltPath
.size());
161 p
[ctx
.config
.pdbAltPath
.size()] = '\0';
164 mutable codeview::DebugInfo
*buildId
= nullptr;
167 const COFFLinkerContext
&ctx
;
170 class ExtendedDllCharacteristicsChunk
: public NonSectionChunk
{
172 ExtendedDllCharacteristicsChunk(uint32_t c
) : characteristics(c
) {}
174 size_t getSize() const override
{ return 4; }
176 void writeTo(uint8_t *buf
) const override
{ write32le(buf
, characteristics
); }
178 uint32_t characteristics
= 0;
181 // PartialSection represents a group of chunks that contribute to an
182 // OutputSection. Collating a collection of PartialSections of same name and
183 // characteristics constitutes the OutputSection.
184 class PartialSectionKey
{
187 unsigned characteristics
;
189 bool operator<(const PartialSectionKey
&other
) const {
190 int c
= name
.compare(other
.name
);
194 return characteristics
< other
.characteristics
;
200 Chunk
*first
= nullptr, *last
;
203 // The writer writes a SymbolTable result to a file.
206 Writer(COFFLinkerContext
&c
)
207 : buffer(c
.e
.outputBuffer
), delayIdata(c
), ctx(c
) {}
211 void calculateStubDependentSizes();
212 void createSections();
213 void createMiscChunks();
214 void createImportTables();
215 void appendImportThunks();
216 void locateImportTables();
217 void createExportTable();
218 void mergeSections();
220 void appendECImportTables();
221 void removeUnusedSections();
222 void assignAddresses();
223 bool isInRange(uint16_t relType
, uint64_t s
, uint64_t p
, int margin
,
224 MachineTypes machine
);
225 std::pair
<Defined
*, bool> getThunk(DenseMap
<uint64_t, Defined
*> &lastThunks
,
226 Defined
*target
, uint64_t p
,
227 uint16_t type
, int margin
,
228 MachineTypes machine
);
229 bool createThunks(OutputSection
*os
, int margin
);
230 bool verifyRanges(const std::vector
<Chunk
*> chunks
);
231 void createECCodeMap();
232 void finalizeAddresses();
233 void removeEmptySections();
234 void assignOutputSectionIndices();
235 void createSymbolAndStringTable();
236 void openFile(StringRef outputPath
);
237 template <typename PEHeaderTy
> void writeHeader();
238 void createSEHTable();
239 void createRuntimePseudoRelocs();
240 void createECChunks();
241 void insertCtorDtorSymbols();
242 void markSymbolsWithRelocations(ObjFile
*file
, SymbolRVASet
&usedSymbols
);
243 void createGuardCFTables();
244 void markSymbolsForRVATable(ObjFile
*file
,
245 ArrayRef
<SectionChunk
*> symIdxChunks
,
246 SymbolRVASet
&tableSymbols
);
247 void getSymbolsFromSections(ObjFile
*file
,
248 ArrayRef
<SectionChunk
*> symIdxChunks
,
249 std::vector
<Symbol
*> &symbols
);
250 void maybeAddRVATable(SymbolRVASet tableSymbols
, StringRef tableSym
,
251 StringRef countSym
, bool hasFlag
=false);
252 void setSectionPermissions();
254 void writeSections();
256 void writePEChecksum();
258 template <typename T
> void sortExceptionTable(ChunkRange
&exceptionTable
);
259 void sortExceptionTables();
260 void sortCRTSectionChunks(std::vector
<Chunk
*> &chunks
);
261 void addSyntheticIdata();
262 void sortBySectionOrder(std::vector
<Chunk
*> &chunks
);
263 void fixPartialSectionChars(StringRef name
, uint32_t chars
);
264 bool fixGnuImportChunks();
265 void fixTlsAlignment();
266 PartialSection
*createPartialSection(StringRef name
, uint32_t outChars
);
267 PartialSection
*findPartialSection(StringRef name
, uint32_t outChars
);
269 std::optional
<coff_symbol16
> createSymbol(Defined
*d
);
270 size_t addEntryToStringTable(StringRef str
);
272 OutputSection
*findSection(StringRef name
);
274 void addBaserelBlocks(std::vector
<Baserel
> &v
);
275 void createDynamicRelocs();
277 uint32_t getSizeOfInitializedData();
279 void prepareLoadConfig();
280 template <typename T
>
281 void prepareLoadConfig(SymbolTable
&symtab
, T
*loadConfig
);
283 std::unique_ptr
<FileOutputBuffer
> &buffer
;
284 std::map
<PartialSectionKey
, PartialSection
*> partialSections
;
285 std::vector
<char> strtab
;
286 std::vector
<llvm::object::coff_symbol16
> outputSymtab
;
287 std::vector
<ECCodeMapEntry
> codeMap
;
289 Chunk
*importTableStart
= nullptr;
290 uint64_t importTableSize
= 0;
291 Chunk
*iatStart
= nullptr;
292 uint64_t iatSize
= 0;
293 DelayLoadContents delayIdata
;
294 bool setNoSEHCharacteristic
= false;
295 uint32_t tlsAlignment
= 0;
297 DebugDirectoryChunk
*debugDirectory
= nullptr;
298 std::vector
<std::pair
<COFF::DebugType
, Chunk
*>> debugRecords
;
299 CVDebugRecordChunk
*buildId
= nullptr;
300 ArrayRef
<uint8_t> sectionTable
;
302 // List of Arm64EC export thunks.
303 std::vector
<std::pair
<Chunk
*, Defined
*>> exportThunks
;
306 uint32_t pointerToSymbolTable
= 0;
307 uint64_t sizeOfImage
;
308 uint64_t sizeOfHeaders
;
310 uint32_t dosStubSize
;
311 uint32_t coffHeaderOffset
;
312 uint32_t peHeaderOffset
;
313 uint32_t dataDirOffset64
;
315 OutputSection
*textSec
;
316 OutputSection
*hexpthkSec
;
317 OutputSection
*rdataSec
;
318 OutputSection
*buildidSec
;
319 OutputSection
*dataSec
;
320 OutputSection
*pdataSec
;
321 OutputSection
*idataSec
;
322 OutputSection
*edataSec
;
323 OutputSection
*didatSec
;
324 OutputSection
*a64xrmSec
;
325 OutputSection
*rsrcSec
;
326 OutputSection
*relocSec
;
327 OutputSection
*ctorsSec
;
328 OutputSection
*dtorsSec
;
329 // Either .rdata section or .buildid section.
330 OutputSection
*debugInfoSec
;
332 // The range of .pdata sections in the output file.
334 // We need to keep track of the location of .pdata in whichever section it
335 // gets merged into so that we can sort its contents and emit a correct data
336 // directory entry for the exception table. This is also the case for some
337 // other sections (such as .edata) but because the contents of those sections
338 // are entirely linker-generated we can keep track of their locations using
339 // the chunks that the linker creates. All .pdata chunks come from input
340 // files, so we need to keep track of them separately.
343 // x86_64 .pdata sections on ARM64EC/ARM64X targets.
344 ChunkRange hybridPdata
;
346 COFFLinkerContext
&ctx
;
348 } // anonymous namespace
350 void lld::coff::writeResult(COFFLinkerContext
&ctx
) {
351 llvm::TimeTraceScope
timeScope("Write output(s)");
355 void OutputSection::addChunk(Chunk
*c
) {
359 void OutputSection::insertChunkAtStart(Chunk
*c
) {
360 chunks
.insert(chunks
.begin(), c
);
363 void OutputSection::setPermissions(uint32_t c
) {
364 header
.Characteristics
&= ~permMask
;
365 header
.Characteristics
|= c
;
368 void OutputSection::merge(OutputSection
*other
) {
369 chunks
.insert(chunks
.end(), other
->chunks
.begin(), other
->chunks
.end());
370 other
->chunks
.clear();
371 contribSections
.insert(contribSections
.end(), other
->contribSections
.begin(),
372 other
->contribSections
.end());
373 other
->contribSections
.clear();
375 // MS link.exe compatibility: when merging a code section into a data section,
376 // mark the target section as a code section.
377 if (other
->header
.Characteristics
& IMAGE_SCN_CNT_CODE
) {
378 header
.Characteristics
|= IMAGE_SCN_CNT_CODE
;
379 header
.Characteristics
&=
380 ~(IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_CNT_UNINITIALIZED_DATA
);
384 // Write the section header to a given buffer.
385 void OutputSection::writeHeaderTo(uint8_t *buf
, bool isDebug
) {
386 auto *hdr
= reinterpret_cast<coff_section
*>(buf
);
388 if (stringTableOff
) {
389 // If name is too long, write offset into the string table as a name.
390 encodeSectionName(hdr
->Name
, stringTableOff
);
392 assert(!isDebug
|| name
.size() <= COFF::NameSize
||
393 (hdr
->Characteristics
& IMAGE_SCN_MEM_DISCARDABLE
) == 0);
394 strncpy(hdr
->Name
, name
.data(),
395 std::min(name
.size(), (size_t)COFF::NameSize
));
399 void OutputSection::addContributingPartialSection(PartialSection
*sec
) {
400 contribSections
.push_back(sec
);
403 // Check whether the target address S is in range from a relocation
404 // of type relType at address P.
405 bool Writer::isInRange(uint16_t relType
, uint64_t s
, uint64_t p
, int margin
,
406 MachineTypes machine
) {
407 if (machine
== ARMNT
) {
408 int64_t diff
= AbsoluteDifference(s
, p
+ 4) + margin
;
410 case IMAGE_REL_ARM_BRANCH20T
:
411 return isInt
<21>(diff
);
412 case IMAGE_REL_ARM_BRANCH24T
:
413 case IMAGE_REL_ARM_BLX23T
:
414 return isInt
<25>(diff
);
418 } else if (isAnyArm64(machine
)) {
419 int64_t diff
= AbsoluteDifference(s
, p
) + margin
;
421 case IMAGE_REL_ARM64_BRANCH26
:
422 return isInt
<28>(diff
);
423 case IMAGE_REL_ARM64_BRANCH19
:
424 return isInt
<21>(diff
);
425 case IMAGE_REL_ARM64_BRANCH14
:
426 return isInt
<16>(diff
);
435 // Return the last thunk for the given target if it is in range,
436 // or create a new one.
437 std::pair
<Defined
*, bool>
438 Writer::getThunk(DenseMap
<uint64_t, Defined
*> &lastThunks
, Defined
*target
,
439 uint64_t p
, uint16_t type
, int margin
, MachineTypes machine
) {
440 Defined
*&lastThunk
= lastThunks
[target
->getRVA()];
441 if (lastThunk
&& isInRange(type
, lastThunk
->getRVA(), p
, margin
, machine
))
442 return {lastThunk
, false};
444 switch (getMachineArchType(machine
)) {
446 c
= make
<RangeExtensionThunkARM
>(ctx
, target
);
448 case Triple::aarch64
:
449 c
= make
<RangeExtensionThunkARM64
>(machine
, target
);
452 llvm_unreachable("Unexpected architecture");
454 Defined
*d
= make
<DefinedSynthetic
>("range_extension_thunk", c
);
459 // This checks all relocations, and for any relocation which isn't in range
460 // it adds a thunk after the section chunk that contains the relocation.
461 // If the latest thunk for the specific target is in range, that is used
462 // instead of creating a new thunk. All range checks are done with the
463 // specified margin, to make sure that relocations that originally are in
464 // range, but only barely, also get thunks - in case other added thunks makes
465 // the target go out of range.
467 // After adding thunks, we verify that all relocations are in range (with
468 // no extra margin requirements). If this failed, we restart (throwing away
469 // the previously created thunks) and retry with a wider margin.
470 bool Writer::createThunks(OutputSection
*os
, int margin
) {
471 bool addressesChanged
= false;
472 DenseMap
<uint64_t, Defined
*> lastThunks
;
473 DenseMap
<std::pair
<ObjFile
*, Defined
*>, uint32_t> thunkSymtabIndices
;
474 size_t thunksSize
= 0;
475 // Recheck Chunks.size() each iteration, since we can insert more
477 for (size_t i
= 0; i
!= os
->chunks
.size(); ++i
) {
478 SectionChunk
*sc
= dyn_cast
<SectionChunk
>(os
->chunks
[i
]);
480 auto chunk
= cast
<NonSectionChunk
>(os
->chunks
[i
]);
481 if (uint32_t size
= chunk
->extendRanges()) {
483 addressesChanged
= true;
487 MachineTypes machine
= sc
->getMachine();
488 size_t thunkInsertionSpot
= i
+ 1;
490 // Try to get a good enough estimate of where new thunks will be placed.
491 // Offset this by the size of the new thunks added so far, to make the
492 // estimate slightly better.
493 size_t thunkInsertionRVA
= sc
->getRVA() + sc
->getSize() + thunksSize
;
494 ObjFile
*file
= sc
->file
;
495 std::vector
<std::pair
<uint32_t, uint32_t>> relocReplacements
;
496 ArrayRef
<coff_relocation
> originalRelocs
=
497 file
->getCOFFObj()->getRelocations(sc
->header
);
498 for (size_t j
= 0, e
= originalRelocs
.size(); j
< e
; ++j
) {
499 const coff_relocation
&rel
= originalRelocs
[j
];
500 Symbol
*relocTarget
= file
->getSymbol(rel
.SymbolTableIndex
);
502 // The estimate of the source address P should be pretty accurate,
503 // but we don't know whether the target Symbol address should be
504 // offset by thunksSize or not (or by some of thunksSize but not all of
505 // it), giving us some uncertainty once we have added one thunk.
506 uint64_t p
= sc
->getRVA() + rel
.VirtualAddress
+ thunksSize
;
508 Defined
*sym
= dyn_cast_or_null
<Defined
>(relocTarget
);
512 uint64_t s
= sym
->getRVA();
514 if (isInRange(rel
.Type
, s
, p
, margin
, machine
))
517 // If the target isn't in range, hook it up to an existing or new thunk.
518 auto [thunk
, wasNew
] =
519 getThunk(lastThunks
, sym
, p
, rel
.Type
, margin
, machine
);
521 Chunk
*thunkChunk
= thunk
->getChunk();
523 thunkInsertionRVA
); // Estimate of where it will be located.
524 os
->chunks
.insert(os
->chunks
.begin() + thunkInsertionSpot
, thunkChunk
);
525 thunkInsertionSpot
++;
526 thunksSize
+= thunkChunk
->getSize();
527 thunkInsertionRVA
+= thunkChunk
->getSize();
528 addressesChanged
= true;
531 // To redirect the relocation, add a symbol to the parent object file's
532 // symbol table, and replace the relocation symbol table index with the
534 auto insertion
= thunkSymtabIndices
.insert({{file
, thunk
}, ~0U});
535 uint32_t &thunkSymbolIndex
= insertion
.first
->second
;
536 if (insertion
.second
)
537 thunkSymbolIndex
= file
->addRangeThunkSymbol(thunk
);
538 relocReplacements
.emplace_back(j
, thunkSymbolIndex
);
541 // Get a writable copy of this section's relocations so they can be
542 // modified. If the relocations point into the object file, allocate new
543 // memory. Otherwise, this must be previously allocated memory that can be
544 // modified in place.
545 ArrayRef
<coff_relocation
> curRelocs
= sc
->getRelocs();
546 MutableArrayRef
<coff_relocation
> newRelocs
;
547 if (originalRelocs
.data() == curRelocs
.data()) {
548 newRelocs
= MutableArrayRef(
549 bAlloc().Allocate
<coff_relocation
>(originalRelocs
.size()),
550 originalRelocs
.size());
552 newRelocs
= MutableArrayRef(
553 const_cast<coff_relocation
*>(curRelocs
.data()), curRelocs
.size());
556 // Copy each relocation, but replace the symbol table indices which need
558 auto nextReplacement
= relocReplacements
.begin();
559 auto endReplacement
= relocReplacements
.end();
560 for (size_t i
= 0, e
= originalRelocs
.size(); i
!= e
; ++i
) {
561 newRelocs
[i
] = originalRelocs
[i
];
562 if (nextReplacement
!= endReplacement
&& nextReplacement
->first
== i
) {
563 newRelocs
[i
].SymbolTableIndex
= nextReplacement
->second
;
568 sc
->setRelocs(newRelocs
);
570 return addressesChanged
;
573 // Create a code map for CHPE metadata.
574 void Writer::createECCodeMap() {
578 // Clear the map in case we were're recomputing the map after adding
579 // a range extension thunk.
582 std::optional
<chpe_range_type
> lastType
;
585 auto closeRange
= [&]() {
587 codeMap
.push_back({first
, last
, *lastType
});
592 for (OutputSection
*sec
: ctx
.outputSections
) {
593 for (Chunk
*c
: sec
->chunks
) {
594 // Skip empty section chunks. MS link.exe does not seem to do that and
595 // generates empty code ranges in some cases.
596 if (isa
<SectionChunk
>(c
) && !c
->getSize())
599 std::optional
<chpe_range_type
> chunkType
= c
->getArm64ECRangeType();
600 if (chunkType
!= lastType
) {
603 lastType
= chunkType
;
611 Symbol
*tableCountSym
=
612 ctx
.symtabEC
->findUnderscore("__hybrid_code_map_count");
613 cast
<DefinedAbsolute
>(tableCountSym
)->setVA(codeMap
.size());
616 // Verify that all relocations are in range, with no extra margin requirements.
617 bool Writer::verifyRanges(const std::vector
<Chunk
*> chunks
) {
618 for (Chunk
*c
: chunks
) {
619 SectionChunk
*sc
= dyn_cast
<SectionChunk
>(c
);
621 if (!cast
<NonSectionChunk
>(c
)->verifyRanges())
625 MachineTypes machine
= sc
->getMachine();
627 ArrayRef
<coff_relocation
> relocs
= sc
->getRelocs();
628 for (const coff_relocation
&rel
: relocs
) {
629 Symbol
*relocTarget
= sc
->file
->getSymbol(rel
.SymbolTableIndex
);
631 Defined
*sym
= dyn_cast_or_null
<Defined
>(relocTarget
);
635 uint64_t p
= sc
->getRVA() + rel
.VirtualAddress
;
636 uint64_t s
= sym
->getRVA();
638 if (!isInRange(rel
.Type
, s
, p
, 0, machine
))
645 // Assign addresses and add thunks if necessary.
646 void Writer::finalizeAddresses() {
648 if (ctx
.config
.machine
!= ARMNT
&& !isAnyArm64(ctx
.config
.machine
))
651 size_t origNumChunks
= 0;
652 for (OutputSection
*sec
: ctx
.outputSections
) {
653 sec
->origChunks
= sec
->chunks
;
654 origNumChunks
+= sec
->chunks
.size();
658 int margin
= 1024 * 100;
660 llvm::TimeTraceScope
timeScope2("Add thunks pass");
662 // First check whether we need thunks at all, or if the previous pass of
663 // adding them turned out ok.
664 bool rangesOk
= true;
665 size_t numChunks
= 0;
667 llvm::TimeTraceScope
timeScope3("Verify ranges");
668 for (OutputSection
*sec
: ctx
.outputSections
) {
669 if (!verifyRanges(sec
->chunks
)) {
673 numChunks
+= sec
->chunks
.size();
678 Log(ctx
) << "Added " << (numChunks
- origNumChunks
) << " thunks with "
679 << "margin " << margin
<< " in " << pass
<< " passes";
684 Fatal(ctx
) << "adding thunks hasn't converged after " << pass
688 // If the previous pass didn't work out, reset everything back to the
689 // original conditions before retrying with a wider margin. This should
690 // ideally never happen under real circumstances.
691 for (OutputSection
*sec
: ctx
.outputSections
)
692 sec
->chunks
= sec
->origChunks
;
696 // Try adding thunks everywhere where it is needed, with a margin
697 // to avoid things going out of range due to the added thunks.
698 bool addressesChanged
= false;
700 llvm::TimeTraceScope
timeScope3("Create thunks");
701 for (OutputSection
*sec
: ctx
.outputSections
)
702 addressesChanged
|= createThunks(sec
, margin
);
704 // If the verification above thought we needed thunks, we should have
706 assert(addressesChanged
);
707 (void)addressesChanged
;
709 // Recalculate the layout for the whole image (and verify the ranges at
710 // the start of the next round).
717 void Writer::writePEChecksum() {
718 if (!ctx
.config
.writeCheckSum
) {
722 llvm::TimeTraceScope
timeScope("PE checksum");
724 // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#checksum
725 uint32_t *buf
= (uint32_t *)buffer
->getBufferStart();
726 uint32_t size
= (uint32_t)(buffer
->getBufferSize());
728 pe32_header
*peHeader
= (pe32_header
*)((uint8_t *)buf
+ coffHeaderOffset
+
729 sizeof(coff_file_header
));
732 uint32_t count
= size
;
733 ulittle16_t
*addr
= (ulittle16_t
*)buf
;
735 // The PE checksum algorithm, implemented as suggested in RFC1071
741 // Add left-over byte, if any
743 sum
+= *(unsigned char *)addr
;
745 // Fold 32-bit sum to 16 bits
747 sum
= (sum
& 0xffff) + (sum
>> 16);
751 peHeader
->CheckSum
= sum
;
754 // The main function of the writer.
757 llvm::TimeTraceScope
timeScope("Write PE");
758 ScopedTimer
t1(ctx
.codeLayoutTimer
);
760 calculateStubDependentSizes();
761 if (ctx
.config
.machine
== ARM64X
)
762 ctx
.dynamicRelocs
= make
<DynamicRelocsChunk
>();
763 createImportTables();
765 appendImportThunks();
766 // Import thunks must be added before the Control Flow Guard tables are
772 appendECImportTables();
773 createDynamicRelocs();
774 removeUnusedSections();
776 removeEmptySections();
777 assignOutputSectionIndices();
778 setSectionPermissions();
780 createSymbolAndStringTable();
782 if (fileSize
> UINT32_MAX
)
783 Fatal(ctx
) << "image size (" << fileSize
<< ") "
784 << "exceeds maximum allowable size (" << UINT32_MAX
<< ")";
786 openFile(ctx
.config
.outputFile
);
787 if (ctx
.config
.is64()) {
788 writeHeader
<pe32plus_header
>();
790 writeHeader
<pe32_header
>();
794 sortExceptionTables();
796 // Fix up the alignment in the TLS Directory's characteristic field,
797 // if a specific alignment value is needed
802 if (!ctx
.config
.pdbPath
.empty() && ctx
.config
.debug
) {
804 createPDB(ctx
, sectionTable
, buildId
->buildId
);
808 writeLLDMapFile(ctx
);
816 llvm::TimeTraceScope
timeScope("Commit PE to disk");
817 ScopedTimer
t2(ctx
.outputCommitTimer
);
818 if (auto e
= buffer
->commit())
819 Fatal(ctx
) << "failed to write output '" << buffer
->getPath()
820 << "': " << toString(std::move(e
));
823 static StringRef
getOutputSectionName(StringRef name
) {
824 StringRef s
= name
.split('$').first
;
826 // Treat a later period as a separator for MinGW, for sections like
828 return s
.substr(0, s
.find('.', 1));
832 void Writer::sortBySectionOrder(std::vector
<Chunk
*> &chunks
) {
833 auto getPriority
= [&ctx
= ctx
](const Chunk
*c
) {
834 if (auto *sec
= dyn_cast
<SectionChunk
>(c
))
836 return ctx
.config
.order
.lookup(sec
->sym
->getName());
840 llvm::stable_sort(chunks
, [=](const Chunk
*a
, const Chunk
*b
) {
841 return getPriority(a
) < getPriority(b
);
845 // Change the characteristics of existing PartialSections that belong to the
846 // section Name to Chars.
847 void Writer::fixPartialSectionChars(StringRef name
, uint32_t chars
) {
848 for (auto it
: partialSections
) {
849 PartialSection
*pSec
= it
.second
;
850 StringRef curName
= pSec
->name
;
851 if (!curName
.consume_front(name
) ||
852 (!curName
.empty() && !curName
.starts_with("$")))
854 if (pSec
->characteristics
== chars
)
856 PartialSection
*destSec
= createPartialSection(pSec
->name
, chars
);
857 destSec
->chunks
.insert(destSec
->chunks
.end(), pSec
->chunks
.begin(),
859 pSec
->chunks
.clear();
863 // Sort concrete section chunks from GNU import libraries.
865 // GNU binutils doesn't use short import files, but instead produces import
866 // libraries that consist of object files, with section chunks for the .idata$*
867 // sections. These are linked just as regular static libraries. Each import
868 // library consists of one header object, one object file for every imported
869 // symbol, and one trailer object. In order for the .idata tables/lists to
870 // be formed correctly, the section chunks within each .idata$* section need
871 // to be grouped by library, and sorted alphabetically within each library
872 // (which makes sure the header comes first and the trailer last).
873 bool Writer::fixGnuImportChunks() {
874 uint32_t rdata
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
876 // Make sure all .idata$* section chunks are mapped as RDATA in order to
877 // be sorted into the same sections as our own synthesized .idata chunks.
878 fixPartialSectionChars(".idata", rdata
);
880 bool hasIdata
= false;
881 // Sort all .idata$* chunks, grouping chunks from the same library,
882 // with alphabetical ordering of the object files within a library.
883 for (auto it
: partialSections
) {
884 PartialSection
*pSec
= it
.second
;
885 if (!pSec
->name
.starts_with(".idata"))
888 if (!pSec
->chunks
.empty())
890 llvm::stable_sort(pSec
->chunks
, [&](Chunk
*s
, Chunk
*t
) {
891 SectionChunk
*sc1
= dyn_cast
<SectionChunk
>(s
);
892 SectionChunk
*sc2
= dyn_cast
<SectionChunk
>(t
);
894 // if SC1, order them ascending. If SC2 or both null,
895 // S is not less than T.
896 return sc1
!= nullptr;
898 // Make a string with "libraryname/objectfile" for sorting, achieving
899 // both grouping by library and sorting of objects within a library,
902 (sc1
->file
->parentName
+ "/" + sc1
->file
->getName()).str();
904 (sc2
->file
->parentName
+ "/" + sc2
->file
->getName()).str();
911 // Add generated idata chunks, for imported symbols and DLLs, and a
912 // terminator in .idata$2.
913 void Writer::addSyntheticIdata() {
914 uint32_t rdata
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
917 // Add the .idata content in the right section groups, to allow
918 // chunks from other linked in object files to be grouped together.
919 // See Microsoft PE/COFF spec 5.4 for details.
920 auto add
= [&](StringRef n
, std::vector
<Chunk
*> &v
) {
921 PartialSection
*pSec
= createPartialSection(n
, rdata
);
922 pSec
->chunks
.insert(pSec
->chunks
.end(), v
.begin(), v
.end());
925 // The loader assumes a specific order of data.
926 // Add each type in the correct order.
927 add(".idata$2", idata
.dirs
);
928 add(".idata$4", idata
.lookups
);
929 add(".idata$5", idata
.addresses
);
930 if (!idata
.hints
.empty())
931 add(".idata$6", idata
.hints
);
932 add(".idata$7", idata
.dllNames
);
933 if (!idata
.auxIat
.empty())
934 add(".idata$9", idata
.auxIat
);
935 if (!idata
.auxIatCopy
.empty())
936 add(".idata$a", idata
.auxIatCopy
);
939 void Writer::appendECImportTables() {
940 if (!isArm64EC(ctx
.config
.machine
))
943 const uint32_t rdata
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
945 // IAT is always placed at the beginning of .rdata section and its size
946 // is aligned to 4KB. Insert it here, after all merges all done.
947 if (PartialSection
*importAddresses
= findPartialSection(".idata$5", rdata
)) {
948 if (!rdataSec
->chunks
.empty())
949 rdataSec
->chunks
.front()->setAlignment(
950 std::max(0x1000u
, rdataSec
->chunks
.front()->getAlignment()));
951 iatSize
= alignTo(iatSize
, 0x1000);
953 rdataSec
->chunks
.insert(rdataSec
->chunks
.begin(),
954 importAddresses
->chunks
.begin(),
955 importAddresses
->chunks
.end());
956 rdataSec
->contribSections
.insert(rdataSec
->contribSections
.begin(),
960 // The auxiliary IAT is always placed at the end of the .rdata section
961 // and is aligned to 4KB.
962 if (PartialSection
*auxIat
= findPartialSection(".idata$9", rdata
)) {
963 auxIat
->chunks
.front()->setAlignment(0x1000);
964 rdataSec
->chunks
.insert(rdataSec
->chunks
.end(), auxIat
->chunks
.begin(),
965 auxIat
->chunks
.end());
966 rdataSec
->addContributingPartialSection(auxIat
);
969 if (!delayIdata
.getAuxIat().empty()) {
970 delayIdata
.getAuxIat().front()->setAlignment(0x1000);
971 rdataSec
->chunks
.insert(rdataSec
->chunks
.end(),
972 delayIdata
.getAuxIat().begin(),
973 delayIdata
.getAuxIat().end());
977 // Locate the first Chunk and size of the import directory list and the
979 void Writer::locateImportTables() {
980 uint32_t rdata
= IMAGE_SCN_CNT_INITIALIZED_DATA
| IMAGE_SCN_MEM_READ
;
982 if (PartialSection
*importDirs
= findPartialSection(".idata$2", rdata
)) {
983 if (!importDirs
->chunks
.empty())
984 importTableStart
= importDirs
->chunks
.front();
985 for (Chunk
*c
: importDirs
->chunks
)
986 importTableSize
+= c
->getSize();
989 if (PartialSection
*importAddresses
= findPartialSection(".idata$5", rdata
)) {
990 if (!importAddresses
->chunks
.empty())
991 iatStart
= importAddresses
->chunks
.front();
992 for (Chunk
*c
: importAddresses
->chunks
)
993 iatSize
+= c
->getSize();
997 // Return whether a SectionChunk's suffix (the dollar and any trailing
998 // suffix) should be removed and sorted into the main suffixless
1000 static bool shouldStripSectionSuffix(SectionChunk
*sc
, StringRef name
,
1002 // On MinGW, comdat groups are formed by putting the comdat group name
1003 // after the '$' in the section name. For .eh_frame$<symbol>, that must
1004 // still be sorted before the .eh_frame trailer from crtend.o, thus just
1005 // strip the section name trailer. For other sections, such as
1006 // .tls$$<symbol> (where non-comdat .tls symbols are otherwise stored in
1007 // ".tls$"), they must be strictly sorted after .tls. And for the
1008 // hypothetical case of comdat .CRT$XCU, we definitely need to keep the
1009 // suffix for sorting. Thus, to play it safe, only strip the suffix for
1010 // the standard sections.
1013 if (!sc
|| !sc
->isCOMDAT())
1015 return name
.starts_with(".text$") || name
.starts_with(".data$") ||
1016 name
.starts_with(".rdata$") || name
.starts_with(".pdata$") ||
1017 name
.starts_with(".xdata$") || name
.starts_with(".eh_frame$");
1020 void Writer::sortSections() {
1021 if (!ctx
.config
.callGraphProfile
.empty()) {
1022 DenseMap
<const SectionChunk
*, int> order
=
1023 computeCallGraphProfileOrder(ctx
);
1024 for (auto it
: order
) {
1025 if (DefinedRegular
*sym
= it
.first
->sym
)
1026 ctx
.config
.order
[sym
->getName()] = it
.second
;
1029 if (!ctx
.config
.order
.empty())
1030 for (auto it
: partialSections
)
1031 sortBySectionOrder(it
.second
->chunks
);
1034 void Writer::calculateStubDependentSizes() {
1035 if (ctx
.config
.dosStub
)
1036 dosStubSize
= alignTo(ctx
.config
.dosStub
->getBufferSize(), 8);
1038 dosStubSize
= sizeof(dos_header
) + sizeof(dosProgram
);
1040 coffHeaderOffset
= dosStubSize
+ sizeof(PEMagic
);
1041 peHeaderOffset
= coffHeaderOffset
+ sizeof(coff_file_header
);
1042 dataDirOffset64
= peHeaderOffset
+ sizeof(pe32plus_header
);
1045 // Create output section objects and add them to OutputSections.
1046 void Writer::createSections() {
1047 llvm::TimeTraceScope
timeScope("Output sections");
1048 // First, create the builtin sections.
1049 const uint32_t data
= IMAGE_SCN_CNT_INITIALIZED_DATA
;
1050 const uint32_t bss
= IMAGE_SCN_CNT_UNINITIALIZED_DATA
;
1051 const uint32_t code
= IMAGE_SCN_CNT_CODE
;
1052 const uint32_t discardable
= IMAGE_SCN_MEM_DISCARDABLE
;
1053 const uint32_t r
= IMAGE_SCN_MEM_READ
;
1054 const uint32_t w
= IMAGE_SCN_MEM_WRITE
;
1055 const uint32_t x
= IMAGE_SCN_MEM_EXECUTE
;
1057 SmallDenseMap
<std::pair
<StringRef
, uint32_t>, OutputSection
*> sections
;
1058 auto createSection
= [&](StringRef name
, uint32_t outChars
) {
1059 OutputSection
*&sec
= sections
[{name
, outChars
}];
1061 sec
= make
<OutputSection
>(name
, outChars
);
1062 ctx
.outputSections
.push_back(sec
);
1067 // Try to match the section order used by link.exe.
1068 textSec
= createSection(".text", code
| r
| x
);
1069 if (isArm64EC(ctx
.config
.machine
))
1070 hexpthkSec
= createSection(".hexpthk", code
| r
| x
);
1071 createSection(".bss", bss
| r
| w
);
1072 rdataSec
= createSection(".rdata", data
| r
);
1073 buildidSec
= createSection(".buildid", data
| r
);
1074 dataSec
= createSection(".data", data
| r
| w
);
1075 pdataSec
= createSection(".pdata", data
| r
);
1076 idataSec
= createSection(".idata", data
| r
);
1077 edataSec
= createSection(".edata", data
| r
);
1078 didatSec
= createSection(".didat", data
| r
);
1079 if (isArm64EC(ctx
.config
.machine
))
1080 a64xrmSec
= createSection(".a64xrm", data
| r
);
1081 rsrcSec
= createSection(".rsrc", data
| r
);
1082 relocSec
= createSection(".reloc", data
| discardable
| r
);
1083 ctorsSec
= createSection(".ctors", data
| r
| w
);
1084 dtorsSec
= createSection(".dtors", data
| r
| w
);
1086 // Then bin chunks by name and output characteristics.
1087 for (Chunk
*c
: ctx
.driver
.getChunks()) {
1088 auto *sc
= dyn_cast
<SectionChunk
>(c
);
1089 if (sc
&& !sc
->live
) {
1090 if (ctx
.config
.verbose
)
1091 sc
->printDiscardedMessage();
1094 StringRef name
= c
->getSectionName();
1095 if (shouldStripSectionSuffix(sc
, name
, ctx
.config
.mingw
))
1096 name
= name
.split('$').first
;
1098 if (name
.starts_with(".tls"))
1099 tlsAlignment
= std::max(tlsAlignment
, c
->getAlignment());
1101 PartialSection
*pSec
= createPartialSection(name
,
1102 c
->getOutputCharacteristics());
1103 pSec
->chunks
.push_back(c
);
1106 fixPartialSectionChars(".rsrc", data
| r
);
1107 fixPartialSectionChars(".edata", data
| r
);
1108 // Even in non MinGW cases, we might need to link against GNU import
1110 bool hasIdata
= fixGnuImportChunks();
1115 addSyntheticIdata();
1120 locateImportTables();
1122 // Then create an OutputSection for each section.
1123 // '$' and all following characters in input section names are
1124 // discarded when determining output section. So, .text$foo
1125 // contributes to .text, for example. See PE/COFF spec 3.2.
1126 for (auto it
: partialSections
) {
1127 PartialSection
*pSec
= it
.second
;
1128 StringRef name
= getOutputSectionName(pSec
->name
);
1129 uint32_t outChars
= pSec
->characteristics
;
1131 if (name
== ".CRT") {
1132 // In link.exe, there is a special case for the I386 target where .CRT
1133 // sections are treated as if they have output characteristics DATA | R if
1134 // their characteristics are DATA | R | W. This implements the same
1135 // special case for all architectures.
1136 outChars
= data
| r
;
1138 Log(ctx
) << "Processing section " << pSec
->name
<< " -> " << name
;
1140 sortCRTSectionChunks(pSec
->chunks
);
1143 // ARM64EC has specific placement and alignment requirements for the IAT.
1144 // Delay adding its chunks until appendECImportTables.
1145 if (isArm64EC(ctx
.config
.machine
) &&
1146 (pSec
->name
== ".idata$5" || pSec
->name
== ".idata$9"))
1149 OutputSection
*sec
= createSection(name
, outChars
);
1150 for (Chunk
*c
: pSec
->chunks
)
1153 sec
->addContributingPartialSection(pSec
);
1156 // Finally, move some output sections to the end.
1157 auto sectionOrder
= [&](const OutputSection
*s
) {
1158 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file
1159 // because the loader cannot handle holes. Stripping can remove other
1160 // discardable ones than .reloc, which is first of them (created early).
1161 if (s
->header
.Characteristics
& IMAGE_SCN_MEM_DISCARDABLE
) {
1162 // Move discardable sections named .debug_ to the end, after other
1163 // discardable sections. Stripping only removes the sections named
1164 // .debug_* - thus try to avoid leaving holes after stripping.
1165 if (s
->name
.starts_with(".debug_"))
1169 // .rsrc should come at the end of the non-discardable sections because its
1170 // size may change by the Win32 UpdateResources() function, causing
1171 // subsequent sections to move (see https://crbug.com/827082).
1176 llvm::stable_sort(ctx
.outputSections
,
1177 [&](const OutputSection
*s
, const OutputSection
*t
) {
1178 return sectionOrder(s
) < sectionOrder(t
);
1182 void Writer::createMiscChunks() {
1183 llvm::TimeTraceScope
timeScope("Misc chunks");
1184 Configuration
*config
= &ctx
.config
;
1186 for (MergeChunk
*p
: ctx
.mergeChunkInstances
) {
1188 p
->finalizeContents();
1189 rdataSec
->addChunk(p
);
1193 // Create thunks for locally-dllimported symbols.
1194 if (!ctx
.symtab
.localImportChunks
.empty()) {
1195 for (Chunk
*c
: ctx
.symtab
.localImportChunks
)
1196 rdataSec
->addChunk(c
);
1199 // Create Debug Information Chunks
1200 debugInfoSec
= config
->mingw
? buildidSec
: rdataSec
;
1201 if (config
->buildIDHash
!= BuildIDHash::None
|| config
->debug
||
1202 config
->repro
|| config
->cetCompat
) {
1204 make
<DebugDirectoryChunk
>(ctx
, debugRecords
, config
->repro
);
1205 debugDirectory
->setAlignment(4);
1206 debugInfoSec
->addChunk(debugDirectory
);
1209 if (config
->debug
|| config
->buildIDHash
!= BuildIDHash::None
) {
1210 // Make a CVDebugRecordChunk even when /DEBUG:CV is not specified. We
1211 // output a PDB no matter what, and this chunk provides the only means of
1212 // allowing a debugger to match a PDB and an executable. So we need it even
1213 // if we're ultimately not going to write CodeView data to the PDB.
1214 buildId
= make
<CVDebugRecordChunk
>(ctx
);
1215 debugRecords
.emplace_back(COFF::IMAGE_DEBUG_TYPE_CODEVIEW
, buildId
);
1216 if (Symbol
*buildidSym
= ctx
.symtab
.findUnderscore("__buildid"))
1217 replaceSymbol
<DefinedSynthetic
>(buildidSym
, buildidSym
->getName(),
1221 if (config
->cetCompat
) {
1222 debugRecords
.emplace_back(COFF::IMAGE_DEBUG_TYPE_EX_DLLCHARACTERISTICS
,
1223 make
<ExtendedDllCharacteristicsChunk
>(
1224 IMAGE_DLL_CHARACTERISTICS_EX_CET_COMPAT
));
1227 // Align and add each chunk referenced by the debug data directory.
1228 for (std::pair
<COFF::DebugType
, Chunk
*> r
: debugRecords
) {
1229 r
.second
->setAlignment(4);
1230 debugInfoSec
->addChunk(r
.second
);
1233 // Create SEH table. x86-only.
1234 if (config
->safeSEH
)
1237 // Create /guard:cf tables if requested.
1238 createGuardCFTables();
1242 if (config
->autoImport
)
1243 createRuntimePseudoRelocs();
1246 insertCtorDtorSymbols();
1249 // Create .idata section for the DLL-imported symbol table.
1250 // The format of this section is inherently Windows-specific.
1251 // IdataContents class abstracted away the details for us,
1252 // so we just let it create chunks and add them to the section.
1253 void Writer::createImportTables() {
1254 llvm::TimeTraceScope
timeScope("Import tables");
1255 // Initialize DLLOrder so that import entries are ordered in
1256 // the same order as in the command line. (That affects DLL
1257 // initialization order, and this ordering is MSVC-compatible.)
1258 for (ImportFile
*file
: ctx
.importFileInstances
) {
1262 std::string dll
= StringRef(file
->dllName
).lower();
1263 if (ctx
.config
.dllOrder
.count(dll
) == 0)
1264 ctx
.config
.dllOrder
[dll
] = ctx
.config
.dllOrder
.size();
1266 if (file
->impSym
&& !isa
<DefinedImportData
>(file
->impSym
))
1267 Fatal(ctx
) << file
->impSym
<< " was replaced";
1268 DefinedImportData
*impSym
= cast_or_null
<DefinedImportData
>(file
->impSym
);
1269 if (ctx
.config
.delayLoads
.count(StringRef(file
->dllName
).lower())) {
1270 if (!file
->thunkSym
)
1271 Fatal(ctx
) << "cannot delay-load " << toString(file
)
1272 << " due to import of data: " << impSym
;
1273 delayIdata
.add(impSym
);
1280 void Writer::appendImportThunks() {
1281 if (ctx
.importFileInstances
.empty())
1284 llvm::TimeTraceScope
timeScope("Import thunks");
1285 for (ImportFile
*file
: ctx
.importFileInstances
) {
1289 if (file
->thunkSym
) {
1290 if (!isa
<DefinedImportThunk
>(file
->thunkSym
))
1291 Fatal(ctx
) << file
->thunkSym
<< " was replaced";
1292 auto *chunk
= cast
<DefinedImportThunk
>(file
->thunkSym
)->getChunk();
1294 textSec
->addChunk(chunk
);
1297 if (file
->auxThunkSym
) {
1298 if (!isa
<DefinedImportThunk
>(file
->auxThunkSym
))
1299 Fatal(ctx
) << file
->auxThunkSym
<< " was replaced";
1300 auto *chunk
= cast
<DefinedImportThunk
>(file
->auxThunkSym
)->getChunk();
1302 textSec
->addChunk(chunk
);
1305 if (file
->impchkThunk
)
1306 textSec
->addChunk(file
->impchkThunk
);
1309 if (!delayIdata
.empty()) {
1310 delayIdata
.create();
1311 for (Chunk
*c
: delayIdata
.getChunks())
1312 didatSec
->addChunk(c
);
1313 for (Chunk
*c
: delayIdata
.getDataChunks())
1314 dataSec
->addChunk(c
);
1315 for (Chunk
*c
: delayIdata
.getCodeChunks())
1316 textSec
->addChunk(c
);
1317 for (Chunk
*c
: delayIdata
.getCodePData())
1318 pdataSec
->addChunk(c
);
1319 for (Chunk
*c
: delayIdata
.getAuxIatCopy())
1320 rdataSec
->addChunk(c
);
1321 for (Chunk
*c
: delayIdata
.getCodeUnwindInfo())
1322 rdataSec
->addChunk(c
);
1326 void Writer::createExportTable() {
1327 llvm::TimeTraceScope
timeScope("Export table");
1328 if (!edataSec
->chunks
.empty()) {
1329 // Allow using a custom built export table from input object files, instead
1330 // of having the linker synthesize the tables.
1331 if (!ctx
.hybridSymtab
) {
1332 ctx
.symtab
.edataStart
= edataSec
->chunks
.front();
1333 ctx
.symtab
.edataEnd
= edataSec
->chunks
.back();
1335 // On hybrid target, split EC and native chunks.
1336 llvm::stable_sort(edataSec
->chunks
, [=](const Chunk
*a
, const Chunk
*b
) {
1337 return (a
->getMachine() != ARM64
) < (b
->getMachine() != ARM64
);
1340 for (auto chunk
: edataSec
->chunks
) {
1341 if (chunk
->getMachine() != ARM64
) {
1342 ctx
.hybridSymtab
->edataStart
= chunk
;
1343 ctx
.hybridSymtab
->edataEnd
= edataSec
->chunks
.back();
1347 if (!ctx
.symtab
.edataStart
)
1348 ctx
.symtab
.edataStart
= chunk
;
1349 ctx
.symtab
.edataEnd
= chunk
;
1353 ctx
.forEachSymtab([&](SymbolTable
&symtab
) {
1354 if (symtab
.edataStart
) {
1355 if (symtab
.hadExplicitExports
)
1356 Warn(ctx
) << "literal .edata sections override exports";
1357 } else if (!symtab
.exports
.empty()) {
1358 std::vector
<Chunk
*> edataChunks
;
1359 createEdataChunks(symtab
, edataChunks
);
1360 for (Chunk
*c
: edataChunks
)
1361 edataSec
->addChunk(c
);
1362 symtab
.edataStart
= edataChunks
.front();
1363 symtab
.edataEnd
= edataChunks
.back();
1366 // Warn on exported deleting destructor.
1367 for (auto e
: symtab
.exports
)
1368 if (e
.sym
&& e
.sym
->getName().starts_with("??_G"))
1369 Warn(ctx
) << "export of deleting dtor: " << toString(ctx
, *e
.sym
);
1373 void Writer::removeUnusedSections() {
1374 llvm::TimeTraceScope
timeScope("Remove unused sections");
1375 // Remove sections that we can be sure won't get content, to avoid
1376 // allocating space for their section headers.
1377 auto isUnused
= [this](OutputSection
*s
) {
1379 return false; // This section is populated later.
1380 // MergeChunks have zero size at this point, as their size is finalized
1381 // later. Only remove sections that have no Chunks at all.
1382 return s
->chunks
.empty();
1384 llvm::erase_if(ctx
.outputSections
, isUnused
);
1387 // The Windows loader doesn't seem to like empty sections,
1388 // so we remove them if any.
1389 void Writer::removeEmptySections() {
1390 llvm::TimeTraceScope
timeScope("Remove empty sections");
1391 auto isEmpty
= [](OutputSection
*s
) { return s
->getVirtualSize() == 0; };
1392 llvm::erase_if(ctx
.outputSections
, isEmpty
);
1395 void Writer::assignOutputSectionIndices() {
1396 llvm::TimeTraceScope
timeScope("Output sections indices");
1397 // Assign final output section indices, and assign each chunk to its output
1400 for (OutputSection
*os
: ctx
.outputSections
) {
1401 os
->sectionIndex
= idx
;
1402 for (Chunk
*c
: os
->chunks
)
1403 c
->setOutputSectionIdx(idx
);
1407 // Merge chunks are containers of chunks, so assign those an output section
1409 for (MergeChunk
*mc
: ctx
.mergeChunkInstances
)
1411 for (SectionChunk
*sc
: mc
->sections
)
1413 sc
->setOutputSectionIdx(mc
->getOutputSectionIdx());
1416 size_t Writer::addEntryToStringTable(StringRef str
) {
1417 assert(str
.size() > COFF::NameSize
);
1418 size_t offsetOfEntry
= strtab
.size() + 4; // +4 for the size field
1419 strtab
.insert(strtab
.end(), str
.begin(), str
.end());
1420 strtab
.push_back('\0');
1421 return offsetOfEntry
;
1424 std::optional
<coff_symbol16
> Writer::createSymbol(Defined
*def
) {
1426 switch (def
->kind()) {
1427 case Symbol::DefinedAbsoluteKind
: {
1428 auto *da
= dyn_cast
<DefinedAbsolute
>(def
);
1429 // Note: COFF symbol can only store 32-bit values, so 64-bit absolute
1430 // values will be truncated.
1431 sym
.Value
= da
->getVA();
1432 sym
.SectionNumber
= IMAGE_SYM_ABSOLUTE
;
1436 // Don't write symbols that won't be written to the output to the symbol
1438 // We also try to write DefinedSynthetic as a normal symbol. Some of these
1439 // symbols do point to an actual chunk, like __safe_se_handler_table. Others
1440 // like __ImageBase are outside of sections and thus cannot be represented.
1441 Chunk
*c
= def
->getChunk();
1443 return std::nullopt
;
1444 OutputSection
*os
= ctx
.getOutputSection(c
);
1446 return std::nullopt
;
1448 sym
.Value
= def
->getRVA() - os
->getRVA();
1449 sym
.SectionNumber
= os
->sectionIndex
;
1454 // Symbols that are runtime pseudo relocations don't point to the actual
1455 // symbol data itself (as they are imported), but points to the IAT entry
1456 // instead. Avoid emitting them to the symbol table, as they can confuse
1458 if (def
->isRuntimePseudoReloc
)
1459 return std::nullopt
;
1461 StringRef name
= def
->getName();
1462 if (name
.size() > COFF::NameSize
) {
1463 sym
.Name
.Offset
.Zeroes
= 0;
1464 sym
.Name
.Offset
.Offset
= addEntryToStringTable(name
);
1466 memset(sym
.Name
.ShortName
, 0, COFF::NameSize
);
1467 memcpy(sym
.Name
.ShortName
, name
.data(), name
.size());
1470 if (auto *d
= dyn_cast
<DefinedCOFF
>(def
)) {
1471 COFFSymbolRef ref
= d
->getCOFFSymbol();
1472 sym
.Type
= ref
.getType();
1473 sym
.StorageClass
= ref
.getStorageClass();
1474 } else if (def
->kind() == Symbol::DefinedImportThunkKind
) {
1475 sym
.Type
= (IMAGE_SYM_DTYPE_FUNCTION
<< SCT_COMPLEX_TYPE_SHIFT
) |
1476 IMAGE_SYM_TYPE_NULL
;
1477 sym
.StorageClass
= IMAGE_SYM_CLASS_EXTERNAL
;
1479 sym
.Type
= IMAGE_SYM_TYPE_NULL
;
1480 sym
.StorageClass
= IMAGE_SYM_CLASS_EXTERNAL
;
1482 sym
.NumberOfAuxSymbols
= 0;
1486 void Writer::createSymbolAndStringTable() {
1487 llvm::TimeTraceScope
timeScope("Symbol and string table");
1488 // PE/COFF images are limited to 8 byte section names. Longer names can be
1489 // supported by writing a non-standard string table, but this string table is
1490 // not mapped at runtime and the long names will therefore be inaccessible.
1491 // link.exe always truncates section names to 8 bytes, whereas binutils always
1492 // preserves long section names via the string table. LLD adopts a hybrid
1493 // solution where discardable sections have long names preserved and
1494 // non-discardable sections have their names truncated, to ensure that any
1495 // section which is mapped at runtime also has its name mapped at runtime.
1496 for (OutputSection
*sec
: ctx
.outputSections
) {
1497 if (sec
->name
.size() <= COFF::NameSize
)
1499 if ((sec
->header
.Characteristics
& IMAGE_SCN_MEM_DISCARDABLE
) == 0)
1501 if (ctx
.config
.warnLongSectionNames
) {
1503 << "section name " << sec
->name
1504 << " is longer than 8 characters and will use a non-standard string "
1507 sec
->setStringTableOff(addEntryToStringTable(sec
->name
));
1510 if (ctx
.config
.writeSymtab
) {
1511 for (ObjFile
*file
: ctx
.objFileInstances
) {
1512 for (Symbol
*b
: file
->getSymbols()) {
1513 auto *d
= dyn_cast_or_null
<Defined
>(b
);
1514 if (!d
|| d
->writtenToSymtab
)
1516 d
->writtenToSymtab
= true;
1517 if (auto *dc
= dyn_cast_or_null
<DefinedCOFF
>(d
)) {
1518 COFFSymbolRef symRef
= dc
->getCOFFSymbol();
1519 if (symRef
.isSectionDefinition() ||
1520 symRef
.getStorageClass() == COFF::IMAGE_SYM_CLASS_LABEL
)
1524 if (std::optional
<coff_symbol16
> sym
= createSymbol(d
))
1525 outputSymtab
.push_back(*sym
);
1527 if (auto *dthunk
= dyn_cast
<DefinedImportThunk
>(d
)) {
1528 if (!dthunk
->wrappedSym
->writtenToSymtab
) {
1529 dthunk
->wrappedSym
->writtenToSymtab
= true;
1530 if (std::optional
<coff_symbol16
> sym
=
1531 createSymbol(dthunk
->wrappedSym
))
1532 outputSymtab
.push_back(*sym
);
1539 if (outputSymtab
.empty() && strtab
.empty())
1542 // We position the symbol table to be adjacent to the end of the last section.
1543 uint64_t fileOff
= fileSize
;
1544 pointerToSymbolTable
= fileOff
;
1545 fileOff
+= outputSymtab
.size() * sizeof(coff_symbol16
);
1546 fileOff
+= 4 + strtab
.size();
1547 fileSize
= alignTo(fileOff
, ctx
.config
.fileAlign
);
1550 void Writer::mergeSections() {
1551 llvm::TimeTraceScope
timeScope("Merge sections");
1552 if (!pdataSec
->chunks
.empty()) {
1553 if (isArm64EC(ctx
.config
.machine
)) {
1554 // On ARM64EC .pdata may contain both ARM64 and X64 data. Split them by
1555 // sorting and store their regions separately.
1556 llvm::stable_sort(pdataSec
->chunks
, [=](const Chunk
*a
, const Chunk
*b
) {
1557 return (a
->getMachine() == AMD64
) < (b
->getMachine() == AMD64
);
1560 for (auto chunk
: pdataSec
->chunks
) {
1561 if (chunk
->getMachine() == AMD64
) {
1562 hybridPdata
.first
= chunk
;
1563 hybridPdata
.last
= pdataSec
->chunks
.back();
1568 pdata
.first
= chunk
;
1572 pdata
.first
= pdataSec
->chunks
.front();
1573 pdata
.last
= pdataSec
->chunks
.back();
1577 for (auto &p
: ctx
.config
.merge
) {
1578 StringRef toName
= p
.second
;
1579 if (p
.first
== toName
)
1583 if (!names
.insert(toName
).second
)
1584 Fatal(ctx
) << "/merge: cycle found for section '" << p
.first
<< "'";
1585 auto i
= ctx
.config
.merge
.find(toName
);
1586 if (i
== ctx
.config
.merge
.end())
1590 OutputSection
*from
= findSection(p
.first
);
1591 OutputSection
*to
= findSection(toName
);
1595 from
->name
= toName
;
1602 // EC targets may have chunks of various architectures mixed together at this
1603 // point. Group code chunks of the same architecture together by sorting chunks
1604 // by their EC range type.
1605 void Writer::sortECChunks() {
1606 if (!isArm64EC(ctx
.config
.machine
))
1609 for (OutputSection
*sec
: ctx
.outputSections
) {
1610 if (sec
->isCodeSection())
1611 llvm::stable_sort(sec
->chunks
, [=](const Chunk
*a
, const Chunk
*b
) {
1612 std::optional
<chpe_range_type
> aType
= a
->getArm64ECRangeType(),
1613 bType
= b
->getArm64ECRangeType();
1614 return bType
&& (!aType
|| *aType
< *bType
);
1619 // Visits all sections to assign incremental, non-overlapping RVAs and
1621 void Writer::assignAddresses() {
1622 llvm::TimeTraceScope
timeScope("Assign addresses");
1623 Configuration
*config
= &ctx
.config
;
1625 // We need to create EC code map so that ECCodeMapChunk knows its size.
1626 // We do it here to make sure that we account for range extension chunks.
1629 sizeOfHeaders
= dosStubSize
+ sizeof(PEMagic
) + sizeof(coff_file_header
) +
1630 sizeof(data_directory
) * numberOfDataDirectory
+
1631 sizeof(coff_section
) * ctx
.outputSections
.size();
1633 config
->is64() ? sizeof(pe32plus_header
) : sizeof(pe32_header
);
1634 sizeOfHeaders
= alignTo(sizeOfHeaders
, config
->fileAlign
);
1635 fileSize
= sizeOfHeaders
;
1637 // The first page is kept unmapped.
1638 uint64_t rva
= alignTo(sizeOfHeaders
, config
->align
);
1640 for (OutputSection
*sec
: ctx
.outputSections
) {
1641 llvm::TimeTraceScope
timeScope("Section: ", sec
->name
);
1642 if (sec
== relocSec
) {
1643 sec
->chunks
.clear();
1645 if (ctx
.dynamicRelocs
) {
1646 ctx
.dynamicRelocs
->finalize();
1647 relocSec
->addChunk(ctx
.dynamicRelocs
);
1650 uint64_t rawSize
= 0, virtualSize
= 0;
1651 sec
->header
.VirtualAddress
= rva
;
1653 // If /FUNCTIONPADMIN is used, functions are padded in order to create a
1654 // hotpatchable image.
1655 uint32_t padding
= sec
->isCodeSection() ? config
->functionPadMin
: 0;
1656 std::optional
<chpe_range_type
> prevECRange
;
1658 for (Chunk
*c
: sec
->chunks
) {
1659 // Alignment EC code range baudaries.
1660 if (isArm64EC(ctx
.config
.machine
) && sec
->isCodeSection()) {
1661 std::optional
<chpe_range_type
> rangeType
= c
->getArm64ECRangeType();
1662 if (rangeType
!= prevECRange
) {
1663 virtualSize
= alignTo(virtualSize
, 4096);
1664 prevECRange
= rangeType
;
1667 if (padding
&& c
->isHotPatchable())
1668 virtualSize
+= padding
;
1669 // If chunk has EC entry thunk, reserve a space for an offset to the
1671 if (c
->getEntryThunk())
1672 virtualSize
+= sizeof(uint32_t);
1673 virtualSize
= alignTo(virtualSize
, c
->getAlignment());
1674 c
->setRVA(rva
+ virtualSize
);
1675 virtualSize
+= c
->getSize();
1677 rawSize
= alignTo(virtualSize
, config
->fileAlign
);
1679 if (virtualSize
> UINT32_MAX
)
1680 Err(ctx
) << "section larger than 4 GiB: " << sec
->name
;
1681 sec
->header
.VirtualSize
= virtualSize
;
1682 sec
->header
.SizeOfRawData
= rawSize
;
1684 sec
->header
.PointerToRawData
= fileSize
;
1685 rva
+= alignTo(virtualSize
, config
->align
);
1686 fileSize
+= alignTo(rawSize
, config
->fileAlign
);
1688 sizeOfImage
= alignTo(rva
, config
->align
);
1690 // Assign addresses to sections in MergeChunks.
1691 for (MergeChunk
*mc
: ctx
.mergeChunkInstances
)
1693 mc
->assignSubsectionRVAs();
1696 template <typename PEHeaderTy
> void Writer::writeHeader() {
1697 // Write DOS header. For backwards compatibility, the first part of a PE/COFF
1698 // executable consists of an MS-DOS MZ executable. If the executable is run
1699 // under DOS, that program gets run (usually to just print an error message).
1700 // When run under Windows, the loader looks at AddressOfNewExeHeader and uses
1701 // the PE header instead.
1702 Configuration
*config
= &ctx
.config
;
1704 uint8_t *buf
= buffer
->getBufferStart();
1705 auto *dos
= reinterpret_cast<dos_header
*>(buf
);
1707 // Write DOS program.
1708 if (config
->dosStub
) {
1709 memcpy(buf
, config
->dosStub
->getBufferStart(),
1710 config
->dosStub
->getBufferSize());
1711 // MS link.exe accepts an invalid `e_lfanew` (AddressOfNewExeHeader) and
1712 // updates it automatically. Replicate the same behaviour.
1713 dos
->AddressOfNewExeHeader
= alignTo(config
->dosStub
->getBufferSize(), 8);
1714 // Unlike MS link.exe, LLD accepts non-8-byte-aligned stubs.
1715 // In that case, we add zero paddings ourselves.
1716 buf
+= alignTo(config
->dosStub
->getBufferSize(), 8);
1718 buf
+= sizeof(dos_header
);
1719 dos
->Magic
[0] = 'M';
1720 dos
->Magic
[1] = 'Z';
1721 dos
->UsedBytesInTheLastPage
= dosStubSize
% 512;
1722 dos
->FileSizeInPages
= divideCeil(dosStubSize
, 512);
1723 dos
->HeaderSizeInParagraphs
= sizeof(dos_header
) / 16;
1725 dos
->AddressOfRelocationTable
= sizeof(dos_header
);
1726 dos
->AddressOfNewExeHeader
= dosStubSize
;
1728 memcpy(buf
, dosProgram
, sizeof(dosProgram
));
1729 buf
+= sizeof(dosProgram
);
1732 // Make sure DOS stub is aligned to 8 bytes at this point
1733 assert((buf
- buffer
->getBufferStart()) % 8 == 0);
1736 memcpy(buf
, PEMagic
, sizeof(PEMagic
));
1737 buf
+= sizeof(PEMagic
);
1739 // Write COFF header
1740 assert(coffHeaderOffset
== buf
- buffer
->getBufferStart());
1741 auto *coff
= reinterpret_cast<coff_file_header
*>(buf
);
1742 buf
+= sizeof(*coff
);
1743 switch (config
->machine
) {
1745 coff
->Machine
= AMD64
;
1748 coff
->Machine
= ARM64
;
1751 coff
->Machine
= config
->machine
;
1753 coff
->NumberOfSections
= ctx
.outputSections
.size();
1754 coff
->Characteristics
= IMAGE_FILE_EXECUTABLE_IMAGE
;
1755 if (config
->largeAddressAware
)
1756 coff
->Characteristics
|= IMAGE_FILE_LARGE_ADDRESS_AWARE
;
1757 if (!config
->is64())
1758 coff
->Characteristics
|= IMAGE_FILE_32BIT_MACHINE
;
1760 coff
->Characteristics
|= IMAGE_FILE_DLL
;
1761 if (config
->driverUponly
)
1762 coff
->Characteristics
|= IMAGE_FILE_UP_SYSTEM_ONLY
;
1763 if (!config
->relocatable
)
1764 coff
->Characteristics
|= IMAGE_FILE_RELOCS_STRIPPED
;
1765 if (config
->swaprunCD
)
1766 coff
->Characteristics
|= IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP
;
1767 if (config
->swaprunNet
)
1768 coff
->Characteristics
|= IMAGE_FILE_NET_RUN_FROM_SWAP
;
1769 coff
->SizeOfOptionalHeader
=
1770 sizeof(PEHeaderTy
) + sizeof(data_directory
) * numberOfDataDirectory
;
1773 assert(peHeaderOffset
== buf
- buffer
->getBufferStart());
1774 auto *pe
= reinterpret_cast<PEHeaderTy
*>(buf
);
1776 pe
->Magic
= config
->is64() ? PE32Header::PE32_PLUS
: PE32Header::PE32
;
1778 // If {Major,Minor}LinkerVersion is left at 0.0, then for some
1779 // reason signing the resulting PE file with Authenticode produces a
1780 // signature that fails to validate on Windows 7 (but is OK on 10).
1781 // Set it to 14.0, which is what VS2015 outputs, and which avoids
1783 pe
->MajorLinkerVersion
= 14;
1784 pe
->MinorLinkerVersion
= 0;
1786 pe
->ImageBase
= config
->imageBase
;
1787 pe
->SectionAlignment
= config
->align
;
1788 pe
->FileAlignment
= config
->fileAlign
;
1789 pe
->MajorImageVersion
= config
->majorImageVersion
;
1790 pe
->MinorImageVersion
= config
->minorImageVersion
;
1791 pe
->MajorOperatingSystemVersion
= config
->majorOSVersion
;
1792 pe
->MinorOperatingSystemVersion
= config
->minorOSVersion
;
1793 pe
->MajorSubsystemVersion
= config
->majorSubsystemVersion
;
1794 pe
->MinorSubsystemVersion
= config
->minorSubsystemVersion
;
1795 pe
->Subsystem
= config
->subsystem
;
1796 pe
->SizeOfImage
= sizeOfImage
;
1797 pe
->SizeOfHeaders
= sizeOfHeaders
;
1798 if (!config
->noEntry
) {
1799 Defined
*entry
= cast
<Defined
>(ctx
.symtab
.entry
);
1800 pe
->AddressOfEntryPoint
= entry
->getRVA();
1801 // Pointer to thumb code must have the LSB set, so adjust it.
1802 if (config
->machine
== ARMNT
)
1803 pe
->AddressOfEntryPoint
|= 1;
1805 pe
->SizeOfStackReserve
= config
->stackReserve
;
1806 pe
->SizeOfStackCommit
= config
->stackCommit
;
1807 pe
->SizeOfHeapReserve
= config
->heapReserve
;
1808 pe
->SizeOfHeapCommit
= config
->heapCommit
;
1809 if (config
->appContainer
)
1810 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER
;
1811 if (config
->driverWdm
)
1812 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_WDM_DRIVER
;
1813 if (config
->dynamicBase
)
1814 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE
;
1815 if (config
->highEntropyVA
)
1816 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
;
1817 if (!config
->allowBind
)
1818 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_NO_BIND
;
1819 if (config
->nxCompat
)
1820 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
;
1821 if (!config
->allowIsolation
)
1822 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
;
1823 if (config
->guardCF
!= GuardCFLevel::Off
)
1824 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_GUARD_CF
;
1825 if (config
->integrityCheck
)
1826 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_FORCE_INTEGRITY
;
1827 if (setNoSEHCharacteristic
|| config
->noSEH
)
1828 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_NO_SEH
;
1829 if (config
->terminalServerAware
)
1830 pe
->DLLCharacteristics
|= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
;
1831 pe
->NumberOfRvaAndSize
= numberOfDataDirectory
;
1832 if (textSec
->getVirtualSize()) {
1833 pe
->BaseOfCode
= textSec
->getRVA();
1834 pe
->SizeOfCode
= textSec
->getRawSize();
1836 pe
->SizeOfInitializedData
= getSizeOfInitializedData();
1838 // Write data directory
1839 assert(!ctx
.config
.is64() ||
1840 dataDirOffset64
== buf
- buffer
->getBufferStart());
1841 auto *dir
= reinterpret_cast<data_directory
*>(buf
);
1842 buf
+= sizeof(*dir
) * numberOfDataDirectory
;
1843 if (ctx
.symtab
.edataStart
) {
1844 dir
[EXPORT_TABLE
].RelativeVirtualAddress
= ctx
.symtab
.edataStart
->getRVA();
1845 dir
[EXPORT_TABLE
].Size
= ctx
.symtab
.edataEnd
->getRVA() +
1846 ctx
.symtab
.edataEnd
->getSize() -
1847 ctx
.symtab
.edataStart
->getRVA();
1849 if (importTableStart
) {
1850 dir
[IMPORT_TABLE
].RelativeVirtualAddress
= importTableStart
->getRVA();
1851 dir
[IMPORT_TABLE
].Size
= importTableSize
;
1854 dir
[IAT
].RelativeVirtualAddress
= iatStart
->getRVA();
1855 dir
[IAT
].Size
= iatSize
;
1857 if (rsrcSec
->getVirtualSize()) {
1858 dir
[RESOURCE_TABLE
].RelativeVirtualAddress
= rsrcSec
->getRVA();
1859 dir
[RESOURCE_TABLE
].Size
= rsrcSec
->getVirtualSize();
1861 // ARM64EC (but not ARM64X) contains x86_64 exception table in data directory.
1862 ChunkRange
&exceptionTable
=
1863 ctx
.config
.machine
== ARM64EC
? hybridPdata
: pdata
;
1864 if (exceptionTable
.first
) {
1865 dir
[EXCEPTION_TABLE
].RelativeVirtualAddress
=
1866 exceptionTable
.first
->getRVA();
1867 dir
[EXCEPTION_TABLE
].Size
= exceptionTable
.last
->getRVA() +
1868 exceptionTable
.last
->getSize() -
1869 exceptionTable
.first
->getRVA();
1871 size_t relocSize
= relocSec
->getVirtualSize();
1872 if (ctx
.dynamicRelocs
)
1873 relocSize
-= ctx
.dynamicRelocs
->getSize();
1875 dir
[BASE_RELOCATION_TABLE
].RelativeVirtualAddress
= relocSec
->getRVA();
1876 dir
[BASE_RELOCATION_TABLE
].Size
= relocSize
;
1878 if (Symbol
*sym
= ctx
.symtab
.findUnderscore("_tls_used")) {
1879 if (Defined
*b
= dyn_cast
<Defined
>(sym
)) {
1880 dir
[TLS_TABLE
].RelativeVirtualAddress
= b
->getRVA();
1881 dir
[TLS_TABLE
].Size
= config
->is64()
1882 ? sizeof(object::coff_tls_directory64
)
1883 : sizeof(object::coff_tls_directory32
);
1886 if (debugDirectory
) {
1887 dir
[DEBUG_DIRECTORY
].RelativeVirtualAddress
= debugDirectory
->getRVA();
1888 dir
[DEBUG_DIRECTORY
].Size
= debugDirectory
->getSize();
1890 if (ctx
.symtab
.loadConfigSym
) {
1891 dir
[LOAD_CONFIG_TABLE
].RelativeVirtualAddress
=
1892 ctx
.symtab
.loadConfigSym
->getRVA();
1893 dir
[LOAD_CONFIG_TABLE
].Size
= ctx
.symtab
.loadConfigSize
;
1895 if (!delayIdata
.empty()) {
1896 dir
[DELAY_IMPORT_DESCRIPTOR
].RelativeVirtualAddress
=
1897 delayIdata
.getDirRVA();
1898 dir
[DELAY_IMPORT_DESCRIPTOR
].Size
= delayIdata
.getDirSize();
1901 // Write section table
1902 for (OutputSection
*sec
: ctx
.outputSections
) {
1903 sec
->writeHeaderTo(buf
, config
->debug
);
1904 buf
+= sizeof(coff_section
);
1906 sectionTable
= ArrayRef
<uint8_t>(
1907 buf
- ctx
.outputSections
.size() * sizeof(coff_section
), buf
);
1909 if (outputSymtab
.empty() && strtab
.empty())
1912 coff
->PointerToSymbolTable
= pointerToSymbolTable
;
1913 uint32_t numberOfSymbols
= outputSymtab
.size();
1914 coff
->NumberOfSymbols
= numberOfSymbols
;
1915 auto *symbolTable
= reinterpret_cast<coff_symbol16
*>(
1916 buffer
->getBufferStart() + coff
->PointerToSymbolTable
);
1917 for (size_t i
= 0; i
!= numberOfSymbols
; ++i
)
1918 symbolTable
[i
] = outputSymtab
[i
];
1919 // Create the string table, it follows immediately after the symbol table.
1920 // The first 4 bytes is length including itself.
1921 buf
= reinterpret_cast<uint8_t *>(&symbolTable
[numberOfSymbols
]);
1922 write32le(buf
, strtab
.size() + 4);
1923 if (!strtab
.empty())
1924 memcpy(buf
+ 4, strtab
.data(), strtab
.size());
1927 void Writer::openFile(StringRef path
) {
1929 FileOutputBuffer::create(path
, fileSize
, FileOutputBuffer::F_executable
),
1930 "failed to open " + path
);
1933 void Writer::createSEHTable() {
1934 SymbolRVASet handlers
;
1935 for (ObjFile
*file
: ctx
.objFileInstances
) {
1936 if (!file
->hasSafeSEH())
1937 Err(ctx
) << "/safeseh: " << file
->getName()
1938 << " is not compatible with SEH";
1939 markSymbolsForRVATable(file
, file
->getSXDataChunks(), handlers
);
1942 // Set the "no SEH" characteristic if there really were no handlers, or if
1943 // there is no load config object to point to the table of handlers.
1944 setNoSEHCharacteristic
=
1945 handlers
.empty() || !ctx
.symtab
.findUnderscore("_load_config_used");
1947 maybeAddRVATable(std::move(handlers
), "__safe_se_handler_table",
1948 "__safe_se_handler_count");
1951 // Add a symbol to an RVA set. Two symbols may have the same RVA, but an RVA set
1952 // cannot contain duplicates. Therefore, the set is uniqued by Chunk and the
1953 // symbol's offset into that Chunk.
1954 static void addSymbolToRVASet(SymbolRVASet
&rvaSet
, Defined
*s
) {
1955 Chunk
*c
= s
->getChunk();
1958 if (auto *sc
= dyn_cast
<SectionChunk
>(c
))
1959 c
= sc
->repl
; // Look through ICF replacement.
1960 uint32_t off
= s
->getRVA() - (c
? c
->getRVA() : 0);
1961 rvaSet
.insert({c
, off
});
1964 // Given a symbol, add it to the GFIDs table if it is a live, defined, function
1965 // symbol in an executable section.
1966 static void maybeAddAddressTakenFunction(SymbolRVASet
&addressTakenSyms
,
1971 switch (s
->kind()) {
1972 case Symbol::DefinedLocalImportKind
:
1973 case Symbol::DefinedImportDataKind
:
1974 // Defines an __imp_ pointer, so it is data, so it is ignored.
1976 case Symbol::DefinedCommonKind
:
1977 // Common is always data, so it is ignored.
1979 case Symbol::DefinedAbsoluteKind
:
1980 case Symbol::DefinedSyntheticKind
:
1981 // Absolute is never code, synthetic generally isn't and usually isn't
1984 case Symbol::LazyArchiveKind
:
1985 case Symbol::LazyObjectKind
:
1986 case Symbol::LazyDLLSymbolKind
:
1987 case Symbol::UndefinedKind
:
1988 // Undefined symbols resolve to zero, so they don't have an RVA. Lazy
1989 // symbols shouldn't have relocations.
1992 case Symbol::DefinedImportThunkKind
:
1993 // Thunks are always code, include them.
1994 addSymbolToRVASet(addressTakenSyms
, cast
<Defined
>(s
));
1997 case Symbol::DefinedRegularKind
: {
1998 // This is a regular, defined, symbol from a COFF file. Mark the symbol as
1999 // address taken if the symbol type is function and it's in an executable
2001 auto *d
= cast
<DefinedRegular
>(s
);
2002 if (d
->getCOFFSymbol().getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION
) {
2003 SectionChunk
*sc
= dyn_cast
<SectionChunk
>(d
->getChunk());
2004 if (sc
&& sc
->live
&&
2005 sc
->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE
)
2006 addSymbolToRVASet(addressTakenSyms
, d
);
2013 // Visit all relocations from all section contributions of this object file and
2014 // mark the relocation target as address-taken.
2015 void Writer::markSymbolsWithRelocations(ObjFile
*file
,
2016 SymbolRVASet
&usedSymbols
) {
2017 for (Chunk
*c
: file
->getChunks()) {
2018 // We only care about live section chunks. Common chunks and other chunks
2019 // don't generally contain relocations.
2020 SectionChunk
*sc
= dyn_cast
<SectionChunk
>(c
);
2021 if (!sc
|| !sc
->live
)
2024 for (const coff_relocation
&reloc
: sc
->getRelocs()) {
2025 if (ctx
.config
.machine
== I386
&&
2026 reloc
.Type
== COFF::IMAGE_REL_I386_REL32
)
2027 // Ignore relative relocations on x86. On x86_64 they can't be ignored
2028 // since they're also used to compute absolute addresses.
2031 Symbol
*ref
= sc
->file
->getSymbol(reloc
.SymbolTableIndex
);
2032 maybeAddAddressTakenFunction(usedSymbols
, ref
);
2037 // Create the guard function id table. This is a table of RVAs of all
2038 // address-taken functions. It is sorted and uniqued, just like the safe SEH
2040 void Writer::createGuardCFTables() {
2041 Configuration
*config
= &ctx
.config
;
2043 if (config
->guardCF
== GuardCFLevel::Off
) {
2044 // MSVC marks the entire image as instrumented if any input object was built
2046 for (ObjFile
*file
: ctx
.objFileInstances
) {
2047 if (file
->hasGuardCF()) {
2048 Symbol
*flagSym
= ctx
.symtab
.findUnderscore("__guard_flags");
2049 cast
<DefinedAbsolute
>(flagSym
)->setVA(
2050 uint32_t(GuardFlags::CF_INSTRUMENTED
));
2057 SymbolRVASet addressTakenSyms
;
2058 SymbolRVASet giatsRVASet
;
2059 std::vector
<Symbol
*> giatsSymbols
;
2060 SymbolRVASet longJmpTargets
;
2061 SymbolRVASet ehContTargets
;
2062 for (ObjFile
*file
: ctx
.objFileInstances
) {
2063 // If the object was compiled with /guard:cf, the address taken symbols
2064 // are in .gfids$y sections, and the longjmp targets are in .gljmp$y
2065 // sections. If the object was not compiled with /guard:cf, we assume there
2066 // were no setjmp targets, and that all code symbols with relocations are
2067 // possibly address-taken.
2068 if (file
->hasGuardCF()) {
2069 markSymbolsForRVATable(file
, file
->getGuardFidChunks(), addressTakenSyms
);
2070 markSymbolsForRVATable(file
, file
->getGuardIATChunks(), giatsRVASet
);
2071 getSymbolsFromSections(file
, file
->getGuardIATChunks(), giatsSymbols
);
2072 markSymbolsForRVATable(file
, file
->getGuardLJmpChunks(), longJmpTargets
);
2074 markSymbolsWithRelocations(file
, addressTakenSyms
);
2076 // If the object was compiled with /guard:ehcont, the ehcont targets are in
2077 // .gehcont$y sections.
2078 if (file
->hasGuardEHCont())
2079 markSymbolsForRVATable(file
, file
->getGuardEHContChunks(), ehContTargets
);
2082 // Mark the image entry as address-taken.
2083 ctx
.forEachSymtab([&](SymbolTable
&symtab
) {
2085 maybeAddAddressTakenFunction(addressTakenSyms
, symtab
.entry
);
2087 // Mark exported symbols in executable sections as address-taken.
2088 for (Export
&e
: symtab
.exports
)
2089 maybeAddAddressTakenFunction(addressTakenSyms
, e
.sym
);
2092 // For each entry in the .giats table, check if it has a corresponding load
2093 // thunk (e.g. because the DLL that defines it will be delay-loaded) and, if
2094 // so, add the load thunk to the address taken (.gfids) table.
2095 for (Symbol
*s
: giatsSymbols
) {
2096 if (auto *di
= dyn_cast
<DefinedImportData
>(s
)) {
2097 if (di
->loadThunkSym
)
2098 addSymbolToRVASet(addressTakenSyms
, di
->loadThunkSym
);
2102 // Ensure sections referenced in the gfid table are 16-byte aligned.
2103 for (const ChunkAndOffset
&c
: addressTakenSyms
)
2104 if (c
.inputChunk
->getAlignment() < 16)
2105 c
.inputChunk
->setAlignment(16);
2107 maybeAddRVATable(std::move(addressTakenSyms
), "__guard_fids_table",
2108 "__guard_fids_count");
2110 // Add the Guard Address Taken IAT Entry Table (.giats).
2111 maybeAddRVATable(std::move(giatsRVASet
), "__guard_iat_table",
2112 "__guard_iat_count");
2114 // Add the longjmp target table unless the user told us not to.
2115 if (config
->guardCF
& GuardCFLevel::LongJmp
)
2116 maybeAddRVATable(std::move(longJmpTargets
), "__guard_longjmp_table",
2117 "__guard_longjmp_count");
2119 // Add the ehcont target table unless the user told us not to.
2120 if (config
->guardCF
& GuardCFLevel::EHCont
)
2121 maybeAddRVATable(std::move(ehContTargets
), "__guard_eh_cont_table",
2122 "__guard_eh_cont_count");
2124 // Set __guard_flags, which will be used in the load config to indicate that
2125 // /guard:cf was enabled.
2126 uint32_t guardFlags
= uint32_t(GuardFlags::CF_INSTRUMENTED
) |
2127 uint32_t(GuardFlags::CF_FUNCTION_TABLE_PRESENT
);
2128 if (config
->guardCF
& GuardCFLevel::LongJmp
)
2129 guardFlags
|= uint32_t(GuardFlags::CF_LONGJUMP_TABLE_PRESENT
);
2130 if (config
->guardCF
& GuardCFLevel::EHCont
)
2131 guardFlags
|= uint32_t(GuardFlags::EH_CONTINUATION_TABLE_PRESENT
);
2132 Symbol
*flagSym
= ctx
.symtab
.findUnderscore("__guard_flags");
2133 cast
<DefinedAbsolute
>(flagSym
)->setVA(guardFlags
);
2136 // Take a list of input sections containing symbol table indices and add those
2137 // symbols to a vector. The challenge is that symbol RVAs are not known and
2138 // depend on the table size, so we can't directly build a set of integers.
2139 void Writer::getSymbolsFromSections(ObjFile
*file
,
2140 ArrayRef
<SectionChunk
*> symIdxChunks
,
2141 std::vector
<Symbol
*> &symbols
) {
2142 for (SectionChunk
*c
: symIdxChunks
) {
2143 // Skip sections discarded by linker GC. This comes up when a .gfids section
2144 // is associated with something like a vtable and the vtable is discarded.
2145 // In this case, the associated gfids section is discarded, and we don't
2146 // mark the virtual member functions as address-taken by the vtable.
2150 // Validate that the contents look like symbol table indices.
2151 ArrayRef
<uint8_t> data
= c
->getContents();
2152 if (data
.size() % 4 != 0) {
2153 Warn(ctx
) << "ignoring " << c
->getSectionName()
2154 << " symbol table index section in object " << file
;
2158 // Read each symbol table index and check if that symbol was included in the
2159 // final link. If so, add it to the vector of symbols.
2160 ArrayRef
<ulittle32_t
> symIndices(
2161 reinterpret_cast<const ulittle32_t
*>(data
.data()), data
.size() / 4);
2162 ArrayRef
<Symbol
*> objSymbols
= file
->getSymbols();
2163 for (uint32_t symIndex
: symIndices
) {
2164 if (symIndex
>= objSymbols
.size()) {
2165 Warn(ctx
) << "ignoring invalid symbol table index in section "
2166 << c
->getSectionName() << " in object " << file
;
2169 if (Symbol
*s
= objSymbols
[symIndex
]) {
2171 symbols
.push_back(cast
<Symbol
>(s
));
2177 // Take a list of input sections containing symbol table indices and add those
2178 // symbols to an RVA table.
2179 void Writer::markSymbolsForRVATable(ObjFile
*file
,
2180 ArrayRef
<SectionChunk
*> symIdxChunks
,
2181 SymbolRVASet
&tableSymbols
) {
2182 std::vector
<Symbol
*> syms
;
2183 getSymbolsFromSections(file
, symIdxChunks
, syms
);
2185 for (Symbol
*s
: syms
)
2186 addSymbolToRVASet(tableSymbols
, cast
<Defined
>(s
));
2189 // Replace the absolute table symbol with a synthetic symbol pointing to
2190 // tableChunk so that we can emit base relocations for it and resolve section
2191 // relative relocations.
2192 void Writer::maybeAddRVATable(SymbolRVASet tableSymbols
, StringRef tableSym
,
2193 StringRef countSym
, bool hasFlag
) {
2194 if (tableSymbols
.empty())
2197 NonSectionChunk
*tableChunk
;
2199 tableChunk
= make
<RVAFlagTableChunk
>(std::move(tableSymbols
));
2201 tableChunk
= make
<RVATableChunk
>(std::move(tableSymbols
));
2202 rdataSec
->addChunk(tableChunk
);
2204 Symbol
*t
= ctx
.symtab
.findUnderscore(tableSym
);
2205 Symbol
*c
= ctx
.symtab
.findUnderscore(countSym
);
2206 replaceSymbol
<DefinedSynthetic
>(t
, t
->getName(), tableChunk
);
2207 cast
<DefinedAbsolute
>(c
)->setVA(tableChunk
->getSize() / (hasFlag
? 5 : 4));
2210 // Create CHPE metadata chunks.
2211 void Writer::createECChunks() {
2212 SymbolTable
*symtab
= ctx
.symtabEC
;
2216 for (Symbol
*s
: symtab
->expSymbols
) {
2217 auto sym
= dyn_cast
<Defined
>(s
);
2218 if (!sym
|| !sym
->getChunk())
2220 if (auto thunk
= dyn_cast
<ECExportThunkChunk
>(sym
->getChunk())) {
2221 hexpthkSec
->addChunk(thunk
);
2222 exportThunks
.push_back({thunk
, thunk
->target
});
2223 } else if (auto def
= dyn_cast
<DefinedRegular
>(sym
)) {
2224 // Allow section chunk to be treated as an export thunk if it looks like
2226 SectionChunk
*chunk
= def
->getChunk();
2227 if (!chunk
->live
|| chunk
->getMachine() != AMD64
)
2229 assert(sym
->getName().starts_with("EXP+"));
2230 StringRef targetName
= sym
->getName().substr(strlen("EXP+"));
2231 // If EXP+#foo is an export thunk of a hybrid patchable function,
2232 // we should use the #foo$hp_target symbol as the redirection target.
2233 // First, try to look up the $hp_target symbol. If it can't be found,
2234 // assume it's a regular function and look for #foo instead.
2235 Symbol
*targetSym
= symtab
->find((targetName
+ "$hp_target").str());
2237 targetSym
= symtab
->find(targetName
);
2238 Defined
*t
= dyn_cast_or_null
<Defined
>(targetSym
);
2239 if (t
&& isArm64EC(t
->getChunk()->getMachine()))
2240 exportThunks
.push_back({chunk
, t
});
2244 auto codeMapChunk
= make
<ECCodeMapChunk
>(codeMap
);
2245 rdataSec
->addChunk(codeMapChunk
);
2246 Symbol
*codeMapSym
= symtab
->findUnderscore("__hybrid_code_map");
2247 replaceSymbol
<DefinedSynthetic
>(codeMapSym
, codeMapSym
->getName(),
2250 CHPECodeRangesChunk
*ranges
= make
<CHPECodeRangesChunk
>(exportThunks
);
2251 rdataSec
->addChunk(ranges
);
2253 symtab
->findUnderscore("__x64_code_ranges_to_entry_points");
2254 replaceSymbol
<DefinedSynthetic
>(rangesSym
, rangesSym
->getName(), ranges
);
2256 CHPERedirectionChunk
*entryPoints
= make
<CHPERedirectionChunk
>(exportThunks
);
2257 a64xrmSec
->addChunk(entryPoints
);
2258 Symbol
*entryPointsSym
=
2259 symtab
->findUnderscore("__arm64x_redirection_metadata");
2260 replaceSymbol
<DefinedSynthetic
>(entryPointsSym
, entryPointsSym
->getName(),
2264 // MinGW specific. Gather all relocations that are imported from a DLL even
2265 // though the code didn't expect it to, produce the table that the runtime
2266 // uses for fixing them up, and provide the synthetic symbols that the
2267 // runtime uses for finding the table.
2268 void Writer::createRuntimePseudoRelocs() {
2269 std::vector
<RuntimePseudoReloc
> rels
;
2271 for (Chunk
*c
: ctx
.driver
.getChunks()) {
2272 auto *sc
= dyn_cast
<SectionChunk
>(c
);
2273 if (!sc
|| !sc
->live
)
2275 // Don't create pseudo relocations for sections that won't be
2276 // mapped at runtime.
2277 if (sc
->header
->Characteristics
& IMAGE_SCN_MEM_DISCARDABLE
)
2279 sc
->getRuntimePseudoRelocs(rels
);
2282 if (!ctx
.config
.pseudoRelocs
) {
2283 // Not writing any pseudo relocs; if some were needed, error out and
2284 // indicate what required them.
2285 for (const RuntimePseudoReloc
&rpr
: rels
)
2286 Err(ctx
) << "automatic dllimport of " << rpr
.sym
->getName() << " in "
2287 << toString(rpr
.target
->file
) << " requires pseudo relocations";
2291 if (!rels
.empty()) {
2292 Log(ctx
) << "Writing " << rels
.size() << " runtime pseudo relocations";
2293 const char *symbolName
= "_pei386_runtime_relocator";
2294 Symbol
*relocator
= ctx
.symtab
.findUnderscore(symbolName
);
2297 << "output image has runtime pseudo relocations, but the function "
2299 << " is missing; it is needed for fixing the relocations at runtime";
2302 PseudoRelocTableChunk
*table
= make
<PseudoRelocTableChunk
>(rels
);
2303 rdataSec
->addChunk(table
);
2304 EmptyChunk
*endOfList
= make
<EmptyChunk
>();
2305 rdataSec
->addChunk(endOfList
);
2307 Symbol
*headSym
= ctx
.symtab
.findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST__");
2309 ctx
.symtab
.findUnderscore("__RUNTIME_PSEUDO_RELOC_LIST_END__");
2310 replaceSymbol
<DefinedSynthetic
>(headSym
, headSym
->getName(), table
);
2311 replaceSymbol
<DefinedSynthetic
>(endSym
, endSym
->getName(), endOfList
);
2315 // The MinGW .ctors and .dtors lists have sentinels at each end;
2316 // a (uintptr_t)-1 at the start and a (uintptr_t)0 at the end.
2317 // There's a symbol pointing to the start sentinel pointer, __CTOR_LIST__
2318 // and __DTOR_LIST__ respectively.
2319 void Writer::insertCtorDtorSymbols() {
2320 AbsolutePointerChunk
*ctorListHead
= make
<AbsolutePointerChunk
>(ctx
, -1);
2321 AbsolutePointerChunk
*ctorListEnd
= make
<AbsolutePointerChunk
>(ctx
, 0);
2322 AbsolutePointerChunk
*dtorListHead
= make
<AbsolutePointerChunk
>(ctx
, -1);
2323 AbsolutePointerChunk
*dtorListEnd
= make
<AbsolutePointerChunk
>(ctx
, 0);
2324 ctorsSec
->insertChunkAtStart(ctorListHead
);
2325 ctorsSec
->addChunk(ctorListEnd
);
2326 dtorsSec
->insertChunkAtStart(dtorListHead
);
2327 dtorsSec
->addChunk(dtorListEnd
);
2329 Symbol
*ctorListSym
= ctx
.symtab
.findUnderscore("__CTOR_LIST__");
2330 Symbol
*dtorListSym
= ctx
.symtab
.findUnderscore("__DTOR_LIST__");
2331 replaceSymbol
<DefinedSynthetic
>(ctorListSym
, ctorListSym
->getName(),
2333 replaceSymbol
<DefinedSynthetic
>(dtorListSym
, dtorListSym
->getName(),
2337 // Handles /section options to allow users to overwrite
2338 // section attributes.
2339 void Writer::setSectionPermissions() {
2340 llvm::TimeTraceScope
timeScope("Sections permissions");
2341 for (auto &p
: ctx
.config
.section
) {
2342 StringRef name
= p
.first
;
2343 uint32_t perm
= p
.second
;
2344 for (OutputSection
*sec
: ctx
.outputSections
)
2345 if (sec
->name
== name
)
2346 sec
->setPermissions(perm
);
2350 // Set symbols used by ARM64EC metadata.
2351 void Writer::setECSymbols() {
2352 SymbolTable
*symtab
= ctx
.symtabEC
;
2356 llvm::stable_sort(exportThunks
, [](const std::pair
<Chunk
*, Defined
*> &a
,
2357 const std::pair
<Chunk
*, Defined
*> &b
) {
2358 return a
.first
->getRVA() < b
.first
->getRVA();
2361 Symbol
*rfeTableSym
= symtab
->findUnderscore("__arm64x_extra_rfe_table");
2362 replaceSymbol
<DefinedSynthetic
>(rfeTableSym
, "__arm64x_extra_rfe_table",
2366 Symbol
*rfeSizeSym
=
2367 symtab
->findUnderscore("__arm64x_extra_rfe_table_size");
2368 cast
<DefinedAbsolute
>(rfeSizeSym
)
2369 ->setVA(pdata
.last
->getRVA() + pdata
.last
->getSize() -
2370 pdata
.first
->getRVA());
2373 Symbol
*rangesCountSym
=
2374 symtab
->findUnderscore("__x64_code_ranges_to_entry_points_count");
2375 cast
<DefinedAbsolute
>(rangesCountSym
)->setVA(exportThunks
.size());
2377 Symbol
*entryPointCountSym
=
2378 symtab
->findUnderscore("__arm64x_redirection_metadata_count");
2379 cast
<DefinedAbsolute
>(entryPointCountSym
)->setVA(exportThunks
.size());
2381 Symbol
*iatSym
= symtab
->findUnderscore("__hybrid_auxiliary_iat");
2382 replaceSymbol
<DefinedSynthetic
>(iatSym
, "__hybrid_auxiliary_iat",
2383 idata
.auxIat
.empty() ? nullptr
2384 : idata
.auxIat
.front());
2386 Symbol
*iatCopySym
= symtab
->findUnderscore("__hybrid_auxiliary_iat_copy");
2387 replaceSymbol
<DefinedSynthetic
>(
2388 iatCopySym
, "__hybrid_auxiliary_iat_copy",
2389 idata
.auxIatCopy
.empty() ? nullptr : idata
.auxIatCopy
.front());
2391 Symbol
*delayIatSym
=
2392 symtab
->findUnderscore("__hybrid_auxiliary_delayload_iat");
2393 replaceSymbol
<DefinedSynthetic
>(
2394 delayIatSym
, "__hybrid_auxiliary_delayload_iat",
2395 delayIdata
.getAuxIat().empty() ? nullptr
2396 : delayIdata
.getAuxIat().front());
2398 Symbol
*delayIatCopySym
=
2399 symtab
->findUnderscore("__hybrid_auxiliary_delayload_iat_copy");
2400 replaceSymbol
<DefinedSynthetic
>(
2401 delayIatCopySym
, "__hybrid_auxiliary_delayload_iat_copy",
2402 delayIdata
.getAuxIatCopy().empty() ? nullptr
2403 : delayIdata
.getAuxIatCopy().front());
2405 if (ctx
.hybridSymtab
) {
2406 // For the hybrid image, set the alternate entry point to the EC entry
2407 // point. In the hybrid view, it is swapped to the native entry point
2408 // using ARM64X relocations.
2409 if (auto altEntrySym
= cast_or_null
<Defined
>(ctx
.hybridSymtab
->entry
)) {
2410 // If the entry is an EC export thunk, use its target instead.
2411 if (auto thunkChunk
=
2412 dyn_cast
<ECExportThunkChunk
>(altEntrySym
->getChunk()))
2413 altEntrySym
= thunkChunk
->target
;
2414 symtab
->findUnderscore("__arm64x_native_entrypoint")
2415 ->replaceKeepingName(altEntrySym
, sizeof(SymbolUnion
));
2418 if (symtab
->edataStart
)
2419 ctx
.dynamicRelocs
->set(
2420 dataDirOffset64
+ EXPORT_TABLE
* sizeof(data_directory
) +
2421 offsetof(data_directory
, Size
),
2422 symtab
->edataEnd
->getRVA() - symtab
->edataStart
->getRVA() +
2423 symtab
->edataEnd
->getSize());
2424 if (hybridPdata
.first
)
2425 ctx
.dynamicRelocs
->set(
2426 dataDirOffset64
+ EXCEPTION_TABLE
* sizeof(data_directory
) +
2427 offsetof(data_directory
, Size
),
2428 hybridPdata
.last
->getRVA() - hybridPdata
.first
->getRVA() +
2429 hybridPdata
.last
->getSize());
2433 // Write section contents to a mmap'ed file.
2434 void Writer::writeSections() {
2435 llvm::TimeTraceScope
timeScope("Write sections");
2436 uint8_t *buf
= buffer
->getBufferStart();
2437 for (OutputSection
*sec
: ctx
.outputSections
) {
2438 uint8_t *secBuf
= buf
+ sec
->getFileOff();
2439 // Fill gaps between functions in .text with INT3 instructions
2440 // instead of leaving as NUL bytes (which can be interpreted as
2441 // ADD instructions). Only fill the gaps between chunks. Most
2442 // chunks overwrite it anyway, but uninitialized data chunks
2443 // merged into a code section don't.
2444 if ((sec
->header
.Characteristics
& IMAGE_SCN_CNT_CODE
) &&
2445 (ctx
.config
.machine
== AMD64
|| ctx
.config
.machine
== I386
)) {
2446 uint32_t prevEnd
= 0;
2447 for (Chunk
*c
: sec
->chunks
) {
2448 uint32_t off
= c
->getRVA() - sec
->getRVA();
2449 memset(secBuf
+ prevEnd
, 0xCC, off
- prevEnd
);
2450 prevEnd
= off
+ c
->getSize();
2452 memset(secBuf
+ prevEnd
, 0xCC, sec
->getRawSize() - prevEnd
);
2455 parallelForEach(sec
->chunks
, [&](Chunk
*c
) {
2456 c
->writeTo(secBuf
+ c
->getRVA() - sec
->getRVA());
2461 void Writer::writeBuildId() {
2462 llvm::TimeTraceScope
timeScope("Write build ID");
2464 // There are two important parts to the build ID.
2465 // 1) If building with debug info, the COFF debug directory contains a
2466 // timestamp as well as a Guid and Age of the PDB.
2467 // 2) In all cases, the PE COFF file header also contains a timestamp.
2468 // For reproducibility, instead of a timestamp we want to use a hash of the
2470 Configuration
*config
= &ctx
.config
;
2471 bool generateSyntheticBuildId
= config
->buildIDHash
== BuildIDHash::Binary
;
2472 if (generateSyntheticBuildId
) {
2473 assert(buildId
&& "BuildId is not set!");
2474 // BuildId->BuildId was filled in when the PDB was written.
2477 // At this point the only fields in the COFF file which remain unset are the
2478 // "timestamp" in the COFF file header, and the ones in the coff debug
2479 // directory. Now we can hash the file and write that hash to the various
2480 // timestamp fields in the file.
2481 StringRef
outputFileData(
2482 reinterpret_cast<const char *>(buffer
->getBufferStart()),
2483 buffer
->getBufferSize());
2485 uint32_t timestamp
= config
->timestamp
;
2488 if (config
->repro
|| generateSyntheticBuildId
)
2489 hash
= xxh3_64bits(outputFileData
);
2492 timestamp
= static_cast<uint32_t>(hash
);
2494 if (generateSyntheticBuildId
) {
2495 buildId
->buildId
->PDB70
.CVSignature
= OMF::Signature::PDB70
;
2496 buildId
->buildId
->PDB70
.Age
= 1;
2497 memcpy(buildId
->buildId
->PDB70
.Signature
, &hash
, 8);
2498 // xxhash only gives us 8 bytes, so put some fixed data in the other half.
2499 memcpy(&buildId
->buildId
->PDB70
.Signature
[8], "LLD PDB.", 8);
2503 debugDirectory
->setTimeDateStamp(timestamp
);
2505 uint8_t *buf
= buffer
->getBufferStart();
2506 buf
+= dosStubSize
+ sizeof(PEMagic
);
2507 object::coff_file_header
*coffHeader
=
2508 reinterpret_cast<coff_file_header
*>(buf
);
2509 coffHeader
->TimeDateStamp
= timestamp
;
2512 // Sort .pdata section contents according to PE/COFF spec 5.5.
2513 template <typename T
>
2514 void Writer::sortExceptionTable(ChunkRange
&exceptionTable
) {
2515 if (!exceptionTable
.first
)
2518 // We assume .pdata contains function table entries only.
2519 auto bufAddr
= [&](Chunk
*c
) {
2520 OutputSection
*os
= ctx
.getOutputSection(c
);
2521 return buffer
->getBufferStart() + os
->getFileOff() + c
->getRVA() -
2524 uint8_t *begin
= bufAddr(exceptionTable
.first
);
2525 uint8_t *end
= bufAddr(exceptionTable
.last
) + exceptionTable
.last
->getSize();
2526 if ((end
- begin
) % sizeof(T
) != 0) {
2527 Fatal(ctx
) << "unexpected .pdata size: " << (end
- begin
)
2528 << " is not a multiple of " << sizeof(T
);
2531 parallelSort(MutableArrayRef
<T
>(reinterpret_cast<T
*>(begin
),
2532 reinterpret_cast<T
*>(end
)),
2533 [](const T
&a
, const T
&b
) { return a
.begin
< b
.begin
; });
2536 // Sort .pdata section contents according to PE/COFF spec 5.5.
2537 void Writer::sortExceptionTables() {
2538 llvm::TimeTraceScope
timeScope("Sort exception table");
2541 ulittle32_t begin
, end
, unwind
;
2544 ulittle32_t begin
, unwind
;
2547 switch (ctx
.config
.machine
) {
2549 sortExceptionTable
<EntryX64
>(pdata
);
2553 sortExceptionTable
<EntryX64
>(hybridPdata
);
2557 sortExceptionTable
<EntryArm
>(pdata
);
2561 ctx
.e
.errs() << "warning: don't know how to handle .pdata\n";
2566 // The CRT section contains, among other things, the array of function
2567 // pointers that initialize every global variable that is not trivially
2568 // constructed. The CRT calls them one after the other prior to invoking
2571 // As per C++ spec, 3.6.2/2.3,
2572 // "Variables with ordered initialization defined within a single
2573 // translation unit shall be initialized in the order of their definitions
2574 // in the translation unit"
2576 // It is therefore critical to sort the chunks containing the function
2577 // pointers in the order that they are listed in the object file (top to
2578 // bottom), otherwise global objects might not be initialized in the
2580 void Writer::sortCRTSectionChunks(std::vector
<Chunk
*> &chunks
) {
2581 auto sectionChunkOrder
= [](const Chunk
*a
, const Chunk
*b
) {
2582 auto sa
= dyn_cast
<SectionChunk
>(a
);
2583 auto sb
= dyn_cast
<SectionChunk
>(b
);
2584 assert(sa
&& sb
&& "Non-section chunks in CRT section!");
2586 StringRef sAObj
= sa
->file
->mb
.getBufferIdentifier();
2587 StringRef sBObj
= sb
->file
->mb
.getBufferIdentifier();
2589 return sAObj
== sBObj
&& sa
->getSectionNumber() < sb
->getSectionNumber();
2591 llvm::stable_sort(chunks
, sectionChunkOrder
);
2593 if (ctx
.config
.verbose
) {
2594 for (auto &c
: chunks
) {
2595 auto sc
= dyn_cast
<SectionChunk
>(c
);
2596 Log(ctx
) << " " << sc
->file
->mb
.getBufferIdentifier().str()
2597 << ", SectionID: " << sc
->getSectionNumber();
2602 OutputSection
*Writer::findSection(StringRef name
) {
2603 for (OutputSection
*sec
: ctx
.outputSections
)
2604 if (sec
->name
== name
)
2609 uint32_t Writer::getSizeOfInitializedData() {
2611 for (OutputSection
*s
: ctx
.outputSections
)
2612 if (s
->header
.Characteristics
& IMAGE_SCN_CNT_INITIALIZED_DATA
)
2613 res
+= s
->getRawSize();
2617 // Add base relocations to .reloc section.
2618 void Writer::addBaserels() {
2619 if (!ctx
.config
.relocatable
)
2621 std::vector
<Baserel
> v
;
2622 for (OutputSection
*sec
: ctx
.outputSections
) {
2623 if (sec
->header
.Characteristics
& IMAGE_SCN_MEM_DISCARDABLE
)
2625 llvm::TimeTraceScope
timeScope("Base relocations: ", sec
->name
);
2626 // Collect all locations for base relocations.
2627 for (Chunk
*c
: sec
->chunks
)
2629 // Add the addresses to .reloc section.
2631 addBaserelBlocks(v
);
2636 // Add addresses to .reloc section. Note that addresses are grouped by page.
2637 void Writer::addBaserelBlocks(std::vector
<Baserel
> &v
) {
2638 const uint32_t mask
= ~uint32_t(pageSize
- 1);
2639 uint32_t page
= v
[0].rva
& mask
;
2640 size_t i
= 0, j
= 1;
2642 [](const Baserel
&x
, const Baserel
&y
) { return x
.rva
< y
.rva
; });
2643 for (size_t e
= v
.size(); j
< e
; ++j
) {
2644 uint32_t p
= v
[j
].rva
& mask
;
2647 relocSec
->addChunk(make
<BaserelChunk
>(page
, &v
[i
], &v
[0] + j
));
2653 relocSec
->addChunk(make
<BaserelChunk
>(page
, &v
[i
], &v
[0] + j
));
2656 void Writer::createDynamicRelocs() {
2657 if (!ctx
.dynamicRelocs
)
2660 // Adjust the Machine field in the COFF header to AMD64.
2661 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint16_t),
2662 coffHeaderOffset
+ offsetof(coff_file_header
, Machine
),
2665 if (ctx
.symtab
.entry
!= ctx
.hybridSymtab
->entry
) {
2666 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2668 offsetof(pe32plus_header
, AddressOfEntryPoint
),
2669 cast_or_null
<Defined
>(ctx
.hybridSymtab
->entry
));
2671 // Swap the alternate entry point in the CHPE metadata.
2672 Symbol
*s
= ctx
.hybridSymtab
->findUnderscore("__chpe_metadata");
2673 if (auto chpeSym
= cast_or_null
<DefinedRegular
>(s
))
2674 ctx
.dynamicRelocs
->add(
2675 IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2676 Arm64XRelocVal(chpeSym
, offsetof(chpe_metadata
, AlternateEntryPoint
)),
2677 cast_or_null
<Defined
>(ctx
.symtab
.entry
));
2679 Warn(ctx
) << "'__chpe_metadata' is missing for ARM64X target";
2682 if (ctx
.symtab
.edataStart
!= ctx
.hybridSymtab
->edataStart
) {
2683 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2685 EXPORT_TABLE
* sizeof(data_directory
) +
2686 offsetof(data_directory
, RelativeVirtualAddress
),
2687 ctx
.hybridSymtab
->edataStart
);
2688 // The Size value is assigned after addresses are finalized.
2689 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2691 EXPORT_TABLE
* sizeof(data_directory
) +
2692 offsetof(data_directory
, Size
));
2695 if (pdata
.first
!= hybridPdata
.first
) {
2696 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2698 EXCEPTION_TABLE
* sizeof(data_directory
) +
2699 offsetof(data_directory
, RelativeVirtualAddress
),
2701 // The Size value is assigned after addresses are finalized.
2702 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2704 EXCEPTION_TABLE
* sizeof(data_directory
) +
2705 offsetof(data_directory
, Size
));
2708 // Set the hybrid load config to the EC load config.
2709 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2711 LOAD_CONFIG_TABLE
* sizeof(data_directory
) +
2712 offsetof(data_directory
, RelativeVirtualAddress
),
2713 ctx
.hybridSymtab
->loadConfigSym
);
2714 ctx
.dynamicRelocs
->add(IMAGE_DVRT_ARM64X_FIXUP_TYPE_VALUE
, sizeof(uint32_t),
2716 LOAD_CONFIG_TABLE
* sizeof(data_directory
) +
2717 offsetof(data_directory
, Size
),
2718 ctx
.hybridSymtab
->loadConfigSize
);
2721 PartialSection
*Writer::createPartialSection(StringRef name
,
2722 uint32_t outChars
) {
2723 PartialSection
*&pSec
= partialSections
[{name
, outChars
}];
2726 pSec
= make
<PartialSection
>(name
, outChars
);
2730 PartialSection
*Writer::findPartialSection(StringRef name
, uint32_t outChars
) {
2731 auto it
= partialSections
.find({name
, outChars
});
2732 if (it
!= partialSections
.end())
2737 void Writer::fixTlsAlignment() {
2739 dyn_cast_or_null
<Defined
>(ctx
.symtab
.findUnderscore("_tls_used"));
2743 OutputSection
*sec
= ctx
.getOutputSection(tlsSym
->getChunk());
2744 assert(sec
&& tlsSym
->getRVA() >= sec
->getRVA() &&
2745 "no output section for _tls_used");
2747 uint8_t *secBuf
= buffer
->getBufferStart() + sec
->getFileOff();
2748 uint64_t tlsOffset
= tlsSym
->getRVA() - sec
->getRVA();
2749 uint64_t directorySize
= ctx
.config
.is64()
2750 ? sizeof(object::coff_tls_directory64
)
2751 : sizeof(object::coff_tls_directory32
);
2753 if (tlsOffset
+ directorySize
> sec
->getRawSize())
2754 Fatal(ctx
) << "_tls_used sym is malformed";
2756 if (ctx
.config
.is64()) {
2757 object::coff_tls_directory64
*tlsDir
=
2758 reinterpret_cast<object::coff_tls_directory64
*>(&secBuf
[tlsOffset
]);
2759 tlsDir
->setAlignment(tlsAlignment
);
2761 object::coff_tls_directory32
*tlsDir
=
2762 reinterpret_cast<object::coff_tls_directory32
*>(&secBuf
[tlsOffset
]);
2763 tlsDir
->setAlignment(tlsAlignment
);
2767 void Writer::prepareLoadConfig() {
2768 ctx
.forEachSymtab([&](SymbolTable
&symtab
) {
2769 if (!symtab
.loadConfigSym
)
2772 OutputSection
*sec
= ctx
.getOutputSection(symtab
.loadConfigSym
->getChunk());
2773 uint8_t *secBuf
= buffer
->getBufferStart() + sec
->getFileOff();
2774 uint8_t *symBuf
= secBuf
+ (symtab
.loadConfigSym
->getRVA() - sec
->getRVA());
2776 if (ctx
.config
.is64())
2777 prepareLoadConfig(symtab
,
2778 reinterpret_cast<coff_load_configuration64
*>(symBuf
));
2780 prepareLoadConfig(symtab
,
2781 reinterpret_cast<coff_load_configuration32
*>(symBuf
));
2785 template <typename T
>
2786 void Writer::prepareLoadConfig(SymbolTable
&symtab
, T
*loadConfig
) {
2787 size_t loadConfigSize
= loadConfig
->Size
;
2789 #define RETURN_IF_NOT_CONTAINS(field) \
2790 if (loadConfigSize < offsetof(T, field) + sizeof(T::field)) { \
2791 Warn(ctx) << "'_load_config_used' structure too small to include " #field; \
2795 #define IF_CONTAINS(field) \
2796 if (loadConfigSize >= offsetof(T, field) + sizeof(T::field))
2798 #define CHECK_VA(field, sym) \
2799 if (auto *s = dyn_cast<DefinedSynthetic>(symtab.findUnderscore(sym))) \
2800 if (loadConfig->field != ctx.config.imageBase + s->getRVA()) \
2801 Warn(ctx) << #field " not set correctly in '_load_config_used'";
2803 #define CHECK_ABSOLUTE(field, sym) \
2804 if (auto *s = dyn_cast<DefinedAbsolute>(symtab.findUnderscore(sym))) \
2805 if (loadConfig->field != s->getVA()) \
2806 Warn(ctx) << #field " not set correctly in '_load_config_used'";
2808 if (ctx
.config
.dependentLoadFlags
) {
2809 RETURN_IF_NOT_CONTAINS(DependentLoadFlags
)
2810 loadConfig
->DependentLoadFlags
= ctx
.config
.dependentLoadFlags
;
2813 if (ctx
.dynamicRelocs
) {
2814 IF_CONTAINS(DynamicValueRelocTableSection
) {
2815 loadConfig
->DynamicValueRelocTableSection
= relocSec
->sectionIndex
;
2816 loadConfig
->DynamicValueRelocTableOffset
=
2817 ctx
.dynamicRelocs
->getRVA() - relocSec
->getRVA();
2820 Warn(ctx
) << "'_load_config_used' structure too small to include dynamic "
2825 IF_CONTAINS(CHPEMetadataPointer
) {
2826 // On ARM64X, only the EC version of the load config contains
2827 // CHPEMetadataPointer. Copy its value to the native load config.
2828 if (ctx
.hybridSymtab
&& !symtab
.isEC() &&
2829 ctx
.hybridSymtab
->loadConfigSize
>=
2830 offsetof(T
, CHPEMetadataPointer
) + sizeof(T::CHPEMetadataPointer
)) {
2831 OutputSection
*sec
=
2832 ctx
.getOutputSection(ctx
.hybridSymtab
->loadConfigSym
->getChunk());
2833 uint8_t *secBuf
= buffer
->getBufferStart() + sec
->getFileOff();
2834 auto hybridLoadConfig
=
2835 reinterpret_cast<const coff_load_configuration64
*>(
2837 (ctx
.hybridSymtab
->loadConfigSym
->getRVA() - sec
->getRVA()));
2838 loadConfig
->CHPEMetadataPointer
= hybridLoadConfig
->CHPEMetadataPointer
;
2842 if (ctx
.config
.guardCF
== GuardCFLevel::Off
)
2844 RETURN_IF_NOT_CONTAINS(GuardFlags
)
2845 CHECK_VA(GuardCFFunctionTable
, "__guard_fids_table")
2846 CHECK_ABSOLUTE(GuardCFFunctionCount
, "__guard_fids_count")
2847 CHECK_ABSOLUTE(GuardFlags
, "__guard_flags")
2848 IF_CONTAINS(GuardAddressTakenIatEntryCount
) {
2849 CHECK_VA(GuardAddressTakenIatEntryTable
, "__guard_iat_table")
2850 CHECK_ABSOLUTE(GuardAddressTakenIatEntryCount
, "__guard_iat_count")
2853 if (!(ctx
.config
.guardCF
& GuardCFLevel::LongJmp
))
2855 RETURN_IF_NOT_CONTAINS(GuardLongJumpTargetCount
)
2856 CHECK_VA(GuardLongJumpTargetTable
, "__guard_longjmp_table")
2857 CHECK_ABSOLUTE(GuardLongJumpTargetCount
, "__guard_longjmp_count")
2859 if (!(ctx
.config
.guardCF
& GuardCFLevel::EHCont
))
2861 RETURN_IF_NOT_CONTAINS(GuardEHContinuationCount
)
2862 CHECK_VA(GuardEHContinuationTable
, "__guard_eh_cont_table")
2863 CHECK_ABSOLUTE(GuardEHContinuationCount
, "__guard_eh_cont_count")
2865 #undef RETURN_IF_NOT_CONTAINS
2868 #undef CHECK_ABSOLUTE