1 //===- ARM.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 "Symbols.h" 13 #include "SyntheticSections.h" 14 #include "Target.h" 15 #include "Thunks.h" 16 #include "llvm/Object/ELF.h" 17 #include "llvm/Support/Endian.h" 18 19 using namespace llvm; 20 using namespace llvm::support::endian; 21 using namespace llvm::ELF; 22 using namespace lld; 23 using namespace lld::elf; 24 25 namespace { 26 class ARM final : public TargetInfo { 27 public: 28 ARM(); 29 RelExpr getRelExpr(RelType Type, const SymbolBody &S, 30 const uint8_t *Loc) const override; 31 bool isPicRel(RelType Type) const override; 32 RelType getDynRel(RelType Type) const override; 33 int64_t getImplicitAddend(const uint8_t *Buf, RelType Type) const override; 34 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override; 35 void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override; 36 void writePltHeader(uint8_t *Buf) const override; 37 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr, 38 int32_t Index, unsigned RelOff) const override; 39 void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override; 40 void addPltHeaderSymbols(InputSectionBase *ISD) const override; 41 bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File, 42 const SymbolBody &S) const override; 43 bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override; 44 void relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const override; 45 }; 46 } // namespace 47 48 ARM::ARM() { 49 CopyRel = R_ARM_COPY; 50 RelativeRel = R_ARM_RELATIVE; 51 IRelativeRel = R_ARM_IRELATIVE; 52 GotRel = R_ARM_GLOB_DAT; 53 PltRel = R_ARM_JUMP_SLOT; 54 TlsGotRel = R_ARM_TLS_TPOFF32; 55 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32; 56 TlsOffsetRel = R_ARM_TLS_DTPOFF32; 57 GotEntrySize = 4; 58 GotPltEntrySize = 4; 59 PltEntrySize = 16; 60 PltHeaderSize = 20; 61 TrapInstr = 0xd4d4d4d4; 62 // ARM uses Variant 1 TLS 63 TcbSize = 8; 64 NeedsThunks = true; 65 } 66 67 RelExpr ARM::getRelExpr(RelType Type, const SymbolBody &S, 68 const uint8_t *Loc) const { 69 switch (Type) { 70 case R_ARM_THM_JUMP11: 71 return R_PC; 72 case R_ARM_CALL: 73 case R_ARM_JUMP24: 74 case R_ARM_PC24: 75 case R_ARM_PLT32: 76 case R_ARM_PREL31: 77 case R_ARM_THM_JUMP19: 78 case R_ARM_THM_JUMP24: 79 case R_ARM_THM_CALL: 80 return R_PLT_PC; 81 case R_ARM_GOTOFF32: 82 // (S + A) - GOT_ORG 83 return R_GOTREL; 84 case R_ARM_GOT_BREL: 85 // GOT(S) + A - GOT_ORG 86 return R_GOT_OFF; 87 case R_ARM_GOT_PREL: 88 case R_ARM_TLS_IE32: 89 // GOT(S) + A - P 90 return R_GOT_PC; 91 case R_ARM_SBREL32: 92 return R_ARM_SBREL; 93 case R_ARM_TARGET1: 94 return Config->Target1Rel ? R_PC : R_ABS; 95 case R_ARM_TARGET2: 96 if (Config->Target2 == Target2Policy::Rel) 97 return R_PC; 98 if (Config->Target2 == Target2Policy::Abs) 99 return R_ABS; 100 return R_GOT_PC; 101 case R_ARM_TLS_GD32: 102 return R_TLSGD_PC; 103 case R_ARM_TLS_LDM32: 104 return R_TLSLD_PC; 105 case R_ARM_BASE_PREL: 106 // B(S) + A - P 107 // FIXME: currently B(S) assumed to be .got, this may not hold for all 108 // platforms. 109 return R_GOTONLY_PC; 110 case R_ARM_MOVW_PREL_NC: 111 case R_ARM_MOVT_PREL: 112 case R_ARM_REL32: 113 case R_ARM_THM_MOVW_PREL_NC: 114 case R_ARM_THM_MOVT_PREL: 115 return R_PC; 116 case R_ARM_NONE: 117 return R_NONE; 118 case R_ARM_TLS_LE32: 119 return R_TLS; 120 default: 121 return R_ABS; 122 } 123 } 124 125 bool ARM::isPicRel(RelType Type) const { 126 return (Type == R_ARM_TARGET1 && !Config->Target1Rel) || 127 (Type == R_ARM_ABS32); 128 } 129 130 RelType ARM::getDynRel(RelType Type) const { 131 if (Type == R_ARM_TARGET1 && !Config->Target1Rel) 132 return R_ARM_ABS32; 133 if (Type == R_ARM_ABS32) 134 return Type; 135 // Keep it going with a dummy value so that we can find more reloc errors. 136 return R_ARM_ABS32; 137 } 138 139 void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const { 140 write32le(Buf, InX::Plt->getVA()); 141 } 142 143 void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const { 144 // An ARM entry is the address of the ifunc resolver function. 145 write32le(Buf, S.getVA()); 146 } 147 148 void ARM::writePltHeader(uint8_t *Buf) const { 149 const uint8_t PltData[] = { 150 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]! 151 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2 152 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr 153 0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8] 154 0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8 155 }; 156 memcpy(Buf, PltData, sizeof(PltData)); 157 uint64_t GotPlt = InX::GotPlt->getVA(); 158 uint64_t L1 = InX::Plt->getVA() + 8; 159 write32le(Buf + 16, GotPlt - L1 - 8); 160 } 161 162 void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const { 163 auto *IS = cast<InputSection>(ISD); 164 addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS); 165 addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS); 166 } 167 168 void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, 169 uint64_t PltEntryAddr, int32_t Index, 170 unsigned RelOff) const { 171 // FIXME: Using simple code sequence with simple relocations. 172 // There is a more optimal sequence but it requires support for the group 173 // relocations. See ELF for the ARM Architecture Appendix A.3 174 const uint8_t PltData[] = { 175 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2 176 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc 177 0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip] 178 0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8 179 }; 180 memcpy(Buf, PltData, sizeof(PltData)); 181 uint64_t L1 = PltEntryAddr + 4; 182 write32le(Buf + 12, GotPltEntryAddr - L1 - 8); 183 } 184 185 void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const { 186 auto *IS = cast<InputSection>(ISD); 187 addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS); 188 addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS); 189 } 190 191 bool ARM::needsThunk(RelExpr Expr, RelType Type, const InputFile *File, 192 const SymbolBody &S) const { 193 // If S is an undefined weak symbol in an executable we don't need a Thunk. 194 // In a DSO calls to undefined symbols, including weak ones get PLT entries 195 // which may need a thunk. 196 if (S.isUndefWeak() && !Config->Shared) 197 return false; 198 // A state change from ARM to Thumb and vice versa must go through an 199 // interworking thunk if the relocation type is not R_ARM_CALL or 200 // R_ARM_THM_CALL. 201 switch (Type) { 202 case R_ARM_PC24: 203 case R_ARM_PLT32: 204 case R_ARM_JUMP24: 205 // Source is ARM, all PLT entries are ARM so no interworking required. 206 // Otherwise we need to interwork if Symbol has bit 0 set (Thumb). 207 if (Expr == R_PC && ((S.getVA() & 1) == 1)) 208 return true; 209 break; 210 case R_ARM_THM_JUMP19: 211 case R_ARM_THM_JUMP24: 212 // Source is Thumb, all PLT entries are ARM so interworking is required. 213 // Otherwise we need to interwork if Symbol has bit 0 clear (ARM). 214 if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0)) 215 return true; 216 break; 217 } 218 return false; 219 } 220 221 bool ARM::inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const { 222 uint64_t Range; 223 uint64_t InstrSize; 224 225 switch (Type) { 226 case R_ARM_PC24: 227 case R_ARM_PLT32: 228 case R_ARM_JUMP24: 229 case R_ARM_CALL: 230 Range = 0x2000000; 231 InstrSize = 4; 232 break; 233 case R_ARM_THM_JUMP19: 234 Range = 0x100000; 235 InstrSize = 2; 236 break; 237 case R_ARM_THM_JUMP24: 238 case R_ARM_THM_CALL: 239 Range = 0x1000000; 240 InstrSize = 2; 241 break; 242 default: 243 return true; 244 } 245 // PC at Src is 2 instructions ahead, immediate of branch is signed 246 if (Src > Dst) 247 Range -= 2 * InstrSize; 248 else 249 Range += InstrSize; 250 251 if ((Dst & 0x1) == 0) 252 // Destination is ARM, if ARM caller then Src is already 4-byte aligned. 253 // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure 254 // destination will be 4 byte aligned. 255 Src &= ~0x3; 256 else 257 // Bit 0 == 1 denotes Thumb state, it is not part of the range 258 Dst &= ~0x1; 259 260 uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src; 261 return Distance <= Range; 262 } 263 264 void ARM::relocateOne(uint8_t *Loc, RelType Type, uint64_t Val) const { 265 switch (Type) { 266 case R_ARM_ABS32: 267 case R_ARM_BASE_PREL: 268 case R_ARM_GLOB_DAT: 269 case R_ARM_GOTOFF32: 270 case R_ARM_GOT_BREL: 271 case R_ARM_GOT_PREL: 272 case R_ARM_REL32: 273 case R_ARM_RELATIVE: 274 case R_ARM_SBREL32: 275 case R_ARM_TARGET1: 276 case R_ARM_TARGET2: 277 case R_ARM_TLS_GD32: 278 case R_ARM_TLS_IE32: 279 case R_ARM_TLS_LDM32: 280 case R_ARM_TLS_LDO32: 281 case R_ARM_TLS_LE32: 282 case R_ARM_TLS_TPOFF32: 283 case R_ARM_TLS_DTPOFF32: 284 write32le(Loc, Val); 285 break; 286 case R_ARM_TLS_DTPMOD32: 287 write32le(Loc, 1); 288 break; 289 case R_ARM_PREL31: 290 checkInt<31>(Loc, Val, Type); 291 write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000)); 292 break; 293 case R_ARM_CALL: 294 // R_ARM_CALL is used for BL and BLX instructions, depending on the 295 // value of bit 0 of Val, we must select a BL or BLX instruction 296 if (Val & 1) { 297 // If bit 0 of Val is 1 the target is Thumb, we must select a BLX. 298 // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1' 299 checkInt<26>(Loc, Val, Type); 300 write32le(Loc, 0xfa000000 | // opcode 301 ((Val & 2) << 23) | // H 302 ((Val >> 2) & 0x00ffffff)); // imm24 303 break; 304 } 305 if ((read32le(Loc) & 0xfe000000) == 0xfa000000) 306 // BLX (always unconditional) instruction to an ARM Target, select an 307 // unconditional BL. 308 write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff)); 309 // fall through as BL encoding is shared with B 310 LLVM_FALLTHROUGH; 311 case R_ARM_JUMP24: 312 case R_ARM_PC24: 313 case R_ARM_PLT32: 314 checkInt<26>(Loc, Val, Type); 315 write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff)); 316 break; 317 case R_ARM_THM_JUMP11: 318 checkInt<12>(Loc, Val, Type); 319 write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff)); 320 break; 321 case R_ARM_THM_JUMP19: 322 // Encoding T3: Val = S:J2:J1:imm6:imm11:0 323 checkInt<21>(Loc, Val, Type); 324 write16le(Loc, 325 (read16le(Loc) & 0xfbc0) | // opcode cond 326 ((Val >> 10) & 0x0400) | // S 327 ((Val >> 12) & 0x003f)); // imm6 328 write16le(Loc + 2, 329 0x8000 | // opcode 330 ((Val >> 8) & 0x0800) | // J2 331 ((Val >> 5) & 0x2000) | // J1 332 ((Val >> 1) & 0x07ff)); // imm11 333 break; 334 case R_ARM_THM_CALL: 335 // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the 336 // value of bit 0 of Val, we must select a BL or BLX instruction 337 if ((Val & 1) == 0) { 338 // Ensure BLX destination is 4-byte aligned. As BLX instruction may 339 // only be two byte aligned. This must be done before overflow check 340 Val = alignTo(Val, 4); 341 } 342 // Bit 12 is 0 for BLX, 1 for BL 343 write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12); 344 // Fall through as rest of encoding is the same as B.W 345 LLVM_FALLTHROUGH; 346 case R_ARM_THM_JUMP24: 347 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0 348 // FIXME: Use of I1 and I2 require v6T2ops 349 checkInt<25>(Loc, Val, Type); 350 write16le(Loc, 351 0xf000 | // opcode 352 ((Val >> 14) & 0x0400) | // S 353 ((Val >> 12) & 0x03ff)); // imm10 354 write16le(Loc + 2, 355 (read16le(Loc + 2) & 0xd000) | // opcode 356 (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1 357 (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2 358 ((Val >> 1) & 0x07ff)); // imm11 359 break; 360 case R_ARM_MOVW_ABS_NC: 361 case R_ARM_MOVW_PREL_NC: 362 write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) | 363 (Val & 0x0fff)); 364 break; 365 case R_ARM_MOVT_ABS: 366 case R_ARM_MOVT_PREL: 367 checkInt<32>(Loc, Val, Type); 368 write32le(Loc, (read32le(Loc) & ~0x000f0fff) | 369 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff)); 370 break; 371 case R_ARM_THM_MOVT_ABS: 372 case R_ARM_THM_MOVT_PREL: 373 // Encoding T1: A = imm4:i:imm3:imm8 374 checkInt<32>(Loc, Val, Type); 375 write16le(Loc, 376 0xf2c0 | // opcode 377 ((Val >> 17) & 0x0400) | // i 378 ((Val >> 28) & 0x000f)); // imm4 379 write16le(Loc + 2, 380 (read16le(Loc + 2) & 0x8f00) | // opcode 381 ((Val >> 12) & 0x7000) | // imm3 382 ((Val >> 16) & 0x00ff)); // imm8 383 break; 384 case R_ARM_THM_MOVW_ABS_NC: 385 case R_ARM_THM_MOVW_PREL_NC: 386 // Encoding T3: A = imm4:i:imm3:imm8 387 write16le(Loc, 388 0xf240 | // opcode 389 ((Val >> 1) & 0x0400) | // i 390 ((Val >> 12) & 0x000f)); // imm4 391 write16le(Loc + 2, 392 (read16le(Loc + 2) & 0x8f00) | // opcode 393 ((Val << 4) & 0x7000) | // imm3 394 (Val & 0x00ff)); // imm8 395 break; 396 default: 397 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type)); 398 } 399 } 400 401 int64_t ARM::getImplicitAddend(const uint8_t *Buf, RelType Type) const { 402 switch (Type) { 403 default: 404 return 0; 405 case R_ARM_ABS32: 406 case R_ARM_BASE_PREL: 407 case R_ARM_GOTOFF32: 408 case R_ARM_GOT_BREL: 409 case R_ARM_GOT_PREL: 410 case R_ARM_REL32: 411 case R_ARM_TARGET1: 412 case R_ARM_TARGET2: 413 case R_ARM_TLS_GD32: 414 case R_ARM_TLS_LDM32: 415 case R_ARM_TLS_LDO32: 416 case R_ARM_TLS_IE32: 417 case R_ARM_TLS_LE32: 418 return SignExtend64<32>(read32le(Buf)); 419 case R_ARM_PREL31: 420 return SignExtend64<31>(read32le(Buf)); 421 case R_ARM_CALL: 422 case R_ARM_JUMP24: 423 case R_ARM_PC24: 424 case R_ARM_PLT32: 425 return SignExtend64<26>(read32le(Buf) << 2); 426 case R_ARM_THM_JUMP11: 427 return SignExtend64<12>(read16le(Buf) << 1); 428 case R_ARM_THM_JUMP19: { 429 // Encoding T3: A = S:J2:J1:imm10:imm6:0 430 uint16_t Hi = read16le(Buf); 431 uint16_t Lo = read16le(Buf + 2); 432 return SignExtend64<20>(((Hi & 0x0400) << 10) | // S 433 ((Lo & 0x0800) << 8) | // J2 434 ((Lo & 0x2000) << 5) | // J1 435 ((Hi & 0x003f) << 12) | // imm6 436 ((Lo & 0x07ff) << 1)); // imm11:0 437 } 438 case R_ARM_THM_CALL: 439 case R_ARM_THM_JUMP24: { 440 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0 441 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S) 442 // FIXME: I1 and I2 require v6T2ops 443 uint16_t Hi = read16le(Buf); 444 uint16_t Lo = read16le(Buf + 2); 445 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S 446 (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1 447 (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2 448 ((Hi & 0x003ff) << 12) | // imm0 449 ((Lo & 0x007ff) << 1)); // imm11:0 450 } 451 // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and 452 // MOVT is in the range -32768 <= A < 32768 453 case R_ARM_MOVW_ABS_NC: 454 case R_ARM_MOVT_ABS: 455 case R_ARM_MOVW_PREL_NC: 456 case R_ARM_MOVT_PREL: { 457 uint64_t Val = read32le(Buf) & 0x000f0fff; 458 return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff)); 459 } 460 case R_ARM_THM_MOVW_ABS_NC: 461 case R_ARM_THM_MOVT_ABS: 462 case R_ARM_THM_MOVW_PREL_NC: 463 case R_ARM_THM_MOVT_PREL: { 464 // Encoding T3: A = imm4:i:imm3:imm8 465 uint16_t Hi = read16le(Buf); 466 uint16_t Lo = read16le(Buf + 2); 467 return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4 468 ((Hi & 0x0400) << 1) | // i 469 ((Lo & 0x7000) >> 4) | // imm3 470 (Lo & 0x00ff)); // imm8 471 } 472 } 473 } 474 475 TargetInfo *elf::getARMTargetInfo() { 476 static ARM Target; 477 return &Target; 478 } 479