Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Object/RelocationResolver.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- RelocationResolver.cpp ------------------------------------*- C++ -*-===//
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
// This file defines utilities to resolve relocations in object files.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "llvm/Object/RelocationResolver.h"
14
15
namespace llvm {
16
namespace object {
17
18
7.54k
static int64_t getELFAddend(RelocationRef R) {
19
7.54k
  Expected<int64_t> AddendOrErr = ELFRelocationRef(R).getAddend();
20
7.54k
  handleAllErrors(AddendOrErr.takeError(), [](const ErrorInfoBase &EI) {
21
1
    report_fatal_error(EI.message());
22
1
  });
23
7.54k
  return *AddendOrErr;
24
7.54k
}
25
26
5.04k
static bool supportsX86_64(uint64_t Type) {
27
5.04k
  switch (Type) {
28
5.04k
  case ELF::R_X86_64_NONE:
29
5.04k
  case ELF::R_X86_64_64:
30
5.04k
  case ELF::R_X86_64_DTPOFF32:
31
5.04k
  case ELF::R_X86_64_DTPOFF64:
32
5.04k
  case ELF::R_X86_64_PC32:
33
5.04k
  case ELF::R_X86_64_32:
34
5.04k
  case ELF::R_X86_64_32S:
35
5.04k
    return true;
36
5.04k
  default:
37
0
    return false;
38
5.04k
  }
39
5.04k
}
40
41
6.67k
static uint64_t resolveX86_64(RelocationRef R, uint64_t S, uint64_t A) {
42
6.67k
  switch (R.getType()) {
43
6.67k
  case ELF::R_X86_64_NONE:
44
0
    return A;
45
6.67k
  case ELF::R_X86_64_64:
46
1.09k
  case ELF::R_X86_64_DTPOFF32:
47
1.09k
  case ELF::R_X86_64_DTPOFF64:
48
1.09k
    return S + getELFAddend(R);
49
1.09k
  case ELF::R_X86_64_PC32:
50
0
    return S + getELFAddend(R) - R.getOffset();
51
5.57k
  case ELF::R_X86_64_32:
52
5.57k
  case ELF::R_X86_64_32S:
53
5.57k
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
54
5.57k
  default:
55
0
    llvm_unreachable("Invalid relocation type");
56
6.67k
  }
57
6.67k
}
58
59
223
static bool supportsAArch64(uint64_t Type) {
60
223
  switch (Type) {
61
223
  case ELF::R_AARCH64_ABS32:
62
197
  case ELF::R_AARCH64_ABS64:
63
197
    return true;
64
197
  default:
65
26
    return false;
66
223
  }
67
223
}
68
69
299
static uint64_t resolveAArch64(RelocationRef R, uint64_t S, uint64_t A) {
70
299
  switch (R.getType()) {
71
299
  case ELF::R_AARCH64_ABS32:
72
246
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
73
299
  case ELF::R_AARCH64_ABS64:
74
53
    return S + getELFAddend(R);
75
299
  default:
76
0
    llvm_unreachable("Invalid relocation type");
77
299
  }
78
299
}
79
80
40
static bool supportsBPF(uint64_t Type) {
81
40
  switch (Type) {
82
40
  case ELF::R_BPF_64_32:
83
40
  case ELF::R_BPF_64_64:
84
40
    return true;
85
40
  default:
86
0
    return false;
87
40
  }
88
40
}
89
90
6
static uint64_t resolveBPF(RelocationRef R, uint64_t S, uint64_t A) {
91
6
  switch (R.getType()) {
92
6
  case ELF::R_BPF_64_32:
93
4
    return S & 0xFFFFFFFF;
94
6
  case ELF::R_BPF_64_64:
95
2
    return S;
96
6
  default:
97
0
    llvm_unreachable("Invalid relocation type");
98
6
  }
99
6
}
100
101
31
static bool supportsMips64(uint64_t Type) {
102
31
  switch (Type) {
103
31
  case ELF::R_MIPS_32:
104
31
  case ELF::R_MIPS_64:
105
31
  case ELF::R_MIPS_TLS_DTPREL64:
106
31
    return true;
107
31
  default:
108
0
    return false;
109
31
  }
110
31
}
111
112
26
static uint64_t resolveMips64(RelocationRef R, uint64_t S, uint64_t A) {
113
26
  switch (R.getType()) {
114
26
  case ELF::R_MIPS_32:
115
19
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
116
26
  case ELF::R_MIPS_64:
117
7
    return S + getELFAddend(R);
118
26
  case ELF::R_MIPS_TLS_DTPREL64:
119
0
    return S + getELFAddend(R) - 0x8000;
120
26
  default:
121
0
    llvm_unreachable("Invalid relocation type");
122
26
  }
123
26
}
124
125
static bool supportsPPC64(uint64_t Type) {
126
  switch (Type) {
127
  case ELF::R_PPC64_ADDR32:
128
  case ELF::R_PPC64_ADDR64:
129
    return true;
130
  default:
131
    return false;
132
  }
133
}
134
135
0
static uint64_t resolvePPC64(RelocationRef R, uint64_t S, uint64_t A) {
136
0
  switch (R.getType()) {
137
0
  case ELF::R_PPC64_ADDR32:
138
0
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
139
0
  case ELF::R_PPC64_ADDR64:
140
0
    return S + getELFAddend(R);
141
0
  default:
142
0
    llvm_unreachable("Invalid relocation type");
143
0
  }
144
0
}
145
146
37
static bool supportsSystemZ(uint64_t Type) {
147
37
  switch (Type) {
148
37
  case ELF::R_390_32:
149
37
  case ELF::R_390_64:
150
37
    return true;
151
37
  default:
152
0
    return false;
153
37
  }
154
37
}
155
156
61
static uint64_t resolveSystemZ(RelocationRef R, uint64_t S, uint64_t A) {
157
61
  switch (R.getType()) {
158
61
  case ELF::R_390_32:
159
50
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
160
61
  case ELF::R_390_64:
161
11
    return S + getELFAddend(R);
162
61
  default:
163
0
    llvm_unreachable("Invalid relocation type");
164
61
  }
165
61
}
166
167
29
static bool supportsSparc64(uint64_t Type) {
168
29
  switch (Type) {
169
29
  case ELF::R_SPARC_32:
170
28
  case ELF::R_SPARC_64:
171
28
  case ELF::R_SPARC_UA32:
172
28
  case ELF::R_SPARC_UA64:
173
28
    return true;
174
28
  default:
175
1
    return false;
176
29
  }
177
29
}
178
179
19
static uint64_t resolveSparc64(RelocationRef R, uint64_t S, uint64_t A) {
180
19
  switch (R.getType()) {
181
19
  case ELF::R_SPARC_32:
182
19
  case ELF::R_SPARC_64:
183
19
  case ELF::R_SPARC_UA32:
184
19
  case ELF::R_SPARC_UA64:
185
19
    return S + getELFAddend(R);
186
19
  default:
187
0
    llvm_unreachable("Invalid relocation type");
188
19
  }
189
19
}
190
191
115
static bool supportsAmdgpu(uint64_t Type) {
192
115
  switch (Type) {
193
115
  case ELF::R_AMDGPU_ABS32:
194
115
  case ELF::R_AMDGPU_ABS64:
195
115
    return true;
196
115
  default:
197
0
    return false;
198
115
  }
199
115
}
200
201
265
static uint64_t resolveAmdgpu(RelocationRef R, uint64_t S, uint64_t A) {
202
265
  switch (R.getType()) {
203
265
  case ELF::R_AMDGPU_ABS32:
204
265
  case ELF::R_AMDGPU_ABS64:
205
265
    return S + getELFAddend(R);
206
265
  default:
207
0
    llvm_unreachable("Invalid relocation type");
208
265
  }
209
265
}
210
211
249
static bool supportsX86(uint64_t Type) {
212
249
  switch (Type) {
213
249
  case ELF::R_386_NONE:
214
248
  case ELF::R_386_32:
215
248
  case ELF::R_386_PC32:
216
248
    return true;
217
248
  default:
218
1
    return false;
219
249
  }
220
249
}
221
222
322
static uint64_t resolveX86(RelocationRef R, uint64_t S, uint64_t A) {
223
322
  switch (R.getType()) {
224
322
  case ELF::R_386_NONE:
225
0
    return A;
226
322
  case ELF::R_386_32:
227
322
    return S + A;
228
322
  case ELF::R_386_PC32:
229
0
    return S - R.getOffset() + A;
230
322
  default:
231
0
    llvm_unreachable("Invalid relocation type");
232
322
  }
233
322
}
234
235
0
static bool supportsPPC32(uint64_t Type) {
236
0
  return Type == ELF::R_PPC_ADDR32;
237
0
}
238
239
0
static uint64_t resolvePPC32(RelocationRef R, uint64_t S, uint64_t A) {
240
0
  if (R.getType() == ELF::R_PPC_ADDR32)
241
0
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
242
0
  llvm_unreachable("Invalid relocation type");
243
0
}
244
245
191
static bool supportsARM(uint64_t Type) {
246
191
  return Type == ELF::R_ARM_ABS32;
247
191
}
248
249
280
static uint64_t resolveARM(RelocationRef R, uint64_t S, uint64_t A) {
250
280
  if (R.getType() == ELF::R_ARM_ABS32)
251
280
    return (S + A) & 0xFFFFFFFF;
252
0
  llvm_unreachable("Invalid relocation type");
253
0
}
254
255
static bool supportsAVR(uint64_t Type) {
256
  switch (Type) {
257
  case ELF::R_AVR_16:
258
  case ELF::R_AVR_32:
259
    return true;
260
  default:
261
    return false;
262
  }
263
}
264
265
0
static uint64_t resolveAVR(RelocationRef R, uint64_t S, uint64_t A) {
266
0
  switch (R.getType()) {
267
0
  case ELF::R_AVR_16:
268
0
    return (S + getELFAddend(R)) & 0xFFFF;
269
0
  case ELF::R_AVR_32:
270
0
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
271
0
  default:
272
0
    llvm_unreachable("Invalid relocation type");
273
0
  }
274
0
}
275
276
0
static bool supportsLanai(uint64_t Type) {
277
0
  return Type == ELF::R_LANAI_32;
278
0
}
279
280
0
static uint64_t resolveLanai(RelocationRef R, uint64_t S, uint64_t A) {
281
0
  if (R.getType() == ELF::R_LANAI_32)
282
0
    return (S + getELFAddend(R)) & 0xFFFFFFFF;
283
0
  llvm_unreachable("Invalid relocation type");
284
0
}
285
286
116
static bool supportsMips32(uint64_t Type) {
287
116
  switch (Type) {
288
116
  case ELF::R_MIPS_32:
289
116
  case ELF::R_MIPS_TLS_DTPREL32:
290
116
    return true;
291
116
  default:
292
0
    return false;
293
116
  }
294
116
}
295
296
184
static uint64_t resolveMips32(RelocationRef R, uint64_t S, uint64_t A) {
297
184
  // FIXME: Take in account implicit addends to get correct results.
298
184
  uint32_t Rel = R.getType();
299
184
  if (Rel == ELF::R_MIPS_32)
300
184
    return (S + A) & 0xFFFFFFFF;
301
0
  if (Rel == ELF::R_MIPS_TLS_DTPREL32)
302
0
    return (S + A) & 0xFFFFFFFF;
303
0
  llvm_unreachable("Invalid relocation type");
304
0
}
305
306
14
static bool supportsSparc32(uint64_t Type) {
307
14
  switch (Type) {
308
14
  case ELF::R_SPARC_32:
309
14
  case ELF::R_SPARC_UA32:
310
14
    return true;
311
14
  default:
312
0
    return false;
313
14
  }
314
14
}
315
316
18
static uint64_t resolveSparc32(RelocationRef R, uint64_t S, uint64_t A) {
317
18
  uint32_t Rel = R.getType();
318
18
  if (Rel == ELF::R_SPARC_32 || 
Rel == ELF::R_SPARC_UA3212
)
319
18
    return S + getELFAddend(R);
320
0
  return A;
321
0
}
322
323
42
static bool supportsHexagon(uint64_t Type) {
324
42
  return Type == ELF::R_HEX_32;
325
42
}
326
327
78
static uint64_t resolveHexagon(RelocationRef R, uint64_t S, uint64_t A) {
328
78
  if (R.getType() == ELF::R_HEX_32)
329
78
    return S + getELFAddend(R);
330
0
  llvm_unreachable("Invalid relocation type");
331
0
}
332
333
123
static bool supportsRISCV(uint64_t Type) {
334
123
  switch (Type) {
335
123
  case ELF::R_RISCV_NONE:
336
121
  case ELF::R_RISCV_32:
337
121
  case ELF::R_RISCV_64:
338
121
  case ELF::R_RISCV_SET6:
339
121
  case ELF::R_RISCV_SUB6:
340
121
  case ELF::R_RISCV_ADD8:
341
121
  case ELF::R_RISCV_SUB8:
342
121
  case ELF::R_RISCV_ADD16:
343
121
  case ELF::R_RISCV_SUB16:
344
121
  case ELF::R_RISCV_ADD32:
345
121
  case ELF::R_RISCV_SUB32:
346
121
  case ELF::R_RISCV_ADD64:
347
121
  case ELF::R_RISCV_SUB64:
348
121
    return true;
349
121
  default:
350
2
    return false;
351
123
  }
352
123
}
353
354
106
static uint64_t resolveRISCV(RelocationRef R, uint64_t S, uint64_t A) {
355
106
  int64_t RA = getELFAddend(R);
356
106
  switch (R.getType()) {
357
106
  case ELF::R_RISCV_NONE:
358
0
    return A;
359
106
  case ELF::R_RISCV_32:
360
68
    return (S + RA) & 0xFFFFFFFF;
361
106
  case ELF::R_RISCV_64:
362
0
    return S + RA;
363
106
  case ELF::R_RISCV_SET6:
364
7
    return (A + (S + RA)) & 0xFF;
365
106
  case ELF::R_RISCV_SUB6:
366
7
    return (A - (S + RA)) & 0xFF;
367
106
  case ELF::R_RISCV_ADD8:
368
0
    return (A + (S + RA)) & 0xFF;
369
106
  case ELF::R_RISCV_SUB8:
370
0
    return (A - (S + RA)) & 0xFF;
371
106
  case ELF::R_RISCV_ADD16:
372
6
    return (A + (S + RA)) & 0xFFFF;
373
106
  case ELF::R_RISCV_SUB16:
374
6
    return (A - (S + RA)) & 0xFFFF;
375
106
  case ELF::R_RISCV_ADD32:
376
6
    return (A + (S + RA)) & 0xFFFFFFFF;
377
106
  case ELF::R_RISCV_SUB32:
378
6
    return (A - (S + RA)) & 0xFFFFFFFF;
379
106
  case ELF::R_RISCV_ADD64:
380
0
    return (A + (S + RA));
381
106
  case ELF::R_RISCV_SUB64:
382
0
    return (A - (S + RA));
383
106
  default:
384
0
    llvm_unreachable("Invalid relocation type");
385
106
  }
386
106
}
387
388
74
static bool supportsCOFFX86(uint64_t Type) {
389
74
  switch (Type) {
390
74
  case COFF::IMAGE_REL_I386_SECREL:
391
74
  case COFF::IMAGE_REL_I386_DIR32:
392
74
    return true;
393
74
  default:
394
0
    return false;
395
74
  }
396
74
}
397
398
110
static uint64_t resolveCOFFX86(RelocationRef R, uint64_t S, uint64_t A) {
399
110
  switch (R.getType()) {
400
110
  case COFF::IMAGE_REL_I386_SECREL:
401
110
  case COFF::IMAGE_REL_I386_DIR32:
402
110
    return (S + A) & 0xFFFFFFFF;
403
110
  default:
404
0
    llvm_unreachable("Invalid relocation type");
405
110
  }
406
110
}
407
408
106
static bool supportsCOFFX86_64(uint64_t Type) {
409
106
  switch (Type) {
410
106
  case COFF::IMAGE_REL_AMD64_SECREL:
411
106
  case COFF::IMAGE_REL_AMD64_ADDR64:
412
106
    return true;
413
106
  default:
414
0
    return false;
415
106
  }
416
106
}
417
418
139
static uint64_t resolveCOFFX86_64(RelocationRef R, uint64_t S, uint64_t A) {
419
139
  switch (R.getType()) {
420
139
  case COFF::IMAGE_REL_AMD64_SECREL:
421
122
    return (S + A) & 0xFFFFFFFF;
422
139
  case COFF::IMAGE_REL_AMD64_ADDR64:
423
17
    return S + A;
424
139
  default:
425
0
    llvm_unreachable("Invalid relocation type");
426
139
  }
427
139
}
428
429
13
static bool supportsMachOX86_64(uint64_t Type) {
430
13
  return Type == MachO::X86_64_RELOC_UNSIGNED;
431
13
}
432
433
13
static uint64_t resolveMachOX86_64(RelocationRef R, uint64_t S, uint64_t A) {
434
13
  if (R.getType() == MachO::X86_64_RELOC_UNSIGNED)
435
13
    return S;
436
0
  llvm_unreachable("Invalid relocation type");
437
0
}
438
439
16
static bool supportsWasm32(uint64_t Type) {
440
16
  switch (Type) {
441
16
  case wasm::R_WASM_FUNCTION_INDEX_LEB:
442
16
  case wasm::R_WASM_TABLE_INDEX_SLEB:
443
16
  case wasm::R_WASM_TABLE_INDEX_I32:
444
16
  case wasm::R_WASM_MEMORY_ADDR_LEB:
445
16
  case wasm::R_WASM_MEMORY_ADDR_SLEB:
446
16
  case wasm::R_WASM_MEMORY_ADDR_I32:
447
16
  case wasm::R_WASM_TYPE_INDEX_LEB:
448
16
  case wasm::R_WASM_GLOBAL_INDEX_LEB:
449
16
  case wasm::R_WASM_FUNCTION_OFFSET_I32:
450
16
  case wasm::R_WASM_SECTION_OFFSET_I32:
451
16
  case wasm::R_WASM_EVENT_INDEX_LEB:
452
16
    return true;
453
16
  default:
454
0
    return false;
455
16
  }
456
16
}
457
458
22
static uint64_t resolveWasm32(RelocationRef R, uint64_t S, uint64_t A) {
459
22
  switch (R.getType()) {
460
22
  case wasm::R_WASM_FUNCTION_INDEX_LEB:
461
22
  case wasm::R_WASM_TABLE_INDEX_SLEB:
462
22
  case wasm::R_WASM_TABLE_INDEX_I32:
463
22
  case wasm::R_WASM_MEMORY_ADDR_LEB:
464
22
  case wasm::R_WASM_MEMORY_ADDR_SLEB:
465
22
  case wasm::R_WASM_MEMORY_ADDR_I32:
466
22
  case wasm::R_WASM_TYPE_INDEX_LEB:
467
22
  case wasm::R_WASM_GLOBAL_INDEX_LEB:
468
22
  case wasm::R_WASM_FUNCTION_OFFSET_I32:
469
22
  case wasm::R_WASM_SECTION_OFFSET_I32:
470
22
  case wasm::R_WASM_EVENT_INDEX_LEB:
471
22
    // For wasm section, its offset at 0 -- ignoring Value
472
22
    return A;
473
22
  default:
474
0
    llvm_unreachable("Invalid relocation type");
475
22
  }
476
22
}
477
478
std::pair<bool (*)(uint64_t), RelocationResolver>
479
1.49k
getRelocationResolver(const ObjectFile &Obj) {
480
1.49k
  if (Obj.isCOFF()) {
481
45
    if (Obj.getBytesInAddress() == 8)
482
22
      return {supportsCOFFX86_64, resolveCOFFX86_64};
483
23
    return {supportsCOFFX86, resolveCOFFX86};
484
1.45k
  } else if (Obj.isELF()) {
485
1.44k
    if (Obj.getBytesInAddress() == 8) {
486
1.27k
      switch (Obj.getArch()) {
487
1.27k
      case Triple::x86_64:
488
1.14k
        return {supportsX86_64, resolveX86_64};
489
1.27k
      case Triple::aarch64:
490
56
      case Triple::aarch64_be:
491
56
        return {supportsAArch64, resolveAArch64};
492
56
      case Triple::bpfel:
493
10
      case Triple::bpfeb:
494
10
        return {supportsBPF, resolveBPF};
495
12
      case Triple::mips64el:
496
12
      case Triple::mips64:
497
12
        return {supportsMips64, resolveMips64};
498
12
      case Triple::ppc64le:
499
0
      case Triple::ppc64:
500
0
        return {supportsPPC64, resolvePPC64};
501
8
      case Triple::systemz:
502
8
        return {supportsSystemZ, resolveSystemZ};
503
10
      case Triple::sparcv9:
504
10
        return {supportsSparc64, resolveSparc64};
505
24
      case Triple::amdgcn:
506
24
        return {supportsAmdgpu, resolveAmdgpu};
507
1
      case Triple::riscv64:
508
1
        return {supportsRISCV, resolveRISCV};
509
0
      default:
510
0
        return {nullptr, nullptr};
511
174
      }
512
174
    }
513
174
514
174
    // 32-bit object file
515
174
    assert(Obj.getBytesInAddress() == 4 &&
516
174
           "Invalid word size in object file");
517
174
518
174
    switch (Obj.getArch()) {
519
174
    case Triple::x86:
520
68
      return {supportsX86, resolveX86};
521
174
    case Triple::ppc:
522
0
      return {supportsPPC32, resolvePPC32};
523
174
    case Triple::arm:
524
50
    case Triple::armeb:
525
50
      return {supportsARM, resolveARM};
526
50
    case Triple::avr:
527
0
      return {supportsAVR, resolveAVR};
528
50
    case Triple::lanai:
529
0
      return {supportsLanai, resolveLanai};
530
50
    case Triple::mipsel:
531
27
    case Triple::mips:
532
27
      return {supportsMips32, resolveMips32};
533
27
    case Triple::sparc:
534
5
      return {supportsSparc32, resolveSparc32};
535
27
    case Triple::hexagon:
536
10
      return {supportsHexagon, resolveHexagon};
537
27
    case Triple::riscv32:
538
12
      return {supportsRISCV, resolveRISCV};
539
27
    default:
540
2
      return {nullptr, nullptr};
541
10
    }
542
10
  } else if (Obj.isMachO()) {
543
6
    if (Obj.getArch() == Triple::x86_64)
544
6
      return {supportsMachOX86_64, resolveMachOX86_64};
545
0
    return {nullptr, nullptr};
546
4
  } else if (Obj.isWasm()) {
547
4
    if (Obj.getArch() == Triple::wasm32)
548
4
      return {supportsWasm32, resolveWasm32};
549
0
    return {nullptr, nullptr};
550
0
  }
551
0
552
0
  llvm_unreachable("Invalid object file");
553
0
}
554
555
} // namespace object
556
} // namespace llvm