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