1 //===- MIPS.cpp -----------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Error.h" 11 #include "InputFiles.h" 12 #include "OutputSections.h" 13 #include "Symbols.h" 14 #include "SyntheticSections.h" 15 #include "Target.h" 16 #include "Thunks.h" 17 #include "llvm/Object/ELF.h" 18 #include "llvm/Support/Endian.h" 19 20 using namespace llvm; 21 using namespace llvm::object; 22 using namespace llvm::support::endian; 23 using namespace llvm::ELF; 24 using namespace lld; 25 using namespace lld::elf; 26 27 namespace { 28 template <class ELFT> class MIPS final : public TargetInfo { 29 public: 30 MIPS(); 31 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S, 32 const uint8_t *Loc) const override; 33 int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override; 34 bool isPicRel(uint32_t Type) const override; 35 uint32_t getDynRel(uint32_t Type) const override; 36 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; 37 void writePltHeader(uint8_t *Buf) const override; 38 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, 39 int32_t Index, unsigned RelOff) const override; 40 bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File, 41 const SymbolBody &S) const override; 42 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override; 43 bool usesOnlyLowPageBits(uint32_t Type) const override; 44 }; 45 } // namespace 46 47 template <class ELFT> MIPS<ELFT>::MIPS() { 48 GotPltHeaderEntriesNum = 2; 49 DefaultMaxPageSize = 65536; 50 GotEntrySize = sizeof(typename ELFT::uint); 51 GotPltEntrySize = sizeof(typename ELFT::uint); 52 PltEntrySize = 16; 53 PltHeaderSize = 32; 54 CopyRel = R_MIPS_COPY; 55 PltRel = R_MIPS_JUMP_SLOT; 56 NeedsThunks = true; 57 TrapInstr = 0xefefefef; 58 59 if (ELFT::Is64Bits) { 60 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32; 61 TlsGotRel = R_MIPS_TLS_TPREL64; 62 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64; 63 TlsOffsetRel = R_MIPS_TLS_DTPREL64; 64 } else { 65 RelativeRel = R_MIPS_REL32; 66 TlsGotRel = R_MIPS_TLS_TPREL32; 67 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32; 68 TlsOffsetRel = R_MIPS_TLS_DTPREL32; 69 } 70 } 71 72 template <class ELFT> 73 RelExpr MIPS<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S, 74 const uint8_t *Loc) const { 75 // See comment in the calculateMipsRelChain. 76 if (ELFT::Is64Bits || Config->MipsN32Abi) 77 Type &= 0xff; 78 switch (Type) { 79 default: 80 return R_ABS; 81 case R_MIPS_JALR: 82 return R_HINT; 83 case R_MIPS_GPREL16: 84 case R_MIPS_GPREL32: 85 return R_MIPS_GOTREL; 86 case R_MIPS_26: 87 return R_PLT; 88 case R_MIPS_HI16: 89 case R_MIPS_LO16: 90 // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate 91 // offset between start of function and 'gp' value which by default 92 // equal to the start of .got section. In that case we consider these 93 // relocations as relative. 94 if (&S == ElfSym::MipsGpDisp) 95 return R_MIPS_GOT_GP_PC; 96 if (&S == ElfSym::MipsLocalGp) 97 return R_MIPS_GOT_GP; 98 LLVM_FALLTHROUGH; 99 case R_MIPS_GOT_OFST: 100 return R_ABS; 101 case R_MIPS_PC32: 102 case R_MIPS_PC16: 103 case R_MIPS_PC19_S2: 104 case R_MIPS_PC21_S2: 105 case R_MIPS_PC26_S2: 106 case R_MIPS_PCHI16: 107 case R_MIPS_PCLO16: 108 return R_PC; 109 case R_MIPS_GOT16: 110 if (S.isLocal()) 111 return R_MIPS_GOT_LOCAL_PAGE; 112 LLVM_FALLTHROUGH; 113 case R_MIPS_CALL16: 114 case R_MIPS_GOT_DISP: 115 case R_MIPS_TLS_GOTTPREL: 116 return R_MIPS_GOT_OFF; 117 case R_MIPS_CALL_HI16: 118 case R_MIPS_CALL_LO16: 119 case R_MIPS_GOT_HI16: 120 case R_MIPS_GOT_LO16: 121 return R_MIPS_GOT_OFF32; 122 case R_MIPS_GOT_PAGE: 123 return R_MIPS_GOT_LOCAL_PAGE; 124 case R_MIPS_TLS_GD: 125 return R_MIPS_TLSGD; 126 case R_MIPS_TLS_LDM: 127 return R_MIPS_TLSLD; 128 } 129 } 130 131 template <class ELFT> bool MIPS<ELFT>::isPicRel(uint32_t Type) const { 132 return Type == R_MIPS_32 || Type == R_MIPS_64; 133 } 134 135 template <class ELFT> uint32_t MIPS<ELFT>::getDynRel(uint32_t Type) const { 136 return RelativeRel; 137 } 138 139 template <class ELFT> 140 void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { 141 write32<ELFT::TargetEndianness>(Buf, InX::Plt->getVA()); 142 } 143 144 template <endianness E, uint8_t BSIZE, uint8_t SHIFT> 145 static int64_t getPcRelocAddend(const uint8_t *Loc) { 146 uint32_t Instr = read32<E>(Loc); 147 uint32_t Mask = 0xffffffff >> (32 - BSIZE); 148 return SignExtend64<BSIZE + SHIFT>((Instr & Mask) << SHIFT); 149 } 150 151 template <endianness E, uint8_t BSIZE, uint8_t SHIFT> 152 static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t V) { 153 uint32_t Mask = 0xffffffff >> (32 - BSIZE); 154 uint32_t Instr = read32<E>(Loc); 155 if (SHIFT > 0) 156 checkAlignment<(1 << SHIFT)>(Loc, V, Type); 157 checkInt<BSIZE + SHIFT>(Loc, V, Type); 158 write32<E>(Loc, (Instr & ~Mask) | ((V >> SHIFT) & Mask)); 159 } 160 161 template <endianness E> static void writeMipsHi16(uint8_t *Loc, uint64_t V) { 162 uint32_t Instr = read32<E>(Loc); 163 uint16_t Res = ((V + 0x8000) >> 16) & 0xffff; 164 write32<E>(Loc, (Instr & 0xffff0000) | Res); 165 } 166 167 template <endianness E> static void writeMipsHigher(uint8_t *Loc, uint64_t V) { 168 uint32_t Instr = read32<E>(Loc); 169 uint16_t Res = ((V + 0x80008000) >> 32) & 0xffff; 170 write32<E>(Loc, (Instr & 0xffff0000) | Res); 171 } 172 173 template <endianness E> static void writeMipsHighest(uint8_t *Loc, uint64_t V) { 174 uint32_t Instr = read32<E>(Loc); 175 uint16_t Res = ((V + 0x800080008000) >> 48) & 0xffff; 176 write32<E>(Loc, (Instr & 0xffff0000) | Res); 177 } 178 179 template <endianness E> static void writeMipsLo16(uint8_t *Loc, uint64_t V) { 180 uint32_t Instr = read32<E>(Loc); 181 write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff)); 182 } 183 184 template <class ELFT> static bool isMipsR6() { 185 const auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf); 186 uint32_t Arch = FirstObj.getObj().getHeader()->e_flags & EF_MIPS_ARCH; 187 return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6; 188 } 189 190 template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const { 191 const endianness E = ELFT::TargetEndianness; 192 if (Config->MipsN32Abi) { 193 write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0]) 194 write32<E>(Buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14) 195 write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0]) 196 write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14 197 } else { 198 write32<E>(Buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0]) 199 write32<E>(Buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28) 200 write32<E>(Buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0]) 201 write32<E>(Buf + 12, 0x031cc023); // subu $24, $24, $28 202 } 203 204 write32<E>(Buf + 16, 0x03e07825); // move $15, $31 205 write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2 206 write32<E>(Buf + 24, 0x0320f809); // jalr $25 207 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2 208 209 uint64_t GotPlt = InX::GotPlt->getVA(); 210 writeMipsHi16<E>(Buf, GotPlt); 211 writeMipsLo16<E>(Buf + 4, GotPlt); 212 writeMipsLo16<E>(Buf + 8, GotPlt); 213 } 214 215 template <class ELFT> 216 void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, 217 uint64_t PltEntryAddr, int32_t Index, 218 unsigned RelOff) const { 219 const endianness E = ELFT::TargetEndianness; 220 write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry) 221 write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15) 222 // jr $25 223 write32<E>(Buf + 8, isMipsR6<ELFT>() ? 0x03200009 : 0x03200008); 224 write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry) 225 writeMipsHi16<E>(Buf, GotPltEntryAddr); 226 writeMipsLo16<E>(Buf + 4, GotPltEntryAddr); 227 writeMipsLo16<E>(Buf + 12, GotPltEntryAddr); 228 } 229 230 template <class ELFT> 231 bool MIPS<ELFT>::needsThunk(RelExpr Expr, uint32_t Type, const InputFile *File, 232 const SymbolBody &S) const { 233 // Any MIPS PIC code function is invoked with its address in register $t9. 234 // So if we have a branch instruction from non-PIC code to the PIC one 235 // we cannot make the jump directly and need to create a small stubs 236 // to save the target function address. 237 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf 238 if (Type != R_MIPS_26) 239 return false; 240 auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File); 241 if (!F) 242 return false; 243 // If current file has PIC code, LA25 stub is not required. 244 if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC) 245 return false; 246 auto *D = dyn_cast<DefinedRegular>(&S); 247 // LA25 is required if target file has PIC code 248 // or target symbol is a PIC symbol. 249 return D && D->isMipsPIC<ELFT>(); 250 } 251 252 template <class ELFT> 253 int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const { 254 const endianness E = ELFT::TargetEndianness; 255 switch (Type) { 256 default: 257 return 0; 258 case R_MIPS_32: 259 case R_MIPS_GPREL32: 260 case R_MIPS_TLS_DTPREL32: 261 case R_MIPS_TLS_TPREL32: 262 return SignExtend64<32>(read32<E>(Buf)); 263 case R_MIPS_26: 264 // FIXME (simon): If the relocation target symbol is not a PLT entry 265 // we should use another expression for calculation: 266 // ((A << 2) | (P & 0xf0000000)) >> 2 267 return SignExtend64<28>((read32<E>(Buf) & 0x3ffffff) << 2); 268 case R_MIPS_GPREL16: 269 case R_MIPS_LO16: 270 case R_MIPS_PCLO16: 271 case R_MIPS_TLS_DTPREL_HI16: 272 case R_MIPS_TLS_DTPREL_LO16: 273 case R_MIPS_TLS_TPREL_HI16: 274 case R_MIPS_TLS_TPREL_LO16: 275 return SignExtend64<16>(read32<E>(Buf)); 276 case R_MIPS_PC16: 277 return getPcRelocAddend<E, 16, 2>(Buf); 278 case R_MIPS_PC19_S2: 279 return getPcRelocAddend<E, 19, 2>(Buf); 280 case R_MIPS_PC21_S2: 281 return getPcRelocAddend<E, 21, 2>(Buf); 282 case R_MIPS_PC26_S2: 283 return getPcRelocAddend<E, 26, 2>(Buf); 284 case R_MIPS_PC32: 285 return getPcRelocAddend<E, 32, 0>(Buf); 286 } 287 } 288 289 static std::pair<uint32_t, uint64_t> 290 calculateMipsRelChain(uint8_t *Loc, uint32_t Type, uint64_t Val) { 291 // MIPS N64 ABI packs multiple relocations into the single relocation 292 // record. In general, all up to three relocations can have arbitrary 293 // types. In fact, Clang and GCC uses only a few combinations. For now, 294 // we support two of them. That is allow to pass at least all LLVM 295 // test suite cases. 296 // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16 297 // <any relocation> / R_MIPS_64 / R_MIPS_NONE 298 // The first relocation is a 'real' relocation which is calculated 299 // using the corresponding symbol's value. The second and the third 300 // relocations used to modify result of the first one: extend it to 301 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation 302 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf 303 uint32_t Type2 = (Type >> 8) & 0xff; 304 uint32_t Type3 = (Type >> 16) & 0xff; 305 if (Type2 == R_MIPS_NONE && Type3 == R_MIPS_NONE) 306 return std::make_pair(Type, Val); 307 if (Type2 == R_MIPS_64 && Type3 == R_MIPS_NONE) 308 return std::make_pair(Type2, Val); 309 if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16)) 310 return std::make_pair(Type3, -Val); 311 error(getErrorLocation(Loc) + "unsupported relocations combination " + 312 Twine(Type)); 313 return std::make_pair(Type & 0xff, Val); 314 } 315 316 template <class ELFT> 317 void MIPS<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const { 318 const endianness E = ELFT::TargetEndianness; 319 // Thread pointer and DRP offsets from the start of TLS data area. 320 // https://www.linux-mips.org/wiki/NPTL 321 if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 || 322 Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64) 323 Val -= 0x8000; 324 else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 || 325 Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64) 326 Val -= 0x7000; 327 if (ELFT::Is64Bits || Config->MipsN32Abi) 328 std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val); 329 switch (Type) { 330 case R_MIPS_32: 331 case R_MIPS_GPREL32: 332 case R_MIPS_TLS_DTPREL32: 333 case R_MIPS_TLS_TPREL32: 334 write32<E>(Loc, Val); 335 break; 336 case R_MIPS_64: 337 case R_MIPS_TLS_DTPREL64: 338 case R_MIPS_TLS_TPREL64: 339 write64<E>(Loc, Val); 340 break; 341 case R_MIPS_26: 342 write32<E>(Loc, (read32<E>(Loc) & ~0x3ffffff) | ((Val >> 2) & 0x3ffffff)); 343 break; 344 case R_MIPS_GOT16: 345 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode 346 // is updated addend (not a GOT index). In that case write high 16 bits 347 // to store a correct addend value. 348 if (Config->Relocatable) 349 writeMipsHi16<E>(Loc, Val); 350 else { 351 checkInt<16>(Loc, Val, Type); 352 writeMipsLo16<E>(Loc, Val); 353 } 354 break; 355 case R_MIPS_GOT_DISP: 356 case R_MIPS_GOT_PAGE: 357 case R_MIPS_GPREL16: 358 case R_MIPS_TLS_GD: 359 case R_MIPS_TLS_LDM: 360 checkInt<16>(Loc, Val, Type); 361 LLVM_FALLTHROUGH; 362 case R_MIPS_CALL16: 363 case R_MIPS_CALL_LO16: 364 case R_MIPS_GOT_LO16: 365 case R_MIPS_GOT_OFST: 366 case R_MIPS_LO16: 367 case R_MIPS_PCLO16: 368 case R_MIPS_TLS_DTPREL_LO16: 369 case R_MIPS_TLS_GOTTPREL: 370 case R_MIPS_TLS_TPREL_LO16: 371 writeMipsLo16<E>(Loc, Val); 372 break; 373 case R_MIPS_CALL_HI16: 374 case R_MIPS_GOT_HI16: 375 case R_MIPS_HI16: 376 case R_MIPS_PCHI16: 377 case R_MIPS_TLS_DTPREL_HI16: 378 case R_MIPS_TLS_TPREL_HI16: 379 writeMipsHi16<E>(Loc, Val); 380 break; 381 case R_MIPS_HIGHER: 382 writeMipsHigher<E>(Loc, Val); 383 break; 384 case R_MIPS_HIGHEST: 385 writeMipsHighest<E>(Loc, Val); 386 break; 387 case R_MIPS_JALR: 388 // Ignore this optimization relocation for now 389 break; 390 case R_MIPS_PC16: 391 applyMipsPcReloc<E, 16, 2>(Loc, Type, Val); 392 break; 393 case R_MIPS_PC19_S2: 394 applyMipsPcReloc<E, 19, 2>(Loc, Type, Val); 395 break; 396 case R_MIPS_PC21_S2: 397 applyMipsPcReloc<E, 21, 2>(Loc, Type, Val); 398 break; 399 case R_MIPS_PC26_S2: 400 applyMipsPcReloc<E, 26, 2>(Loc, Type, Val); 401 break; 402 case R_MIPS_PC32: 403 applyMipsPcReloc<E, 32, 0>(Loc, Type, Val); 404 break; 405 default: 406 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); 407 } 408 } 409 410 template <class ELFT> 411 bool MIPS<ELFT>::usesOnlyLowPageBits(uint32_t Type) const { 412 return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST; 413 } 414 415 template <class ELFT> TargetInfo *elf::getMipsTargetInfo() { 416 static MIPS<ELFT> Target; 417 return &Target; 418 } 419 420 template TargetInfo *elf::getMipsTargetInfo<ELF32LE>(); 421 template TargetInfo *elf::getMipsTargetInfo<ELF32BE>(); 422 template TargetInfo *elf::getMipsTargetInfo<ELF64LE>(); 423 template TargetInfo *elf::getMipsTargetInfo<ELF64BE>(); 424