Coverage Report

Created: 2018-10-23 15:26

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