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