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