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