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() {
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(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
>();
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
|| config
->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(getErrorLocation(loc
) +
91 "found R_MIPS_JALR relocation against non-function symbol " +
92 toString(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() & 0x1))
102 case R_MICROMIPS_JALR
:
106 case R_MICROMIPS_GPREL16
:
107 case R_MICROMIPS_GPREL7_S2
:
108 return R_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
== ElfSym::mipsGpDisp
)
125 return R_MIPS_GOT_GP_PC
;
126 if (&s
== ElfSym::mipsLocalGp
)
127 return R_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 R_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 R_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 R_MIPS_GOT_OFF32
;
183 case R_MIPS_GOT_PAGE
:
184 return R_MIPS_GOT_LOCAL_PAGE
;
186 case R_MICROMIPS_TLS_GD
:
189 case R_MICROMIPS_TLS_LDM
:
194 error(getErrorLocation(loc
) + "unknown relocation (" + Twine(type
) +
195 ") against symbol " + toString(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
= in
.plt
->getVA();
214 template <endianness E
> static uint32_t readShuffle(const uint8_t *loc
) {
215 // The major opcode of a microMIPS instruction needs to appear
216 // in the first 16-bit word (lowest address) for efficient hardware
217 // decode so that it knows if the instruction is 16-bit or 32-bit
218 // as early as possible. To do so, little-endian binaries keep 16-bit
219 // words in a big-endian order. That is why we have to swap these
220 // words to get a correct value.
221 uint32_t v
= read32(loc
);
222 if (E
== llvm::endianness::little
)
223 return (v
<< 16) | (v
>> 16);
227 static void writeValue(uint8_t *loc
, uint64_t v
, uint8_t bitsSize
,
229 uint32_t instr
= read32(loc
);
230 uint32_t mask
= 0xffffffff >> (32 - bitsSize
);
231 uint32_t data
= (instr
& ~mask
) | ((v
>> shift
) & mask
);
235 template <endianness E
>
236 static void writeShuffleValue(uint8_t *loc
, uint64_t v
, uint8_t bitsSize
,
238 // See comments in readShuffle for purpose of this code.
239 uint16_t *words
= (uint16_t *)loc
;
240 if (E
== llvm::endianness::little
)
241 std::swap(words
[0], words
[1]);
243 writeValue(loc
, v
, bitsSize
, shift
);
245 if (E
== llvm::endianness::little
)
246 std::swap(words
[0], words
[1]);
249 template <endianness E
>
250 static void writeMicroRelocation16(uint8_t *loc
, uint64_t v
, uint8_t bitsSize
,
252 uint16_t instr
= read16(loc
);
253 uint16_t mask
= 0xffff >> (16 - bitsSize
);
254 uint16_t data
= (instr
& ~mask
) | ((v
>> shift
) & mask
);
258 template <class ELFT
> void MIPS
<ELFT
>::writePltHeader(uint8_t *buf
) const {
260 uint64_t gotPlt
= in
.gotPlt
->getVA();
261 uint64_t plt
= in
.plt
->getVA();
262 // Overwrite trap instructions written by Writer::writeTrapInstr.
263 memset(buf
, 0, pltHeaderSize
);
265 write16(buf
, isMipsR6() ? 0x7860 : 0x7980); // addiupc v1, (GOTPLT) - .
266 write16(buf
+ 4, 0xff23); // lw $25, 0($3)
267 write16(buf
+ 8, 0x0535); // subu16 $2, $2, $3
268 write16(buf
+ 10, 0x2525); // srl16 $2, $2, 2
269 write16(buf
+ 12, 0x3302); // addiu $24, $2, -2
270 write16(buf
+ 14, 0xfffe);
271 write16(buf
+ 16, 0x0dff); // move $15, $31
273 write16(buf
+ 18, 0x0f83); // move $28, $3
274 write16(buf
+ 20, 0x472b); // jalrc $25
275 write16(buf
+ 22, 0x0c00); // nop
276 relocateNoSym(buf
, R_MICROMIPS_PC19_S2
, gotPlt
- plt
);
278 write16(buf
+ 18, 0x45f9); // jalrc $25
279 write16(buf
+ 20, 0x0f83); // move $28, $3
280 write16(buf
+ 22, 0x0c00); // nop
281 relocateNoSym(buf
, R_MICROMIPS_PC23_S2
, gotPlt
- plt
);
286 if (config
->mipsN32Abi
) {
287 write32(buf
, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
288 write32(buf
+ 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
289 write32(buf
+ 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
290 write32(buf
+ 12, 0x030ec023); // subu $24, $24, $14
291 write32(buf
+ 16, 0x03e07825); // move $15, $31
292 write32(buf
+ 20, 0x0018c082); // srl $24, $24, 2
293 } else if (ELFT::Is64Bits
) {
294 write32(buf
, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
295 write32(buf
+ 4, 0xddd90000); // ld $25, %lo(&GOTPLT[0])($14)
296 write32(buf
+ 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
297 write32(buf
+ 12, 0x030ec023); // subu $24, $24, $14
298 write32(buf
+ 16, 0x03e07825); // move $15, $31
299 write32(buf
+ 20, 0x0018c0c2); // srl $24, $24, 3
301 write32(buf
, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
302 write32(buf
+ 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
303 write32(buf
+ 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
304 write32(buf
+ 12, 0x031cc023); // subu $24, $24, $28
305 write32(buf
+ 16, 0x03e07825); // move $15, $31
306 write32(buf
+ 20, 0x0018c082); // srl $24, $24, 2
309 uint32_t jalrInst
= config
->zHazardplt
? 0x0320fc09 : 0x0320f809;
310 write32(buf
+ 24, jalrInst
); // jalr.hb $25 or jalr $25
311 write32(buf
+ 28, 0x2718fffe); // subu $24, $24, 2
313 uint64_t gotPlt
= in
.gotPlt
->getVA();
314 writeValue(buf
, gotPlt
+ 0x8000, 16, 16);
315 writeValue(buf
+ 4, gotPlt
, 16, 0);
316 writeValue(buf
+ 8, gotPlt
, 16, 0);
319 template <class ELFT
>
320 void MIPS
<ELFT
>::writePlt(uint8_t *buf
, const Symbol
&sym
,
321 uint64_t pltEntryAddr
) const {
322 uint64_t gotPltEntryAddr
= sym
.getGotPltVA();
324 // Overwrite trap instructions written by Writer::writeTrapInstr.
325 memset(buf
, 0, pltEntrySize
);
328 write16(buf
, 0x7840); // addiupc $2, (GOTPLT) - .
329 write16(buf
+ 4, 0xff22); // lw $25, 0($2)
330 write16(buf
+ 8, 0x0f02); // move $24, $2
331 write16(buf
+ 10, 0x4723); // jrc $25 / jr16 $25
332 relocateNoSym(buf
, R_MICROMIPS_PC19_S2
, gotPltEntryAddr
- pltEntryAddr
);
334 write16(buf
, 0x7900); // addiupc $2, (GOTPLT) - .
335 write16(buf
+ 4, 0xff22); // lw $25, 0($2)
336 write16(buf
+ 8, 0x4599); // jrc $25 / jr16 $25
337 write16(buf
+ 10, 0x0f02); // move $24, $2
338 relocateNoSym(buf
, R_MICROMIPS_PC23_S2
, gotPltEntryAddr
- pltEntryAddr
);
343 uint32_t loadInst
= ELFT::Is64Bits
? 0xddf90000 : 0x8df90000;
344 uint32_t jrInst
= isMipsR6() ? (config
->zHazardplt
? 0x03200409 : 0x03200009)
345 : (config
->zHazardplt
? 0x03200408 : 0x03200008);
346 uint32_t addInst
= ELFT::Is64Bits
? 0x65f80000 : 0x25f80000;
348 write32(buf
, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
349 write32(buf
+ 4, loadInst
); // l[wd] $25, %lo(.got.plt entry)($15)
350 write32(buf
+ 8, jrInst
); // jr $25 / jr.hb $25
351 write32(buf
+ 12, addInst
); // [d]addiu $24, $15, %lo(.got.plt entry)
352 writeValue(buf
, gotPltEntryAddr
+ 0x8000, 16, 16);
353 writeValue(buf
+ 4, gotPltEntryAddr
, 16, 0);
354 writeValue(buf
+ 12, gotPltEntryAddr
, 16, 0);
357 template <class ELFT
>
358 bool MIPS
<ELFT
>::needsThunk(RelExpr expr
, RelType type
, const InputFile
*file
,
359 uint64_t branchAddr
, const Symbol
&s
,
360 int64_t /*a*/) const {
361 // Any MIPS PIC code function is invoked with its address in register $t9.
362 // So if we have a branch instruction from non-PIC code to the PIC one
363 // we cannot make the jump directly and need to create a small stubs
364 // to save the target function address.
365 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
366 if (type
!= R_MIPS_26
&& type
!= R_MIPS_PC26_S2
&&
367 type
!= R_MICROMIPS_26_S1
&& type
!= R_MICROMIPS_PC26_S1
)
369 auto *f
= dyn_cast_or_null
<ObjFile
<ELFT
>>(file
);
372 // If current file has PIC code, LA25 stub is not required.
373 if (f
->getObj().getHeader().e_flags
& EF_MIPS_PIC
)
375 auto *d
= dyn_cast
<Defined
>(&s
);
376 // LA25 is required if target file has PIC code
377 // or target symbol is a PIC symbol.
378 return d
&& isMipsPIC
<ELFT
>(d
);
381 template <class ELFT
>
382 int64_t MIPS
<ELFT
>::getImplicitAddend(const uint8_t *buf
, RelType type
) const {
383 const endianness e
= ELFT::TargetEndianness
;
388 case R_MIPS_TLS_DTPREL32
:
389 case R_MIPS_TLS_DTPMOD32
:
390 case R_MIPS_TLS_TPREL32
:
391 return SignExtend64
<32>(read32(buf
));
393 // FIXME (simon): If the relocation target symbol is not a PLT entry
394 // we should use another expression for calculation:
395 // ((A << 2) | (P & 0xf0000000)) >> 2
396 return SignExtend64
<28>(read32(buf
) << 2);
397 case R_MIPS_CALL_HI16
:
399 case R_MIPS_GOT_HI16
:
402 return SignExtend64
<16>(read32(buf
)) << 16;
404 case R_MIPS_CALL_LO16
:
405 case R_MIPS_GOT_LO16
:
409 case R_MIPS_TLS_DTPREL_HI16
:
410 case R_MIPS_TLS_DTPREL_LO16
:
412 case R_MIPS_TLS_GOTTPREL
:
414 case R_MIPS_TLS_TPREL_HI16
:
415 case R_MIPS_TLS_TPREL_LO16
:
416 return SignExtend64
<16>(read32(buf
));
417 case R_MICROMIPS_GOT16
:
418 case R_MICROMIPS_HI16
:
419 return SignExtend64
<16>(readShuffle
<e
>(buf
)) << 16;
420 case R_MICROMIPS_CALL16
:
421 case R_MICROMIPS_GPREL16
:
422 case R_MICROMIPS_LO16
:
423 case R_MICROMIPS_TLS_DTPREL_HI16
:
424 case R_MICROMIPS_TLS_DTPREL_LO16
:
425 case R_MICROMIPS_TLS_GD
:
426 case R_MICROMIPS_TLS_GOTTPREL
:
427 case R_MICROMIPS_TLS_LDM
:
428 case R_MICROMIPS_TLS_TPREL_HI16
:
429 case R_MICROMIPS_TLS_TPREL_LO16
:
430 return SignExtend64
<16>(readShuffle
<e
>(buf
));
431 case R_MICROMIPS_GPREL7_S2
:
432 return SignExtend64
<9>(readShuffle
<e
>(buf
) << 2);
434 return SignExtend64
<18>(read32(buf
) << 2);
436 return SignExtend64
<21>(read32(buf
) << 2);
438 return SignExtend64
<23>(read32(buf
) << 2);
440 return SignExtend64
<28>(read32(buf
) << 2);
442 return SignExtend64
<32>(read32(buf
));
443 case R_MICROMIPS_26_S1
:
444 return SignExtend64
<27>(readShuffle
<e
>(buf
) << 1);
445 case R_MICROMIPS_PC7_S1
:
446 return SignExtend64
<8>(read16(buf
) << 1);
447 case R_MICROMIPS_PC10_S1
:
448 return SignExtend64
<11>(read16(buf
) << 1);
449 case R_MICROMIPS_PC16_S1
:
450 return SignExtend64
<17>(readShuffle
<e
>(buf
) << 1);
451 case R_MICROMIPS_PC18_S3
:
452 return SignExtend64
<21>(readShuffle
<e
>(buf
) << 3);
453 case R_MICROMIPS_PC19_S2
:
454 return SignExtend64
<21>(readShuffle
<e
>(buf
) << 2);
455 case R_MICROMIPS_PC21_S1
:
456 return SignExtend64
<22>(readShuffle
<e
>(buf
) << 1);
457 case R_MICROMIPS_PC23_S2
:
458 return SignExtend64
<25>(readShuffle
<e
>(buf
) << 2);
459 case R_MICROMIPS_PC26_S1
:
460 return SignExtend64
<27>(readShuffle
<e
>(buf
) << 1);
462 case R_MIPS_TLS_DTPMOD64
:
463 case R_MIPS_TLS_DTPREL64
:
464 case R_MIPS_TLS_TPREL64
:
465 case (R_MIPS_64
<< 8) | R_MIPS_REL32
:
468 return config
->is64
? read64(buf
) : read32(buf
);
470 case R_MIPS_JUMP_SLOT
:
472 // These relocations are defined as not having an implicit addend.
475 internalLinkerError(getErrorLocation(buf
),
476 "cannot read addend for relocation " + toString(type
));
481 static std::pair
<uint32_t, uint64_t>
482 calculateMipsRelChain(uint8_t *loc
, RelType type
, uint64_t val
) {
483 // MIPS N64 ABI packs multiple relocations into the single relocation
484 // record. In general, all up to three relocations can have arbitrary
485 // types. In fact, Clang and GCC uses only a few combinations. For now,
486 // we support two of them. That is allow to pass at least all LLVM
488 // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
489 // <any relocation> / R_MIPS_64 / R_MIPS_NONE
490 // The first relocation is a 'real' relocation which is calculated
491 // using the corresponding symbol's value. The second and the third
492 // relocations used to modify result of the first one: extend it to
493 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
494 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
495 RelType type2
= (type
>> 8) & 0xff;
496 RelType type3
= (type
>> 16) & 0xff;
497 if (type2
== R_MIPS_NONE
&& type3
== R_MIPS_NONE
)
498 return std::make_pair(type
, val
);
499 if (type2
== R_MIPS_64
&& type3
== R_MIPS_NONE
)
500 return std::make_pair(type2
, val
);
501 if (type2
== R_MIPS_SUB
&& (type3
== R_MIPS_HI16
|| type3
== R_MIPS_LO16
))
502 return std::make_pair(type3
, -val
);
503 error(getErrorLocation(loc
) + "unsupported relocations combination " +
505 return std::make_pair(type
& 0xff, val
);
508 static bool isBranchReloc(RelType type
) {
509 return type
== R_MIPS_26
|| type
== R_MIPS_PC26_S2
||
510 type
== R_MIPS_PC21_S2
|| type
== R_MIPS_PC16
;
513 static bool isMicroBranchReloc(RelType type
) {
514 return type
== R_MICROMIPS_26_S1
|| type
== R_MICROMIPS_PC16_S1
||
515 type
== R_MICROMIPS_PC10_S1
|| type
== R_MICROMIPS_PC7_S1
;
518 template <class ELFT
>
519 static uint64_t fixupCrossModeJump(uint8_t *loc
, RelType type
, uint64_t val
) {
520 // Here we need to detect jump/branch from regular MIPS code
521 // to a microMIPS target and vice versa. In that cases jump
522 // instructions need to be replaced by their "cross-mode"
524 const endianness e
= ELFT::TargetEndianness
;
525 bool isMicroTgt
= val
& 0x1;
526 bool isCrossJump
= (isMicroTgt
&& isBranchReloc(type
)) ||
527 (!isMicroTgt
&& isMicroBranchReloc(type
));
533 uint32_t inst
= read32(loc
) >> 26;
534 if (inst
== 0x3 || inst
== 0x1d) { // JAL or JALX
535 writeValue(loc
, 0x1d << 26, 32, 0);
540 case R_MICROMIPS_26_S1
: {
541 uint32_t inst
= readShuffle
<e
>(loc
) >> 26;
542 if (inst
== 0x3d || inst
== 0x3c) { // JAL32 or JALX32
544 writeShuffleValue
<e
>(loc
, 0x3c << 26, 32, 0);
552 case R_MICROMIPS_PC16_S1
:
553 case R_MICROMIPS_PC10_S1
:
554 case R_MICROMIPS_PC7_S1
:
555 // FIXME (simon): Support valid branch relocations.
558 llvm_unreachable("unexpected jump/branch relocation");
561 error(getErrorLocation(loc
) +
562 "unsupported jump/branch instruction between ISA modes referenced by " +
563 toString(type
) + " relocation");
567 template <class ELFT
>
568 void MIPS
<ELFT
>::relocate(uint8_t *loc
, const Relocation
&rel
,
569 uint64_t val
) const {
570 const endianness e
= ELFT::TargetEndianness
;
571 RelType type
= rel
.type
;
573 if (ELFT::Is64Bits
|| config
->mipsN32Abi
)
574 std::tie(type
, val
) = calculateMipsRelChain(loc
, type
, val
);
576 // Detect cross-mode jump/branch and fix instruction.
577 val
= fixupCrossModeJump
<ELFT
>(loc
, type
, val
);
579 // Thread pointer and DRP offsets from the start of TLS data area.
580 // https://www.linux-mips.org/wiki/NPTL
581 if (type
== R_MIPS_TLS_DTPREL_HI16
|| type
== R_MIPS_TLS_DTPREL_LO16
||
582 type
== R_MIPS_TLS_DTPREL32
|| type
== R_MIPS_TLS_DTPREL64
||
583 type
== R_MICROMIPS_TLS_DTPREL_HI16
||
584 type
== R_MICROMIPS_TLS_DTPREL_LO16
) {
591 case R_MIPS_TLS_DTPREL32
:
592 case R_MIPS_TLS_TPREL32
:
596 case R_MIPS_TLS_DTPREL64
:
597 case R_MIPS_TLS_TPREL64
:
601 writeValue(loc
, val
, 26, 2);
604 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
605 // is updated addend (not a GOT index). In that case write high 16 bits
606 // to store a correct addend value.
607 if (config
->relocatable
) {
608 writeValue(loc
, val
+ 0x8000, 16, 16);
610 checkInt(loc
, val
, 16, rel
);
611 writeValue(loc
, val
, 16, 0);
614 case R_MICROMIPS_GOT16
:
615 if (config
->relocatable
) {
616 writeShuffleValue
<e
>(loc
, val
+ 0x8000, 16, 16);
618 checkInt(loc
, val
, 16, rel
);
619 writeShuffleValue
<e
>(loc
, val
, 16, 0);
623 case R_MIPS_GOT_DISP
:
624 case R_MIPS_GOT_PAGE
:
627 case R_MIPS_TLS_GOTTPREL
:
629 checkInt(loc
, val
, 16, rel
);
631 case R_MIPS_CALL_LO16
:
632 case R_MIPS_GOT_LO16
:
633 case R_MIPS_GOT_OFST
:
636 case R_MIPS_TLS_DTPREL_LO16
:
637 case R_MIPS_TLS_TPREL_LO16
:
638 writeValue(loc
, val
, 16, 0);
640 case R_MICROMIPS_GPREL16
:
641 case R_MICROMIPS_TLS_GD
:
642 case R_MICROMIPS_TLS_LDM
:
643 checkInt(loc
, val
, 16, rel
);
644 writeShuffleValue
<e
>(loc
, val
, 16, 0);
646 case R_MICROMIPS_CALL16
:
647 case R_MICROMIPS_CALL_LO16
:
648 case R_MICROMIPS_LO16
:
649 case R_MICROMIPS_TLS_DTPREL_LO16
:
650 case R_MICROMIPS_TLS_GOTTPREL
:
651 case R_MICROMIPS_TLS_TPREL_LO16
:
652 writeShuffleValue
<e
>(loc
, val
, 16, 0);
654 case R_MICROMIPS_GPREL7_S2
:
655 checkInt(loc
, val
, 7, rel
);
656 writeShuffleValue
<e
>(loc
, val
, 7, 2);
658 case R_MIPS_CALL_HI16
:
659 case R_MIPS_GOT_HI16
:
662 case R_MIPS_TLS_DTPREL_HI16
:
663 case R_MIPS_TLS_TPREL_HI16
:
664 writeValue(loc
, val
+ 0x8000, 16, 16);
666 case R_MICROMIPS_CALL_HI16
:
667 case R_MICROMIPS_GOT_HI16
:
668 case R_MICROMIPS_HI16
:
669 case R_MICROMIPS_TLS_DTPREL_HI16
:
670 case R_MICROMIPS_TLS_TPREL_HI16
:
671 writeShuffleValue
<e
>(loc
, val
+ 0x8000, 16, 16);
674 writeValue(loc
, val
+ 0x80008000, 16, 32);
677 writeValue(loc
, val
+ 0x800080008000, 16, 48);
681 // Replace jalr/jr instructions by bal/b if the target
682 // offset fits into the 18-bit range.
683 if (isInt
<18>(val
)) {
684 switch (read32(loc
)) {
685 case 0x0320f809: // jalr $25 => bal sym
686 write32(loc
, 0x04110000 | ((val
>> 2) & 0xffff));
688 case 0x03200008: // jr $25 => b sym
689 write32(loc
, 0x10000000 | ((val
>> 2) & 0xffff));
694 case R_MICROMIPS_JALR
:
695 // Ignore this optimization relocation for now
698 checkAlignment(loc
, val
, 4, rel
);
699 checkInt(loc
, val
, 18, rel
);
700 writeValue(loc
, val
, 16, 2);
703 checkAlignment(loc
, val
, 4, rel
);
704 checkInt(loc
, val
, 21, rel
);
705 writeValue(loc
, val
, 19, 2);
708 checkAlignment(loc
, val
, 4, rel
);
709 checkInt(loc
, val
, 23, rel
);
710 writeValue(loc
, val
, 21, 2);
713 checkAlignment(loc
, val
, 4, rel
);
714 checkInt(loc
, val
, 28, rel
);
715 writeValue(loc
, val
, 26, 2);
718 writeValue(loc
, val
, 32, 0);
720 case R_MICROMIPS_26_S1
:
721 case R_MICROMIPS_PC26_S1
:
722 checkInt(loc
, val
, 27, rel
);
723 writeShuffleValue
<e
>(loc
, val
, 26, 1);
725 case R_MICROMIPS_PC7_S1
:
726 checkInt(loc
, val
, 8, rel
);
727 writeMicroRelocation16
<e
>(loc
, val
, 7, 1);
729 case R_MICROMIPS_PC10_S1
:
730 checkInt(loc
, val
, 11, rel
);
731 writeMicroRelocation16
<e
>(loc
, val
, 10, 1);
733 case R_MICROMIPS_PC16_S1
:
734 checkInt(loc
, val
, 17, rel
);
735 writeShuffleValue
<e
>(loc
, val
, 16, 1);
737 case R_MICROMIPS_PC18_S3
:
738 checkInt(loc
, val
, 21, rel
);
739 writeShuffleValue
<e
>(loc
, val
, 18, 3);
741 case R_MICROMIPS_PC19_S2
:
742 checkInt(loc
, val
, 21, rel
);
743 writeShuffleValue
<e
>(loc
, val
, 19, 2);
745 case R_MICROMIPS_PC21_S1
:
746 checkInt(loc
, val
, 22, rel
);
747 writeShuffleValue
<e
>(loc
, val
, 21, 1);
749 case R_MICROMIPS_PC23_S2
:
750 checkInt(loc
, val
, 25, rel
);
751 writeShuffleValue
<e
>(loc
, val
, 23, 2);
754 llvm_unreachable("unknown relocation");
758 template <class ELFT
> bool MIPS
<ELFT
>::usesOnlyLowPageBits(RelType type
) const {
759 return type
== R_MIPS_LO16
|| type
== R_MIPS_GOT_OFST
||
760 type
== R_MICROMIPS_LO16
;
763 // Return true if the symbol is a PIC function.
764 template <class ELFT
> bool elf::isMipsPIC(const Defined
*sym
) {
768 if (sym
->stOther
& STO_MIPS_PIC
)
774 ObjFile
<ELFT
> *file
=
775 cast
<InputSectionBase
>(sym
->section
)->template getFile
<ELFT
>();
779 return file
->getObj().getHeader().e_flags
& EF_MIPS_PIC
;
782 template <class ELFT
> TargetInfo
*elf::getMipsTargetInfo() {
783 static MIPS
<ELFT
> target
;
787 template TargetInfo
*elf::getMipsTargetInfo
<ELF32LE
>();
788 template TargetInfo
*elf::getMipsTargetInfo
<ELF32BE
>();
789 template TargetInfo
*elf::getMipsTargetInfo
<ELF64LE
>();
790 template TargetInfo
*elf::getMipsTargetInfo
<ELF64BE
>();
792 template bool elf::isMipsPIC
<ELF32LE
>(const Defined
*);
793 template bool elf::isMipsPIC
<ELF32BE
>(const Defined
*);
794 template bool elf::isMipsPIC
<ELF64LE
>(const Defined
*);
795 template bool elf::isMipsPIC
<ELF64BE
>(const Defined
*);