Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/ELF/Arch/RISCV.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- RISCV.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 "InputFiles.h"
10
#include "SyntheticSections.h"
11
#include "Target.h"
12
13
using namespace llvm;
14
using namespace llvm::object;
15
using namespace llvm::support::endian;
16
using namespace llvm::ELF;
17
using namespace lld;
18
using namespace lld::elf;
19
20
namespace {
21
22
class RISCV final : public TargetInfo {
23
public:
24
  RISCV();
25
  uint32_t calcEFlags() const override;
26
  void writeGotHeader(uint8_t *buf) const override;
27
  void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
28
  void writePltHeader(uint8_t *buf) const override;
29
  void writePlt(uint8_t *buf, uint64_t gotPltEntryAddr, uint64_t pltEntryAddr,
30
                int32_t index, unsigned relOff) const override;
31
  RelType getDynRel(RelType type) const override;
32
  RelExpr getRelExpr(RelType type, const Symbol &s,
33
                     const uint8_t *loc) const override;
34
  void relocateOne(uint8_t *loc, RelType type, uint64_t val) const override;
35
};
36
37
} // end anonymous namespace
38
39
const uint64_t dtpOffset = 0x800;
40
41
enum Op {
42
  ADDI = 0x13,
43
  AUIPC = 0x17,
44
  JALR = 0x67,
45
  LD = 0x3003,
46
  LW = 0x2003,
47
  SRLI = 0x5013,
48
  SUB = 0x40000033,
49
};
50
51
enum Reg {
52
  X_RA = 1,
53
  X_T0 = 5,
54
  X_T1 = 6,
55
  X_T2 = 7,
56
  X_T3 = 28,
57
};
58
59
14
static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; }
60
20
static uint32_t lo12(uint32_t val) { return val & 4095; }
61
62
60
static uint32_t itype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t imm) {
63
60
  return op | (rd << 7) | (rs1 << 15) | (imm << 20);
64
60
}
65
6
static uint32_t rtype(uint32_t op, uint32_t rd, uint32_t rs1, uint32_t rs2) {
66
6
  return op | (rd << 7) | (rs1 << 15) | (rs2 << 20);
67
6
}
68
14
static uint32_t utype(uint32_t op, uint32_t rd, uint32_t imm) {
69
14
  return op | (rd << 7) | (imm << 12);
70
14
}
71
72
90
RISCV::RISCV() {
73
90
  copyRel = R_RISCV_COPY;
74
90
  noneRel = R_RISCV_NONE;
75
90
  pltRel = R_RISCV_JUMP_SLOT;
76
90
  relativeRel = R_RISCV_RELATIVE;
77
90
  if (config->is64) {
78
46
    symbolicRel = R_RISCV_64;
79
46
    tlsModuleIndexRel = R_RISCV_TLS_DTPMOD64;
80
46
    tlsOffsetRel = R_RISCV_TLS_DTPREL64;
81
46
    tlsGotRel = R_RISCV_TLS_TPREL64;
82
46
  } else {
83
44
    symbolicRel = R_RISCV_32;
84
44
    tlsModuleIndexRel = R_RISCV_TLS_DTPMOD32;
85
44
    tlsOffsetRel = R_RISCV_TLS_DTPREL32;
86
44
    tlsGotRel = R_RISCV_TLS_TPREL32;
87
44
  }
88
90
  gotRel = symbolicRel;
89
90
90
90
  // .got[0] = _DYNAMIC
91
90
  gotBaseSymInGotPlt = false;
92
90
  gotHeaderEntriesNum = 1;
93
90
94
90
  // .got.plt[0] = _dl_runtime_resolve, .got.plt[1] = link_map
95
90
  gotPltHeaderEntriesNum = 2;
96
90
97
90
  pltEntrySize = 16;
98
90
  pltHeaderSize = 32;
99
90
}
100
101
194
static uint32_t getEFlags(InputFile *f) {
102
194
  if (config->is64)
103
99
    return cast<ObjFile<ELF64LE>>(f)->getObj().getHeader()->e_flags;
104
95
  return cast<ObjFile<ELF32LE>>(f)->getObj().getHeader()->e_flags;
105
95
}
106
107
90
uint32_t RISCV::calcEFlags() const {
108
90
  assert(!objectFiles.empty());
109
90
110
90
  uint32_t target = getEFlags(objectFiles.front());
111
90
112
104
  for (InputFile *f : objectFiles) {
113
104
    uint32_t eflags = getEFlags(f);
114
104
    if (eflags & EF_RISCV_RVC)
115
0
      target |= EF_RISCV_RVC;
116
104
117
104
    if ((eflags & EF_RISCV_FLOAT_ABI) != (target & EF_RISCV_FLOAT_ABI))
118
0
      error(toString(f) +
119
0
            ": cannot link object files with different floating-point ABI");
120
104
121
104
    if ((eflags & EF_RISCV_RVE) != (target & EF_RISCV_RVE))
122
0
      error(toString(f) +
123
0
            ": cannot link object files with different EF_RISCV_RVE");
124
104
  }
125
90
126
90
  return target;
127
90
}
128
129
18
void RISCV::writeGotHeader(uint8_t *buf) const {
130
18
  if (config->is64)
131
9
    write64le(buf, mainPart->dynamic->getVA());
132
9
  else
133
9
    write32le(buf, mainPart->dynamic->getVA());
134
18
}
135
136
8
void RISCV::writeGotPlt(uint8_t *buf, const Symbol &s) const {
137
8
  if (config->is64)
138
4
    write64le(buf, in.plt->getVA());
139
4
  else
140
4
    write32le(buf, in.plt->getVA());
141
8
}
142
143
6
void RISCV::writePltHeader(uint8_t *buf) const {
144
6
  // 1: auipc t2, %pcrel_hi(.got.plt)
145
6
  // sub t1, t1, t3
146
6
  // l[wd] t3, %pcrel_lo(1b)(t2); t3 = _dl_runtime_resolve
147
6
  // addi t1, t1, -pltHeaderSize-12; t1 = &.plt[i] - &.plt[0]
148
6
  // addi t0, t2, %pcrel_lo(1b)
149
6
  // srli t1, t1, (rv64?1:2); t1 = &.got.plt[i] - &.got.plt[0]
150
6
  // l[wd] t0, Wordsize(t0); t0 = link_map
151
6
  // jr t3
152
6
  uint32_t offset = in.gotPlt->getVA() - in.plt->getVA();
153
6
  uint32_t load = config->is64 ? 
LD3
:
LW3
;
154
6
  write32le(buf + 0, utype(AUIPC, X_T2, hi20(offset)));
155
6
  write32le(buf + 4, rtype(SUB, X_T1, X_T1, X_T3));
156
6
  write32le(buf + 8, itype(load, X_T3, X_T2, lo12(offset)));
157
6
  write32le(buf + 12, itype(ADDI, X_T1, X_T1, -target->pltHeaderSize - 12));
158
6
  write32le(buf + 16, itype(ADDI, X_T0, X_T2, lo12(offset)));
159
6
  write32le(buf + 20, itype(SRLI, X_T1, X_T1, config->is64 ? 
13
:
23
));
160
6
  write32le(buf + 24, itype(load, X_T0, X_T0, config->wordsize));
161
6
  write32le(buf + 28, itype(JALR, 0, X_T3, 0));
162
6
}
163
164
void RISCV::writePlt(uint8_t *buf, uint64_t gotPltEntryAddr,
165
                     uint64_t pltEntryAddr, int32_t index,
166
8
                     unsigned relOff) const {
167
8
  // 1: auipc t3, %pcrel_hi(f@.got.plt)
168
8
  // l[wd] t3, %pcrel_lo(1b)(t3)
169
8
  // jalr t1, t3
170
8
  // nop
171
8
  uint32_t offset = gotPltEntryAddr - pltEntryAddr;
172
8
  write32le(buf + 0, utype(AUIPC, X_T3, hi20(offset)));
173
8
  write32le(buf + 4, itype(config->is64 ? 
LD4
:
LW4
, X_T3, X_T3, lo12(offset)));
174
8
  write32le(buf + 8, itype(JALR, X_T1, X_T3, 0));
175
8
  write32le(buf + 12, itype(ADDI, 0, 0, 0));
176
8
}
177
178
5
RelType RISCV::getDynRel(RelType type) const {
179
5
  return type == target->symbolicRel ? 
type4
180
5
                                     : 
static_cast<RelType>(R_RISCV_NONE)1
;
181
5
}
182
183
RelExpr RISCV::getRelExpr(const RelType type, const Symbol &s,
184
288
                          const uint8_t *loc) const {
185
288
  switch (type) {
186
288
  case R_RISCV_ADD8:
187
20
  case R_RISCV_ADD16:
188
20
  case R_RISCV_ADD32:
189
20
  case R_RISCV_ADD64:
190
20
  case R_RISCV_SET6:
191
20
  case R_RISCV_SET8:
192
20
  case R_RISCV_SET16:
193
20
  case R_RISCV_SET32:
194
20
  case R_RISCV_SUB6:
195
20
  case R_RISCV_SUB8:
196
20
  case R_RISCV_SUB16:
197
20
  case R_RISCV_SUB32:
198
20
  case R_RISCV_SUB64:
199
20
    return R_RISCV_ADD;
200
58
  case R_RISCV_JAL:
201
58
  case R_RISCV_BRANCH:
202
58
  case R_RISCV_PCREL_HI20:
203
58
  case R_RISCV_RVC_BRANCH:
204
58
  case R_RISCV_RVC_JUMP:
205
58
  case R_RISCV_32_PCREL:
206
58
    return R_PC;
207
58
  case R_RISCV_CALL:
208
38
  case R_RISCV_CALL_PLT:
209
38
    return R_PLT_PC;
210
38
  case R_RISCV_GOT_HI20:
211
8
    return R_GOT_PC;
212
77
  case R_RISCV_PCREL_LO12_I:
213
77
  case R_RISCV_PCREL_LO12_S:
214
77
    return R_RISCV_PC_INDIRECT;
215
77
  case R_RISCV_TLS_GD_HI20:
216
20
    return R_TLSGD_PC;
217
77
  case R_RISCV_TLS_GOT_HI20:
218
8
    config->hasStaticTlsModel = true;
219
8
    return R_GOT_PC;
220
77
  case R_RISCV_TPREL_HI20:
221
16
  case R_RISCV_TPREL_LO12_I:
222
16
  case R_RISCV_TPREL_LO12_S:
223
16
    return R_TLS;
224
16
  case R_RISCV_RELAX:
225
8
  case R_RISCV_ALIGN:
226
8
  case R_RISCV_TPREL_ADD:
227
8
    return R_HINT;
228
35
  default:
229
35
    return R_ABS;
230
288
  }
231
288
}
232
233
// Extract bits V[Begin:End], where range is inclusive, and Begin must be < 63.
234
188
static uint32_t extractBits(uint64_t v, uint32_t begin, uint32_t end) {
235
188
  return (v & ((1ULL << (begin + 1)) - 1)) >> end;
236
188
}
237
238
void RISCV::relocateOne(uint8_t *loc, const RelType type,
239
377
                        const uint64_t val) const {
240
377
  const unsigned bits = config->wordsize * 8;
241
377
242
377
  switch (type) {
243
377
  case R_RISCV_32:
244
10
    write32le(loc, val);
245
10
    return;
246
377
  case R_RISCV_64:
247
10
    write64le(loc, val);
248
10
    return;
249
377
250
377
  case R_RISCV_RVC_BRANCH: {
251
0
    checkInt(loc, static_cast<int64_t>(val) >> 1, 8, type);
252
0
    checkAlignment(loc, val, 2, type);
253
0
    uint16_t insn = read16le(loc) & 0xE383;
254
0
    uint16_t imm8 = extractBits(val, 8, 8) << 12;
255
0
    uint16_t imm4_3 = extractBits(val, 4, 3) << 10;
256
0
    uint16_t imm7_6 = extractBits(val, 7, 6) << 5;
257
0
    uint16_t imm2_1 = extractBits(val, 2, 1) << 3;
258
0
    uint16_t imm5 = extractBits(val, 5, 5) << 2;
259
0
    insn |= imm8 | imm4_3 | imm7_6 | imm2_1 | imm5;
260
0
261
0
    write16le(loc, insn);
262
0
    return;
263
377
  }
264
377
265
377
  case R_RISCV_RVC_JUMP: {
266
0
    checkInt(loc, static_cast<int64_t>(val) >> 1, 11, type);
267
0
    checkAlignment(loc, val, 2, type);
268
0
    uint16_t insn = read16le(loc) & 0xE003;
269
0
    uint16_t imm11 = extractBits(val, 11, 11) << 12;
270
0
    uint16_t imm4 = extractBits(val, 4, 4) << 11;
271
0
    uint16_t imm9_8 = extractBits(val, 9, 8) << 9;
272
0
    uint16_t imm10 = extractBits(val, 10, 10) << 8;
273
0
    uint16_t imm6 = extractBits(val, 6, 6) << 7;
274
0
    uint16_t imm7 = extractBits(val, 7, 7) << 6;
275
0
    uint16_t imm3_1 = extractBits(val, 3, 1) << 3;
276
0
    uint16_t imm5 = extractBits(val, 5, 5) << 2;
277
0
    insn |= imm11 | imm4 | imm9_8 | imm10 | imm6 | imm7 | imm3_1 | imm5;
278
0
279
0
    write16le(loc, insn);
280
0
    return;
281
377
  }
282
377
283
377
  case R_RISCV_RVC_LUI: {
284
0
    int64_t imm = SignExtend64(val + 0x800, bits) >> 12;
285
0
    checkInt(loc, imm, 6, type);
286
0
    if (imm == 0) { // `c.lui rd, 0` is illegal, convert to `c.li rd, 0`
287
0
      write16le(loc, (read16le(loc) & 0x0F83) | 0x4000);
288
0
    } else {
289
0
      uint16_t imm17 = extractBits(val + 0x800, 17, 17) << 12;
290
0
      uint16_t imm16_12 = extractBits(val + 0x800, 16, 12) << 2;
291
0
      write16le(loc, (read16le(loc) & 0xEF83) | imm17 | imm16_12);
292
0
    }
293
0
    return;
294
377
  }
295
377
296
377
  case R_RISCV_JAL: {
297
16
    checkInt(loc, static_cast<int64_t>(val) >> 1, 20, type);
298
16
    checkAlignment(loc, val, 2, type);
299
16
300
16
    uint32_t insn = read32le(loc) & 0xFFF;
301
16
    uint32_t imm20 = extractBits(val, 20, 20) << 31;
302
16
    uint32_t imm10_1 = extractBits(val, 10, 1) << 21;
303
16
    uint32_t imm11 = extractBits(val, 11, 11) << 20;
304
16
    uint32_t imm19_12 = extractBits(val, 19, 12) << 12;
305
16
    insn |= imm20 | imm10_1 | imm11 | imm19_12;
306
16
307
16
    write32le(loc, insn);
308
16
    return;
309
377
  }
310
377
311
377
  case R_RISCV_BRANCH: {
312
16
    checkInt(loc, static_cast<int64_t>(val) >> 1, 12, type);
313
16
    checkAlignment(loc, val, 2, type);
314
16
315
16
    uint32_t insn = read32le(loc) & 0x1FFF07F;
316
16
    uint32_t imm12 = extractBits(val, 12, 12) << 31;
317
16
    uint32_t imm10_5 = extractBits(val, 10, 5) << 25;
318
16
    uint32_t imm4_1 = extractBits(val, 4, 1) << 8;
319
16
    uint32_t imm11 = extractBits(val, 11, 11) << 7;
320
16
    insn |= imm12 | imm10_5 | imm4_1 | imm11;
321
16
322
16
    write32le(loc, insn);
323
16
    return;
324
377
  }
325
377
326
377
  // auipc + jalr pair
327
377
  case R_RISCV_CALL:
328
38
  case R_RISCV_CALL_PLT: {
329
38
    int64_t hi = SignExtend64(val + 0x800, bits) >> 12;
330
38
    checkInt(loc, hi, 20, type);
331
38
    if (isInt<20>(hi)) {
332
36
      relocateOne(loc, R_RISCV_PCREL_HI20, val);
333
36
      relocateOne(loc + 4, R_RISCV_PCREL_LO12_I, val);
334
36
    }
335
38
    return;
336
38
  }
337
38
338
112
  case R_RISCV_GOT_HI20:
339
112
  case R_RISCV_PCREL_HI20:
340
112
  case R_RISCV_TLS_GD_HI20:
341
112
  case R_RISCV_TLS_GOT_HI20:
342
112
  case R_RISCV_TPREL_HI20:
343
112
  case R_RISCV_HI20: {
344
112
    uint64_t hi = val + 0x800;
345
112
    checkInt(loc, SignExtend64(hi, bits) >> 12, 20, type);
346
112
    write32le(loc, (read32le(loc) & 0xFFF) | (hi & 0xFFFFF000));
347
112
    return;
348
112
  }
349
112
350
112
  case R_RISCV_PCREL_LO12_I:
351
109
  case R_RISCV_TPREL_LO12_I:
352
109
  case R_RISCV_LO12_I: {
353
109
    uint64_t hi = (val + 0x800) >> 12;
354
109
    uint64_t lo = val - (hi << 12);
355
109
    write32le(loc, (read32le(loc) & 0xFFFFF) | ((lo & 0xFFF) << 20));
356
109
    return;
357
109
  }
358
109
359
109
  case R_RISCV_PCREL_LO12_S:
360
30
  case R_RISCV_TPREL_LO12_S:
361
30
  case R_RISCV_LO12_S: {
362
30
    uint64_t hi = (val + 0x800) >> 12;
363
30
    uint64_t lo = val - (hi << 12);
364
30
    uint32_t imm11_5 = extractBits(lo, 11, 5) << 25;
365
30
    uint32_t imm4_0 = extractBits(lo, 4, 0) << 7;
366
30
    write32le(loc, (read32le(loc) & 0x1FFF07F) | imm11_5 | imm4_0);
367
30
    return;
368
30
  }
369
30
370
30
  case R_RISCV_ADD8:
371
2
    *loc += val;
372
2
    return;
373
30
  case R_RISCV_ADD16:
374
2
    write16le(loc, read16le(loc) + val);
375
2
    return;
376
30
  case R_RISCV_ADD32:
377
2
    write32le(loc, read32le(loc) + val);
378
2
    return;
379
30
  case R_RISCV_ADD64:
380
4
    write64le(loc, read64le(loc) + val);
381
4
    return;
382
30
  case R_RISCV_SUB6:
383
0
    *loc = (*loc & 0xc0) | (((*loc & 0x3f) - val) & 0x3f);
384
0
    return;
385
30
  case R_RISCV_SUB8:
386
2
    *loc -= val;
387
2
    return;
388
30
  case R_RISCV_SUB16:
389
2
    write16le(loc, read16le(loc) - val);
390
2
    return;
391
30
  case R_RISCV_SUB32:
392
2
    write32le(loc, read32le(loc) - val);
393
2
    return;
394
30
  case R_RISCV_SUB64:
395
4
    write64le(loc, read64le(loc) - val);
396
4
    return;
397
30
  case R_RISCV_SET6:
398
0
    *loc = (*loc & 0xc0) | (val & 0x3f);
399
0
    return;
400
30
  case R_RISCV_SET8:
401
0
    *loc = val;
402
0
    return;
403
30
  case R_RISCV_SET16:
404
0
    write16le(loc, val);
405
0
    return;
406
30
  case R_RISCV_SET32:
407
2
  case R_RISCV_32_PCREL:
408
2
    write32le(loc, val);
409
2
    return;
410
2
411
7
  case R_RISCV_TLS_DTPREL32:
412
7
    write32le(loc, val - dtpOffset);
413
7
    break;
414
7
  case R_RISCV_TLS_DTPREL64:
415
7
    write64le(loc, val - dtpOffset);
416
7
    break;
417
2
418
2
  case R_RISCV_ALIGN:
419
0
  case R_RISCV_RELAX:
420
0
    return; // Ignored (for now)
421
0
  case R_RISCV_NONE:
422
0
    return; // Do nothing
423
0
424
0
  // These are handled by the dynamic linker
425
0
  case R_RISCV_RELATIVE:
426
0
  case R_RISCV_COPY:
427
0
  case R_RISCV_JUMP_SLOT:
428
0
  // GP-relative relocations are only produced after relaxation, which
429
0
  // we don't support for now
430
0
  case R_RISCV_GPREL_I:
431
0
  case R_RISCV_GPREL_S:
432
0
  default:
433
0
    error(getErrorLocation(loc) +
434
0
          "unimplemented relocation: " + toString(type));
435
0
    return;
436
377
  }
437
377
}
438
439
180
TargetInfo *elf::getRISCVTargetInfo() {
440
180
  static RISCV target;
441
180
  return &target;
442
180
}