Coverage Report

Created: 2019-07-24 05:18

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