1//===- MIPS.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 "RelocScan.h"
11#include "Symbols.h"
12#include "SyntheticSections.h"
13#include "Target.h"
14#include "llvm/BinaryFormat/ELF.h"
15
16using namespace llvm;
17using namespace llvm::object;
18using namespace llvm::ELF;
19using namespace lld;
20using namespace lld::elf;
21
22namespace {
23template <class ELFT> class MIPS final : public TargetInfo {
24public:
25 MIPS(Ctx &);
26 uint32_t calcEFlags() const override;
27 RelExpr getRelExpr(RelType type, const Symbol &s,
28 const uint8_t *loc) const override;
29 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override;
30 RelType getDynRel(RelType type) const override;
31 void writeGotPlt(uint8_t *buf, const Symbol &s) const override;
32 void writePltHeader(uint8_t *buf) const override;
33 void writePlt(uint8_t *buf, const Symbol &sym,
34 uint64_t pltEntryAddr) const override;
35 template <class RelTy>
36 void scanSectionImpl(InputSectionBase &, Relocs<RelTy>);
37 void scanSection(InputSectionBase &) override;
38 bool needsThunk(RelExpr expr, RelType type, const InputFile *file,
39 uint64_t branchAddr, const Symbol &s,
40 int64_t a) const override;
41 void relocate(uint8_t *loc, const Relocation &rel,
42 uint64_t val) const override;
43 bool usesOnlyLowPageBits(RelType type) const override;
44};
45} // namespace
46
47uint64_t elf::getMipsPageAddr(uint64_t addr) {
48 return (addr + 0x8000) & ~0xffff;
49}
50
51template <class ELFT> MIPS<ELFT>::MIPS(Ctx &ctx) : TargetInfo(ctx) {
52 gotPltHeaderEntriesNum = 2;
53 defaultMaxPageSize = 65536;
54 pltEntrySize = 16;
55 pltHeaderSize = 32;
56 copyRel = R_MIPS_COPY;
57 pltRel = R_MIPS_JUMP_SLOT;
58 needsThunks = true;
59
60 // Set `sigrie 1` as a trap instruction.
61 write32(ctx, trapInstr.data(), 0x04170001);
62
63 if (ELFT::Is64Bits) {
64 relativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
65 symbolicRel = R_MIPS_64;
66 tlsGotRel = R_MIPS_TLS_TPREL64;
67 tlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
68 tlsOffsetRel = R_MIPS_TLS_DTPREL64;
69 } else {
70 relativeRel = R_MIPS_REL32;
71 symbolicRel = R_MIPS_32;
72 tlsGotRel = R_MIPS_TLS_TPREL32;
73 tlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
74 tlsOffsetRel = R_MIPS_TLS_DTPREL32;
75 }
76}
77
78template <class ELFT> uint32_t MIPS<ELFT>::calcEFlags() const {
79 return calcMipsEFlags<ELFT>(ctx);
80}
81
82template <class ELFT>
83RelExpr MIPS<ELFT>::getRelExpr(RelType type, const Symbol &s,
84 const uint8_t *loc) const {
85 // See comment in the calculateMipsRelChain.
86 if (ELFT::Is64Bits || ctx.arg.mipsN32Abi)
87 type.v &= 0xff;
88
89 switch (type) {
90 case R_MIPS_JALR:
91 // Older versions of clang would erroneously emit this relocation not only
92 // against functions (loaded from the GOT) but also against data symbols
93 // (e.g. a table of function pointers). When we encounter this, ignore the
94 // relocation and emit a warning instead.
95 if (!s.isFunc() && s.type != STT_NOTYPE) {
96 Warn(ctx) << getErrorLoc(ctx, loc)
97 << "found R_MIPS_JALR relocation against non-function symbol "
98 << &s << ". This is invalid and most likely a compiler bug.";
99 return R_NONE;
100 }
101
102 // If the target symbol is not preemptible and is not microMIPS,
103 // it might be possible to replace jalr/jr instruction by bal/b.
104 // It depends on the target symbol's offset.
105 if (!s.isPreemptible && !(s.getVA(ctx) & 0x1))
106 return R_PC;
107 return R_NONE;
108 case R_MICROMIPS_JALR:
109 return R_NONE;
110 case R_MIPS_GPREL16:
111 case R_MIPS_GPREL32:
112 case R_MICROMIPS_GPREL16:
113 case R_MICROMIPS_GPREL7_S2:
114 return RE_MIPS_GOTREL;
115 case R_MIPS_26:
116 case R_MICROMIPS_26_S1:
117 return R_PLT;
118 case R_MICROMIPS_PC26_S1:
119 return R_PLT_PC;
120 case R_MIPS_HI16:
121 case R_MIPS_LO16:
122 case R_MIPS_HIGHER:
123 case R_MIPS_HIGHEST:
124 case R_MICROMIPS_HI16:
125 case R_MICROMIPS_LO16:
126 // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
127 // offset between start of function and 'gp' value which by default
128 // equal to the start of .got section. In that case we consider these
129 // relocations as relative.
130 if (&s == ctx.sym.mipsGpDisp)
131 return RE_MIPS_GOT_GP_PC;
132 if (&s == ctx.sym.mipsLocalGp)
133 return RE_MIPS_GOT_GP;
134 [[fallthrough]];
135 case R_MIPS_32:
136 case R_MIPS_64:
137 case R_MIPS_GOT_OFST:
138 case R_MIPS_SUB:
139 return R_ABS;
140 case R_MIPS_TLS_DTPREL_HI16:
141 case R_MIPS_TLS_DTPREL_LO16:
142 case R_MIPS_TLS_DTPREL32:
143 case R_MIPS_TLS_DTPREL64:
144 case R_MICROMIPS_TLS_DTPREL_HI16:
145 case R_MICROMIPS_TLS_DTPREL_LO16:
146 return R_DTPREL;
147 case R_MIPS_TLS_TPREL_HI16:
148 case R_MIPS_TLS_TPREL_LO16:
149 case R_MIPS_TLS_TPREL32:
150 case R_MIPS_TLS_TPREL64:
151 case R_MICROMIPS_TLS_TPREL_HI16:
152 case R_MICROMIPS_TLS_TPREL_LO16:
153 return R_TPREL;
154 case R_MIPS_PC32:
155 case R_MIPS_PC16:
156 case R_MIPS_PC19_S2:
157 case R_MIPS_PC21_S2:
158 case R_MIPS_PC26_S2:
159 case R_MIPS_PCHI16:
160 case R_MIPS_PCLO16:
161 case R_MICROMIPS_PC7_S1:
162 case R_MICROMIPS_PC10_S1:
163 case R_MICROMIPS_PC16_S1:
164 case R_MICROMIPS_PC18_S3:
165 case R_MICROMIPS_PC19_S2:
166 case R_MICROMIPS_PC23_S2:
167 case R_MICROMIPS_PC21_S1:
168 return R_PC;
169 case R_MIPS_GOT16:
170 case R_MICROMIPS_GOT16:
171 if (s.isLocal())
172 return RE_MIPS_GOT_LOCAL_PAGE;
173 [[fallthrough]];
174 case R_MIPS_CALL16:
175 case R_MIPS_GOT_DISP:
176 case R_MIPS_TLS_GOTTPREL:
177 case R_MICROMIPS_CALL16:
178 case R_MICROMIPS_TLS_GOTTPREL:
179 return RE_MIPS_GOT_OFF;
180 case R_MIPS_CALL_HI16:
181 case R_MIPS_CALL_LO16:
182 case R_MIPS_GOT_HI16:
183 case R_MIPS_GOT_LO16:
184 case R_MICROMIPS_CALL_HI16:
185 case R_MICROMIPS_CALL_LO16:
186 case R_MICROMIPS_GOT_HI16:
187 case R_MICROMIPS_GOT_LO16:
188 return RE_MIPS_GOT_OFF32;
189 case R_MIPS_GOT_PAGE:
190 return RE_MIPS_GOT_LOCAL_PAGE;
191 case R_MIPS_TLS_GD:
192 case R_MICROMIPS_TLS_GD:
193 return RE_MIPS_TLSGD;
194 case R_MIPS_TLS_LDM:
195 case R_MICROMIPS_TLS_LDM:
196 return RE_MIPS_TLSLD;
197 case R_MIPS_NONE:
198 return R_NONE;
199 default:
200 Err(ctx) << getErrorLoc(ctx, loc) << "unknown relocation (" << type.v
201 << ") against symbol " << &s;
202 return R_NONE;
203 }
204}
205
206template <class ELFT> RelType MIPS<ELFT>::getDynRel(RelType type) const {
207 if (type == symbolicRel)
208 return type;
209 return R_MIPS_NONE;
210}
211
212template <class ELFT>
213void MIPS<ELFT>::writeGotPlt(uint8_t *buf, const Symbol &) const {
214 uint64_t va = ctx.in.plt->getVA();
215 if (isMicroMips(ctx))
216 va |= 1;
217 write32(ctx, buf, va);
218}
219
220template <endianness E>
221static uint32_t readShuffle(Ctx &ctx, const uint8_t *loc) {
222 // The major opcode of a microMIPS instruction needs to appear
223 // in the first 16-bit word (lowest address) for efficient hardware
224 // decode so that it knows if the instruction is 16-bit or 32-bit
225 // as early as possible. To do so, little-endian binaries keep 16-bit
226 // words in a big-endian order. That is why we have to swap these
227 // words to get a correct value.
228 uint32_t v = read32(ctx, p: loc);
229 if (E == llvm::endianness::little)
230 return (v << 16) | (v >> 16);
231 return v;
232}
233
234static void writeValue(Ctx &ctx, uint8_t *loc, uint64_t v, uint8_t bitsSize,
235 uint8_t shift) {
236 uint32_t instr = read32(ctx, p: loc);
237 uint32_t mask = 0xffffffff >> (32 - bitsSize);
238 uint32_t data = (instr & ~mask) | ((v >> shift) & mask);
239 write32(ctx, p: loc, v: data);
240}
241
242template <endianness E>
243static void writeShuffle(Ctx &ctx, uint8_t *loc, uint64_t v, uint8_t bitsSize,
244 uint8_t shift) {
245 // See comments in readShuffle for purpose of this code.
246 uint16_t *words = (uint16_t *)loc;
247 if (E == llvm::endianness::little)
248 std::swap(a&: words[0], b&: words[1]);
249
250 writeValue(ctx, loc, v, bitsSize, shift);
251
252 if (E == llvm::endianness::little)
253 std::swap(a&: words[0], b&: words[1]);
254}
255
256template <endianness E>
257static void writeMicroRelocation16(Ctx &ctx, uint8_t *loc, uint64_t v,
258 uint8_t bitsSize, uint8_t shift) {
259 uint16_t instr = read16(ctx, p: loc);
260 uint16_t mask = 0xffff >> (16 - bitsSize);
261 uint16_t data = (instr & ~mask) | ((v >> shift) & mask);
262 write16(ctx, p: loc, v: data);
263}
264
265template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *buf) const {
266 if (isMicroMips(ctx)) {
267 uint64_t gotPlt = ctx.in.gotPlt->getVA();
268 uint64_t plt = ctx.in.plt->getVA();
269 // Overwrite trap instructions written by Writer::writeTrapInstr.
270 memset(buf, 0, pltHeaderSize);
271
272 write16(ctx, buf,
273 isMipsR6(ctx) ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
274 write16(ctx, buf + 4, 0xff23); // lw $25, 0($3)
275 write16(ctx, buf + 8, 0x0535); // subu16 $2, $2, $3
276 write16(ctx, buf + 10, 0x2525); // srl16 $2, $2, 2
277 write16(ctx, buf + 12, 0x3302); // addiu $24, $2, -2
278 write16(ctx, buf + 14, 0xfffe);
279 write16(ctx, buf + 16, 0x0dff); // move $15, $31
280 if (isMipsR6(ctx)) {
281 write16(ctx, buf + 18, 0x0f83); // move $28, $3
282 write16(ctx, buf + 20, 0x472b); // jalrc $25
283 write16(ctx, buf + 22, 0x0c00); // nop
284 relocateNoSym(loc: buf, type: R_MICROMIPS_PC19_S2, val: gotPlt - plt);
285 } else {
286 write16(ctx, buf + 18, 0x45f9); // jalrc $25
287 write16(ctx, buf + 20, 0x0f83); // move $28, $3
288 write16(ctx, buf + 22, 0x0c00); // nop
289 relocateNoSym(loc: buf, type: R_MICROMIPS_PC23_S2, val: gotPlt - plt);
290 }
291 return;
292 }
293
294 if (ctx.arg.mipsN32Abi) {
295 write32(ctx, buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
296 write32(ctx, buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
297 write32(ctx, buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
298 write32(ctx, buf + 12, 0x030ec023); // subu $24, $24, $14
299 write32(ctx, buf + 16, 0x03e07825); // move $15, $31
300 write32(ctx, buf + 20, 0x0018c082); // srl $24, $24, 2
301 } else if (ELFT::Is64Bits) {
302 write32(ctx, buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
303 write32(ctx, buf + 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
304 write32(ctx, buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
305 write32(ctx, buf + 12, 0x030ec023); // subu $24, $24, $14
306 write32(ctx, buf + 16, 0x03e07825); // move $15, $31
307 write32(ctx, buf + 20, 0x0018c0c2); // srl $24, $24, 3
308 } else {
309 write32(ctx, buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
310 write32(ctx, buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
311 write32(ctx, buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
312 write32(ctx, buf + 12, 0x031cc023); // subu $24, $24, $28
313 write32(ctx, buf + 16, 0x03e07825); // move $15, $31
314 write32(ctx, buf + 20, 0x0018c082); // srl $24, $24, 2
315 }
316
317 uint32_t jalrInst = ctx.arg.zHazardplt ? 0x0320fc09 : 0x0320f809;
318 write32(ctx, buf + 24, jalrInst); // jalr.hb $25 or jalr $25
319 write32(ctx, buf + 28, 0x2718fffe); // subu $24, $24, 2
320
321 uint64_t gotPlt = ctx.in.gotPlt->getVA();
322 writeValue(ctx, buf, gotPlt + 0x8000, 16, 16);
323 writeValue(ctx, buf + 4, gotPlt, 16, 0);
324 writeValue(ctx, buf + 8, gotPlt, 16, 0);
325}
326
327template <class ELFT>
328void MIPS<ELFT>::writePlt(uint8_t *buf, const Symbol &sym,
329 uint64_t pltEntryAddr) const {
330 uint64_t gotPltEntryAddr = sym.getGotPltVA(ctx);
331 if (isMicroMips(ctx)) {
332 // Overwrite trap instructions written by Writer::writeTrapInstr.
333 memset(buf, 0, pltEntrySize);
334
335 if (isMipsR6(ctx)) {
336 write16(ctx, buf, 0x7840); // addiupc $2, (GOTPLT) - .
337 write16(ctx, buf + 4, 0xff22); // lw $25, 0($2)
338 write16(ctx, buf + 8, 0x0f02); // move $24, $2
339 write16(ctx, buf + 10, 0x4723); // jrc $25 / jr16 $25
340 relocateNoSym(loc: buf, type: R_MICROMIPS_PC19_S2, val: gotPltEntryAddr - pltEntryAddr);
341 } else {
342 write16(ctx, buf, 0x7900); // addiupc $2, (GOTPLT) - .
343 write16(ctx, buf + 4, 0xff22); // lw $25, 0($2)
344 write16(ctx, buf + 8, 0x4599); // jrc $25 / jr16 $25
345 write16(ctx, buf + 10, 0x0f02); // move $24, $2
346 relocateNoSym(loc: buf, type: R_MICROMIPS_PC23_S2, val: gotPltEntryAddr - pltEntryAddr);
347 }
348 return;
349 }
350
351 uint32_t loadInst = ELFT::Is64Bits ? 0xddf90000 : 0x8df90000;
352 uint32_t jrInst = isMipsR6(ctx)
353 ? (ctx.arg.zHazardplt ? 0x03200409 : 0x03200009)
354 : (ctx.arg.zHazardplt ? 0x03200408 : 0x03200008);
355 uint32_t addInst = ELFT::Is64Bits ? 0x65f80000 : 0x25f80000;
356
357 write32(ctx, buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
358 write32(ctx, buf + 4, loadInst); // l[wd] $25, %lo(.got.plt entry)($15)
359 write32(ctx, buf + 8, jrInst); // jr $25 / jr.hb $25
360 write32(ctx, buf + 12, addInst); // [d]addiu $24, $15, %lo(.got.plt entry)
361 writeValue(ctx, buf, gotPltEntryAddr + 0x8000, 16, 16);
362 writeValue(ctx, buf + 4, gotPltEntryAddr, 16, 0);
363 writeValue(ctx, buf + 12, gotPltEntryAddr, 16, 0);
364}
365
366template <class ELFT>
367bool MIPS<ELFT>::needsThunk(RelExpr expr, RelType type, const InputFile *file,
368 uint64_t branchAddr, const Symbol &s,
369 int64_t /*a*/) const {
370 // Any MIPS PIC code function is invoked with its address in register $t9.
371 // So if we have a branch instruction from non-PIC code to the PIC one
372 // we cannot make the jump directly and need to create a small stubs
373 // to save the target function address.
374 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
375 if (type != R_MIPS_26 && type != R_MIPS_PC26_S2 &&
376 type != R_MICROMIPS_26_S1 && type != R_MICROMIPS_PC26_S1)
377 return false;
378 auto *f = dyn_cast<ObjFile<ELFT>>(file);
379 if (!f)
380 return false;
381 // If current file has PIC code, LA25 stub is not required.
382 if (f->getObj().getHeader().e_flags & EF_MIPS_PIC)
383 return false;
384 auto *d = dyn_cast<Defined>(Val: &s);
385 // LA25 is required if target file has PIC code
386 // or target symbol is a PIC symbol.
387 return d && isMipsPIC<ELFT>(d);
388}
389
390template <class ELFT>
391int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *buf, RelType type) const {
392 const endianness e = ELFT::Endianness;
393 switch (type) {
394 case R_MIPS_32:
395 case R_MIPS_REL32:
396 case R_MIPS_GPREL32:
397 case R_MIPS_TLS_DTPREL32:
398 case R_MIPS_TLS_DTPMOD32:
399 case R_MIPS_TLS_TPREL32:
400 return SignExtend64<32>(read32(ctx, buf));
401 case R_MIPS_26:
402 // FIXME (simon): If the relocation target symbol is not a PLT entry
403 // we should use another expression for calculation:
404 // ((A << 2) | (P & 0xf0000000)) >> 2
405 return SignExtend64<28>(read32(ctx, buf) << 2);
406 case R_MIPS_CALL_HI16:
407 case R_MIPS_GOT16:
408 case R_MIPS_GOT_HI16:
409 case R_MIPS_HI16:
410 case R_MIPS_PCHI16:
411 return SignExtend64<16>(read32(ctx, buf)) << 16;
412 case R_MIPS_CALL16:
413 case R_MIPS_CALL_LO16:
414 case R_MIPS_GOT_LO16:
415 case R_MIPS_GPREL16:
416 case R_MIPS_LO16:
417 case R_MIPS_PCLO16:
418 case R_MIPS_TLS_DTPREL_HI16:
419 case R_MIPS_TLS_DTPREL_LO16:
420 case R_MIPS_TLS_GD:
421 case R_MIPS_TLS_GOTTPREL:
422 case R_MIPS_TLS_LDM:
423 case R_MIPS_TLS_TPREL_HI16:
424 case R_MIPS_TLS_TPREL_LO16:
425 return SignExtend64<16>(read32(ctx, buf));
426 case R_MICROMIPS_GOT16:
427 case R_MICROMIPS_HI16:
428 return SignExtend64<16>(readShuffle<e>(ctx, buf)) << 16;
429 case R_MICROMIPS_CALL16:
430 case R_MICROMIPS_GPREL16:
431 case R_MICROMIPS_LO16:
432 case R_MICROMIPS_TLS_DTPREL_HI16:
433 case R_MICROMIPS_TLS_DTPREL_LO16:
434 case R_MICROMIPS_TLS_GD:
435 case R_MICROMIPS_TLS_GOTTPREL:
436 case R_MICROMIPS_TLS_LDM:
437 case R_MICROMIPS_TLS_TPREL_HI16:
438 case R_MICROMIPS_TLS_TPREL_LO16:
439 return SignExtend64<16>(readShuffle<e>(ctx, buf));
440 case R_MICROMIPS_GPREL7_S2:
441 return SignExtend64<9>(readShuffle<e>(ctx, buf) << 2);
442 case R_MIPS_PC16:
443 return SignExtend64<18>(read32(ctx, buf) << 2);
444 case R_MIPS_PC19_S2:
445 return SignExtend64<21>(read32(ctx, buf) << 2);
446 case R_MIPS_PC21_S2:
447 return SignExtend64<23>(read32(ctx, buf) << 2);
448 case R_MIPS_PC26_S2:
449 return SignExtend64<28>(read32(ctx, buf) << 2);
450 case R_MIPS_PC32:
451 return SignExtend64<32>(read32(ctx, buf));
452 case R_MICROMIPS_26_S1:
453 return SignExtend64<27>(readShuffle<e>(ctx, buf) << 1);
454 case R_MICROMIPS_PC7_S1:
455 return SignExtend64<8>(read16(ctx, buf) << 1);
456 case R_MICROMIPS_PC10_S1:
457 return SignExtend64<11>(read16(ctx, buf) << 1);
458 case R_MICROMIPS_PC16_S1:
459 return SignExtend64<17>(readShuffle<e>(ctx, buf) << 1);
460 case R_MICROMIPS_PC18_S3:
461 return SignExtend64<21>(readShuffle<e>(ctx, buf) << 3);
462 case R_MICROMIPS_PC19_S2:
463 return SignExtend64<21>(readShuffle<e>(ctx, buf) << 2);
464 case R_MICROMIPS_PC21_S1:
465 return SignExtend64<22>(readShuffle<e>(ctx, buf) << 1);
466 case R_MICROMIPS_PC23_S2:
467 return SignExtend64<25>(readShuffle<e>(ctx, buf) << 2);
468 case R_MICROMIPS_PC26_S1:
469 return SignExtend64<27>(readShuffle<e>(ctx, buf) << 1);
470 case R_MIPS_64:
471 case R_MIPS_TLS_DTPMOD64:
472 case R_MIPS_TLS_DTPREL64:
473 case R_MIPS_TLS_TPREL64:
474 case (R_MIPS_64 << 8) | R_MIPS_REL32:
475 return read64(ctx, buf);
476 case R_MIPS_COPY:
477 return ctx.arg.is64 ? read64(ctx, buf) : read32(ctx, buf);
478 case R_MIPS_NONE:
479 case R_MIPS_JUMP_SLOT:
480 case R_MIPS_JALR:
481 // These relocations are defined as not having an implicit addend.
482 return 0;
483 default:
484 InternalErr(ctx, buf) << "cannot read addend for relocation " << type;
485 return 0;
486 }
487}
488
489static std::pair<uint32_t, uint64_t>
490calculateMipsRelChain(Ctx &ctx, uint8_t *loc, uint32_t type, uint64_t val) {
491 // MIPS N64 ABI packs multiple relocations into the single relocation
492 // record. In general, all up to three relocations can have arbitrary
493 // types. In fact, Clang and GCC uses only a few combinations. For now,
494 // we support two of them. That is allow to pass at least all LLVM
495 // test suite cases.
496 // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
497 // <any relocation> / R_MIPS_64 / R_MIPS_NONE
498 // The first relocation is a 'real' relocation which is calculated
499 // using the corresponding symbol's value. The second and the third
500 // relocations used to modify result of the first one: extend it to
501 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
502 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
503 uint32_t type2 = (type >> 8) & 0xff;
504 uint32_t type3 = (type >> 16) & 0xff;
505 if (type2 == R_MIPS_NONE && type3 == R_MIPS_NONE)
506 return std::make_pair(x&: type, y&: val);
507 if (type2 == R_MIPS_64 && type3 == R_MIPS_NONE)
508 return std::make_pair(x&: type2, y&: val);
509 if (type2 == R_MIPS_SUB && (type3 == R_MIPS_HI16 || type3 == R_MIPS_LO16))
510 return std::make_pair(x&: type3, y: -val);
511 Err(ctx) << getErrorLoc(ctx, loc) << "unsupported relocations combination "
512 << type;
513 return std::make_pair(x: type & 0xff, y&: val);
514}
515
516static bool isBranchReloc(RelType type) {
517 return type == R_MIPS_26 || type == R_MIPS_PC26_S2 ||
518 type == R_MIPS_PC21_S2 || type == R_MIPS_PC16;
519}
520
521static bool isMicroBranchReloc(RelType type) {
522 return type == R_MICROMIPS_26_S1 || type == R_MICROMIPS_PC16_S1 ||
523 type == R_MICROMIPS_PC10_S1 || type == R_MICROMIPS_PC7_S1;
524}
525
526template <class ELFT>
527static uint64_t fixupCrossModeJump(Ctx &ctx, uint8_t *loc, RelType type,
528 uint64_t val) {
529 // Here we need to detect jump/branch from regular MIPS code
530 // to a microMIPS target and vice versa. In that cases jump
531 // instructions need to be replaced by their "cross-mode"
532 // equivalents.
533 const endianness e = ELFT::Endianness;
534 bool isMicroTgt = val & 0x1;
535 bool isCrossJump = (isMicroTgt && isBranchReloc(type)) ||
536 (!isMicroTgt && isMicroBranchReloc(type));
537 if (!isCrossJump)
538 return val;
539
540 switch (type) {
541 case R_MIPS_26: {
542 uint32_t inst = read32(ctx, p: loc) >> 26;
543 if (inst == 0x3 || inst == 0x1d) { // JAL or JALX
544 writeValue(ctx, loc, v: 0x1d << 26, bitsSize: 32, shift: 0);
545 return val;
546 }
547 break;
548 }
549 case R_MICROMIPS_26_S1: {
550 uint32_t inst = readShuffle<e>(ctx, loc) >> 26;
551 if (inst == 0x3d || inst == 0x3c) { // JAL32 or JALX32
552 val >>= 1;
553 writeShuffle<e>(ctx, loc, 0x3c << 26, 32, 0);
554 return val;
555 }
556 break;
557 }
558 case R_MIPS_PC26_S2:
559 case R_MIPS_PC21_S2:
560 case R_MIPS_PC16:
561 case R_MICROMIPS_PC16_S1:
562 case R_MICROMIPS_PC10_S1:
563 case R_MICROMIPS_PC7_S1:
564 // FIXME (simon): Support valid branch relocations.
565 break;
566 default:
567 llvm_unreachable("unexpected jump/branch relocation");
568 }
569
570 ErrAlways(ctx)
571 << getErrorLoc(ctx, loc)
572 << "unsupported jump/branch instruction between ISA modes referenced by "
573 << type << " relocation";
574 return val;
575}
576
577template <class RelTy>
578static RelType getMipsN32RelType(Ctx &ctx, RelTy *&rel, RelTy *end) {
579 uint32_t type = 0;
580 uint64_t offset = rel->r_offset;
581 int n = 0;
582 while (rel != end && rel->r_offset == offset)
583 type |= (rel++)->getType(ctx.arg.isMips64EL) << (8 * n++);
584 return type;
585}
586
587static RelType getMipsPairType(RelType type, bool isLocal) {
588 switch (type) {
589 case R_MIPS_HI16:
590 return R_MIPS_LO16;
591 case R_MIPS_GOT16:
592 // In case of global symbol, the R_MIPS_GOT16 relocation does not
593 // have a pair. Each global symbol has a unique entry in the GOT
594 // and a corresponding instruction with help of the R_MIPS_GOT16
595 // relocation loads an address of the symbol. In case of local
596 // symbol, the R_MIPS_GOT16 relocation creates a GOT entry to hold
597 // the high 16 bits of the symbol's value. A paired R_MIPS_LO16
598 // relocations handle low 16 bits of the address. That allows
599 // to allocate only one GOT entry for every 64 KiB of local data.
600 return isLocal ? R_MIPS_LO16 : R_MIPS_NONE;
601 case R_MICROMIPS_GOT16:
602 return isLocal ? R_MICROMIPS_LO16 : R_MIPS_NONE;
603 case R_MIPS_PCHI16:
604 return R_MIPS_PCLO16;
605 case R_MICROMIPS_HI16:
606 return R_MICROMIPS_LO16;
607 default:
608 return R_MIPS_NONE;
609 }
610}
611
612template <class ELFT>
613template <class RelTy>
614void MIPS<ELFT>::scanSectionImpl(InputSectionBase &sec, Relocs<RelTy> rels) {
615 RelocScan rs(ctx, &sec);
616 sec.relocations.reserve(N: rels.size());
617 RelType type;
618 for (auto it = rels.begin(); it != rels.end();) {
619 const RelTy &rel = *it;
620 uint64_t offset = rel.r_offset;
621 if constexpr (ELFT::Is64Bits) {
622 type = it->getType(ctx.arg.isMips64EL);
623 ++it;
624 } else {
625 if (ctx.arg.mipsN32Abi) {
626 type = getMipsN32RelType(ctx, it, rels.end());
627 } else {
628 type = it->getType(ctx.arg.isMips64EL);
629 ++it;
630 }
631 }
632
633 uint32_t symIdx = rel.getSymbol(ctx.arg.isMips64EL);
634 Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIdx);
635 RelExpr expr = getRelExpr(type, s: sym, loc: sec.content().data() + rel.r_offset);
636 if (expr == R_NONE)
637 continue;
638 if (sym.isUndefined() && symIdx != 0 &&
639 rs.maybeReportUndefined(sym&: cast<Undefined>(Val&: sym), offset))
640 continue;
641
642 auto addend = rs.getAddend<ELFT>(rel, type);
643 if (expr == RE_MIPS_GOTREL && sym.isLocal()) {
644 addend += sec.getFile<ELFT>()->mipsGp0;
645 } else if (!RelTy::HasAddend) {
646 // MIPS has an odd notion of "paired" relocations to calculate addends.
647 // For example, if a relocation is of R_MIPS_HI16, there must be a
648 // R_MIPS_LO16 relocation after that, and an addend is calculated using
649 // the two relocations.
650 RelType pairTy = getMipsPairType(type, isLocal: sym.isLocal());
651 if (pairTy != R_MIPS_NONE) {
652 const uint8_t *buf = sec.content().data();
653 // To make things worse, paired relocations might not be contiguous in
654 // the relocation table, so we need to do linear search. *sigh*
655 bool found = false;
656 for (auto *ri = &rel; ri != rels.end(); ++ri) {
657 if (ri->getType(ctx.arg.isMips64EL) == pairTy &&
658 ri->getSymbol(ctx.arg.isMips64EL) == symIdx) {
659 addend += getImplicitAddend(buf: buf + ri->r_offset, type: pairTy);
660 found = true;
661 break;
662 }
663 }
664
665 if (!found)
666 Warn(ctx) << "can't find matching " << pairTy << " relocation for "
667 << type;
668 }
669 }
670
671 if (expr == RE_MIPS_TLSLD) {
672 ctx.in.mipsGot->addTlsIndex(file&: *sec.file);
673 sec.addReloc(r: {expr, type, offset, addend, &sym});
674 } else if (expr == RE_MIPS_TLSGD) {
675 ctx.in.mipsGot->addDynTlsEntry(file&: *sec.file, sym);
676 sec.addReloc(r: {expr, type, offset, addend, &sym});
677 } else {
678 if (expr == R_TPREL && rs.checkTlsLe(offset, sym, type))
679 continue;
680 rs.process(expr, type, offset, sym, addend);
681 }
682 }
683}
684
685template <class ELFT> void MIPS<ELFT>::scanSection(InputSectionBase &sec) {
686 auto relocs = sec.template relsOrRelas<ELFT>();
687 if (relocs.areRelocsRel())
688 scanSectionImpl(sec, relocs.rels);
689 else
690 scanSectionImpl(sec, relocs.relas);
691}
692
693template <class ELFT>
694void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
695 uint64_t val) const {
696 const endianness e = ELFT::Endianness;
697 RelType type = rel.type;
698
699 if (ELFT::Is64Bits || ctx.arg.mipsN32Abi)
700 std::tie(args&: type, args&: val) = calculateMipsRelChain(ctx, loc, type, val);
701
702 // Detect cross-mode jump/branch and fix instruction.
703 val = fixupCrossModeJump<ELFT>(ctx, loc, type, val);
704
705 // Thread pointer and DRP offsets from the start of TLS data area.
706 // https://www.linux-mips.org/wiki/NPTL
707 if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
708 type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
709 type == R_MICROMIPS_TLS_DTPREL_HI16 ||
710 type == R_MICROMIPS_TLS_DTPREL_LO16) {
711 val -= 0x8000;
712 }
713
714 switch (type) {
715 case R_MIPS_32:
716 case R_MIPS_REL32:
717 case R_MIPS_GPREL32:
718 case R_MIPS_TLS_DTPREL32:
719 case R_MIPS_TLS_TPREL32:
720 write32(ctx, loc, val);
721 break;
722 case R_MIPS_64:
723 case R_MIPS_TLS_DTPREL64:
724 case R_MIPS_TLS_TPREL64:
725 case (R_MIPS_64 << 8) | R_MIPS_REL32:
726 write64(ctx, loc, val);
727 break;
728 case R_MIPS_26:
729 writeValue(ctx, loc, val, 26, 2);
730 break;
731 case R_MIPS_GOT16:
732 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
733 // is updated addend (not a GOT index). In that case write high 16 bits
734 // to store a correct addend value.
735 if (ctx.arg.relocatable) {
736 writeValue(ctx, loc, val + 0x8000, 16, 16);
737 } else {
738 checkInt(ctx, loc, val, 16, rel);
739 writeValue(ctx, loc, val, 16, 0);
740 }
741 break;
742 case R_MICROMIPS_GOT16:
743 if (ctx.arg.relocatable) {
744 writeShuffle<e>(ctx, loc, val + 0x8000, 16, 16);
745 } else {
746 checkInt(ctx, loc, val, 16, rel);
747 writeShuffle<e>(ctx, loc, val, 16, 0);
748 }
749 break;
750 case R_MIPS_CALL16:
751 case R_MIPS_GOT_DISP:
752 case R_MIPS_GOT_PAGE:
753 case R_MIPS_GPREL16:
754 case R_MIPS_TLS_GD:
755 case R_MIPS_TLS_GOTTPREL:
756 case R_MIPS_TLS_LDM:
757 checkInt(ctx, loc, val, 16, rel);
758 [[fallthrough]];
759 case R_MIPS_CALL_LO16:
760 case R_MIPS_GOT_LO16:
761 case R_MIPS_GOT_OFST:
762 case R_MIPS_LO16:
763 case R_MIPS_PCLO16:
764 case R_MIPS_TLS_DTPREL_LO16:
765 case R_MIPS_TLS_TPREL_LO16:
766 writeValue(ctx, loc, val, 16, 0);
767 break;
768 case R_MICROMIPS_GPREL16:
769 case R_MICROMIPS_TLS_GD:
770 case R_MICROMIPS_TLS_LDM:
771 checkInt(ctx, loc, val, 16, rel);
772 writeShuffle<e>(ctx, loc, val, 16, 0);
773 break;
774 case R_MICROMIPS_CALL16:
775 case R_MICROMIPS_CALL_LO16:
776 case R_MICROMIPS_LO16:
777 case R_MICROMIPS_TLS_DTPREL_LO16:
778 case R_MICROMIPS_TLS_GOTTPREL:
779 case R_MICROMIPS_TLS_TPREL_LO16:
780 writeShuffle<e>(ctx, loc, val, 16, 0);
781 break;
782 case R_MICROMIPS_GPREL7_S2:
783 checkInt(ctx, loc, val, 7, rel);
784 writeShuffle<e>(ctx, loc, val, 7, 2);
785 break;
786 case R_MIPS_CALL_HI16:
787 case R_MIPS_GOT_HI16:
788 case R_MIPS_HI16:
789 case R_MIPS_PCHI16:
790 case R_MIPS_TLS_DTPREL_HI16:
791 case R_MIPS_TLS_TPREL_HI16:
792 writeValue(ctx, loc, val + 0x8000, 16, 16);
793 break;
794 case R_MICROMIPS_CALL_HI16:
795 case R_MICROMIPS_GOT_HI16:
796 case R_MICROMIPS_HI16:
797 case R_MICROMIPS_TLS_DTPREL_HI16:
798 case R_MICROMIPS_TLS_TPREL_HI16:
799 writeShuffle<e>(ctx, loc, val + 0x8000, 16, 16);
800 break;
801 case R_MIPS_HIGHER:
802 writeValue(ctx, loc, val + 0x80008000, 16, 32);
803 break;
804 case R_MIPS_HIGHEST:
805 writeValue(ctx, loc, val + 0x800080008000, 16, 48);
806 break;
807 case R_MIPS_JALR:
808 val -= 4;
809 // Replace jalr/jr instructions by bal/b if the target
810 // offset fits into the 18-bit range.
811 if (isInt<18>(x: val)) {
812 switch (read32(ctx, loc)) {
813 case 0x0320f809: // jalr $25 => bal sym
814 write32(ctx, loc, 0x04110000 | ((val >> 2) & 0xffff));
815 break;
816 case 0x03200008: // jr $25 => b sym
817 write32(ctx, loc, 0x10000000 | ((val >> 2) & 0xffff));
818 break;
819 }
820 }
821 break;
822 case R_MICROMIPS_JALR:
823 // Ignore this optimization relocation for now
824 break;
825 case R_MIPS_PC16:
826 checkAlignment(ctx, loc, val, 4, rel);
827 checkInt(ctx, loc, val, 18, rel);
828 writeValue(ctx, loc, val, 16, 2);
829 break;
830 case R_MIPS_PC19_S2:
831 checkAlignment(ctx, loc, val, 4, rel);
832 checkInt(ctx, loc, val, 21, rel);
833 writeValue(ctx, loc, val, 19, 2);
834 break;
835 case R_MIPS_PC21_S2:
836 checkAlignment(ctx, loc, val, 4, rel);
837 checkInt(ctx, loc, val, 23, rel);
838 writeValue(ctx, loc, val, 21, 2);
839 break;
840 case R_MIPS_PC26_S2:
841 checkAlignment(ctx, loc, val, 4, rel);
842 checkInt(ctx, loc, val, 28, rel);
843 writeValue(ctx, loc, val, 26, 2);
844 break;
845 case R_MIPS_PC32:
846 writeValue(ctx, loc, val, 32, 0);
847 break;
848 case R_MICROMIPS_26_S1:
849 case R_MICROMIPS_PC26_S1:
850 checkInt(ctx, loc, val, 27, rel);
851 writeShuffle<e>(ctx, loc, val, 26, 1);
852 break;
853 case R_MICROMIPS_PC7_S1:
854 checkInt(ctx, loc, val, 8, rel);
855 writeMicroRelocation16<e>(ctx, loc, val, 7, 1);
856 break;
857 case R_MICROMIPS_PC10_S1:
858 checkInt(ctx, loc, val, 11, rel);
859 writeMicroRelocation16<e>(ctx, loc, val, 10, 1);
860 break;
861 case R_MICROMIPS_PC16_S1:
862 checkInt(ctx, loc, val, 17, rel);
863 writeShuffle<e>(ctx, loc, val, 16, 1);
864 break;
865 case R_MICROMIPS_PC18_S3:
866 checkInt(ctx, loc, val, 21, rel);
867 writeShuffle<e>(ctx, loc, val, 18, 3);
868 break;
869 case R_MICROMIPS_PC19_S2:
870 checkInt(ctx, loc, val, 21, rel);
871 writeShuffle<e>(ctx, loc, val, 19, 2);
872 break;
873 case R_MICROMIPS_PC21_S1:
874 checkInt(ctx, loc, val, 22, rel);
875 writeShuffle<e>(ctx, loc, val, 21, 1);
876 break;
877 case R_MICROMIPS_PC23_S2:
878 checkInt(ctx, loc, val, 25, rel);
879 writeShuffle<e>(ctx, loc, val, 23, 2);
880 break;
881 default:
882 llvm_unreachable("unknown relocation");
883 }
884}
885
886template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
887 return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
888 type == R_MICROMIPS_LO16;
889}
890
891// Return true if the symbol is a PIC function.
892template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
893 if (!sym->isFunc())
894 return false;
895
896 if (sym->stOther & STO_MIPS_PIC)
897 return true;
898
899 if (!sym->section)
900 return false;
901
902 InputFile *file = cast<InputSectionBase>(Val: sym->section)->file;
903 if (!file || file->isInternal())
904 return false;
905
906 return cast<ObjFile<ELFT>>(file)->getObj().getHeader().e_flags & EF_MIPS_PIC;
907}
908
909void elf::setMipsTargetInfo(Ctx &ctx) {
910 switch (ctx.arg.ekind) {
911 case ELF32LEKind: {
912 ctx.target.reset(p: new MIPS<ELF32LE>(ctx));
913 return;
914 }
915 case ELF32BEKind: {
916 ctx.target.reset(p: new MIPS<ELF32BE>(ctx));
917 return;
918 }
919 case ELF64LEKind: {
920 ctx.target.reset(p: new MIPS<ELF64LE>(ctx));
921 return;
922 }
923 case ELF64BEKind: {
924 ctx.target.reset(p: new MIPS<ELF64BE>(ctx));
925 return;
926 }
927 default:
928 llvm_unreachable("unsupported target");
929 }
930}
931
932template bool elf::isMipsPIC<ELF32LE>(const Defined *);
933template bool elf::isMipsPIC<ELF32BE>(const Defined *);
934template bool elf::isMipsPIC<ELF64LE>(const Defined *);
935template bool elf::isMipsPIC<ELF64BE>(const Defined *);
936