xref: /llvm-project-15.0.7/lld/COFF/Chunks.cpp (revision f2d571c8)
1 //===- Chunks.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 "Chunks.h"
11 #include "Error.h"
12 #include "InputFiles.h"
13 #include "Symbols.h"
14 #include "Writer.h"
15 #include "llvm/ADT/Twine.h"
16 #include "llvm/BinaryFormat/COFF.h"
17 #include "llvm/Object/COFF.h"
18 #include "llvm/Support/Debug.h"
19 #include "llvm/Support/Endian.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <algorithm>
22 
23 using namespace llvm;
24 using namespace llvm::object;
25 using namespace llvm::support::endian;
26 using namespace llvm::COFF;
27 using llvm::support::ulittle32_t;
28 
29 namespace lld {
30 namespace coff {
31 
32 SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
33     : Chunk(SectionKind), Repl(this), Header(H), File(F),
34       Relocs(File->getCOFFObj()->getRelocations(Header)),
35       NumRelocs(std::distance(Relocs.begin(), Relocs.end())) {
36   // Initialize SectionName.
37   File->getCOFFObj()->getSectionName(Header, SectionName);
38 
39   Align = Header->getAlignment();
40 
41   // Chunks may be discarded during comdat merging.
42   Discarded = false;
43 
44   // If linker GC is disabled, every chunk starts out alive.  If linker GC is
45   // enabled, treat non-comdat sections as roots. Generally optimized object
46   // files will be built with -ffunction-sections or /Gy, so most things worth
47   // stripping will be in a comdat.
48   Live = !Config->DoGC || !isCOMDAT();
49 }
50 
51 static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
52 static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
53 static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
54 static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
55 
56 static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
57                         OutputSection *OS, uint64_t S) {
58   if (!OS) {
59     if (Sec->isCodeView())
60       return;
61     fatal("SECREL relocation cannot be applied to absolute symbols");
62   }
63   uint64_t SecRel = S - OS->getRVA();
64   assert(SecRel < INT32_MAX && "overflow in SECREL relocation");
65   add32(Off, SecRel);
66 }
67 
68 static void applySecIdx(uint8_t *Off, OutputSection *OS) {
69   // If we have no output section, this must be an absolute symbol. Use the
70   // sentinel absolute symbol section index.
71   uint16_t SecIdx = OS ? OS->SectionIndex : DefinedAbsolute::OutputSectionIndex;
72   add16(Off, SecIdx);
73 }
74 
75 void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
76                                uint64_t S, uint64_t P) const {
77   switch (Type) {
78   case IMAGE_REL_AMD64_ADDR32:   add32(Off, S + Config->ImageBase); break;
79   case IMAGE_REL_AMD64_ADDR64:   add64(Off, S + Config->ImageBase); break;
80   case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
81   case IMAGE_REL_AMD64_REL32:    add32(Off, S - P - 4); break;
82   case IMAGE_REL_AMD64_REL32_1:  add32(Off, S - P - 5); break;
83   case IMAGE_REL_AMD64_REL32_2:  add32(Off, S - P - 6); break;
84   case IMAGE_REL_AMD64_REL32_3:  add32(Off, S - P - 7); break;
85   case IMAGE_REL_AMD64_REL32_4:  add32(Off, S - P - 8); break;
86   case IMAGE_REL_AMD64_REL32_5:  add32(Off, S - P - 9); break;
87   case IMAGE_REL_AMD64_SECTION:  applySecIdx(Off, OS); break;
88   case IMAGE_REL_AMD64_SECREL:   applySecRel(this, Off, OS, S); break;
89   default:
90     fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
91   }
92 }
93 
94 void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
95                                uint64_t S, uint64_t P) const {
96   switch (Type) {
97   case IMAGE_REL_I386_ABSOLUTE: break;
98   case IMAGE_REL_I386_DIR32:    add32(Off, S + Config->ImageBase); break;
99   case IMAGE_REL_I386_DIR32NB:  add32(Off, S); break;
100   case IMAGE_REL_I386_REL32:    add32(Off, S - P - 4); break;
101   case IMAGE_REL_I386_SECTION:  applySecIdx(Off, OS); break;
102   case IMAGE_REL_I386_SECREL:   applySecRel(this, Off, OS, S); break;
103   default:
104     fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
105   }
106 }
107 
108 static void applyMOV(uint8_t *Off, uint16_t V) {
109   write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
110   write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
111 }
112 
113 static uint16_t readMOV(uint8_t *Off) {
114   uint16_t Opcode1 = read16le(Off);
115   uint16_t Opcode2 = read16le(Off + 2);
116   uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700);
117   Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12);
118   return Imm;
119 }
120 
121 static void applyMOV32T(uint8_t *Off, uint32_t V) {
122   uint16_t ImmW = readMOV(Off);     // read MOVW operand
123   uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
124   uint32_t Imm = ImmW | (ImmT << 16);
125   V += Imm;                         // add the immediate offset
126   applyMOV(Off, V);           // set MOVW operand
127   applyMOV(Off + 4, V >> 16); // set MOVT operand
128 }
129 
130 static void applyBranch20T(uint8_t *Off, int32_t V) {
131   uint32_t S = V < 0 ? 1 : 0;
132   uint32_t J1 = (V >> 19) & 1;
133   uint32_t J2 = (V >> 18) & 1;
134   or16(Off, (S << 10) | ((V >> 12) & 0x3f));
135   or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
136 }
137 
138 static void applyBranch24T(uint8_t *Off, int32_t V) {
139   if (!isInt<25>(V))
140     fatal("relocation out of range");
141   uint32_t S = V < 0 ? 1 : 0;
142   uint32_t J1 = ((~V >> 23) & 1) ^ S;
143   uint32_t J2 = ((~V >> 22) & 1) ^ S;
144   or16(Off, (S << 10) | ((V >> 12) & 0x3ff));
145   // Clear out the J1 and J2 bits which may be set.
146   write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
147 }
148 
149 void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
150                                uint64_t S, uint64_t P) const {
151   // Pointer to thumb code must have the LSB set.
152   uint64_t SX = S;
153   if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
154     SX |= 1;
155   switch (Type) {
156   case IMAGE_REL_ARM_ADDR32:    add32(Off, SX + Config->ImageBase); break;
157   case IMAGE_REL_ARM_ADDR32NB:  add32(Off, SX); break;
158   case IMAGE_REL_ARM_MOV32T:    applyMOV32T(Off, SX + Config->ImageBase); break;
159   case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break;
160   case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break;
161   case IMAGE_REL_ARM_BLX23T:    applyBranch24T(Off, SX - P - 4); break;
162   case IMAGE_REL_ARM_SECTION:   applySecIdx(Off, OS); break;
163   case IMAGE_REL_ARM_SECREL:    applySecRel(this, Off, OS, S); break;
164   default:
165     fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
166   }
167 }
168 
169 void SectionChunk::writeTo(uint8_t *Buf) const {
170   if (!hasData())
171     return;
172   // Copy section contents from source object file to output file.
173   ArrayRef<uint8_t> A = getContents();
174   memcpy(Buf + OutputSectionOff, A.data(), A.size());
175 
176   // Apply relocations.
177   for (const coff_relocation &Rel : Relocs) {
178     uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
179 
180     // Get the output section of the symbol for this relocation.  The output
181     // section is needed to compute SECREL and SECTION relocations used in debug
182     // info.
183     SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
184     Defined *Sym = cast<Defined>(Body);
185     Chunk *C = Sym->getChunk();
186     OutputSection *OS = C ? C->getOutputSection() : nullptr;
187 
188     // Only absolute and __ImageBase symbols lack an output section. For any
189     // other symbol, this indicates that the chunk was discarded.  Normally
190     // relocations against discarded sections are an error.  However, debug info
191     // sections are not GC roots and can end up with these kinds of relocations.
192     // Skip these relocations.
193     if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
194       if (isCodeView())
195         continue;
196       fatal("relocation against symbol in discarded section: " +
197             Sym->getName());
198     }
199     uint64_t S = Sym->getRVA();
200 
201     // Compute the RVA of the relocation for relative relocations.
202     uint64_t P = RVA + Rel.VirtualAddress;
203     switch (Config->Machine) {
204     case AMD64:
205       applyRelX64(Off, Rel.Type, OS, S, P);
206       break;
207     case I386:
208       applyRelX86(Off, Rel.Type, OS, S, P);
209       break;
210     case ARMNT:
211       applyRelARM(Off, Rel.Type, OS, S, P);
212       break;
213     default:
214       llvm_unreachable("unknown machine type");
215     }
216   }
217 }
218 
219 void SectionChunk::addAssociative(SectionChunk *Child) {
220   AssocChildren.push_back(Child);
221 }
222 
223 static uint8_t getBaserelType(const coff_relocation &Rel) {
224   switch (Config->Machine) {
225   case AMD64:
226     if (Rel.Type == IMAGE_REL_AMD64_ADDR64)
227       return IMAGE_REL_BASED_DIR64;
228     return IMAGE_REL_BASED_ABSOLUTE;
229   case I386:
230     if (Rel.Type == IMAGE_REL_I386_DIR32)
231       return IMAGE_REL_BASED_HIGHLOW;
232     return IMAGE_REL_BASED_ABSOLUTE;
233   case ARMNT:
234     if (Rel.Type == IMAGE_REL_ARM_ADDR32)
235       return IMAGE_REL_BASED_HIGHLOW;
236     if (Rel.Type == IMAGE_REL_ARM_MOV32T)
237       return IMAGE_REL_BASED_ARM_MOV32T;
238     return IMAGE_REL_BASED_ABSOLUTE;
239   default:
240     llvm_unreachable("unknown machine type");
241   }
242 }
243 
244 // Windows-specific.
245 // Collect all locations that contain absolute addresses, which need to be
246 // fixed by the loader if load-time relocation is needed.
247 // Only called when base relocation is enabled.
248 void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
249   for (const coff_relocation &Rel : Relocs) {
250     uint8_t Ty = getBaserelType(Rel);
251     if (Ty == IMAGE_REL_BASED_ABSOLUTE)
252       continue;
253     SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
254     if (isa<DefinedAbsolute>(Body))
255       continue;
256     Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
257   }
258 }
259 
260 bool SectionChunk::hasData() const {
261   return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
262 }
263 
264 uint32_t SectionChunk::getPermissions() const {
265   return Header->Characteristics & PermMask;
266 }
267 
268 bool SectionChunk::isCOMDAT() const {
269   return Header->Characteristics & IMAGE_SCN_LNK_COMDAT;
270 }
271 
272 void SectionChunk::printDiscardedMessage() const {
273   // Removed by dead-stripping. If it's removed by ICF, ICF already
274   // printed out the name, so don't repeat that here.
275   if (Sym && this == Repl) {
276     if (Discarded)
277       message("Discarded comdat symbol " + Sym->getName());
278     else if (!Live)
279       message("Discarded " + Sym->getName());
280   }
281 }
282 
283 StringRef SectionChunk::getDebugName() {
284   if (Sym)
285     return Sym->getName();
286   return "";
287 }
288 
289 ArrayRef<uint8_t> SectionChunk::getContents() const {
290   ArrayRef<uint8_t> A;
291   File->getCOFFObj()->getSectionContents(Header, A);
292   return A;
293 }
294 
295 void SectionChunk::replace(SectionChunk *Other) {
296   Other->Repl = Repl;
297   Other->Live = false;
298 }
299 
300 CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
301   // Common symbols are aligned on natural boundaries up to 32 bytes.
302   // This is what MSVC link.exe does.
303   Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
304 }
305 
306 uint32_t CommonChunk::getPermissions() const {
307   return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
308          IMAGE_SCN_MEM_WRITE;
309 }
310 
311 void StringChunk::writeTo(uint8_t *Buf) const {
312   memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
313 }
314 
315 ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
316   // Intel Optimization Manual says that all branch targets
317   // should be 16-byte aligned. MSVC linker does this too.
318   Align = 16;
319 }
320 
321 void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
322   memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
323   // The first two bytes is a JMP instruction. Fill its operand.
324   write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize());
325 }
326 
327 void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *Res) {
328   Res->emplace_back(getRVA() + 2);
329 }
330 
331 void ImportThunkChunkX86::writeTo(uint8_t *Buf) const {
332   memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
333   // The first two bytes is a JMP instruction. Fill its operand.
334   write32le(Buf + OutputSectionOff + 2,
335             ImpSymbol->getRVA() + Config->ImageBase);
336 }
337 
338 void ImportThunkChunkARM::getBaserels(std::vector<Baserel> *Res) {
339   Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T);
340 }
341 
342 void ImportThunkChunkARM::writeTo(uint8_t *Buf) const {
343   memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM));
344   // Fix mov.w and mov.t operands.
345   applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase);
346 }
347 
348 void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
349   Res->emplace_back(getRVA());
350 }
351 
352 size_t LocalImportChunk::getSize() const {
353   return Config->is64() ? 8 : 4;
354 }
355 
356 void LocalImportChunk::writeTo(uint8_t *Buf) const {
357   if (Config->is64()) {
358     write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
359   } else {
360     write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
361   }
362 }
363 
364 void SEHTableChunk::writeTo(uint8_t *Buf) const {
365   ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
366   size_t Cnt = 0;
367   for (Defined *D : Syms)
368     Begin[Cnt++] = D->getRVA();
369   std::sort(Begin, Begin + Cnt);
370 }
371 
372 // Windows-specific. This class represents a block in .reloc section.
373 // The format is described here.
374 //
375 // On Windows, each DLL is linked against a fixed base address and
376 // usually loaded to that address. However, if there's already another
377 // DLL that overlaps, the loader has to relocate it. To do that, DLLs
378 // contain .reloc sections which contain offsets that need to be fixed
379 // up at runtime. If the loader finds that a DLL cannot be loaded to its
380 // desired base address, it loads it to somewhere else, and add <actual
381 // base address> - <desired base address> to each offset that is
382 // specified by the .reloc section. In ELF terms, .reloc sections
383 // contain relative relocations in REL format (as opposed to RELA.)
384 //
385 // This already significantly reduces the size of relocations compared
386 // to ELF .rel.dyn, but Windows does more to reduce it (probably because
387 // it was invented for PCs in the late '80s or early '90s.)  Offsets in
388 // .reloc are grouped by page where the page size is 12 bits, and
389 // offsets sharing the same page address are stored consecutively to
390 // represent them with less space. This is very similar to the page
391 // table which is grouped by (multiple stages of) pages.
392 //
393 // For example, let's say we have 0x00030, 0x00500, 0x00700, 0x00A00,
394 // 0x20004, and 0x20008 in a .reloc section for x64. The uppermost 4
395 // bits have a type IMAGE_REL_BASED_DIR64 or 0xA. In the section, they
396 // are represented like this:
397 //
398 //   0x00000  -- page address (4 bytes)
399 //   16       -- size of this block (4 bytes)
400 //     0xA030 -- entries (2 bytes each)
401 //     0xA500
402 //     0xA700
403 //     0xAA00
404 //   0x20000  -- page address (4 bytes)
405 //   12       -- size of this block (4 bytes)
406 //     0xA004 -- entries (2 bytes each)
407 //     0xA008
408 //
409 // Usually we have a lot of relocations for each page, so the number of
410 // bytes for one .reloc entry is close to 2 bytes on average.
411 BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) {
412   // Block header consists of 4 byte page RVA and 4 byte block size.
413   // Each entry is 2 byte. Last entry may be padding.
414   Data.resize(alignTo((End - Begin) * 2 + 8, 4));
415   uint8_t *P = Data.data();
416   write32le(P, Page);
417   write32le(P + 4, Data.size());
418   P += 8;
419   for (Baserel *I = Begin; I != End; ++I) {
420     write16le(P, (I->Type << 12) | (I->RVA - Page));
421     P += 2;
422   }
423 }
424 
425 void BaserelChunk::writeTo(uint8_t *Buf) const {
426   memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
427 }
428 
429 uint8_t Baserel::getDefaultType() {
430   switch (Config->Machine) {
431   case AMD64:
432     return IMAGE_REL_BASED_DIR64;
433   case I386:
434     return IMAGE_REL_BASED_HIGHLOW;
435   default:
436     llvm_unreachable("unknown machine type");
437   }
438 }
439 
440 } // namespace coff
441 } // namespace lld
442