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