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