1 //===- MIPS.cpp -----------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "InputFiles.h"
10 #include "OutputSections.h"
12 #include "SyntheticSections.h"
14 #include "lld/Common/ErrorHandler.h"
15 #include "llvm/BinaryFormat/ELF.h"
18 using namespace llvm::object
;
19 using namespace llvm::ELF
;
21 using namespace lld::elf
;
24 template <class ELFT
> class MIPS final
: public TargetInfo
{
27 uint32_t calcEFlags() const override
;
28 RelExpr
getRelExpr(RelType type
, const Symbol
&s
,
29 const uint8_t *loc
) const override
;
30 int64_t getImplicitAddend(const uint8_t *buf
, RelType type
) const override
;
31 RelType
getDynRel(RelType type
) const override
;
32 void writeGotPlt(uint8_t *buf
, const Symbol
&s
) const override
;
33 void writePltHeader(uint8_t *buf
) const override
;
34 void writePlt(uint8_t *buf
, const Symbol
&sym
,
35 uint64_t pltEntryAddr
) const override
;
36 bool needsThunk(RelExpr expr
, RelType type
, const InputFile
*file
,
37 uint64_t branchAddr
, const Symbol
&s
,
38 int64_t a
) const override
;
39 void relocate(uint8_t *loc
, const Relocation
&rel
,
40 uint64_t val
) const override
;
41 bool usesOnlyLowPageBits(RelType type
) const override
;
45 template <class ELFT
> MIPS
<ELFT
>::MIPS(Ctx
&ctx
) : TargetInfo(ctx
) {
46 gotPltHeaderEntriesNum
= 2;
47 defaultMaxPageSize
= 65536;
50 copyRel
= R_MIPS_COPY
;
51 pltRel
= R_MIPS_JUMP_SLOT
;
54 // Set `sigrie 1` as a trap instruction.
55 write32(ctx
, trapInstr
.data(), 0x04170001);
58 relativeRel
= (R_MIPS_64
<< 8) | R_MIPS_REL32
;
59 symbolicRel
= R_MIPS_64
;
60 tlsGotRel
= R_MIPS_TLS_TPREL64
;
61 tlsModuleIndexRel
= R_MIPS_TLS_DTPMOD64
;
62 tlsOffsetRel
= R_MIPS_TLS_DTPREL64
;
64 relativeRel
= R_MIPS_REL32
;
65 symbolicRel
= R_MIPS_32
;
66 tlsGotRel
= R_MIPS_TLS_TPREL32
;
67 tlsModuleIndexRel
= R_MIPS_TLS_DTPMOD32
;
68 tlsOffsetRel
= R_MIPS_TLS_DTPREL32
;
72 template <class ELFT
> uint32_t MIPS
<ELFT
>::calcEFlags() const {
73 return calcMipsEFlags
<ELFT
>(ctx
);
77 RelExpr MIPS
<ELFT
>::getRelExpr(RelType type
, const Symbol
&s
,
78 const uint8_t *loc
) const {
79 // See comment in the calculateMipsRelChain.
80 if (ELFT::Is64Bits
|| ctx
.arg
.mipsN32Abi
)
85 // Older versions of clang would erroneously emit this relocation not only
86 // against functions (loaded from the GOT) but also against data symbols
87 // (e.g. a table of function pointers). When we encounter this, ignore the
88 // relocation and emit a warning instead.
89 if (!s
.isFunc() && s
.type
!= STT_NOTYPE
) {
90 Warn(ctx
) << getErrorLoc(ctx
, loc
)
91 << "found R_MIPS_JALR relocation against non-function symbol "
92 << &s
<< ". This is invalid and most likely a compiler bug.";
96 // If the target symbol is not preemptible and is not microMIPS,
97 // it might be possible to replace jalr/jr instruction by bal/b.
98 // It depends on the target symbol's offset.
99 if (!s
.isPreemptible
&& !(s
.getVA(ctx
) & 0x1))
102 case R_MICROMIPS_JALR
:
106 case R_MICROMIPS_GPREL16
:
107 case R_MICROMIPS_GPREL7_S2
:
108 return RE_MIPS_GOTREL
;
110 case R_MICROMIPS_26_S1
:
112 case R_MICROMIPS_PC26_S1
:
118 case R_MICROMIPS_HI16
:
119 case R_MICROMIPS_LO16
:
120 // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
121 // offset between start of function and 'gp' value which by default
122 // equal to the start of .got section. In that case we consider these
123 // relocations as relative.
124 if (&s
== ctx
.sym
.mipsGpDisp
)
125 return RE_MIPS_GOT_GP_PC
;
126 if (&s
== ctx
.sym
.mipsLocalGp
)
127 return RE_MIPS_GOT_GP
;
131 case R_MIPS_GOT_OFST
:
134 case R_MIPS_TLS_DTPREL_HI16
:
135 case R_MIPS_TLS_DTPREL_LO16
:
136 case R_MIPS_TLS_DTPREL32
:
137 case R_MIPS_TLS_DTPREL64
:
138 case R_MICROMIPS_TLS_DTPREL_HI16
:
139 case R_MICROMIPS_TLS_DTPREL_LO16
:
141 case R_MIPS_TLS_TPREL_HI16
:
142 case R_MIPS_TLS_TPREL_LO16
:
143 case R_MIPS_TLS_TPREL32
:
144 case R_MIPS_TLS_TPREL64
:
145 case R_MICROMIPS_TLS_TPREL_HI16
:
146 case R_MICROMIPS_TLS_TPREL_LO16
:
155 case R_MICROMIPS_PC7_S1
:
156 case R_MICROMIPS_PC10_S1
:
157 case R_MICROMIPS_PC16_S1
:
158 case R_MICROMIPS_PC18_S3
:
159 case R_MICROMIPS_PC19_S2
:
160 case R_MICROMIPS_PC23_S2
:
161 case R_MICROMIPS_PC21_S1
:
164 case R_MICROMIPS_GOT16
:
166 return RE_MIPS_GOT_LOCAL_PAGE
;
169 case R_MIPS_GOT_DISP
:
170 case R_MIPS_TLS_GOTTPREL
:
171 case R_MICROMIPS_CALL16
:
172 case R_MICROMIPS_TLS_GOTTPREL
:
173 return RE_MIPS_GOT_OFF
;
174 case R_MIPS_CALL_HI16
:
175 case R_MIPS_CALL_LO16
:
176 case R_MIPS_GOT_HI16
:
177 case R_MIPS_GOT_LO16
:
178 case R_MICROMIPS_CALL_HI16
:
179 case R_MICROMIPS_CALL_LO16
:
180 case R_MICROMIPS_GOT_HI16
:
181 case R_MICROMIPS_GOT_LO16
:
182 return RE_MIPS_GOT_OFF32
;
183 case R_MIPS_GOT_PAGE
:
184 return RE_MIPS_GOT_LOCAL_PAGE
;
186 case R_MICROMIPS_TLS_GD
:
187 return RE_MIPS_TLSGD
;
189 case R_MICROMIPS_TLS_LDM
:
190 return RE_MIPS_TLSLD
;
194 Err(ctx
) << getErrorLoc(ctx
, loc
) << "unknown relocation (" << type
.v
195 << ") against symbol " << &s
;
200 template <class ELFT
> RelType MIPS
<ELFT
>::getDynRel(RelType type
) const {
201 if (type
== symbolicRel
)
206 template <class ELFT
>
207 void MIPS
<ELFT
>::writeGotPlt(uint8_t *buf
, const Symbol
&) const {
208 uint64_t va
= ctx
.in
.plt
->getVA();
209 if (isMicroMips(ctx
))
211 write32(ctx
, buf
, va
);
214 template <endianness E
>
215 static uint32_t readShuffle(Ctx
&ctx
, const uint8_t *loc
) {
216 // The major opcode of a microMIPS instruction needs to appear
217 // in the first 16-bit word (lowest address) for efficient hardware
218 // decode so that it knows if the instruction is 16-bit or 32-bit
219 // as early as possible. To do so, little-endian binaries keep 16-bit
220 // words in a big-endian order. That is why we have to swap these
221 // words to get a correct value.
222 uint32_t v
= read32(ctx
, loc
);
223 if (E
== llvm::endianness::little
)
224 return (v
<< 16) | (v
>> 16);
228 static void writeValue(Ctx
&ctx
, uint8_t *loc
, uint64_t v
, uint8_t bitsSize
,
230 uint32_t instr
= read32(ctx
, loc
);
231 uint32_t mask
= 0xffffffff >> (32 - bitsSize
);
232 uint32_t data
= (instr
& ~mask
) | ((v
>> shift
) & mask
);
233 write32(ctx
, loc
, data
);
236 template <endianness E
>
237 static void writeShuffle(Ctx
&ctx
, uint8_t *loc
, uint64_t v
, uint8_t bitsSize
,
239 // See comments in readShuffle for purpose of this code.
240 uint16_t *words
= (uint16_t *)loc
;
241 if (E
== llvm::endianness::little
)
242 std::swap(words
[0], words
[1]);
244 writeValue(ctx
, loc
, v
, bitsSize
, shift
);
246 if (E
== llvm::endianness::little
)
247 std::swap(words
[0], words
[1]);
250 template <endianness E
>
251 static void writeMicroRelocation16(Ctx
&ctx
, uint8_t *loc
, uint64_t v
,
252 uint8_t bitsSize
, uint8_t shift
) {
253 uint16_t instr
= read16(ctx
, loc
);
254 uint16_t mask
= 0xffff >> (16 - bitsSize
);
255 uint16_t data
= (instr
& ~mask
) | ((v
>> shift
) & mask
);
256 write16(ctx
, loc
, data
);
259 template <class ELFT
> void MIPS
<ELFT
>::writePltHeader(uint8_t *buf
) const {
260 if (isMicroMips(ctx
)) {
261 uint64_t gotPlt
= ctx
.in
.gotPlt
->getVA();
262 uint64_t plt
= ctx
.in
.plt
->getVA();
263 // Overwrite trap instructions written by Writer::writeTrapInstr.
264 memset(buf
, 0, pltHeaderSize
);
267 isMipsR6(ctx
) ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
268 write16(ctx
, buf
+ 4, 0xff23); // lw $25, 0($3)
269 write16(ctx
, buf
+ 8, 0x0535); // subu16 $2, $2, $3
270 write16(ctx
, buf
+ 10, 0x2525); // srl16 $2, $2, 2
271 write16(ctx
, buf
+ 12, 0x3302); // addiu $24, $2, -2
272 write16(ctx
, buf
+ 14, 0xfffe);
273 write16(ctx
, buf
+ 16, 0x0dff); // move $15, $31
275 write16(ctx
, buf
+ 18, 0x0f83); // move $28, $3
276 write16(ctx
, buf
+ 20, 0x472b); // jalrc $25
277 write16(ctx
, buf
+ 22, 0x0c00); // nop
278 relocateNoSym(buf
, R_MICROMIPS_PC19_S2
, gotPlt
- plt
);
280 write16(ctx
, buf
+ 18, 0x45f9); // jalrc $25
281 write16(ctx
, buf
+ 20, 0x0f83); // move $28, $3
282 write16(ctx
, buf
+ 22, 0x0c00); // nop
283 relocateNoSym(buf
, R_MICROMIPS_PC23_S2
, gotPlt
- plt
);
288 if (ctx
.arg
.mipsN32Abi
) {
289 write32(ctx
, buf
, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
290 write32(ctx
, buf
+ 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
291 write32(ctx
, buf
+ 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
292 write32(ctx
, buf
+ 12, 0x030ec023); // subu $24, $24, $14
293 write32(ctx
, buf
+ 16, 0x03e07825); // move $15, $31
294 write32(ctx
, buf
+ 20, 0x0018c082); // srl $24, $24, 2
295 } else if (ELFT::Is64Bits
) {
296 write32(ctx
, buf
, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
297 write32(ctx
, buf
+ 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
298 write32(ctx
, buf
+ 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
299 write32(ctx
, buf
+ 12, 0x030ec023); // subu $24, $24, $14
300 write32(ctx
, buf
+ 16, 0x03e07825); // move $15, $31
301 write32(ctx
, buf
+ 20, 0x0018c0c2); // srl $24, $24, 3
303 write32(ctx
, buf
, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
304 write32(ctx
, buf
+ 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
305 write32(ctx
, buf
+ 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
306 write32(ctx
, buf
+ 12, 0x031cc023); // subu $24, $24, $28
307 write32(ctx
, buf
+ 16, 0x03e07825); // move $15, $31
308 write32(ctx
, buf
+ 20, 0x0018c082); // srl $24, $24, 2
311 uint32_t jalrInst
= ctx
.arg
.zHazardplt
? 0x0320fc09 : 0x0320f809;
312 write32(ctx
, buf
+ 24, jalrInst
); // jalr.hb $25 or jalr $25
313 write32(ctx
, buf
+ 28, 0x2718fffe); // subu $24, $24, 2
315 uint64_t gotPlt
= ctx
.in
.gotPlt
->getVA();
316 writeValue(ctx
, buf
, gotPlt
+ 0x8000, 16, 16);
317 writeValue(ctx
, buf
+ 4, gotPlt
, 16, 0);
318 writeValue(ctx
, buf
+ 8, gotPlt
, 16, 0);
321 template <class ELFT
>
322 void MIPS
<ELFT
>::writePlt(uint8_t *buf
, const Symbol
&sym
,
323 uint64_t pltEntryAddr
) const {
324 uint64_t gotPltEntryAddr
= sym
.getGotPltVA(ctx
);
325 if (isMicroMips(ctx
)) {
326 // Overwrite trap instructions written by Writer::writeTrapInstr.
327 memset(buf
, 0, pltEntrySize
);
330 write16(ctx
, buf
, 0x7840); // addiupc $2, (GOTPLT) - .
331 write16(ctx
, buf
+ 4, 0xff22); // lw $25, 0($2)
332 write16(ctx
, buf
+ 8, 0x0f02); // move $24, $2
333 write16(ctx
, buf
+ 10, 0x4723); // jrc $25 / jr16 $25
334 relocateNoSym(buf
, R_MICROMIPS_PC19_S2
, gotPltEntryAddr
- pltEntryAddr
);
336 write16(ctx
, buf
, 0x7900); // addiupc $2, (GOTPLT) - .
337 write16(ctx
, buf
+ 4, 0xff22); // lw $25, 0($2)
338 write16(ctx
, buf
+ 8, 0x4599); // jrc $25 / jr16 $25
339 write16(ctx
, buf
+ 10, 0x0f02); // move $24, $2
340 relocateNoSym(buf
, R_MICROMIPS_PC23_S2
, gotPltEntryAddr
- pltEntryAddr
);
345 uint32_t loadInst
= ELFT::Is64Bits
? 0xddf90000 : 0x8df90000;
346 uint32_t jrInst
= isMipsR6(ctx
)
347 ? (ctx
.arg
.zHazardplt
? 0x03200409 : 0x03200009)
348 : (ctx
.arg
.zHazardplt
? 0x03200408 : 0x03200008);
349 uint32_t addInst
= ELFT::Is64Bits
? 0x65f80000 : 0x25f80000;
351 write32(ctx
, buf
, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
352 write32(ctx
, buf
+ 4, loadInst
); // l[wd] $25, %lo(.got.plt entry)($15)
353 write32(ctx
, buf
+ 8, jrInst
); // jr $25 / jr.hb $25
354 write32(ctx
, buf
+ 12, addInst
); // [d]addiu $24, $15, %lo(.got.plt entry)
355 writeValue(ctx
, buf
, gotPltEntryAddr
+ 0x8000, 16, 16);
356 writeValue(ctx
, buf
+ 4, gotPltEntryAddr
, 16, 0);
357 writeValue(ctx
, buf
+ 12, gotPltEntryAddr
, 16, 0);
360 template <class ELFT
>
361 bool MIPS
<ELFT
>::needsThunk(RelExpr expr
, RelType type
, const InputFile
*file
,
362 uint64_t branchAddr
, const Symbol
&s
,
363 int64_t /*a*/) const {
364 // Any MIPS PIC code function is invoked with its address in register $t9.
365 // So if we have a branch instruction from non-PIC code to the PIC one
366 // we cannot make the jump directly and need to create a small stubs
367 // to save the target function address.
368 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
369 if (type
!= R_MIPS_26
&& type
!= R_MIPS_PC26_S2
&&
370 type
!= R_MICROMIPS_26_S1
&& type
!= R_MICROMIPS_PC26_S1
)
372 auto *f
= dyn_cast
<ObjFile
<ELFT
>>(file
);
375 // If current file has PIC code, LA25 stub is not required.
376 if (f
->getObj().getHeader().e_flags
& EF_MIPS_PIC
)
378 auto *d
= dyn_cast
<Defined
>(&s
);
379 // LA25 is required if target file has PIC code
380 // or target symbol is a PIC symbol.
381 return d
&& isMipsPIC
<ELFT
>(d
);
384 template <class ELFT
>
385 int64_t MIPS
<ELFT
>::getImplicitAddend(const uint8_t *buf
, RelType type
) const {
386 const endianness e
= ELFT::Endianness
;
391 case R_MIPS_TLS_DTPREL32
:
392 case R_MIPS_TLS_DTPMOD32
:
393 case R_MIPS_TLS_TPREL32
:
394 return SignExtend64
<32>(read32(ctx
, buf
));
396 // FIXME (simon): If the relocation target symbol is not a PLT entry
397 // we should use another expression for calculation:
398 // ((A << 2) | (P & 0xf0000000)) >> 2
399 return SignExtend64
<28>(read32(ctx
, buf
) << 2);
400 case R_MIPS_CALL_HI16
:
402 case R_MIPS_GOT_HI16
:
405 return SignExtend64
<16>(read32(ctx
, buf
)) << 16;
407 case R_MIPS_CALL_LO16
:
408 case R_MIPS_GOT_LO16
:
412 case R_MIPS_TLS_DTPREL_HI16
:
413 case R_MIPS_TLS_DTPREL_LO16
:
415 case R_MIPS_TLS_GOTTPREL
:
417 case R_MIPS_TLS_TPREL_HI16
:
418 case R_MIPS_TLS_TPREL_LO16
:
419 return SignExtend64
<16>(read32(ctx
, buf
));
420 case R_MICROMIPS_GOT16
:
421 case R_MICROMIPS_HI16
:
422 return SignExtend64
<16>(readShuffle
<e
>(ctx
, buf
)) << 16;
423 case R_MICROMIPS_CALL16
:
424 case R_MICROMIPS_GPREL16
:
425 case R_MICROMIPS_LO16
:
426 case R_MICROMIPS_TLS_DTPREL_HI16
:
427 case R_MICROMIPS_TLS_DTPREL_LO16
:
428 case R_MICROMIPS_TLS_GD
:
429 case R_MICROMIPS_TLS_GOTTPREL
:
430 case R_MICROMIPS_TLS_LDM
:
431 case R_MICROMIPS_TLS_TPREL_HI16
:
432 case R_MICROMIPS_TLS_TPREL_LO16
:
433 return SignExtend64
<16>(readShuffle
<e
>(ctx
, buf
));
434 case R_MICROMIPS_GPREL7_S2
:
435 return SignExtend64
<9>(readShuffle
<e
>(ctx
, buf
) << 2);
437 return SignExtend64
<18>(read32(ctx
, buf
) << 2);
439 return SignExtend64
<21>(read32(ctx
, buf
) << 2);
441 return SignExtend64
<23>(read32(ctx
, buf
) << 2);
443 return SignExtend64
<28>(read32(ctx
, buf
) << 2);
445 return SignExtend64
<32>(read32(ctx
, buf
));
446 case R_MICROMIPS_26_S1
:
447 return SignExtend64
<27>(readShuffle
<e
>(ctx
, buf
) << 1);
448 case R_MICROMIPS_PC7_S1
:
449 return SignExtend64
<8>(read16(ctx
, buf
) << 1);
450 case R_MICROMIPS_PC10_S1
:
451 return SignExtend64
<11>(read16(ctx
, buf
) << 1);
452 case R_MICROMIPS_PC16_S1
:
453 return SignExtend64
<17>(readShuffle
<e
>(ctx
, buf
) << 1);
454 case R_MICROMIPS_PC18_S3
:
455 return SignExtend64
<21>(readShuffle
<e
>(ctx
, buf
) << 3);
456 case R_MICROMIPS_PC19_S2
:
457 return SignExtend64
<21>(readShuffle
<e
>(ctx
, buf
) << 2);
458 case R_MICROMIPS_PC21_S1
:
459 return SignExtend64
<22>(readShuffle
<e
>(ctx
, buf
) << 1);
460 case R_MICROMIPS_PC23_S2
:
461 return SignExtend64
<25>(readShuffle
<e
>(ctx
, buf
) << 2);
462 case R_MICROMIPS_PC26_S1
:
463 return SignExtend64
<27>(readShuffle
<e
>(ctx
, buf
) << 1);
465 case R_MIPS_TLS_DTPMOD64
:
466 case R_MIPS_TLS_DTPREL64
:
467 case R_MIPS_TLS_TPREL64
:
468 case (R_MIPS_64
<< 8) | R_MIPS_REL32
:
469 return read64(ctx
, buf
);
471 return ctx
.arg
.is64
? read64(ctx
, buf
) : read32(ctx
, buf
);
473 case R_MIPS_JUMP_SLOT
:
475 // These relocations are defined as not having an implicit addend.
478 InternalErr(ctx
, buf
) << "cannot read addend for relocation " << type
;
483 static std::pair
<uint32_t, uint64_t>
484 calculateMipsRelChain(Ctx
&ctx
, uint8_t *loc
, uint32_t type
, uint64_t val
) {
485 // MIPS N64 ABI packs multiple relocations into the single relocation
486 // record. In general, all up to three relocations can have arbitrary
487 // types. In fact, Clang and GCC uses only a few combinations. For now,
488 // we support two of them. That is allow to pass at least all LLVM
490 // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
491 // <any relocation> / R_MIPS_64 / R_MIPS_NONE
492 // The first relocation is a 'real' relocation which is calculated
493 // using the corresponding symbol's value. The second and the third
494 // relocations used to modify result of the first one: extend it to
495 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
496 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
497 uint32_t type2
= (type
>> 8) & 0xff;
498 uint32_t type3
= (type
>> 16) & 0xff;
499 if (type2
== R_MIPS_NONE
&& type3
== R_MIPS_NONE
)
500 return std::make_pair(type
, val
);
501 if (type2
== R_MIPS_64
&& type3
== R_MIPS_NONE
)
502 return std::make_pair(type2
, val
);
503 if (type2
== R_MIPS_SUB
&& (type3
== R_MIPS_HI16
|| type3
== R_MIPS_LO16
))
504 return std::make_pair(type3
, -val
);
505 Err(ctx
) << getErrorLoc(ctx
, loc
) << "unsupported relocations combination "
507 return std::make_pair(type
& 0xff, val
);
510 static bool isBranchReloc(RelType type
) {
511 return type
== R_MIPS_26
|| type
== R_MIPS_PC26_S2
||
512 type
== R_MIPS_PC21_S2
|| type
== R_MIPS_PC16
;
515 static bool isMicroBranchReloc(RelType type
) {
516 return type
== R_MICROMIPS_26_S1
|| type
== R_MICROMIPS_PC16_S1
||
517 type
== R_MICROMIPS_PC10_S1
|| type
== R_MICROMIPS_PC7_S1
;
520 template <class ELFT
>
521 static uint64_t fixupCrossModeJump(Ctx
&ctx
, uint8_t *loc
, RelType type
,
523 // Here we need to detect jump/branch from regular MIPS code
524 // to a microMIPS target and vice versa. In that cases jump
525 // instructions need to be replaced by their "cross-mode"
527 const endianness e
= ELFT::Endianness
;
528 bool isMicroTgt
= val
& 0x1;
529 bool isCrossJump
= (isMicroTgt
&& isBranchReloc(type
)) ||
530 (!isMicroTgt
&& isMicroBranchReloc(type
));
536 uint32_t inst
= read32(ctx
, loc
) >> 26;
537 if (inst
== 0x3 || inst
== 0x1d) { // JAL or JALX
538 writeValue(ctx
, loc
, 0x1d << 26, 32, 0);
543 case R_MICROMIPS_26_S1
: {
544 uint32_t inst
= readShuffle
<e
>(ctx
, loc
) >> 26;
545 if (inst
== 0x3d || inst
== 0x3c) { // JAL32 or JALX32
547 writeShuffle
<e
>(ctx
, loc
, 0x3c << 26, 32, 0);
555 case R_MICROMIPS_PC16_S1
:
556 case R_MICROMIPS_PC10_S1
:
557 case R_MICROMIPS_PC7_S1
:
558 // FIXME (simon): Support valid branch relocations.
561 llvm_unreachable("unexpected jump/branch relocation");
565 << getErrorLoc(ctx
, loc
)
566 << "unsupported jump/branch instruction between ISA modes referenced by "
567 << type
<< " relocation";
571 template <class ELFT
>
572 void MIPS
<ELFT
>::relocate(uint8_t *loc
, const Relocation
&rel
,
573 uint64_t val
) const {
574 const endianness e
= ELFT::Endianness
;
575 RelType type
= rel
.type
;
577 if (ELFT::Is64Bits
|| ctx
.arg
.mipsN32Abi
)
578 std::tie(type
, val
) = calculateMipsRelChain(ctx
, loc
, type
, val
);
580 // Detect cross-mode jump/branch and fix instruction.
581 val
= fixupCrossModeJump
<ELFT
>(ctx
, loc
, type
, val
);
583 // Thread pointer and DRP offsets from the start of TLS data area.
584 // https://www.linux-mips.org/wiki/NPTL
585 if (type
== R_MIPS_TLS_DTPREL_HI16
|| type
== R_MIPS_TLS_DTPREL_LO16
||
586 type
== R_MIPS_TLS_DTPREL32
|| type
== R_MIPS_TLS_DTPREL64
||
587 type
== R_MICROMIPS_TLS_DTPREL_HI16
||
588 type
== R_MICROMIPS_TLS_DTPREL_LO16
) {
595 case R_MIPS_TLS_DTPREL32
:
596 case R_MIPS_TLS_TPREL32
:
597 write32(ctx
, loc
, val
);
600 case R_MIPS_TLS_DTPREL64
:
601 case R_MIPS_TLS_TPREL64
:
602 write64(ctx
, loc
, val
);
605 writeValue(ctx
, loc
, val
, 26, 2);
608 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
609 // is updated addend (not a GOT index). In that case write high 16 bits
610 // to store a correct addend value.
611 if (ctx
.arg
.relocatable
) {
612 writeValue(ctx
, loc
, val
+ 0x8000, 16, 16);
614 checkInt(ctx
, loc
, val
, 16, rel
);
615 writeValue(ctx
, loc
, val
, 16, 0);
618 case R_MICROMIPS_GOT16
:
619 if (ctx
.arg
.relocatable
) {
620 writeShuffle
<e
>(ctx
, loc
, val
+ 0x8000, 16, 16);
622 checkInt(ctx
, loc
, val
, 16, rel
);
623 writeShuffle
<e
>(ctx
, loc
, val
, 16, 0);
627 case R_MIPS_GOT_DISP
:
628 case R_MIPS_GOT_PAGE
:
631 case R_MIPS_TLS_GOTTPREL
:
633 checkInt(ctx
, loc
, val
, 16, rel
);
635 case R_MIPS_CALL_LO16
:
636 case R_MIPS_GOT_LO16
:
637 case R_MIPS_GOT_OFST
:
640 case R_MIPS_TLS_DTPREL_LO16
:
641 case R_MIPS_TLS_TPREL_LO16
:
642 writeValue(ctx
, loc
, val
, 16, 0);
644 case R_MICROMIPS_GPREL16
:
645 case R_MICROMIPS_TLS_GD
:
646 case R_MICROMIPS_TLS_LDM
:
647 checkInt(ctx
, loc
, val
, 16, rel
);
648 writeShuffle
<e
>(ctx
, loc
, val
, 16, 0);
650 case R_MICROMIPS_CALL16
:
651 case R_MICROMIPS_CALL_LO16
:
652 case R_MICROMIPS_LO16
:
653 case R_MICROMIPS_TLS_DTPREL_LO16
:
654 case R_MICROMIPS_TLS_GOTTPREL
:
655 case R_MICROMIPS_TLS_TPREL_LO16
:
656 writeShuffle
<e
>(ctx
, loc
, val
, 16, 0);
658 case R_MICROMIPS_GPREL7_S2
:
659 checkInt(ctx
, loc
, val
, 7, rel
);
660 writeShuffle
<e
>(ctx
, loc
, val
, 7, 2);
662 case R_MIPS_CALL_HI16
:
663 case R_MIPS_GOT_HI16
:
666 case R_MIPS_TLS_DTPREL_HI16
:
667 case R_MIPS_TLS_TPREL_HI16
:
668 writeValue(ctx
, loc
, val
+ 0x8000, 16, 16);
670 case R_MICROMIPS_CALL_HI16
:
671 case R_MICROMIPS_GOT_HI16
:
672 case R_MICROMIPS_HI16
:
673 case R_MICROMIPS_TLS_DTPREL_HI16
:
674 case R_MICROMIPS_TLS_TPREL_HI16
:
675 writeShuffle
<e
>(ctx
, loc
, val
+ 0x8000, 16, 16);
678 writeValue(ctx
, loc
, val
+ 0x80008000, 16, 32);
681 writeValue(ctx
, loc
, val
+ 0x800080008000, 16, 48);
685 // Replace jalr/jr instructions by bal/b if the target
686 // offset fits into the 18-bit range.
687 if (isInt
<18>(val
)) {
688 switch (read32(ctx
, loc
)) {
689 case 0x0320f809: // jalr $25 => bal sym
690 write32(ctx
, loc
, 0x04110000 | ((val
>> 2) & 0xffff));
692 case 0x03200008: // jr $25 => b sym
693 write32(ctx
, loc
, 0x10000000 | ((val
>> 2) & 0xffff));
698 case R_MICROMIPS_JALR
:
699 // Ignore this optimization relocation for now
702 checkAlignment(ctx
, loc
, val
, 4, rel
);
703 checkInt(ctx
, loc
, val
, 18, rel
);
704 writeValue(ctx
, loc
, val
, 16, 2);
707 checkAlignment(ctx
, loc
, val
, 4, rel
);
708 checkInt(ctx
, loc
, val
, 21, rel
);
709 writeValue(ctx
, loc
, val
, 19, 2);
712 checkAlignment(ctx
, loc
, val
, 4, rel
);
713 checkInt(ctx
, loc
, val
, 23, rel
);
714 writeValue(ctx
, loc
, val
, 21, 2);
717 checkAlignment(ctx
, loc
, val
, 4, rel
);
718 checkInt(ctx
, loc
, val
, 28, rel
);
719 writeValue(ctx
, loc
, val
, 26, 2);
722 writeValue(ctx
, loc
, val
, 32, 0);
724 case R_MICROMIPS_26_S1
:
725 case R_MICROMIPS_PC26_S1
:
726 checkInt(ctx
, loc
, val
, 27, rel
);
727 writeShuffle
<e
>(ctx
, loc
, val
, 26, 1);
729 case R_MICROMIPS_PC7_S1
:
730 checkInt(ctx
, loc
, val
, 8, rel
);
731 writeMicroRelocation16
<e
>(ctx
, loc
, val
, 7, 1);
733 case R_MICROMIPS_PC10_S1
:
734 checkInt(ctx
, loc
, val
, 11, rel
);
735 writeMicroRelocation16
<e
>(ctx
, loc
, val
, 10, 1);
737 case R_MICROMIPS_PC16_S1
:
738 checkInt(ctx
, loc
, val
, 17, rel
);
739 writeShuffle
<e
>(ctx
, loc
, val
, 16, 1);
741 case R_MICROMIPS_PC18_S3
:
742 checkInt(ctx
, loc
, val
, 21, rel
);
743 writeShuffle
<e
>(ctx
, loc
, val
, 18, 3);
745 case R_MICROMIPS_PC19_S2
:
746 checkInt(ctx
, loc
, val
, 21, rel
);
747 writeShuffle
<e
>(ctx
, loc
, val
, 19, 2);
749 case R_MICROMIPS_PC21_S1
:
750 checkInt(ctx
, loc
, val
, 22, rel
);
751 writeShuffle
<e
>(ctx
, loc
, val
, 21, 1);
753 case R_MICROMIPS_PC23_S2
:
754 checkInt(ctx
, loc
, val
, 25, rel
);
755 writeShuffle
<e
>(ctx
, loc
, val
, 23, 2);
758 llvm_unreachable("unknown relocation");
762 template <class ELFT
> bool MIPS
<ELFT
>::usesOnlyLowPageBits(RelType type
) const {
763 return type
== R_MIPS_LO16
|| type
== R_MIPS_GOT_OFST
||
764 type
== R_MICROMIPS_LO16
;
767 // Return true if the symbol is a PIC function.
768 template <class ELFT
> bool elf::isMipsPIC(const Defined
*sym
) {
772 if (sym
->stOther
& STO_MIPS_PIC
)
778 InputFile
*file
= cast
<InputSectionBase
>(sym
->section
)->file
;
779 if (!file
|| file
->isInternal())
782 return cast
<ObjFile
<ELFT
>>(file
)->getObj().getHeader().e_flags
& EF_MIPS_PIC
;
785 void elf::setMipsTargetInfo(Ctx
&ctx
) {
786 switch (ctx
.arg
.ekind
) {
788 ctx
.target
.reset(new MIPS
<ELF32LE
>(ctx
));
792 ctx
.target
.reset(new MIPS
<ELF32BE
>(ctx
));
796 ctx
.target
.reset(new MIPS
<ELF64LE
>(ctx
));
800 ctx
.target
.reset(new MIPS
<ELF64BE
>(ctx
));
804 llvm_unreachable("unsupported target");
808 template bool elf::isMipsPIC
<ELF32LE
>(const Defined
*);
809 template bool elf::isMipsPIC
<ELF32BE
>(const Defined
*);
810 template bool elf::isMipsPIC
<ELF64LE
>(const Defined
*);
811 template bool elf::isMipsPIC
<ELF64BE
>(const Defined
*);