xref: /llvm-project-15.0.7/lld/COFF/Writer.cpp (revision 95213c31)
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 "Config.h"
11 #include "Writer.h"
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/Support/Debug.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/FileOutputBuffer.h"
18 #include "llvm/Support/raw_ostream.h"
19 #include <algorithm>
20 #include <cstdio>
21 #include <functional>
22 #include <map>
23 #include <utility>
24 
25 using namespace llvm;
26 using namespace llvm::COFF;
27 using namespace llvm::object;
28 using namespace llvm::support;
29 using namespace llvm::support::endian;
30 
31 static const int PageSize = 4096;
32 static const int FileAlignment = 512;
33 static const int SectionAlignment = 4096;
34 static const int DOSStubSize = 64;
35 static const int NumberfOfDataDirectory = 16;
36 
37 namespace lld {
38 namespace coff {
39 
40 // The main function of the writer.
41 std::error_code Writer::write(StringRef OutputPath) {
42   markLive();
43   createSections();
44   createImportTables();
45   assignAddresses();
46   removeEmptySections();
47   if (auto EC = openFile(OutputPath))
48     return EC;
49   writeHeader();
50   writeSections();
51   return Buffer->commit();
52 }
53 
54 void OutputSection::setRVA(uint64_t RVA) {
55   Header.VirtualAddress = RVA;
56   for (Chunk *C : Chunks)
57     C->setRVA(C->getRVA() + RVA);
58 }
59 
60 void OutputSection::setFileOffset(uint64_t Off) {
61   // If a section has no actual data (i.e. BSS section), we want to
62   // set 0 to its PointerToRawData. Otherwise the output is rejected
63   // by the loader.
64   if (Header.SizeOfRawData == 0)
65     return;
66   Header.PointerToRawData = Off;
67   for (Chunk *C : Chunks)
68     C->setFileOff(C->getFileOff() + Off);
69 }
70 
71 void OutputSection::addChunk(Chunk *C) {
72   Chunks.push_back(C);
73   uint64_t Off = Header.VirtualSize;
74   Off = RoundUpToAlignment(Off, C->getAlign());
75   C->setRVA(Off);
76   C->setFileOff(Off);
77   Off += C->getSize();
78   Header.VirtualSize = Off;
79   if (C->hasData())
80     Header.SizeOfRawData = RoundUpToAlignment(Off, FileAlignment);
81 }
82 
83 void OutputSection::addPermissions(uint32_t C) {
84   Header.Characteristics = Header.Characteristics | (C & PermMask);
85 }
86 
87 // Write the section header to a given buffer.
88 void OutputSection::writeHeaderTo(uint8_t *Buf) {
89   auto *Hdr = reinterpret_cast<coff_section *>(Buf);
90   *Hdr = Header;
91   if (StringTableOff) {
92     // If name is too long, write offset into the string table as a name.
93     sprintf(Hdr->Name, "/%d", StringTableOff);
94   } else {
95     assert(Name.size() <= COFF::NameSize);
96     strncpy(Hdr->Name, Name.data(), Name.size());
97   }
98 }
99 
100 // Set live bit on for each reachable chunk. Unmarked (unreachable)
101 // COMDAT chunks will be ignored in the next step, so that they don't
102 // come to the final output file.
103 void Writer::markLive() {
104   if (!Config->DoGC)
105     return;
106   for (StringRef Name : Config->GCRoots)
107     cast<Defined>(Symtab->find(Name))->markLive();
108   for (Chunk *C : Symtab->getChunks())
109     if (C->isRoot())
110       C->markLive();
111 }
112 
113 // Create output section objects and add them to OutputSections.
114 void Writer::createSections() {
115   // First, bin chunks by name.
116   std::map<StringRef, std::vector<Chunk *>> Map;
117   for (Chunk *C : Symtab->getChunks()) {
118     if (Config->DoGC && !C->isLive()) {
119       if (Config->Verbose)
120         C->printDiscardedMessage();
121       continue;
122     }
123     Map[C->getSectionName()].push_back(C);
124   }
125 
126   // Then create an OutputSection for each section.
127   // '$' and all following characters in input section names are
128   // discarded when determining output section. So, .text$foo
129   // contributes to .text, for example. See PE/COFF spec 3.2.
130   StringRef Name = Map.begin()->first.split('$').first;
131   auto Sec = new (CAlloc.Allocate()) OutputSection(Name, 0);
132   OutputSections.push_back(Sec);
133   for (auto &P : Map) {
134     StringRef SectionName = P.first;
135     StringRef Base = SectionName.split('$').first;
136     if (Base != Sec->getName()) {
137       size_t SectIdx = OutputSections.size();
138       Sec = new (CAlloc.Allocate()) OutputSection(Base, SectIdx);
139       OutputSections.push_back(Sec);
140     }
141     std::vector<Chunk *> &Chunks = P.second;
142     for (Chunk *C : Chunks) {
143       C->setOutputSection(Sec);
144       Sec->addChunk(C);
145       Sec->addPermissions(C->getPermissions());
146     }
147   }
148 }
149 
150 // Create .idata section for the DLL-imported symbol table.
151 // The format of this section is inherently Windows-specific.
152 // IdataContents class abstracted away the details for us,
153 // so we just let it create chunks and add them to the section.
154 void Writer::createImportTables() {
155   if (Symtab->ImportFiles.empty())
156     return;
157   OutputSection *Text = createSection(".text");
158   Idata.reset(new IdataContents());
159   for (std::unique_ptr<ImportFile> &File : Symtab->ImportFiles) {
160     for (SymbolBody *Body : File->getSymbols()) {
161       if (auto *Import = dyn_cast<DefinedImportData>(Body)) {
162         Idata->add(Import);
163         continue;
164       }
165       // Linker-created function thunks for DLL symbols are added to
166       // .text section.
167       Text->addChunk(cast<DefinedImportThunk>(Body)->getChunk());
168     }
169   }
170   OutputSection *Sec = createSection(".idata");
171   for (Chunk *C : Idata->getChunks())
172     Sec->addChunk(C);
173 }
174 
175 // The Windows loader doesn't seem to like empty sections,
176 // so we remove them if any.
177 void Writer::removeEmptySections() {
178   auto IsEmpty = [](OutputSection *S) { return S->getVirtualSize() == 0; };
179   OutputSections.erase(
180       std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty),
181       OutputSections.end());
182 }
183 
184 // Visits all sections to assign incremental, non-overlapping RVAs and
185 // file offsets.
186 void Writer::assignAddresses() {
187   SizeOfHeaders = RoundUpToAlignment(
188       DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
189       sizeof(pe32plus_header) +
190       sizeof(data_directory) * NumberfOfDataDirectory +
191       sizeof(coff_section) * OutputSections.size(), PageSize);
192   uint64_t RVA = 0x1000; // The first page is kept unmapped.
193   uint64_t FileOff = SizeOfHeaders;
194   for (OutputSection *Sec : OutputSections) {
195     Sec->setRVA(RVA);
196     Sec->setFileOffset(FileOff);
197     RVA += RoundUpToAlignment(Sec->getVirtualSize(), PageSize);
198     FileOff += RoundUpToAlignment(Sec->getRawSize(), FileAlignment);
199   }
200   SizeOfImage = SizeOfHeaders + RoundUpToAlignment(RVA - 0x1000, PageSize);
201   FileSize = SizeOfHeaders +
202              RoundUpToAlignment(FileOff - SizeOfHeaders, FileAlignment);
203 }
204 
205 static MachineTypes
206 inferMachineType(std::vector<std::unique_ptr<ObjectFile>> &ObjectFiles) {
207   for (std::unique_ptr<ObjectFile> &File : ObjectFiles) {
208     // Try to infer machine type from the magic byte of the object file.
209     auto MT = static_cast<MachineTypes>(File->getCOFFObj()->getMachine());
210     if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
211       return MT;
212   }
213   return IMAGE_FILE_MACHINE_UNKNOWN;
214 }
215 
216 void Writer::writeHeader() {
217   // Write DOS stub
218   uint8_t *Buf = Buffer->getBufferStart();
219   auto *DOS = reinterpret_cast<dos_header *>(Buf);
220   Buf += DOSStubSize;
221   DOS->Magic[0] = 'M';
222   DOS->Magic[1] = 'Z';
223   DOS->AddressOfRelocationTable = sizeof(dos_header);
224   DOS->AddressOfNewExeHeader = DOSStubSize;
225 
226   // Write PE magic
227   memcpy(Buf, PEMagic, sizeof(PEMagic));
228   Buf += sizeof(PEMagic);
229 
230   // Determine machine type, infer if needed. TODO: diagnose conflicts.
231   MachineTypes MachineType = Config->MachineType;
232   if (MachineType == IMAGE_FILE_MACHINE_UNKNOWN)
233     MachineType = inferMachineType(Symtab->ObjectFiles);
234 
235   // Write COFF header
236   auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
237   Buf += sizeof(*COFF);
238   COFF->Machine = MachineType;
239   COFF->NumberOfSections = OutputSections.size();
240   COFF->Characteristics =
241       (IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_RELOCS_STRIPPED |
242        IMAGE_FILE_LARGE_ADDRESS_AWARE);
243   COFF->SizeOfOptionalHeader =
244       sizeof(pe32plus_header) + sizeof(data_directory) * NumberfOfDataDirectory;
245 
246   // Write PE header
247   auto *PE = reinterpret_cast<pe32plus_header *>(Buf);
248   Buf += sizeof(*PE);
249   PE->Magic = PE32Header::PE32_PLUS;
250   PE->ImageBase = Config->ImageBase;
251   PE->SectionAlignment = SectionAlignment;
252   PE->FileAlignment = FileAlignment;
253   PE->MajorImageVersion = Config->MajorImageVersion;
254   PE->MinorImageVersion = Config->MinorImageVersion;
255   PE->MajorOperatingSystemVersion = Config->MajorOSVersion;
256   PE->MinorOperatingSystemVersion = Config->MinorOSVersion;
257   PE->MajorSubsystemVersion = Config->MajorOSVersion;
258   PE->MinorSubsystemVersion = Config->MinorOSVersion;
259   PE->Subsystem = Config->Subsystem;
260   PE->SizeOfImage = SizeOfImage;
261   PE->SizeOfHeaders = SizeOfHeaders;
262   Defined *Entry = cast<Defined>(Symtab->find(Config->EntryName));
263   PE->AddressOfEntryPoint = Entry->getRVA();
264   PE->SizeOfStackReserve = Config->StackReserve;
265   PE->SizeOfStackCommit = Config->StackCommit;
266   PE->SizeOfHeapReserve = Config->HeapReserve;
267   PE->SizeOfHeapCommit = Config->HeapCommit;
268   PE->NumberOfRvaAndSize = NumberfOfDataDirectory;
269   if (OutputSection *Text = findSection(".text")) {
270     PE->BaseOfCode = Text->getRVA();
271     PE->SizeOfCode = Text->getRawSize();
272   }
273   PE->SizeOfInitializedData = getSizeOfInitializedData();
274 
275   // Write data directory
276   auto *DataDirectory = reinterpret_cast<data_directory *>(Buf);
277   Buf += sizeof(*DataDirectory) * NumberfOfDataDirectory;
278   if (Idata) {
279     DataDirectory[IMPORT_TABLE].RelativeVirtualAddress = Idata->getDirRVA();
280     DataDirectory[IMPORT_TABLE].Size = Idata->getDirSize();
281     DataDirectory[IAT].RelativeVirtualAddress = Idata->getIATRVA();
282     DataDirectory[IAT].Size = Idata->getIATSize();
283   }
284 
285   // Section table
286   // Name field in the section table is 8 byte long. Longer names need
287   // to be written to the string table. First, construct string table.
288   std::vector<char> Strtab;
289   for (OutputSection *Sec : OutputSections) {
290     StringRef Name = Sec->getName();
291     if (Name.size() <= COFF::NameSize)
292       continue;
293     Sec->setStringTableOff(Strtab.size() + 4); // +4 for the size field
294     Strtab.insert(Strtab.end(), Name.begin(), Name.end());
295     Strtab.push_back('\0');
296   }
297 
298   // Write section table
299   for (OutputSection *Sec : OutputSections) {
300     Sec->writeHeaderTo(Buf);
301     Buf += sizeof(coff_section);
302   }
303 
304   // Write string table if we need to. The string table immediately
305   // follows the symbol table, so we create a dummy symbol table
306   // first. The symbol table contains one dummy symbol.
307   if (Strtab.empty())
308     return;
309   COFF->PointerToSymbolTable = Buf - Buffer->getBufferStart();
310   COFF->NumberOfSymbols = 1;
311   auto *SymbolTable = reinterpret_cast<coff_symbol16 *>(Buf);
312   Buf += sizeof(*SymbolTable);
313   // (Set 4 to make the dummy symbol point to the first string table
314   // entry, so that tools to print out symbols don't read NUL bytes.)
315   SymbolTable->Name.Offset.Offset = 4;
316   // Then create the symbol table. The first 4 bytes is length
317   // including itself.
318   write32le(Buf, Strtab.size() + 4);
319   memcpy(Buf + 4, Strtab.data(), Strtab.size());
320 }
321 
322 std::error_code Writer::openFile(StringRef Path) {
323   if (auto EC = FileOutputBuffer::create(Path, FileSize, Buffer,
324                                          FileOutputBuffer::F_executable)) {
325     llvm::errs() << "failed to open " << Path << ": " << EC.message() << "\n";
326     return EC;
327   }
328   return std::error_code();
329 }
330 
331 // Write section contents to a mmap'ed file.
332 void Writer::writeSections() {
333   uint8_t *Buf = Buffer->getBufferStart();
334   for (OutputSection *Sec : OutputSections) {
335     // Fill gaps between functions in .text with INT3 instructions
336     // instead of leaving as NUL bytes (which can be interpreted as
337     // ADD instructions).
338     if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE)
339       memset(Buf + Sec->getFileOff(), 0xCC, Sec->getRawSize());
340     for (Chunk *C : Sec->getChunks())
341       C->writeTo(Buf);
342   }
343 }
344 
345 OutputSection *Writer::findSection(StringRef Name) {
346   for (OutputSection *Sec : OutputSections)
347     if (Sec->getName() == Name)
348       return Sec;
349   return nullptr;
350 }
351 
352 uint32_t Writer::getSizeOfInitializedData() {
353   uint32_t Res = 0;
354   for (OutputSection *S : OutputSections)
355     if (S->getPermissions() & IMAGE_SCN_CNT_INITIALIZED_DATA)
356       Res += S->getRawSize();
357   return Res;
358 }
359 
360 // Returns an existing section or create a new one if not found.
361 OutputSection *Writer::createSection(StringRef Name) {
362   if (auto *Sec = findSection(Name))
363     return Sec;
364   const auto DATA = IMAGE_SCN_CNT_INITIALIZED_DATA;
365   const auto BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
366   const auto CODE = IMAGE_SCN_CNT_CODE;
367   const auto R = IMAGE_SCN_MEM_READ;
368   const auto W = IMAGE_SCN_MEM_WRITE;
369   const auto E = IMAGE_SCN_MEM_EXECUTE;
370   uint32_t Perms = StringSwitch<uint32_t>(Name)
371                        .Case(".bss", BSS | R | W)
372                        .Case(".data", DATA | R | W)
373                        .Case(".didat", DATA | R)
374                        .Case(".idata", DATA | R)
375                        .Case(".rdata", DATA | R)
376                        .Case(".text", CODE | R | E)
377                        .Default(0);
378   if (!Perms)
379     llvm_unreachable("unknown section name");
380   size_t SectIdx = OutputSections.size();
381   auto Sec = new (CAlloc.Allocate()) OutputSection(Name, SectIdx);
382   Sec->addPermissions(Perms);
383   OutputSections.push_back(Sec);
384   return Sec;
385 }
386 
387 } // namespace coff
388 } // namespace lld
389