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>);
38 void scanSection(InputSectionBase &) 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 RelocScan rs(ctx, &sec);
675 sec.relocations.reserve(N: rels.size());
676 RelType type;
677 for (auto it = rels.begin(); it != rels.end();) {
678 const RelTy &rel = *it;
679 uint64_t offset = rel.r_offset;
680 if constexpr (ELFT::Is64Bits) {
681 type = it->getType(ctx.arg.isMips64EL);
682 ++it;
683 } else {
684 if (ctx.arg.mipsN32Abi) {
685 type = getMipsN32RelType(ctx, it, rels.end());
686 } else {
687 type = it->getType(ctx.arg.isMips64EL);
688 ++it;
689 }
690 }
691
692 uint32_t symIdx = rel.getSymbol(ctx.arg.isMips64EL);
693 Symbol &sym = sec.getFile<ELFT>()->getSymbol(symIdx);
694 RelExpr expr = getRelExpr(type, s: sym, loc: sec.content().data() + rel.r_offset);
695 if (expr == R_NONE)
696 continue;
697 if (sym.isUndefined() && symIdx != 0 &&
698 rs.maybeReportUndefined(sym&: cast<Undefined>(Val&: sym), offset))
699 continue;
700
701 auto addend = rs.getAddend<ELFT>(rel, type);
702 if (expr == RE_MIPS_GOTREL && sym.isLocal()) {
703 addend += sec.getFile<ELFT>()->mipsGp0;
704 } else if (!RelTy::HasAddend) {
705 // MIPS has an odd notion of "paired" relocations to calculate addends.
706 // For example, if a relocation is of R_MIPS_HI16, there must be a
707 // R_MIPS_LO16 relocation after that, and an addend is calculated using
708 // the two relocations.
709 RelType pairTy = getMipsPairType(type, isLocal: sym.isLocal());
710 if (pairTy != R_MIPS_NONE) {
711 const uint8_t *buf = sec.content().data();
712 // To make things worse, paired relocations might not be contiguous in
713 // the relocation table, so we need to do linear search. *sigh*
714 bool found = false;
715 for (auto *ri = &rel; ri != rels.end(); ++ri) {
716 if (ri->getType(ctx.arg.isMips64EL) == pairTy &&
717 ri->getSymbol(ctx.arg.isMips64EL) == symIdx) {
718 addend += getImplicitAddend(buf: buf + ri->r_offset, type: pairTy);
719 found = true;
720 break;
721 }
722 }
723
724 if (!found)
725 Warn(ctx) << "can't find matching " << pairTy << " relocation for "
726 << type;
727 }
728 }
729
730 if (expr == RE_MIPS_TLSLD) {
731 ctx.in.mipsGot->addTlsIndex(file&: *sec.file);
732 sec.addReloc(r: {expr, type, offset, addend, &sym});
733 } else if (expr == RE_MIPS_TLSGD) {
734 ctx.in.mipsGot->addDynTlsEntry(file&: *sec.file, sym);
735 sec.addReloc(r: {expr, type, offset, addend, &sym});
736 } else {
737 if (expr == R_TPREL && rs.checkTlsLe(offset, sym, type))
738 continue;
739 rs.process(expr, type, offset, sym, addend);
740 }
741 }
742}
743
744template <class ELFT> void MIPS<ELFT>::scanSection(InputSectionBase &sec) {
745 auto relocs = sec.template relsOrRelas<ELFT>();
746 if (relocs.areRelocsRel())
747 scanSectionImpl(sec, relocs.rels);
748 else
749 scanSectionImpl(sec, relocs.relas);
750}
751
752template <class ELFT>
753void MIPS<ELFT>::relocate(uint8_t *loc, const Relocation &rel,
754 uint64_t val) const {
755 const endianness e = ELFT::Endianness;
756 RelType type = rel.type;
757
758 if (ELFT::Is64Bits || ctx.arg.mipsN32Abi)
759 std::tie(args&: type, args&: val) = calculateMipsRelChain(ctx, loc, type, val);
760
761 // Detect cross-mode jump/branch and fix instruction.
762 val = fixupCrossModeJump<ELFT>(ctx, loc, type, val);
763
764 // Thread pointer and DRP offsets from the start of TLS data area.
765 // https://www.linux-mips.org/wiki/NPTL
766 if (type == R_MIPS_TLS_DTPREL_HI16 || type == R_MIPS_TLS_DTPREL_LO16 ||
767 type == R_MIPS_TLS_DTPREL32 || type == R_MIPS_TLS_DTPREL64 ||
768 type == R_MICROMIPS_TLS_DTPREL_HI16 ||
769 type == R_MICROMIPS_TLS_DTPREL_LO16) {
770 val -= 0x8000;
771 }
772
773 switch (type) {
774 case R_MIPS_32:
775 case R_MIPS_REL32:
776 case R_MIPS_GPREL32:
777 case R_MIPS_TLS_DTPREL32:
778 case R_MIPS_TLS_TPREL32:
779 write32(ctx, loc, val);
780 break;
781 case R_MIPS_64:
782 case R_MIPS_TLS_DTPREL64:
783 case R_MIPS_TLS_TPREL64:
784 case (R_MIPS_64 << 8) | R_MIPS_REL32:
785 write64(ctx, loc, val);
786 break;
787 case R_MIPS_26:
788 writeValue(ctx, loc, val, 26, 2);
789 break;
790 case R_MIPS_GOT16:
791 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
792 // is updated addend (not a GOT index). In that case write high 16 bits
793 // to store a correct addend value.
794 if (ctx.arg.relocatable) {
795 writeValue(ctx, loc, val + 0x8000, 16, 16);
796 } else {
797 checkInt(ctx, loc, val, 16, rel);
798 writeValue(ctx, loc, val, 16, 0);
799 }
800 break;
801 case R_MICROMIPS_GOT16:
802 if (ctx.arg.relocatable) {
803 writeShuffle<e>(ctx, loc, val + 0x8000, 16, 16);
804 } else {
805 checkInt(ctx, loc, val, 16, rel);
806 writeShuffle<e>(ctx, loc, val, 16, 0);
807 }
808 break;
809 case R_MIPS_CALL16:
810 case R_MIPS_GOT_DISP:
811 case R_MIPS_GOT_PAGE:
812 case R_MIPS_GPREL16:
813 case R_MIPS_TLS_GD:
814 case R_MIPS_TLS_GOTTPREL:
815 case R_MIPS_TLS_LDM:
816 checkInt(ctx, loc, val, 16, rel);
817 [[fallthrough]];
818 case R_MIPS_CALL_LO16:
819 case R_MIPS_GOT_LO16:
820 case R_MIPS_GOT_OFST:
821 case R_MIPS_LO16:
822 case R_MIPS_PCLO16:
823 case R_MIPS_TLS_DTPREL_LO16:
824 case R_MIPS_TLS_TPREL_LO16:
825 writeValue(ctx, loc, val, 16, 0);
826 break;
827 case R_MICROMIPS_GPREL16:
828 case R_MICROMIPS_TLS_GD:
829 case R_MICROMIPS_TLS_LDM:
830 checkInt(ctx, loc, val, 16, rel);
831 writeShuffle<e>(ctx, loc, val, 16, 0);
832 break;
833 case R_MICROMIPS_CALL16:
834 case R_MICROMIPS_CALL_LO16:
835 case R_MICROMIPS_LO16:
836 case R_MICROMIPS_TLS_DTPREL_LO16:
837 case R_MICROMIPS_TLS_GOTTPREL:
838 case R_MICROMIPS_TLS_TPREL_LO16:
839 writeShuffle<e>(ctx, loc, val, 16, 0);
840 break;
841 case R_MICROMIPS_GPREL7_S2:
842 checkInt(ctx, loc, val, 7, rel);
843 writeShuffle<e>(ctx, loc, val, 7, 2);
844 break;
845 case R_MIPS_CALL_HI16:
846 case R_MIPS_GOT_HI16:
847 case R_MIPS_HI16:
848 case R_MIPS_PCHI16:
849 case R_MIPS_TLS_DTPREL_HI16:
850 case R_MIPS_TLS_TPREL_HI16:
851 writeValue(ctx, loc, val + 0x8000, 16, 16);
852 break;
853 case R_MICROMIPS_CALL_HI16:
854 case R_MICROMIPS_GOT_HI16:
855 case R_MICROMIPS_HI16:
856 case R_MICROMIPS_TLS_DTPREL_HI16:
857 case R_MICROMIPS_TLS_TPREL_HI16:
858 writeShuffle<e>(ctx, loc, val + 0x8000, 16, 16);
859 break;
860 case R_MIPS_HIGHER:
861 writeValue(ctx, loc, val + 0x80008000, 16, 32);
862 break;
863 case R_MIPS_HIGHEST:
864 writeValue(ctx, loc, val + 0x800080008000, 16, 48);
865 break;
866 case R_MIPS_JALR:
867 val -= 4;
868 // Replace jalr/jr instructions by bal/b if the target
869 // offset fits into the 18-bit range.
870 if (isInt<18>(x: val)) {
871 switch (read32(ctx, loc)) {
872 case 0x0320f809: // jalr $25 => bal sym
873 write32(ctx, loc, 0x04110000 | ((val >> 2) & 0xffff));
874 break;
875 case 0x03200008: // jr $25 => b sym
876 write32(ctx, loc, 0x10000000 | ((val >> 2) & 0xffff));
877 break;
878 }
879 }
880 break;
881 case R_MICROMIPS_JALR:
882 // Ignore this optimization relocation for now
883 break;
884 case R_MIPS_PC16:
885 checkAlignment(ctx, loc, val, 4, rel);
886 checkInt(ctx, loc, val, 18, rel);
887 writeValue(ctx, loc, val, 16, 2);
888 break;
889 case R_MIPS_PC19_S2:
890 checkAlignment(ctx, loc, val, 4, rel);
891 checkInt(ctx, loc, val, 21, rel);
892 writeValue(ctx, loc, val, 19, 2);
893 break;
894 case R_MIPS_PC21_S2:
895 checkAlignment(ctx, loc, val, 4, rel);
896 checkInt(ctx, loc, val, 23, rel);
897 writeValue(ctx, loc, val, 21, 2);
898 break;
899 case R_MIPS_PC26_S2:
900 checkAlignment(ctx, loc, val, 4, rel);
901 checkInt(ctx, loc, val, 28, rel);
902 writeValue(ctx, loc, val, 26, 2);
903 break;
904 case R_MIPS_PC32:
905 writeValue(ctx, loc, val, 32, 0);
906 break;
907 case R_MICROMIPS_26_S1:
908 case R_MICROMIPS_PC26_S1:
909 checkInt(ctx, loc, val, 27, rel);
910 writeShuffle<e>(ctx, loc, val, 26, 1);
911 break;
912 case R_MICROMIPS_PC7_S1:
913 checkInt(ctx, loc, val, 8, rel);
914 writeMicroRelocation16<e>(ctx, loc, val, 7, 1);
915 break;
916 case R_MICROMIPS_PC10_S1:
917 checkInt(ctx, loc, val, 11, rel);
918 writeMicroRelocation16<e>(ctx, loc, val, 10, 1);
919 break;
920 case R_MICROMIPS_PC16_S1:
921 checkInt(ctx, loc, val, 17, rel);
922 writeShuffle<e>(ctx, loc, val, 16, 1);
923 break;
924 case R_MICROMIPS_PC18_S3:
925 checkInt(ctx, loc, val, 21, rel);
926 writeShuffle<e>(ctx, loc, val, 18, 3);
927 break;
928 case R_MICROMIPS_PC19_S2:
929 checkInt(ctx, loc, val, 21, rel);
930 writeShuffle<e>(ctx, loc, val, 19, 2);
931 break;
932 case R_MICROMIPS_PC21_S1:
933 checkInt(ctx, loc, val, 22, rel);
934 writeShuffle<e>(ctx, loc, val, 21, 1);
935 break;
936 case R_MICROMIPS_PC23_S2:
937 checkInt(ctx, loc, val, 25, rel);
938 writeShuffle<e>(ctx, loc, val, 23, 2);
939 break;
940 default:
941 llvm_unreachable("unknown relocation");
942 }
943}
944
945template <class ELFT> bool MIPS<ELFT>::usesOnlyLowPageBits(RelType type) const {
946 return type == R_MIPS_LO16 || type == R_MIPS_GOT_OFST ||
947 type == R_MICROMIPS_LO16;
948}
949
950// Return true if the symbol is a PIC function.
951template <class ELFT> bool elf::isMipsPIC(const Defined *sym) {
952 if (!sym->isFunc())
953 return false;
954
955 if (sym->stOther & STO_MIPS_PIC)
956 return true;
957
958 if (!sym->section)
959 return false;
960
961 InputFile *file = cast<InputSectionBase>(Val: sym->section)->file;
962 if (!file || file->isInternal())
963 return false;
964
965 return cast<ObjFile<ELFT>>(file)->getObj().getHeader().e_flags & EF_MIPS_PIC;
966}
967
968template <class ELFT>
969AbiFlagsSection<ELFT>::AbiFlagsSection(Ctx &ctx)
970 : SyntheticSection(ctx, ".MIPS.abiflags", SHT_MIPS_ABIFLAGS, SHF_ALLOC, 8) {
971 this->entsize = sizeof(Elf_Mips_ABIFlags);
972
973 for (InputSectionBase *sec : ctx.inputSections) {
974 if (sec->type != SHT_MIPS_ABIFLAGS)
975 continue;
976 sec->markDead();
977 needed = true;
978
979 const size_t size = sec->content().size();
980 // Older version of BFD (such as the default FreeBSD linker) concatenate
981 // .MIPS.abiflags instead of merging. To allow for this case (or potential
982 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
983 if (size < sizeof(Elf_Mips_ABIFlags)) {
984 Err(ctx) << sec->file << ": invalid size of .MIPS.abiflags section: got "
985 << size << " instead of " << sizeof(Elf_Mips_ABIFlags);
986 return;
987 }
988 auto *s =
989 reinterpret_cast<const Elf_Mips_ABIFlags *>(sec->content().data());
990 if (s->version != 0) {
991 Err(ctx) << sec->file << ": unexpected .MIPS.abiflags version "
992 << s->version;
993 return;
994 }
995
996 // LLD checks ISA compatibility in calcMipsEFlags(). Here we just
997 // select the highest number of ISA/Rev/Ext.
998 flags.isa_level = std::max(flags.isa_level, s->isa_level);
999 flags.isa_rev = std::max(flags.isa_rev, s->isa_rev);
1000 flags.isa_ext = std::max(flags.isa_ext, s->isa_ext);
1001 flags.gpr_size = std::max(flags.gpr_size, s->gpr_size);
1002 flags.cpr1_size = std::max(flags.cpr1_size, s->cpr1_size);
1003 flags.cpr2_size = std::max(flags.cpr2_size, s->cpr2_size);
1004 flags.ases |= s->ases;
1005 flags.flags1 |= s->flags1;
1006 flags.flags2 |= s->flags2;
1007 flags.fp_abi =
1008 elf::getMipsFpAbiFlag(ctx, file: sec->file, oldFlag: flags.fp_abi, newFlag: s->fp_abi);
1009 }
1010}
1011
1012template <class ELFT>
1013OptionsSection<ELFT>::OptionsSection(Ctx &ctx)
1014 : SyntheticSection(ctx, ".MIPS.options", SHT_MIPS_OPTIONS, SHF_ALLOC, 8) {
1015 this->entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
1016
1017 // N64 ABI only.
1018 if (!ELFT::Is64Bits)
1019 return;
1020
1021 for (InputSectionBase *sec : ctx.inputSections) {
1022 if (sec->type != SHT_MIPS_OPTIONS)
1023 continue;
1024 sec->markDead();
1025 needed = true;
1026
1027 ArrayRef<uint8_t> d = sec->content();
1028 while (!d.empty()) {
1029 if (d.size() < sizeof(Elf_Mips_Options)) {
1030 Err(ctx) << sec->file << ": invalid size of .MIPS.options section";
1031 break;
1032 }
1033
1034 auto *opt = reinterpret_cast<const Elf_Mips_Options *>(d.data());
1035 if (opt->kind == ODK_REGINFO) {
1036 reginfo.ri_gprmask |= opt->getRegInfo().ri_gprmask;
1037 sec->getFile<ELFT>()->mipsGp0 = opt->getRegInfo().ri_gp_value;
1038 break;
1039 }
1040
1041 if (!opt->size) {
1042 Err(ctx) << sec->file << ": zero option descriptor size";
1043 break;
1044 }
1045 d = d.slice(opt->size);
1046 }
1047 }
1048}
1049
1050template <class ELFT> void OptionsSection<ELFT>::writeTo(uint8_t *buf) {
1051 auto *options = reinterpret_cast<Elf_Mips_Options *>(buf);
1052 options->kind = ODK_REGINFO;
1053 options->size = getSize();
1054
1055 if (!ctx.arg.relocatable)
1056 reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
1057 memcpy(buf + sizeof(Elf_Mips_Options), &reginfo, sizeof(reginfo));
1058}
1059
1060template <class ELFT>
1061ReginfoSection<ELFT>::ReginfoSection(Ctx &ctx)
1062 : SyntheticSection(ctx, ".reginfo", SHT_MIPS_REGINFO, SHF_ALLOC, 4) {
1063 this->entsize = sizeof(Elf_Mips_RegInfo);
1064
1065 // Section should be alive for O32 and N32 ABIs only.
1066 if (ELFT::Is64Bits)
1067 return;
1068
1069 for (InputSectionBase *sec : ctx.inputSections) {
1070 if (sec->type != SHT_MIPS_REGINFO)
1071 continue;
1072 sec->markDead();
1073 needed = true;
1074
1075 if (sec->content().size() != sizeof(Elf_Mips_RegInfo)) {
1076 Err(ctx) << sec->file << ": invalid size of .reginfo section";
1077 return;
1078 }
1079
1080 auto *r = reinterpret_cast<const Elf_Mips_RegInfo *>(sec->content().data());
1081 reginfo.ri_gprmask |= r->ri_gprmask;
1082 sec->getFile<ELFT>()->mipsGp0 = r->ri_gp_value;
1083 }
1084}
1085
1086template <class ELFT> void ReginfoSection<ELFT>::writeTo(uint8_t *buf) {
1087 if (!ctx.arg.relocatable)
1088 reginfo.ri_gp_value = ctx.in.mipsGot->getGp();
1089 memcpy(buf, &reginfo, sizeof(reginfo));
1090}
1091
1092void elf::setMipsTargetInfo(Ctx &ctx) {
1093 switch (ctx.arg.ekind) {
1094 case ELF32LEKind: {
1095 ctx.target.reset(p: new MIPS<ELF32LE>(ctx));
1096 return;
1097 }
1098 case ELF32BEKind: {
1099 ctx.target.reset(p: new MIPS<ELF32BE>(ctx));
1100 return;
1101 }
1102 case ELF64LEKind: {
1103 ctx.target.reset(p: new MIPS<ELF64LE>(ctx));
1104 return;
1105 }
1106 case ELF64BEKind: {
1107 ctx.target.reset(p: new MIPS<ELF64BE>(ctx));
1108 return;
1109 }
1110 default:
1111 llvm_unreachable("unsupported target");
1112 }
1113}
1114
1115template bool elf::isMipsPIC<ELF32LE>(const Defined *);
1116template bool elf::isMipsPIC<ELF32BE>(const Defined *);
1117template bool elf::isMipsPIC<ELF64LE>(const Defined *);
1118template bool elf::isMipsPIC<ELF64BE>(const Defined *);
1119