xref: /llvm-project-15.0.7/lld/COFF/Chunks.cpp (revision ccbe567f)
1 //===- Chunks.cpp ---------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "Chunks.h"
10 #include "InputFiles.h"
11 #include "Symbols.h"
12 #include "Writer.h"
13 #include "SymbolTable.h"
14 #include "lld/Common/ErrorHandler.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(ObjFile *F, const coff_section *H)
33     : Chunk(SectionKind), File(F), Header(H),
34       Relocs(File->getCOFFObj()->getRelocations(Header)), Repl(this) {
35   // Initialize SectionName.
36   File->getCOFFObj()->getSectionName(Header, SectionName);
37 
38   Alignment = Header->getAlignment();
39 
40   // If linker GC is disabled, every chunk starts out alive.  If linker GC is
41   // enabled, treat non-comdat sections as roots. Generally optimized object
42   // files will be built with -ffunction-sections or /Gy, so most things worth
43   // stripping will be in a comdat.
44   Live = !Config->DoGC || !isCOMDAT();
45 }
46 
47 // SectionChunk is one of the most frequently allocated classes, so it is
48 // important to keep it as compact as possible. As of this writing, the number
49 // below is the size of this class on x64 platforms.
50 static_assert(sizeof(SectionChunk) <= 128, "SectionChunk grew unexpectedly");
51 
52 static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
53 static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
54 static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
55 static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
56 static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); }
57 
58 // Verify that given sections are appropriate targets for SECREL
59 // relocations. This check is relaxed because unfortunately debug
60 // sections have section-relative relocations against absolute symbols.
61 static bool checkSecRel(const SectionChunk *Sec, OutputSection *OS) {
62   if (OS)
63     return true;
64   if (Sec->isCodeView())
65     return false;
66   error("SECREL relocation cannot be applied to absolute symbols");
67   return false;
68 }
69 
70 static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
71                         OutputSection *OS, uint64_t S) {
72   if (!checkSecRel(Sec, OS))
73     return;
74   uint64_t SecRel = S - OS->getRVA();
75   if (SecRel > UINT32_MAX) {
76     error("overflow in SECREL relocation in section: " + Sec->getSectionName());
77     return;
78   }
79   add32(Off, SecRel);
80 }
81 
82 static void applySecIdx(uint8_t *Off, OutputSection *OS) {
83   // Absolute symbol doesn't have section index, but section index relocation
84   // against absolute symbol should be resolved to one plus the last output
85   // section index. This is required for compatibility with MSVC.
86   if (OS)
87     add16(Off, OS->SectionIndex);
88   else
89     add16(Off, DefinedAbsolute::NumOutputSections + 1);
90 }
91 
92 void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
93                                uint64_t S, uint64_t P) const {
94   switch (Type) {
95   case IMAGE_REL_AMD64_ADDR32:   add32(Off, S + Config->ImageBase); break;
96   case IMAGE_REL_AMD64_ADDR64:   add64(Off, S + Config->ImageBase); break;
97   case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
98   case IMAGE_REL_AMD64_REL32:    add32(Off, S - P - 4); break;
99   case IMAGE_REL_AMD64_REL32_1:  add32(Off, S - P - 5); break;
100   case IMAGE_REL_AMD64_REL32_2:  add32(Off, S - P - 6); break;
101   case IMAGE_REL_AMD64_REL32_3:  add32(Off, S - P - 7); break;
102   case IMAGE_REL_AMD64_REL32_4:  add32(Off, S - P - 8); break;
103   case IMAGE_REL_AMD64_REL32_5:  add32(Off, S - P - 9); break;
104   case IMAGE_REL_AMD64_SECTION:  applySecIdx(Off, OS); break;
105   case IMAGE_REL_AMD64_SECREL:   applySecRel(this, Off, OS, S); break;
106   default:
107     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
108           toString(File));
109   }
110 }
111 
112 void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
113                                uint64_t S, uint64_t P) const {
114   switch (Type) {
115   case IMAGE_REL_I386_ABSOLUTE: break;
116   case IMAGE_REL_I386_DIR32:    add32(Off, S + Config->ImageBase); break;
117   case IMAGE_REL_I386_DIR32NB:  add32(Off, S); break;
118   case IMAGE_REL_I386_REL32:    add32(Off, S - P - 4); break;
119   case IMAGE_REL_I386_SECTION:  applySecIdx(Off, OS); break;
120   case IMAGE_REL_I386_SECREL:   applySecRel(this, Off, OS, S); break;
121   default:
122     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
123           toString(File));
124   }
125 }
126 
127 static void applyMOV(uint8_t *Off, uint16_t V) {
128   write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
129   write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
130 }
131 
132 static uint16_t readMOV(uint8_t *Off, bool MOVT) {
133   uint16_t Op1 = read16le(Off);
134   if ((Op1 & 0xfbf0) != (MOVT ? 0xf2c0 : 0xf240))
135     error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
136           " instruction in MOV32T relocation");
137   uint16_t Op2 = read16le(Off + 2);
138   if ((Op2 & 0x8000) != 0)
139     error("unexpected instruction in " + Twine(MOVT ? "MOVT" : "MOVW") +
140           " instruction in MOV32T relocation");
141   return (Op2 & 0x00ff) | ((Op2 >> 4) & 0x0700) | ((Op1 << 1) & 0x0800) |
142          ((Op1 & 0x000f) << 12);
143 }
144 
145 void applyMOV32T(uint8_t *Off, uint32_t V) {
146   uint16_t ImmW = readMOV(Off, false);    // read MOVW operand
147   uint16_t ImmT = readMOV(Off + 4, true); // read MOVT operand
148   uint32_t Imm = ImmW | (ImmT << 16);
149   V += Imm;                         // add the immediate offset
150   applyMOV(Off, V);           // set MOVW operand
151   applyMOV(Off + 4, V >> 16); // set MOVT operand
152 }
153 
154 static void applyBranch20T(uint8_t *Off, int32_t V) {
155   if (!isInt<21>(V))
156     error("relocation out of range");
157   uint32_t S = V < 0 ? 1 : 0;
158   uint32_t J1 = (V >> 19) & 1;
159   uint32_t J2 = (V >> 18) & 1;
160   or16(Off, (S << 10) | ((V >> 12) & 0x3f));
161   or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
162 }
163 
164 void applyBranch24T(uint8_t *Off, int32_t V) {
165   if (!isInt<25>(V))
166     error("relocation out of range");
167   uint32_t S = V < 0 ? 1 : 0;
168   uint32_t J1 = ((~V >> 23) & 1) ^ S;
169   uint32_t J2 = ((~V >> 22) & 1) ^ S;
170   or16(Off, (S << 10) | ((V >> 12) & 0x3ff));
171   // Clear out the J1 and J2 bits which may be set.
172   write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
173 }
174 
175 void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
176                                uint64_t S, uint64_t P) const {
177   // Pointer to thumb code must have the LSB set.
178   uint64_t SX = S;
179   if (OS && (OS->Header.Characteristics & IMAGE_SCN_MEM_EXECUTE))
180     SX |= 1;
181   switch (Type) {
182   case IMAGE_REL_ARM_ADDR32:    add32(Off, SX + Config->ImageBase); break;
183   case IMAGE_REL_ARM_ADDR32NB:  add32(Off, SX); break;
184   case IMAGE_REL_ARM_MOV32T:    applyMOV32T(Off, SX + Config->ImageBase); break;
185   case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break;
186   case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break;
187   case IMAGE_REL_ARM_BLX23T:    applyBranch24T(Off, SX - P - 4); break;
188   case IMAGE_REL_ARM_SECTION:   applySecIdx(Off, OS); break;
189   case IMAGE_REL_ARM_SECREL:    applySecRel(this, Off, OS, S); break;
190   case IMAGE_REL_ARM_REL32:     add32(Off, SX - P - 4); break;
191   default:
192     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
193           toString(File));
194   }
195 }
196 
197 // Interpret the existing immediate value as a byte offset to the
198 // target symbol, then update the instruction with the immediate as
199 // the page offset from the current instruction to the target.
200 void applyArm64Addr(uint8_t *Off, uint64_t S, uint64_t P, int Shift) {
201   uint32_t Orig = read32le(Off);
202   uint64_t Imm = ((Orig >> 29) & 0x3) | ((Orig >> 3) & 0x1FFFFC);
203   S += Imm;
204   Imm = (S >> Shift) - (P >> Shift);
205   uint32_t ImmLo = (Imm & 0x3) << 29;
206   uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
207   uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
208   write32le(Off, (Orig & ~Mask) | ImmLo | ImmHi);
209 }
210 
211 // Update the immediate field in a AARCH64 ldr, str, and add instruction.
212 // Optionally limit the range of the written immediate by one or more bits
213 // (RangeLimit).
214 void applyArm64Imm(uint8_t *Off, uint64_t Imm, uint32_t RangeLimit) {
215   uint32_t Orig = read32le(Off);
216   Imm += (Orig >> 10) & 0xFFF;
217   Orig &= ~(0xFFF << 10);
218   write32le(Off, Orig | ((Imm & (0xFFF >> RangeLimit)) << 10));
219 }
220 
221 // Add the 12 bit page offset to the existing immediate.
222 // Ldr/str instructions store the opcode immediate scaled
223 // by the load/store size (giving a larger range for larger
224 // loads/stores). The immediate is always (both before and after
225 // fixing up the relocation) stored scaled similarly.
226 // Even if larger loads/stores have a larger range, limit the
227 // effective offset to 12 bit, since it is intended to be a
228 // page offset.
229 static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
230   uint32_t Orig = read32le(Off);
231   uint32_t Size = Orig >> 30;
232   // 0x04000000 indicates SIMD/FP registers
233   // 0x00800000 indicates 128 bit
234   if ((Orig & 0x4800000) == 0x4800000)
235     Size += 4;
236   if ((Imm & ((1 << Size) - 1)) != 0)
237     error("misaligned ldr/str offset");
238   applyArm64Imm(Off, Imm >> Size, Size);
239 }
240 
241 static void applySecRelLow12A(const SectionChunk *Sec, uint8_t *Off,
242                               OutputSection *OS, uint64_t S) {
243   if (checkSecRel(Sec, OS))
244     applyArm64Imm(Off, (S - OS->getRVA()) & 0xfff, 0);
245 }
246 
247 static void applySecRelHigh12A(const SectionChunk *Sec, uint8_t *Off,
248                                OutputSection *OS, uint64_t S) {
249   if (!checkSecRel(Sec, OS))
250     return;
251   uint64_t SecRel = (S - OS->getRVA()) >> 12;
252   if (0xfff < SecRel) {
253     error("overflow in SECREL_HIGH12A relocation in section: " +
254           Sec->getSectionName());
255     return;
256   }
257   applyArm64Imm(Off, SecRel & 0xfff, 0);
258 }
259 
260 static void applySecRelLdr(const SectionChunk *Sec, uint8_t *Off,
261                            OutputSection *OS, uint64_t S) {
262   if (checkSecRel(Sec, OS))
263     applyArm64Ldr(Off, (S - OS->getRVA()) & 0xfff);
264 }
265 
266 void applyArm64Branch26(uint8_t *Off, int64_t V) {
267   if (!isInt<28>(V))
268     error("relocation out of range");
269   or32(Off, (V & 0x0FFFFFFC) >> 2);
270 }
271 
272 static void applyArm64Branch19(uint8_t *Off, int64_t V) {
273   if (!isInt<21>(V))
274     error("relocation out of range");
275   or32(Off, (V & 0x001FFFFC) << 3);
276 }
277 
278 static void applyArm64Branch14(uint8_t *Off, int64_t V) {
279   if (!isInt<16>(V))
280     error("relocation out of range");
281   or32(Off, (V & 0x0000FFFC) << 3);
282 }
283 
284 void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
285                                  uint64_t S, uint64_t P) const {
286   switch (Type) {
287   case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, S, P, 12); break;
288   case IMAGE_REL_ARM64_REL21:          applyArm64Addr(Off, S, P, 0); break;
289   case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff, 0); break;
290   case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break;
291   case IMAGE_REL_ARM64_BRANCH26:       applyArm64Branch26(Off, S - P); break;
292   case IMAGE_REL_ARM64_BRANCH19:       applyArm64Branch19(Off, S - P); break;
293   case IMAGE_REL_ARM64_BRANCH14:       applyArm64Branch14(Off, S - P); break;
294   case IMAGE_REL_ARM64_ADDR32:         add32(Off, S + Config->ImageBase); break;
295   case IMAGE_REL_ARM64_ADDR32NB:       add32(Off, S); break;
296   case IMAGE_REL_ARM64_ADDR64:         add64(Off, S + Config->ImageBase); break;
297   case IMAGE_REL_ARM64_SECREL:         applySecRel(this, Off, OS, S); break;
298   case IMAGE_REL_ARM64_SECREL_LOW12A:  applySecRelLow12A(this, Off, OS, S); break;
299   case IMAGE_REL_ARM64_SECREL_HIGH12A: applySecRelHigh12A(this, Off, OS, S); break;
300   case IMAGE_REL_ARM64_SECREL_LOW12L:  applySecRelLdr(this, Off, OS, S); break;
301   case IMAGE_REL_ARM64_SECTION:        applySecIdx(Off, OS); break;
302   case IMAGE_REL_ARM64_REL32:          add32(Off, S - P - 4); break;
303   default:
304     error("unsupported relocation type 0x" + Twine::utohexstr(Type) + " in " +
305           toString(File));
306   }
307 }
308 
309 static void maybeReportRelocationToDiscarded(const SectionChunk *FromChunk,
310                                              Defined *Sym,
311                                              const coff_relocation &Rel) {
312   // Don't report these errors when the relocation comes from a debug info
313   // section or in mingw mode. MinGW mode object files (built by GCC) can
314   // have leftover sections with relocations against discarded comdat
315   // sections. Such sections are left as is, with relocations untouched.
316   if (FromChunk->isCodeView() || FromChunk->isDWARF() || Config->MinGW)
317     return;
318 
319   // Get the name of the symbol. If it's null, it was discarded early, so we
320   // have to go back to the object file.
321   ObjFile *File = FromChunk->File;
322   StringRef Name;
323   if (Sym) {
324     Name = Sym->getName();
325   } else {
326     COFFSymbolRef COFFSym =
327         check(File->getCOFFObj()->getSymbol(Rel.SymbolTableIndex));
328     File->getCOFFObj()->getSymbolName(COFFSym, Name);
329   }
330 
331   error("relocation against symbol in discarded section: " + Name +
332         getSymbolLocations(File, Rel.SymbolTableIndex));
333 }
334 
335 void SectionChunk::writeTo(uint8_t *Buf) const {
336   if (!hasData())
337     return;
338   // Copy section contents from source object file to output file.
339   ArrayRef<uint8_t> A = getContents();
340   if (!A.empty())
341     memcpy(Buf + OutputSectionOff, A.data(), A.size());
342 
343   // Apply relocations.
344   size_t InputSize = getSize();
345   for (size_t I = 0, E = Relocs.size(); I < E; I++) {
346     const coff_relocation &Rel = Relocs[I];
347 
348     // Check for an invalid relocation offset. This check isn't perfect, because
349     // we don't have the relocation size, which is only known after checking the
350     // machine and relocation type. As a result, a relocation may overwrite the
351     // beginning of the following input section.
352     if (Rel.VirtualAddress >= InputSize) {
353       error("relocation points beyond the end of its parent section");
354       continue;
355     }
356 
357     uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
358 
359     auto *Sym =
360         dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
361 
362     // Get the output section of the symbol for this relocation.  The output
363     // section is needed to compute SECREL and SECTION relocations used in debug
364     // info.
365     Chunk *C = Sym ? Sym->getChunk() : nullptr;
366     OutputSection *OS = C ? C->getOutputSection() : nullptr;
367 
368     // Skip the relocation if it refers to a discarded section, and diagnose it
369     // as an error if appropriate. If a symbol was discarded early, it may be
370     // null. If it was discarded late, the output section will be null, unless
371     // it was an absolute or synthetic symbol.
372     if (!Sym ||
373         (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym))) {
374       maybeReportRelocationToDiscarded(this, Sym, Rel);
375       continue;
376     }
377 
378     uint64_t S = Sym->getRVA();
379 
380     // Compute the RVA of the relocation for relative relocations.
381     uint64_t P = RVA + Rel.VirtualAddress;
382     switch (Config->Machine) {
383     case AMD64:
384       applyRelX64(Off, Rel.Type, OS, S, P);
385       break;
386     case I386:
387       applyRelX86(Off, Rel.Type, OS, S, P);
388       break;
389     case ARMNT:
390       applyRelARM(Off, Rel.Type, OS, S, P);
391       break;
392     case ARM64:
393       applyRelARM64(Off, Rel.Type, OS, S, P);
394       break;
395     default:
396       llvm_unreachable("unknown machine type");
397     }
398   }
399 }
400 
401 void SectionChunk::addAssociative(SectionChunk *Child) {
402   // Insert this child at the head of the list.
403   assert(Child->AssocChildren == nullptr &&
404          "associated sections cannot have their own associated children");
405   Child->AssocChildren = AssocChildren;
406   AssocChildren = Child;
407 }
408 
409 static uint8_t getBaserelType(const coff_relocation &Rel) {
410   switch (Config->Machine) {
411   case AMD64:
412     if (Rel.Type == IMAGE_REL_AMD64_ADDR64)
413       return IMAGE_REL_BASED_DIR64;
414     return IMAGE_REL_BASED_ABSOLUTE;
415   case I386:
416     if (Rel.Type == IMAGE_REL_I386_DIR32)
417       return IMAGE_REL_BASED_HIGHLOW;
418     return IMAGE_REL_BASED_ABSOLUTE;
419   case ARMNT:
420     if (Rel.Type == IMAGE_REL_ARM_ADDR32)
421       return IMAGE_REL_BASED_HIGHLOW;
422     if (Rel.Type == IMAGE_REL_ARM_MOV32T)
423       return IMAGE_REL_BASED_ARM_MOV32T;
424     return IMAGE_REL_BASED_ABSOLUTE;
425   case ARM64:
426     if (Rel.Type == IMAGE_REL_ARM64_ADDR64)
427       return IMAGE_REL_BASED_DIR64;
428     return IMAGE_REL_BASED_ABSOLUTE;
429   default:
430     llvm_unreachable("unknown machine type");
431   }
432 }
433 
434 // Windows-specific.
435 // Collect all locations that contain absolute addresses, which need to be
436 // fixed by the loader if load-time relocation is needed.
437 // Only called when base relocation is enabled.
438 void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
439   for (size_t I = 0, E = Relocs.size(); I < E; I++) {
440     const coff_relocation &Rel = Relocs[I];
441     uint8_t Ty = getBaserelType(Rel);
442     if (Ty == IMAGE_REL_BASED_ABSOLUTE)
443       continue;
444     Symbol *Target = File->getSymbol(Rel.SymbolTableIndex);
445     if (!Target || isa<DefinedAbsolute>(Target))
446       continue;
447     Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
448   }
449 }
450 
451 // MinGW specific.
452 // Check whether a static relocation of type Type can be deferred and
453 // handled at runtime as a pseudo relocation (for references to a module
454 // local variable, which turned out to actually need to be imported from
455 // another DLL) This returns the size the relocation is supposed to update,
456 // in bits, or 0 if the relocation cannot be handled as a runtime pseudo
457 // relocation.
458 static int getRuntimePseudoRelocSize(uint16_t Type) {
459   // Relocations that either contain an absolute address, or a plain
460   // relative offset, since the runtime pseudo reloc implementation
461   // adds 8/16/32/64 bit values to a memory address.
462   //
463   // Given a pseudo relocation entry,
464   //
465   // typedef struct {
466   //   DWORD sym;
467   //   DWORD target;
468   //   DWORD flags;
469   // } runtime_pseudo_reloc_item_v2;
470   //
471   // the runtime relocation performs this adjustment:
472   //     *(base + .target) += *(base + .sym) - (base + .sym)
473   //
474   // This works for both absolute addresses (IMAGE_REL_*_ADDR32/64,
475   // IMAGE_REL_I386_DIR32, where the memory location initially contains
476   // the address of the IAT slot, and for relative addresses (IMAGE_REL*_REL32),
477   // where the memory location originally contains the relative offset to the
478   // IAT slot.
479   //
480   // This requires the target address to be writable, either directly out of
481   // the image, or temporarily changed at runtime with VirtualProtect.
482   // Since this only operates on direct address values, it doesn't work for
483   // ARM/ARM64 relocations, other than the plain ADDR32/ADDR64 relocations.
484   switch (Config->Machine) {
485   case AMD64:
486     switch (Type) {
487     case IMAGE_REL_AMD64_ADDR64:
488       return 64;
489     case IMAGE_REL_AMD64_ADDR32:
490     case IMAGE_REL_AMD64_REL32:
491     case IMAGE_REL_AMD64_REL32_1:
492     case IMAGE_REL_AMD64_REL32_2:
493     case IMAGE_REL_AMD64_REL32_3:
494     case IMAGE_REL_AMD64_REL32_4:
495     case IMAGE_REL_AMD64_REL32_5:
496       return 32;
497     default:
498       return 0;
499     }
500   case I386:
501     switch (Type) {
502     case IMAGE_REL_I386_DIR32:
503     case IMAGE_REL_I386_REL32:
504       return 32;
505     default:
506       return 0;
507     }
508   case ARMNT:
509     switch (Type) {
510     case IMAGE_REL_ARM_ADDR32:
511       return 32;
512     default:
513       return 0;
514     }
515   case ARM64:
516     switch (Type) {
517     case IMAGE_REL_ARM64_ADDR64:
518       return 64;
519     case IMAGE_REL_ARM64_ADDR32:
520       return 32;
521     default:
522       return 0;
523     }
524   default:
525     llvm_unreachable("unknown machine type");
526   }
527 }
528 
529 // MinGW specific.
530 // Append information to the provided vector about all relocations that
531 // need to be handled at runtime as runtime pseudo relocations (references
532 // to a module local variable, which turned out to actually need to be
533 // imported from another DLL).
534 void SectionChunk::getRuntimePseudoRelocs(
535     std::vector<RuntimePseudoReloc> &Res) {
536   for (const coff_relocation &Rel : Relocs) {
537     auto *Target =
538         dyn_cast_or_null<Defined>(File->getSymbol(Rel.SymbolTableIndex));
539     if (!Target || !Target->IsRuntimePseudoReloc)
540       continue;
541     int SizeInBits = getRuntimePseudoRelocSize(Rel.Type);
542     if (SizeInBits == 0) {
543       error("unable to automatically import from " + Target->getName() +
544             " with relocation type " +
545             File->getCOFFObj()->getRelocationTypeName(Rel.Type) + " in " +
546             toString(File));
547       continue;
548     }
549     // SizeInBits is used to initialize the Flags field; currently no
550     // other flags are defined.
551     Res.emplace_back(
552         RuntimePseudoReloc(Target, this, Rel.VirtualAddress, SizeInBits));
553   }
554 }
555 
556 bool SectionChunk::hasData() const {
557   return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
558 }
559 
560 uint32_t SectionChunk::getOutputCharacteristics() const {
561   return Header->Characteristics & (PermMask | TypeMask);
562 }
563 
564 bool SectionChunk::isCOMDAT() const {
565   return Header->Characteristics & IMAGE_SCN_LNK_COMDAT;
566 }
567 
568 void SectionChunk::printDiscardedMessage() const {
569   // Removed by dead-stripping. If it's removed by ICF, ICF already
570   // printed out the name, so don't repeat that here.
571   if (Sym && this == Repl)
572     message("Discarded " + Sym->getName());
573 }
574 
575 StringRef SectionChunk::getDebugName() {
576   if (Sym)
577     return Sym->getName();
578   return "";
579 }
580 
581 ArrayRef<uint8_t> SectionChunk::getContents() const {
582   ArrayRef<uint8_t> A;
583   File->getCOFFObj()->getSectionContents(Header, A);
584   return A;
585 }
586 
587 ArrayRef<uint8_t> SectionChunk::consumeDebugMagic() {
588   assert(isCodeView());
589   return consumeDebugMagic(getContents(), SectionName);
590 }
591 
592 ArrayRef<uint8_t> SectionChunk::consumeDebugMagic(ArrayRef<uint8_t> Data,
593                                                   StringRef SectionName) {
594   if (Data.empty())
595     return {};
596 
597   // First 4 bytes are section magic.
598   if (Data.size() < 4)
599     fatal("the section is too short: " + SectionName);
600 
601   if (!SectionName.startswith(".debug$"))
602     fatal("invalid section: " + SectionName);
603 
604   unsigned Magic = support::endian::read32le(Data.data());
605   unsigned ExpectedMagic = SectionName == ".debug$H"
606                                ? DEBUG_HASHES_SECTION_MAGIC
607                                : DEBUG_SECTION_MAGIC;
608   if (Magic != ExpectedMagic)
609     fatal("section: " + SectionName + " has an invalid magic: " + Twine(Magic));
610   return Data.slice(4);
611 }
612 
613 SectionChunk *SectionChunk::findByName(ArrayRef<SectionChunk *> Sections,
614                                        StringRef Name) {
615   for (SectionChunk *C : Sections)
616     if (C->getSectionName() == Name)
617       return C;
618   return nullptr;
619 }
620 
621 void SectionChunk::replace(SectionChunk *Other) {
622   Alignment = std::max(Alignment, Other->Alignment);
623   Other->Repl = Repl;
624   Other->Live = false;
625 }
626 
627 uint32_t SectionChunk::getSectionNumber() const {
628   DataRefImpl R;
629   R.p = reinterpret_cast<uintptr_t>(Header);
630   SectionRef S(R, File->getCOFFObj());
631   return S.getIndex() + 1;
632 }
633 
634 CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
635   // Common symbols are aligned on natural boundaries up to 32 bytes.
636   // This is what MSVC link.exe does.
637   Alignment = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
638 }
639 
640 uint32_t CommonChunk::getOutputCharacteristics() const {
641   return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
642          IMAGE_SCN_MEM_WRITE;
643 }
644 
645 void StringChunk::writeTo(uint8_t *Buf) const {
646   memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
647   Buf[OutputSectionOff + Str.size()] = '\0';
648 }
649 
650 ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
651   // Intel Optimization Manual says that all branch targets
652   // should be 16-byte aligned. MSVC linker does this too.
653   Alignment = 16;
654 }
655 
656 void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
657   memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
658   // The first two bytes is a JMP instruction. Fill its operand.
659   write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize());
660 }
661 
662 void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *Res) {
663   Res->emplace_back(getRVA() + 2);
664 }
665 
666 void ImportThunkChunkX86::writeTo(uint8_t *Buf) const {
667   memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
668   // The first two bytes is a JMP instruction. Fill its operand.
669   write32le(Buf + OutputSectionOff + 2,
670             ImpSymbol->getRVA() + Config->ImageBase);
671 }
672 
673 void ImportThunkChunkARM::getBaserels(std::vector<Baserel> *Res) {
674   Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T);
675 }
676 
677 void ImportThunkChunkARM::writeTo(uint8_t *Buf) const {
678   memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM));
679   // Fix mov.w and mov.t operands.
680   applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase);
681 }
682 
683 void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
684   int64_t Off = ImpSymbol->getRVA() & 0xfff;
685   memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
686   applyArm64Addr(Buf + OutputSectionOff, ImpSymbol->getRVA(), RVA, 12);
687   applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
688 }
689 
690 // A Thumb2, PIC, non-interworking range extension thunk.
691 const uint8_t ArmThunk[] = {
692     0x40, 0xf2, 0x00, 0x0c, // P:  movw ip,:lower16:S - (P + (L1-P) + 4)
693     0xc0, 0xf2, 0x00, 0x0c, //     movt ip,:upper16:S - (P + (L1-P) + 4)
694     0xe7, 0x44,             // L1: add  pc, ip
695 };
696 
697 size_t RangeExtensionThunkARM::getSize() const {
698   assert(Config->Machine == ARMNT);
699   return sizeof(ArmThunk);
700 }
701 
702 void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
703   assert(Config->Machine == ARMNT);
704   uint64_t Offset = Target->getRVA() - RVA - 12;
705   memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
706   applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
707 }
708 
709 // A position independent ARM64 adrp+add thunk, with a maximum range of
710 // +/- 4 GB, which is enough for any PE-COFF.
711 const uint8_t Arm64Thunk[] = {
712     0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
713     0x10, 0x02, 0x00, 0x91, // add  x16, x16, :lo12:Dest
714     0x00, 0x02, 0x1f, 0xd6, // br   x16
715 };
716 
717 size_t RangeExtensionThunkARM64::getSize() const {
718   assert(Config->Machine == ARM64);
719   return sizeof(Arm64Thunk);
720 }
721 
722 void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
723   assert(Config->Machine == ARM64);
724   memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
725   applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
726   applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
727 }
728 
729 void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
730   Res->emplace_back(getRVA());
731 }
732 
733 size_t LocalImportChunk::getSize() const { return Config->Wordsize; }
734 
735 void LocalImportChunk::writeTo(uint8_t *Buf) const {
736   if (Config->is64()) {
737     write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
738   } else {
739     write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
740   }
741 }
742 
743 void RVATableChunk::writeTo(uint8_t *Buf) const {
744   ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
745   size_t Cnt = 0;
746   for (const ChunkAndOffset &CO : Syms)
747     Begin[Cnt++] = CO.InputChunk->getRVA() + CO.Offset;
748   std::sort(Begin, Begin + Cnt);
749   assert(std::unique(Begin, Begin + Cnt) == Begin + Cnt &&
750          "RVA tables should be de-duplicated");
751 }
752 
753 // MinGW specific, for the "automatic import of variables from DLLs" feature.
754 size_t PseudoRelocTableChunk::getSize() const {
755   if (Relocs.empty())
756     return 0;
757   return 12 + 12 * Relocs.size();
758 }
759 
760 // MinGW specific.
761 void PseudoRelocTableChunk::writeTo(uint8_t *Buf) const {
762   if (Relocs.empty())
763     return;
764 
765   ulittle32_t *Table = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
766   // This is the list header, to signal the runtime pseudo relocation v2
767   // format.
768   Table[0] = 0;
769   Table[1] = 0;
770   Table[2] = 1;
771 
772   size_t Idx = 3;
773   for (const RuntimePseudoReloc &RPR : Relocs) {
774     Table[Idx + 0] = RPR.Sym->getRVA();
775     Table[Idx + 1] = RPR.Target->getRVA() + RPR.TargetOffset;
776     Table[Idx + 2] = RPR.Flags;
777     Idx += 3;
778   }
779 }
780 
781 // Windows-specific. This class represents a block in .reloc section.
782 // The format is described here.
783 //
784 // On Windows, each DLL is linked against a fixed base address and
785 // usually loaded to that address. However, if there's already another
786 // DLL that overlaps, the loader has to relocate it. To do that, DLLs
787 // contain .reloc sections which contain offsets that need to be fixed
788 // up at runtime. If the loader finds that a DLL cannot be loaded to its
789 // desired base address, it loads it to somewhere else, and add <actual
790 // base address> - <desired base address> to each offset that is
791 // specified by the .reloc section. In ELF terms, .reloc sections
792 // contain relative relocations in REL format (as opposed to RELA.)
793 //
794 // This already significantly reduces the size of relocations compared
795 // to ELF .rel.dyn, but Windows does more to reduce it (probably because
796 // it was invented for PCs in the late '80s or early '90s.)  Offsets in
797 // .reloc are grouped by page where the page size is 12 bits, and
798 // offsets sharing the same page address are stored consecutively to
799 // represent them with less space. This is very similar to the page
800 // table which is grouped by (multiple stages of) pages.
801 //
802 // For example, let's say we have 0x00030, 0x00500, 0x00700, 0x00A00,
803 // 0x20004, and 0x20008 in a .reloc section for x64. The uppermost 4
804 // bits have a type IMAGE_REL_BASED_DIR64 or 0xA. In the section, they
805 // are represented like this:
806 //
807 //   0x00000  -- page address (4 bytes)
808 //   16       -- size of this block (4 bytes)
809 //     0xA030 -- entries (2 bytes each)
810 //     0xA500
811 //     0xA700
812 //     0xAA00
813 //   0x20000  -- page address (4 bytes)
814 //   12       -- size of this block (4 bytes)
815 //     0xA004 -- entries (2 bytes each)
816 //     0xA008
817 //
818 // Usually we have a lot of relocations for each page, so the number of
819 // bytes for one .reloc entry is close to 2 bytes on average.
820 BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) {
821   // Block header consists of 4 byte page RVA and 4 byte block size.
822   // Each entry is 2 byte. Last entry may be padding.
823   Data.resize(alignTo((End - Begin) * 2 + 8, 4));
824   uint8_t *P = Data.data();
825   write32le(P, Page);
826   write32le(P + 4, Data.size());
827   P += 8;
828   for (Baserel *I = Begin; I != End; ++I) {
829     write16le(P, (I->Type << 12) | (I->RVA - Page));
830     P += 2;
831   }
832 }
833 
834 void BaserelChunk::writeTo(uint8_t *Buf) const {
835   memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
836 }
837 
838 uint8_t Baserel::getDefaultType() {
839   switch (Config->Machine) {
840   case AMD64:
841   case ARM64:
842     return IMAGE_REL_BASED_DIR64;
843   case I386:
844   case ARMNT:
845     return IMAGE_REL_BASED_HIGHLOW;
846   default:
847     llvm_unreachable("unknown machine type");
848   }
849 }
850 
851 std::map<uint32_t, MergeChunk *> MergeChunk::Instances;
852 
853 MergeChunk::MergeChunk(uint32_t Alignment)
854     : Builder(StringTableBuilder::RAW, Alignment) {
855   this->Alignment = Alignment;
856 }
857 
858 void MergeChunk::addSection(SectionChunk *C) {
859   auto *&MC = Instances[C->Alignment];
860   if (!MC)
861     MC = make<MergeChunk>(C->Alignment);
862   MC->Sections.push_back(C);
863 }
864 
865 void MergeChunk::finalizeContents() {
866   if (!Finalized) {
867     for (SectionChunk *C : Sections)
868       if (C->Live)
869         Builder.add(toStringRef(C->getContents()));
870     Builder.finalize();
871     Finalized = true;
872   }
873 
874   for (SectionChunk *C : Sections) {
875     if (!C->Live)
876       continue;
877     size_t Off = Builder.getOffset(toStringRef(C->getContents()));
878     C->setOutputSection(Out);
879     C->setRVA(RVA + Off);
880     C->OutputSectionOff = OutputSectionOff + Off;
881   }
882 }
883 
884 uint32_t MergeChunk::getOutputCharacteristics() const {
885   return IMAGE_SCN_MEM_READ | IMAGE_SCN_CNT_INITIALIZED_DATA;
886 }
887 
888 size_t MergeChunk::getSize() const {
889   return Builder.getSize();
890 }
891 
892 void MergeChunk::writeTo(uint8_t *Buf) const {
893   Builder.write(Buf + OutputSectionOff);
894 }
895 
896 // MinGW specific.
897 size_t AbsolutePointerChunk::getSize() const { return Config->Wordsize; }
898 
899 void AbsolutePointerChunk::writeTo(uint8_t *Buf) const {
900   if (Config->is64()) {
901     write64le(Buf + OutputSectionOff, Value);
902   } else {
903     write32le(Buf + OutputSectionOff, Value);
904   }
905 }
906 
907 } // namespace coff
908 } // namespace lld
909