File: | tools/lld/COFF/Writer.cpp |
Warning: | line 479, column 23 Called C++ object pointer is null |
1 | //===- Writer.cpp ---------------------------------------------------------===// | |||
2 | // | |||
3 | // The LLVM Linker | |||
4 | // | |||
5 | // This file is distributed under the University of Illinois Open Source | |||
6 | // License. See LICENSE.TXT for details. | |||
7 | // | |||
8 | //===----------------------------------------------------------------------===// | |||
9 | ||||
10 | #include "Writer.h" | |||
11 | #include "Config.h" | |||
12 | #include "DLL.h" | |||
13 | #include "Error.h" | |||
14 | #include "InputFiles.h" | |||
15 | #include "MapFile.h" | |||
16 | #include "Memory.h" | |||
17 | #include "PDB.h" | |||
18 | #include "SymbolTable.h" | |||
19 | #include "Symbols.h" | |||
20 | #include "llvm/ADT/DenseMap.h" | |||
21 | #include "llvm/ADT/STLExtras.h" | |||
22 | #include "llvm/ADT/StringSwitch.h" | |||
23 | #include "llvm/Support/Debug.h" | |||
24 | #include "llvm/Support/Endian.h" | |||
25 | #include "llvm/Support/FileOutputBuffer.h" | |||
26 | #include "llvm/Support/Parallel.h" | |||
27 | #include "llvm/Support/RandomNumberGenerator.h" | |||
28 | #include "llvm/Support/raw_ostream.h" | |||
29 | #include <algorithm> | |||
30 | #include <cstdio> | |||
31 | #include <map> | |||
32 | #include <memory> | |||
33 | #include <utility> | |||
34 | ||||
35 | using namespace llvm; | |||
36 | using namespace llvm::COFF; | |||
37 | using namespace llvm::object; | |||
38 | using namespace llvm::support; | |||
39 | using namespace llvm::support::endian; | |||
40 | using namespace lld; | |||
41 | using namespace lld::coff; | |||
42 | ||||
43 | static const int SectorSize = 512; | |||
44 | static const int DOSStubSize = 64; | |||
45 | static const int NumberfOfDataDirectory = 16; | |||
46 | ||||
47 | namespace { | |||
48 | ||||
49 | class DebugDirectoryChunk : public Chunk { | |||
50 | public: | |||
51 | DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {} | |||
52 | ||||
53 | size_t getSize() const override { | |||
54 | return Records.size() * sizeof(debug_directory); | |||
55 | } | |||
56 | ||||
57 | void writeTo(uint8_t *B) const override { | |||
58 | auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff); | |||
59 | ||||
60 | for (const Chunk *Record : Records) { | |||
61 | D->Characteristics = 0; | |||
62 | D->TimeDateStamp = 0; | |||
63 | D->MajorVersion = 0; | |||
64 | D->MinorVersion = 0; | |||
65 | D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW; | |||
66 | D->SizeOfData = Record->getSize(); | |||
67 | D->AddressOfRawData = Record->getRVA(); | |||
68 | // TODO(compnerd) get the file offset | |||
69 | D->PointerToRawData = 0; | |||
70 | ||||
71 | ++D; | |||
72 | } | |||
73 | } | |||
74 | ||||
75 | private: | |||
76 | const std::vector<Chunk *> &Records; | |||
77 | }; | |||
78 | ||||
79 | class CVDebugRecordChunk : public Chunk { | |||
80 | size_t getSize() const override { | |||
81 | return sizeof(codeview::DebugInfo) + Config->PDBPath.size() + 1; | |||
82 | } | |||
83 | ||||
84 | void writeTo(uint8_t *B) const override { | |||
85 | // Save off the DebugInfo entry to backfill the file signature (build id) | |||
86 | // in Writer::writeBuildId | |||
87 | DI = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff); | |||
88 | ||||
89 | DI->Signature.CVSignature = OMF::Signature::PDB70; | |||
90 | ||||
91 | // variable sized field (PDB Path) | |||
92 | auto *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*DI)); | |||
93 | if (!Config->PDBPath.empty()) | |||
94 | memcpy(P, Config->PDBPath.data(), Config->PDBPath.size()); | |||
95 | P[Config->PDBPath.size()] = '\0'; | |||
96 | } | |||
97 | ||||
98 | public: | |||
99 | mutable codeview::DebugInfo *DI = nullptr; | |||
100 | }; | |||
101 | ||||
102 | // The writer writes a SymbolTable result to a file. | |||
103 | class Writer { | |||
104 | public: | |||
105 | Writer(SymbolTable *T) : Symtab(T) {} | |||
106 | void run(); | |||
107 | ||||
108 | private: | |||
109 | void createSections(); | |||
110 | void createMiscChunks(); | |||
111 | void createImportTables(); | |||
112 | void createExportTable(); | |||
113 | void assignAddresses(); | |||
114 | void removeEmptySections(); | |||
115 | void createSymbolAndStringTable(); | |||
116 | void openFile(StringRef OutputPath); | |||
117 | template <typename PEHeaderTy> void writeHeader(); | |||
118 | void fixSafeSEHSymbols(); | |||
119 | void setSectionPermissions(); | |||
120 | void writeSections(); | |||
121 | void sortExceptionTable(); | |||
122 | void writeBuildId(); | |||
123 | void applyRelocations(); | |||
124 | ||||
125 | llvm::Optional<coff_symbol16> createSymbol(Defined *D); | |||
126 | size_t addEntryToStringTable(StringRef Str); | |||
127 | ||||
128 | OutputSection *findSection(StringRef Name); | |||
129 | OutputSection *createSection(StringRef Name); | |||
130 | void addBaserels(OutputSection *Dest); | |||
131 | void addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V); | |||
132 | ||||
133 | uint32_t getSizeOfInitializedData(); | |||
134 | std::map<StringRef, std::vector<DefinedImportData *>> binImports(); | |||
135 | ||||
136 | SymbolTable *Symtab; | |||
137 | std::unique_ptr<FileOutputBuffer> Buffer; | |||
138 | std::vector<OutputSection *> OutputSections; | |||
139 | std::vector<char> Strtab; | |||
140 | std::vector<llvm::object::coff_symbol16> OutputSymtab; | |||
141 | IdataContents Idata; | |||
142 | DelayLoadContents DelayIdata; | |||
143 | EdataContents Edata; | |||
144 | SEHTableChunk *SEHTable = nullptr; | |||
145 | ||||
146 | Chunk *DebugDirectory = nullptr; | |||
147 | std::vector<Chunk *> DebugRecords; | |||
148 | CVDebugRecordChunk *BuildId = nullptr; | |||
149 | ArrayRef<uint8_t> SectionTable; | |||
150 | ||||
151 | uint64_t FileSize; | |||
152 | uint32_t PointerToSymbolTable = 0; | |||
153 | uint64_t SizeOfImage; | |||
154 | uint64_t SizeOfHeaders; | |||
155 | }; | |||
156 | } // anonymous namespace | |||
157 | ||||
158 | namespace lld { | |||
159 | namespace coff { | |||
160 | ||||
161 | void writeResult(SymbolTable *T) { Writer(T).run(); } | |||
162 | ||||
163 | void OutputSection::setRVA(uint64_t RVA) { | |||
164 | Header.VirtualAddress = RVA; | |||
165 | for (Chunk *C : Chunks) | |||
166 | C->setRVA(C->getRVA() + RVA); | |||
167 | } | |||
168 | ||||
169 | void OutputSection::setFileOffset(uint64_t Off) { | |||
170 | // If a section has no actual data (i.e. BSS section), we want to | |||
171 | // set 0 to its PointerToRawData. Otherwise the output is rejected | |||
172 | // by the loader. | |||
173 | if (Header.SizeOfRawData == 0) | |||
174 | return; | |||
175 | Header.PointerToRawData = Off; | |||
176 | } | |||
177 | ||||
178 | void OutputSection::addChunk(Chunk *C) { | |||
179 | Chunks.push_back(C); | |||
180 | C->setOutputSection(this); | |||
181 | uint64_t Off = Header.VirtualSize; | |||
182 | Off = alignTo(Off, C->getAlign()); | |||
183 | C->setRVA(Off); | |||
184 | C->setOutputSectionOff(Off); | |||
185 | Off += C->getSize(); | |||
186 | Header.VirtualSize = Off; | |||
187 | if (C->hasData()) | |||
188 | Header.SizeOfRawData = alignTo(Off, SectorSize); | |||
189 | } | |||
190 | ||||
191 | void OutputSection::addPermissions(uint32_t C) { | |||
192 | Header.Characteristics |= C & PermMask; | |||
193 | } | |||
194 | ||||
195 | void OutputSection::setPermissions(uint32_t C) { | |||
196 | Header.Characteristics = C & PermMask; | |||
197 | } | |||
198 | ||||
199 | // Write the section header to a given buffer. | |||
200 | void OutputSection::writeHeaderTo(uint8_t *Buf) { | |||
201 | auto *Hdr = reinterpret_cast<coff_section *>(Buf); | |||
202 | *Hdr = Header; | |||
203 | if (StringTableOff) { | |||
204 | // If name is too long, write offset into the string table as a name. | |||
205 | sprintf(Hdr->Name, "/%d", StringTableOff); | |||
206 | } else { | |||
207 | assert(!Config->Debug || Name.size() <= COFF::NameSize)((!Config->Debug || Name.size() <= COFF::NameSize) ? static_cast <void> (0) : __assert_fail ("!Config->Debug || Name.size() <= COFF::NameSize" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 207, __PRETTY_FUNCTION__)); | |||
208 | strncpy(Hdr->Name, Name.data(), | |||
209 | std::min(Name.size(), (size_t)COFF::NameSize)); | |||
210 | } | |||
211 | } | |||
212 | ||||
213 | uint64_t Defined::getSecrel() { | |||
214 | if (auto *D = dyn_cast<DefinedRegular>(this)) | |||
215 | return getRVA() - D->getChunk()->getOutputSection()->getRVA(); | |||
216 | fatal("SECREL relocation points to a non-regular symbol"); | |||
217 | } | |||
218 | ||||
219 | uint64_t Defined::getSectionIndex() { | |||
220 | if (auto *D = dyn_cast<DefinedRegular>(this)) | |||
221 | return D->getChunk()->getOutputSection()->SectionIndex; | |||
222 | fatal("SECTION relocation points to a non-regular symbol"); | |||
223 | } | |||
224 | ||||
225 | bool Defined::isExecutable() { | |||
226 | const auto X = IMAGE_SCN_MEM_EXECUTE; | |||
227 | if (auto *D = dyn_cast<DefinedRegular>(this)) | |||
228 | return D->getChunk()->getOutputSection()->getPermissions() & X; | |||
229 | return isa<DefinedImportThunk>(this); | |||
230 | } | |||
231 | ||||
232 | } // namespace coff | |||
233 | } // namespace lld | |||
234 | ||||
235 | // The main function of the writer. | |||
236 | void Writer::run() { | |||
237 | createSections(); | |||
238 | createMiscChunks(); | |||
239 | createImportTables(); | |||
240 | createExportTable(); | |||
241 | if (Config->Relocatable) | |||
242 | createSection(".reloc"); | |||
243 | assignAddresses(); | |||
244 | removeEmptySections(); | |||
245 | setSectionPermissions(); | |||
246 | createSymbolAndStringTable(); | |||
247 | openFile(Config->OutputFile); | |||
248 | if (Config->is64()) { | |||
249 | writeHeader<pe32plus_header>(); | |||
250 | } else { | |||
251 | writeHeader<pe32_header>(); | |||
252 | } | |||
253 | fixSafeSEHSymbols(); | |||
254 | writeSections(); | |||
255 | sortExceptionTable(); | |||
256 | writeBuildId(); | |||
257 | ||||
258 | if (!Config->PDBPath.empty() && Config->Debug) { | |||
259 | const llvm::codeview::DebugInfo *DI = nullptr; | |||
260 | if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) | |||
261 | DI = BuildId->DI; | |||
262 | createPDB(Config->PDBPath, Symtab, SectionTable, DI); | |||
263 | } | |||
264 | ||||
265 | writeMapFile(OutputSections); | |||
266 | ||||
267 | if (auto EC = Buffer->commit()) | |||
268 | fatal(EC, "failed to write the output file"); | |||
269 | } | |||
270 | ||||
271 | static StringRef getOutputSection(StringRef Name) { | |||
272 | StringRef S = Name.split('$').first; | |||
273 | auto It = Config->Merge.find(S); | |||
274 | if (It == Config->Merge.end()) | |||
275 | return S; | |||
276 | return It->second; | |||
277 | } | |||
278 | ||||
279 | // Create output section objects and add them to OutputSections. | |||
280 | void Writer::createSections() { | |||
281 | // First, bin chunks by name. | |||
282 | std::map<StringRef, std::vector<Chunk *>> Map; | |||
283 | for (Chunk *C : Symtab->getChunks()) { | |||
284 | auto *SC = dyn_cast<SectionChunk>(C); | |||
285 | if (SC && !SC->isLive()) { | |||
286 | if (Config->Verbose) | |||
287 | SC->printDiscardedMessage(); | |||
288 | continue; | |||
289 | } | |||
290 | Map[C->getSectionName()].push_back(C); | |||
291 | } | |||
292 | ||||
293 | // Then create an OutputSection for each section. | |||
294 | // '$' and all following characters in input section names are | |||
295 | // discarded when determining output section. So, .text$foo | |||
296 | // contributes to .text, for example. See PE/COFF spec 3.2. | |||
297 | SmallDenseMap<StringRef, OutputSection *> Sections; | |||
298 | for (auto Pair : Map) { | |||
299 | StringRef Name = getOutputSection(Pair.first); | |||
300 | OutputSection *&Sec = Sections[Name]; | |||
301 | if (!Sec) { | |||
302 | Sec = make<OutputSection>(Name); | |||
303 | OutputSections.push_back(Sec); | |||
304 | } | |||
305 | std::vector<Chunk *> &Chunks = Pair.second; | |||
306 | for (Chunk *C : Chunks) { | |||
307 | Sec->addChunk(C); | |||
308 | Sec->addPermissions(C->getPermissions()); | |||
309 | } | |||
310 | } | |||
311 | } | |||
312 | ||||
313 | void Writer::createMiscChunks() { | |||
314 | OutputSection *RData = createSection(".rdata"); | |||
315 | ||||
316 | // Create thunks for locally-dllimported symbols. | |||
317 | if (!Symtab->LocalImportChunks.empty()) { | |||
318 | for (Chunk *C : Symtab->LocalImportChunks) | |||
319 | RData->addChunk(C); | |||
320 | } | |||
321 | ||||
322 | // Create Debug Information Chunks | |||
323 | if (Config->Debug) { | |||
324 | DebugDirectory = make<DebugDirectoryChunk>(DebugRecords); | |||
325 | ||||
326 | // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled | |||
327 | if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) { | |||
328 | auto *Chunk = make<CVDebugRecordChunk>(); | |||
329 | ||||
330 | BuildId = Chunk; | |||
331 | DebugRecords.push_back(Chunk); | |||
332 | } | |||
333 | ||||
334 | RData->addChunk(DebugDirectory); | |||
335 | for (Chunk *C : DebugRecords) | |||
336 | RData->addChunk(C); | |||
337 | } | |||
338 | ||||
339 | // Create SEH table. x86-only. | |||
340 | if (Config->Machine != I386) | |||
341 | return; | |||
342 | ||||
343 | std::set<Defined *> Handlers; | |||
344 | ||||
345 | for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) { | |||
346 | if (!File->SEHCompat) | |||
347 | return; | |||
348 | for (SymbolBody *B : File->SEHandlers) | |||
349 | Handlers.insert(cast<Defined>(B)); | |||
350 | } | |||
351 | ||||
352 | SEHTable = make<SEHTableChunk>(Handlers); | |||
353 | RData->addChunk(SEHTable); | |||
354 | } | |||
355 | ||||
356 | // Create .idata section for the DLL-imported symbol table. | |||
357 | // The format of this section is inherently Windows-specific. | |||
358 | // IdataContents class abstracted away the details for us, | |||
359 | // so we just let it create chunks and add them to the section. | |||
360 | void Writer::createImportTables() { | |||
361 | if (Symtab->ImportFiles.empty()) | |||
362 | return; | |||
363 | ||||
364 | // Initialize DLLOrder so that import entries are ordered in | |||
365 | // the same order as in the command line. (That affects DLL | |||
366 | // initialization order, and this ordering is MSVC-compatible.) | |||
367 | for (ImportFile *File : Symtab->ImportFiles) { | |||
368 | std::string DLL = StringRef(File->DLLName).lower(); | |||
369 | if (Config->DLLOrder.count(DLL) == 0) | |||
370 | Config->DLLOrder[DLL] = Config->DLLOrder.size(); | |||
371 | } | |||
372 | ||||
373 | OutputSection *Text = createSection(".text"); | |||
374 | for (ImportFile *File : Symtab->ImportFiles) { | |||
375 | if (DefinedImportThunk *Thunk = File->ThunkSym) | |||
376 | if (Thunk->Live) | |||
377 | Text->addChunk(Thunk->getChunk()); | |||
378 | ||||
379 | if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) { | |||
380 | if (File->ImpSym->Live) | |||
381 | DelayIdata.add(File->ImpSym); | |||
382 | } else { | |||
383 | if (File->ImpSym->Live) | |||
384 | Idata.add(File->ImpSym); | |||
385 | } | |||
386 | } | |||
387 | ||||
388 | if (!Idata.empty()) { | |||
389 | OutputSection *Sec = createSection(".idata"); | |||
390 | for (Chunk *C : Idata.getChunks()) | |||
391 | Sec->addChunk(C); | |||
392 | } | |||
393 | ||||
394 | if (!DelayIdata.empty()) { | |||
395 | Defined *Helper = cast<Defined>(Config->DelayLoadHelper); | |||
396 | DelayIdata.create(Helper); | |||
397 | OutputSection *Sec = createSection(".didat"); | |||
398 | for (Chunk *C : DelayIdata.getChunks()) | |||
399 | Sec->addChunk(C); | |||
400 | Sec = createSection(".data"); | |||
401 | for (Chunk *C : DelayIdata.getDataChunks()) | |||
402 | Sec->addChunk(C); | |||
403 | Sec = createSection(".text"); | |||
404 | for (Chunk *C : DelayIdata.getCodeChunks()) | |||
405 | Sec->addChunk(C); | |||
406 | } | |||
407 | } | |||
408 | ||||
409 | void Writer::createExportTable() { | |||
410 | if (Config->Exports.empty()) | |||
411 | return; | |||
412 | OutputSection *Sec = createSection(".edata"); | |||
413 | for (Chunk *C : Edata.Chunks) | |||
414 | Sec->addChunk(C); | |||
415 | } | |||
416 | ||||
417 | // The Windows loader doesn't seem to like empty sections, | |||
418 | // so we remove them if any. | |||
419 | void Writer::removeEmptySections() { | |||
420 | auto IsEmpty = [](OutputSection *S) { return S->getVirtualSize() == 0; }; | |||
421 | OutputSections.erase( | |||
422 | std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty), | |||
423 | OutputSections.end()); | |||
424 | uint32_t Idx = 1; | |||
425 | for (OutputSection *Sec : OutputSections) | |||
426 | Sec->SectionIndex = Idx++; | |||
427 | } | |||
428 | ||||
429 | size_t Writer::addEntryToStringTable(StringRef Str) { | |||
430 | assert(Str.size() > COFF::NameSize)((Str.size() > COFF::NameSize) ? static_cast<void> ( 0) : __assert_fail ("Str.size() > COFF::NameSize", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 430, __PRETTY_FUNCTION__)); | |||
431 | size_t OffsetOfEntry = Strtab.size() + 4; // +4 for the size field | |||
432 | Strtab.insert(Strtab.end(), Str.begin(), Str.end()); | |||
433 | Strtab.push_back('\0'); | |||
434 | return OffsetOfEntry; | |||
435 | } | |||
436 | ||||
437 | Optional<coff_symbol16> Writer::createSymbol(Defined *Def) { | |||
438 | // Relative symbols are unrepresentable in a COFF symbol table. | |||
439 | if (isa<DefinedRelative>(Def)) | |||
| ||||
440 | return None; | |||
441 | ||||
442 | if (auto *D = dyn_cast<DefinedRegular>(Def)) | |||
443 | if (!D->getChunk()->isLive()) | |||
444 | return None; | |||
445 | ||||
446 | coff_symbol16 Sym; | |||
447 | StringRef Name = Def->getName(); | |||
448 | if (Name.size() > COFF::NameSize) { | |||
449 | Sym.Name.Offset.Zeroes = 0; | |||
450 | Sym.Name.Offset.Offset = addEntryToStringTable(Name); | |||
451 | } else { | |||
452 | memset(Sym.Name.ShortName, 0, COFF::NameSize); | |||
453 | memcpy(Sym.Name.ShortName, Name.data(), Name.size()); | |||
454 | } | |||
455 | ||||
456 | if (auto *D = dyn_cast<DefinedCOFF>(Def)) { | |||
457 | COFFSymbolRef Ref = D->getCOFFSymbol(); | |||
458 | Sym.Type = Ref.getType(); | |||
459 | Sym.StorageClass = Ref.getStorageClass(); | |||
460 | } else { | |||
461 | Sym.Type = IMAGE_SYM_TYPE_NULL; | |||
462 | Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL; | |||
463 | } | |||
464 | Sym.NumberOfAuxSymbols = 0; | |||
465 | ||||
466 | switch (Def->kind()) { | |||
467 | case SymbolBody::DefinedAbsoluteKind: | |||
468 | Sym.Value = Def->getRVA(); | |||
469 | Sym.SectionNumber = IMAGE_SYM_ABSOLUTE; | |||
470 | break; | |||
471 | default: { | |||
472 | uint64_t RVA = Def->getRVA(); | |||
473 | OutputSection *Sec = nullptr; | |||
474 | for (OutputSection *S : OutputSections) { | |||
475 | if (S->getRVA() > RVA) | |||
476 | break; | |||
477 | Sec = S; | |||
478 | } | |||
479 | Sym.Value = RVA - Sec->getRVA(); | |||
| ||||
480 | Sym.SectionNumber = Sec->SectionIndex; | |||
481 | break; | |||
482 | } | |||
483 | } | |||
484 | return Sym; | |||
485 | } | |||
486 | ||||
487 | void Writer::createSymbolAndStringTable() { | |||
488 | if (!Config->Debug || !Config->WriteSymtab) | |||
489 | return; | |||
490 | ||||
491 | // Name field in the section table is 8 byte long. Longer names need | |||
492 | // to be written to the string table. First, construct string table. | |||
493 | for (OutputSection *Sec : OutputSections) { | |||
494 | StringRef Name = Sec->getName(); | |||
495 | if (Name.size() <= COFF::NameSize) | |||
496 | continue; | |||
497 | Sec->setStringTableOff(addEntryToStringTable(Name)); | |||
498 | } | |||
499 | ||||
500 | for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) { | |||
501 | for (SymbolBody *B : File->getSymbols()) { | |||
502 | auto *D = dyn_cast<Defined>(B); | |||
503 | if (!D || D->WrittenToSymtab) | |||
504 | continue; | |||
505 | ||||
506 | if (auto *S = dyn_cast<DefinedImportData>(D)) | |||
507 | if (!S->Live) | |||
508 | continue; | |||
509 | if (auto *S = dyn_cast<DefinedImportThunk>(D)) | |||
510 | if (!S->Live) | |||
511 | continue; | |||
512 | ||||
513 | D->WrittenToSymtab = true; | |||
514 | if (Optional<coff_symbol16> Sym = createSymbol(D)) | |||
515 | OutputSymtab.push_back(*Sym); | |||
516 | } | |||
517 | } | |||
518 | ||||
519 | OutputSection *LastSection = OutputSections.back(); | |||
520 | // We position the symbol table to be adjacent to the end of the last section. | |||
521 | uint64_t FileOff = LastSection->getFileOff() + | |||
522 | alignTo(LastSection->getRawSize(), SectorSize); | |||
523 | if (!OutputSymtab.empty()) { | |||
524 | PointerToSymbolTable = FileOff; | |||
525 | FileOff += OutputSymtab.size() * sizeof(coff_symbol16); | |||
526 | } | |||
527 | if (!Strtab.empty()) | |||
528 | FileOff += Strtab.size() + 4; | |||
529 | FileSize = alignTo(FileOff, SectorSize); | |||
530 | } | |||
531 | ||||
532 | // Visits all sections to assign incremental, non-overlapping RVAs and | |||
533 | // file offsets. | |||
534 | void Writer::assignAddresses() { | |||
535 | SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) + | |||
536 | sizeof(data_directory) * NumberfOfDataDirectory + | |||
537 | sizeof(coff_section) * OutputSections.size(); | |||
538 | SizeOfHeaders += | |||
539 | Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header); | |||
540 | SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize); | |||
541 | uint64_t RVA = 0x1000; // The first page is kept unmapped. | |||
542 | FileSize = SizeOfHeaders; | |||
543 | // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because | |||
544 | // the loader cannot handle holes. | |||
545 | std::stable_partition( | |||
546 | OutputSections.begin(), OutputSections.end(), [](OutputSection *S) { | |||
547 | return (S->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0; | |||
548 | }); | |||
549 | for (OutputSection *Sec : OutputSections) { | |||
550 | if (Sec->getName() == ".reloc") | |||
551 | addBaserels(Sec); | |||
552 | Sec->setRVA(RVA); | |||
553 | Sec->setFileOffset(FileSize); | |||
554 | RVA += alignTo(Sec->getVirtualSize(), PageSize); | |||
555 | FileSize += alignTo(Sec->getRawSize(), SectorSize); | |||
556 | } | |||
557 | SizeOfImage = SizeOfHeaders + alignTo(RVA - 0x1000, PageSize); | |||
558 | } | |||
559 | ||||
560 | template <typename PEHeaderTy> void Writer::writeHeader() { | |||
561 | // Write DOS stub | |||
562 | uint8_t *Buf = Buffer->getBufferStart(); | |||
563 | auto *DOS = reinterpret_cast<dos_header *>(Buf); | |||
564 | Buf += DOSStubSize; | |||
565 | DOS->Magic[0] = 'M'; | |||
566 | DOS->Magic[1] = 'Z'; | |||
567 | DOS->AddressOfRelocationTable = sizeof(dos_header); | |||
568 | DOS->AddressOfNewExeHeader = DOSStubSize; | |||
569 | ||||
570 | // Write PE magic | |||
571 | memcpy(Buf, PEMagic, sizeof(PEMagic)); | |||
572 | Buf += sizeof(PEMagic); | |||
573 | ||||
574 | // Write COFF header | |||
575 | auto *COFF = reinterpret_cast<coff_file_header *>(Buf); | |||
576 | Buf += sizeof(*COFF); | |||
577 | COFF->Machine = Config->Machine; | |||
578 | COFF->NumberOfSections = OutputSections.size(); | |||
579 | COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE; | |||
580 | if (Config->LargeAddressAware) | |||
581 | COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE; | |||
582 | if (!Config->is64()) | |||
583 | COFF->Characteristics |= IMAGE_FILE_32BIT_MACHINE; | |||
584 | if (Config->DLL) | |||
585 | COFF->Characteristics |= IMAGE_FILE_DLL; | |||
586 | if (!Config->Relocatable) | |||
587 | COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED; | |||
588 | COFF->SizeOfOptionalHeader = | |||
589 | sizeof(PEHeaderTy) + sizeof(data_directory) * NumberfOfDataDirectory; | |||
590 | ||||
591 | // Write PE header | |||
592 | auto *PE = reinterpret_cast<PEHeaderTy *>(Buf); | |||
593 | Buf += sizeof(*PE); | |||
594 | PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32; | |||
595 | PE->ImageBase = Config->ImageBase; | |||
596 | PE->SectionAlignment = PageSize; | |||
597 | PE->FileAlignment = SectorSize; | |||
598 | PE->MajorImageVersion = Config->MajorImageVersion; | |||
599 | PE->MinorImageVersion = Config->MinorImageVersion; | |||
600 | PE->MajorOperatingSystemVersion = Config->MajorOSVersion; | |||
601 | PE->MinorOperatingSystemVersion = Config->MinorOSVersion; | |||
602 | PE->MajorSubsystemVersion = Config->MajorOSVersion; | |||
603 | PE->MinorSubsystemVersion = Config->MinorOSVersion; | |||
604 | PE->Subsystem = Config->Subsystem; | |||
605 | PE->SizeOfImage = SizeOfImage; | |||
606 | PE->SizeOfHeaders = SizeOfHeaders; | |||
607 | if (!Config->NoEntry) { | |||
608 | Defined *Entry = cast<Defined>(Config->Entry); | |||
609 | PE->AddressOfEntryPoint = Entry->getRVA(); | |||
610 | // Pointer to thumb code must have the LSB set, so adjust it. | |||
611 | if (Config->Machine == ARMNT) | |||
612 | PE->AddressOfEntryPoint |= 1; | |||
613 | } | |||
614 | PE->SizeOfStackReserve = Config->StackReserve; | |||
615 | PE->SizeOfStackCommit = Config->StackCommit; | |||
616 | PE->SizeOfHeapReserve = Config->HeapReserve; | |||
617 | PE->SizeOfHeapCommit = Config->HeapCommit; | |||
618 | if (Config->AppContainer) | |||
619 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER; | |||
620 | if (Config->DynamicBase) | |||
621 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE; | |||
622 | if (Config->HighEntropyVA) | |||
623 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA; | |||
624 | if (!Config->AllowBind) | |||
625 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_BIND; | |||
626 | if (Config->NxCompat) | |||
627 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT; | |||
628 | if (!Config->AllowIsolation) | |||
629 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION; | |||
630 | if (Config->TerminalServerAware) | |||
631 | PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE; | |||
632 | PE->NumberOfRvaAndSize = NumberfOfDataDirectory; | |||
633 | if (OutputSection *Text = findSection(".text")) { | |||
634 | PE->BaseOfCode = Text->getRVA(); | |||
635 | PE->SizeOfCode = Text->getRawSize(); | |||
636 | } | |||
637 | PE->SizeOfInitializedData = getSizeOfInitializedData(); | |||
638 | ||||
639 | // Write data directory | |||
640 | auto *Dir = reinterpret_cast<data_directory *>(Buf); | |||
641 | Buf += sizeof(*Dir) * NumberfOfDataDirectory; | |||
642 | if (OutputSection *Sec = findSection(".edata")) { | |||
643 | Dir[EXPORT_TABLE].RelativeVirtualAddress = Sec->getRVA(); | |||
644 | Dir[EXPORT_TABLE].Size = Sec->getVirtualSize(); | |||
645 | } | |||
646 | if (!Idata.empty()) { | |||
647 | Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA(); | |||
648 | Dir[IMPORT_TABLE].Size = Idata.getDirSize(); | |||
649 | Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA(); | |||
650 | Dir[IAT].Size = Idata.getIATSize(); | |||
651 | } | |||
652 | if (OutputSection *Sec = findSection(".rsrc")) { | |||
653 | Dir[RESOURCE_TABLE].RelativeVirtualAddress = Sec->getRVA(); | |||
654 | Dir[RESOURCE_TABLE].Size = Sec->getVirtualSize(); | |||
655 | } | |||
656 | if (OutputSection *Sec = findSection(".pdata")) { | |||
657 | Dir[EXCEPTION_TABLE].RelativeVirtualAddress = Sec->getRVA(); | |||
658 | Dir[EXCEPTION_TABLE].Size = Sec->getVirtualSize(); | |||
659 | } | |||
660 | if (OutputSection *Sec = findSection(".reloc")) { | |||
661 | Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA(); | |||
662 | Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize(); | |||
663 | } | |||
664 | if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) { | |||
665 | if (Defined *B = dyn_cast<Defined>(Sym->body())) { | |||
666 | Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA(); | |||
667 | Dir[TLS_TABLE].Size = Config->is64() | |||
668 | ? sizeof(object::coff_tls_directory64) | |||
669 | : sizeof(object::coff_tls_directory32); | |||
670 | } | |||
671 | } | |||
672 | if (Config->Debug) { | |||
673 | Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA(); | |||
674 | Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize(); | |||
675 | } | |||
676 | if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) { | |||
677 | if (auto *B = dyn_cast<DefinedRegular>(Sym->body())) { | |||
678 | SectionChunk *SC = B->getChunk(); | |||
679 | assert(B->getRVA() >= SC->getRVA())((B->getRVA() >= SC->getRVA()) ? static_cast<void > (0) : __assert_fail ("B->getRVA() >= SC->getRVA()" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 679, __PRETTY_FUNCTION__)); | |||
680 | uint64_t OffsetInChunk = B->getRVA() - SC->getRVA(); | |||
681 | if (!SC->hasData() || OffsetInChunk + 4 > SC->getSize()) | |||
682 | fatal("_load_config_used is malformed"); | |||
683 | ||||
684 | ArrayRef<uint8_t> SecContents = SC->getContents(); | |||
685 | uint32_t LoadConfigSize = | |||
686 | *reinterpret_cast<const ulittle32_t *>(&SecContents[OffsetInChunk]); | |||
687 | if (OffsetInChunk + LoadConfigSize > SC->getSize()) | |||
688 | fatal("_load_config_used is too large"); | |||
689 | Dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = B->getRVA(); | |||
690 | Dir[LOAD_CONFIG_TABLE].Size = LoadConfigSize; | |||
691 | } | |||
692 | } | |||
693 | if (!DelayIdata.empty()) { | |||
694 | Dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress = | |||
695 | DelayIdata.getDirRVA(); | |||
696 | Dir[DELAY_IMPORT_DESCRIPTOR].Size = DelayIdata.getDirSize(); | |||
697 | } | |||
698 | ||||
699 | // Write section table | |||
700 | for (OutputSection *Sec : OutputSections) { | |||
701 | Sec->writeHeaderTo(Buf); | |||
702 | Buf += sizeof(coff_section); | |||
703 | } | |||
704 | SectionTable = ArrayRef<uint8_t>( | |||
705 | Buf - OutputSections.size() * sizeof(coff_section), Buf); | |||
706 | ||||
707 | if (OutputSymtab.empty()) | |||
708 | return; | |||
709 | ||||
710 | COFF->PointerToSymbolTable = PointerToSymbolTable; | |||
711 | uint32_t NumberOfSymbols = OutputSymtab.size(); | |||
712 | COFF->NumberOfSymbols = NumberOfSymbols; | |||
713 | auto *SymbolTable = reinterpret_cast<coff_symbol16 *>( | |||
714 | Buffer->getBufferStart() + COFF->PointerToSymbolTable); | |||
715 | for (size_t I = 0; I != NumberOfSymbols; ++I) | |||
716 | SymbolTable[I] = OutputSymtab[I]; | |||
717 | // Create the string table, it follows immediately after the symbol table. | |||
718 | // The first 4 bytes is length including itself. | |||
719 | Buf = reinterpret_cast<uint8_t *>(&SymbolTable[NumberOfSymbols]); | |||
720 | write32le(Buf, Strtab.size() + 4); | |||
721 | if (!Strtab.empty()) | |||
722 | memcpy(Buf + 4, Strtab.data(), Strtab.size()); | |||
723 | } | |||
724 | ||||
725 | void Writer::openFile(StringRef Path) { | |||
726 | Buffer = check( | |||
727 | FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable), | |||
728 | "failed to open " + Path); | |||
729 | } | |||
730 | ||||
731 | void Writer::fixSafeSEHSymbols() { | |||
732 | if (!SEHTable) | |||
733 | return; | |||
734 | if (auto *T = dyn_cast<DefinedRelative>(Config->SEHTable->body())) | |||
735 | T->setRVA(SEHTable->getRVA()); | |||
736 | if (auto *C = dyn_cast<DefinedAbsolute>(Config->SEHCount->body())) | |||
737 | C->setVA(SEHTable->getSize() / 4); | |||
738 | } | |||
739 | ||||
740 | // Handles /section options to allow users to overwrite | |||
741 | // section attributes. | |||
742 | void Writer::setSectionPermissions() { | |||
743 | for (auto &P : Config->Section) { | |||
744 | StringRef Name = P.first; | |||
745 | uint32_t Perm = P.second; | |||
746 | if (auto *Sec = findSection(Name)) | |||
747 | Sec->setPermissions(Perm); | |||
748 | } | |||
749 | } | |||
750 | ||||
751 | // Write section contents to a mmap'ed file. | |||
752 | void Writer::writeSections() { | |||
753 | uint8_t *Buf = Buffer->getBufferStart(); | |||
754 | for (OutputSection *Sec : OutputSections) { | |||
755 | uint8_t *SecBuf = Buf + Sec->getFileOff(); | |||
756 | // Fill gaps between functions in .text with INT3 instructions | |||
757 | // instead of leaving as NUL bytes (which can be interpreted as | |||
758 | // ADD instructions). | |||
759 | if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE) | |||
760 | memset(SecBuf, 0xCC, Sec->getRawSize()); | |||
761 | for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(), | |||
762 | [&](Chunk *C) { C->writeTo(SecBuf); }); | |||
763 | } | |||
764 | } | |||
765 | ||||
766 | // Sort .pdata section contents according to PE/COFF spec 5.5. | |||
767 | void Writer::sortExceptionTable() { | |||
768 | OutputSection *Sec = findSection(".pdata"); | |||
769 | if (!Sec) | |||
770 | return; | |||
771 | // We assume .pdata contains function table entries only. | |||
772 | uint8_t *Begin = Buffer->getBufferStart() + Sec->getFileOff(); | |||
773 | uint8_t *End = Begin + Sec->getVirtualSize(); | |||
774 | if (Config->Machine == AMD64) { | |||
775 | struct Entry { ulittle32_t Begin, End, Unwind; }; | |||
776 | sort(parallel::par, (Entry *)Begin, (Entry *)End, | |||
777 | [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); | |||
778 | return; | |||
779 | } | |||
780 | if (Config->Machine == ARMNT) { | |||
781 | struct Entry { ulittle32_t Begin, Unwind; }; | |||
782 | sort(parallel::par, (Entry *)Begin, (Entry *)End, | |||
783 | [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; }); | |||
784 | return; | |||
785 | } | |||
786 | errs() << "warning: don't know how to handle .pdata.\n"; | |||
787 | } | |||
788 | ||||
789 | // Backfill the CVSignature in a PDB70 Debug Record. This backfilling allows us | |||
790 | // to get reproducible builds. | |||
791 | void Writer::writeBuildId() { | |||
792 | // There is nothing to backfill if BuildId was not setup. | |||
793 | if (BuildId == nullptr) | |||
794 | return; | |||
795 | ||||
796 | MD5 Hash; | |||
797 | MD5::MD5Result Res; | |||
798 | ||||
799 | Hash.update(ArrayRef<uint8_t>{Buffer->getBufferStart(), | |||
800 | Buffer->getBufferEnd()}); | |||
801 | Hash.final(Res); | |||
802 | ||||
803 | assert(BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 &&((BuildId->DI->Signature.CVSignature == OMF::Signature:: PDB70 && "only PDB 7.0 is supported") ? static_cast< void> (0) : __assert_fail ("BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 && \"only PDB 7.0 is supported\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 804, __PRETTY_FUNCTION__)) | |||
804 | "only PDB 7.0 is supported")((BuildId->DI->Signature.CVSignature == OMF::Signature:: PDB70 && "only PDB 7.0 is supported") ? static_cast< void> (0) : __assert_fail ("BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 && \"only PDB 7.0 is supported\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 804, __PRETTY_FUNCTION__)); | |||
805 | assert(sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) &&((sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) && "signature size mismatch") ? static_cast<void> (0) : __assert_fail ("sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) && \"signature size mismatch\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 806, __PRETTY_FUNCTION__)) | |||
806 | "signature size mismatch")((sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) && "signature size mismatch") ? static_cast<void> (0) : __assert_fail ("sizeof(Res) == sizeof(BuildId->DI->PDB70.Signature) && \"signature size mismatch\"" , "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 806, __PRETTY_FUNCTION__)); | |||
807 | memcpy(BuildId->DI->PDB70.Signature, Res.Bytes.data(), | |||
808 | sizeof(codeview::PDB70DebugInfo::Signature)); | |||
809 | // TODO(compnerd) track the Age | |||
810 | BuildId->DI->PDB70.Age = 1; | |||
811 | } | |||
812 | ||||
813 | OutputSection *Writer::findSection(StringRef Name) { | |||
814 | for (OutputSection *Sec : OutputSections) | |||
815 | if (Sec->getName() == Name) | |||
816 | return Sec; | |||
817 | return nullptr; | |||
818 | } | |||
819 | ||||
820 | uint32_t Writer::getSizeOfInitializedData() { | |||
821 | uint32_t Res = 0; | |||
822 | for (OutputSection *S : OutputSections) | |||
823 | if (S->getPermissions() & IMAGE_SCN_CNT_INITIALIZED_DATA) | |||
824 | Res += S->getRawSize(); | |||
825 | return Res; | |||
826 | } | |||
827 | ||||
828 | // Returns an existing section or create a new one if not found. | |||
829 | OutputSection *Writer::createSection(StringRef Name) { | |||
830 | if (auto *Sec = findSection(Name)) | |||
831 | return Sec; | |||
832 | const auto DATA = IMAGE_SCN_CNT_INITIALIZED_DATA; | |||
833 | const auto BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA; | |||
834 | const auto CODE = IMAGE_SCN_CNT_CODE; | |||
835 | const auto DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE; | |||
836 | const auto R = IMAGE_SCN_MEM_READ; | |||
837 | const auto W = IMAGE_SCN_MEM_WRITE; | |||
838 | const auto X = IMAGE_SCN_MEM_EXECUTE; | |||
839 | uint32_t Perms = StringSwitch<uint32_t>(Name) | |||
840 | .Case(".bss", BSS | R | W) | |||
841 | .Case(".data", DATA | R | W) | |||
842 | .Cases(".didat", ".edata", ".idata", ".rdata", DATA | R) | |||
843 | .Case(".reloc", DATA | DISCARDABLE | R) | |||
844 | .Case(".text", CODE | R | X) | |||
845 | .Default(0); | |||
846 | if (!Perms) | |||
847 | llvm_unreachable("unknown section name")::llvm::llvm_unreachable_internal("unknown section name", "/tmp/buildd/llvm-toolchain-snapshot-5.0~svn303373/tools/lld/COFF/Writer.cpp" , 847); | |||
848 | auto Sec = make<OutputSection>(Name); | |||
849 | Sec->addPermissions(Perms); | |||
850 | OutputSections.push_back(Sec); | |||
851 | return Sec; | |||
852 | } | |||
853 | ||||
854 | // Dest is .reloc section. Add contents to that section. | |||
855 | void Writer::addBaserels(OutputSection *Dest) { | |||
856 | std::vector<Baserel> V; | |||
857 | for (OutputSection *Sec : OutputSections) { | |||
858 | if (Sec == Dest) | |||
859 | continue; | |||
860 | // Collect all locations for base relocations. | |||
861 | for (Chunk *C : Sec->getChunks()) | |||
862 | C->getBaserels(&V); | |||
863 | // Add the addresses to .reloc section. | |||
864 | if (!V.empty()) | |||
865 | addBaserelBlocks(Dest, V); | |||
866 | V.clear(); | |||
867 | } | |||
868 | } | |||
869 | ||||
870 | // Add addresses to .reloc section. Note that addresses are grouped by page. | |||
871 | void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) { | |||
872 | const uint32_t Mask = ~uint32_t(PageSize - 1); | |||
873 | uint32_t Page = V[0].RVA & Mask; | |||
874 | size_t I = 0, J = 1; | |||
875 | for (size_t E = V.size(); J < E; ++J) { | |||
876 | uint32_t P = V[J].RVA & Mask; | |||
877 | if (P == Page) | |||
878 | continue; | |||
879 | Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); | |||
880 | I = J; | |||
881 | Page = P; | |||
882 | } | |||
883 | if (I == J) | |||
884 | return; | |||
885 | Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J)); | |||
886 | } |