1 //===- AArch64.cpp --------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Symbols.h" 10 #include "SyntheticSections.h" 11 #include "Target.h" 12 #include "lld/Common/ErrorHandler.h" 13 #include "llvm/BinaryFormat/ELF.h" 14 #include "llvm/Support/Endian.h" 15 16 using namespace llvm; 17 using namespace llvm::support::endian; 18 using namespace llvm::ELF; 19 using namespace lld; 20 using namespace lld::elf; 21 22 // Page(Expr) is the page address of the expression Expr, defined 23 // as (Expr & ~0xFFF). (This applies even if the machine page size 24 // supported by the platform has a different value.) 25 uint64_t elf::getAArch64Page(uint64_t expr) { 26 return expr & ~static_cast<uint64_t>(0xFFF); 27 } 28 29 namespace { 30 class AArch64 : public TargetInfo { 31 public: 32 AArch64(); 33 RelExpr getRelExpr(RelType type, const Symbol &s, 34 const uint8_t *loc) const override; 35 RelType getDynRel(RelType type) const override; 36 int64_t getImplicitAddend(const uint8_t *buf, RelType type) const override; 37 void writeGotPlt(uint8_t *buf, const Symbol &s) const override; 38 void writePltHeader(uint8_t *buf) const override; 39 void writePlt(uint8_t *buf, const Symbol &sym, 40 uint64_t pltEntryAddr) const override; 41 bool needsThunk(RelExpr expr, RelType type, const InputFile *file, 42 uint64_t branchAddr, const Symbol &s, 43 int64_t a) const override; 44 uint32_t getThunkSectionSpacing() const override; 45 bool inBranchRange(RelType type, uint64_t src, uint64_t dst) const override; 46 bool usesOnlyLowPageBits(RelType type) const override; 47 void relocate(uint8_t *loc, const Relocation &rel, 48 uint64_t val) const override; 49 RelExpr adjustTlsExpr(RelType type, RelExpr expr) const override; 50 void relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, 51 uint64_t val) const override; 52 void relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, 53 uint64_t val) const override; 54 void relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, 55 uint64_t val) const override; 56 }; 57 } // namespace 58 59 AArch64::AArch64() { 60 copyRel = R_AARCH64_COPY; 61 relativeRel = R_AARCH64_RELATIVE; 62 iRelativeRel = R_AARCH64_IRELATIVE; 63 gotRel = R_AARCH64_GLOB_DAT; 64 pltRel = R_AARCH64_JUMP_SLOT; 65 symbolicRel = R_AARCH64_ABS64; 66 tlsDescRel = R_AARCH64_TLSDESC; 67 tlsGotRel = R_AARCH64_TLS_TPREL64; 68 pltHeaderSize = 32; 69 pltEntrySize = 16; 70 ipltEntrySize = 16; 71 defaultMaxPageSize = 65536; 72 73 // Align to the 2 MiB page size (known as a superpage or huge page). 74 // FreeBSD automatically promotes 2 MiB-aligned allocations. 75 defaultImageBase = 0x200000; 76 77 needsThunks = true; 78 } 79 80 RelExpr AArch64::getRelExpr(RelType type, const Symbol &s, 81 const uint8_t *loc) const { 82 switch (type) { 83 case R_AARCH64_ABS16: 84 case R_AARCH64_ABS32: 85 case R_AARCH64_ABS64: 86 case R_AARCH64_ADD_ABS_LO12_NC: 87 case R_AARCH64_LDST128_ABS_LO12_NC: 88 case R_AARCH64_LDST16_ABS_LO12_NC: 89 case R_AARCH64_LDST32_ABS_LO12_NC: 90 case R_AARCH64_LDST64_ABS_LO12_NC: 91 case R_AARCH64_LDST8_ABS_LO12_NC: 92 case R_AARCH64_MOVW_SABS_G0: 93 case R_AARCH64_MOVW_SABS_G1: 94 case R_AARCH64_MOVW_SABS_G2: 95 case R_AARCH64_MOVW_UABS_G0: 96 case R_AARCH64_MOVW_UABS_G0_NC: 97 case R_AARCH64_MOVW_UABS_G1: 98 case R_AARCH64_MOVW_UABS_G1_NC: 99 case R_AARCH64_MOVW_UABS_G2: 100 case R_AARCH64_MOVW_UABS_G2_NC: 101 case R_AARCH64_MOVW_UABS_G3: 102 return R_ABS; 103 case R_AARCH64_TLSDESC_ADR_PAGE21: 104 return R_AARCH64_TLSDESC_PAGE; 105 case R_AARCH64_TLSDESC_LD64_LO12: 106 case R_AARCH64_TLSDESC_ADD_LO12: 107 return R_TLSDESC; 108 case R_AARCH64_TLSDESC_CALL: 109 return R_TLSDESC_CALL; 110 case R_AARCH64_TLSLE_ADD_TPREL_HI12: 111 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 112 case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 113 case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 114 case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 115 case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 116 case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: 117 case R_AARCH64_TLSLE_MOVW_TPREL_G0: 118 case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: 119 case R_AARCH64_TLSLE_MOVW_TPREL_G1: 120 case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: 121 case R_AARCH64_TLSLE_MOVW_TPREL_G2: 122 return R_TPREL; 123 case R_AARCH64_CALL26: 124 case R_AARCH64_CONDBR19: 125 case R_AARCH64_JUMP26: 126 case R_AARCH64_TSTBR14: 127 case R_AARCH64_PLT32: 128 return R_PLT_PC; 129 case R_AARCH64_PREL16: 130 case R_AARCH64_PREL32: 131 case R_AARCH64_PREL64: 132 case R_AARCH64_ADR_PREL_LO21: 133 case R_AARCH64_LD_PREL_LO19: 134 case R_AARCH64_MOVW_PREL_G0: 135 case R_AARCH64_MOVW_PREL_G0_NC: 136 case R_AARCH64_MOVW_PREL_G1: 137 case R_AARCH64_MOVW_PREL_G1_NC: 138 case R_AARCH64_MOVW_PREL_G2: 139 case R_AARCH64_MOVW_PREL_G2_NC: 140 case R_AARCH64_MOVW_PREL_G3: 141 return R_PC; 142 case R_AARCH64_ADR_PREL_PG_HI21: 143 case R_AARCH64_ADR_PREL_PG_HI21_NC: 144 return R_AARCH64_PAGE_PC; 145 case R_AARCH64_LD64_GOT_LO12_NC: 146 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 147 return R_GOT; 148 case R_AARCH64_LD64_GOTPAGE_LO15: 149 return R_AARCH64_GOT_PAGE; 150 case R_AARCH64_ADR_GOT_PAGE: 151 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 152 return R_AARCH64_GOT_PAGE_PC; 153 case R_AARCH64_NONE: 154 return R_NONE; 155 default: 156 error(getErrorLocation(loc) + "unknown relocation (" + Twine(type) + 157 ") against symbol " + toString(s)); 158 return R_NONE; 159 } 160 } 161 162 RelExpr AArch64::adjustTlsExpr(RelType type, RelExpr expr) const { 163 if (expr == R_RELAX_TLS_GD_TO_IE) { 164 if (type == R_AARCH64_TLSDESC_ADR_PAGE21) 165 return R_AARCH64_RELAX_TLS_GD_TO_IE_PAGE_PC; 166 return R_RELAX_TLS_GD_TO_IE_ABS; 167 } 168 return expr; 169 } 170 171 bool AArch64::usesOnlyLowPageBits(RelType type) const { 172 switch (type) { 173 default: 174 return false; 175 case R_AARCH64_ADD_ABS_LO12_NC: 176 case R_AARCH64_LD64_GOT_LO12_NC: 177 case R_AARCH64_LDST128_ABS_LO12_NC: 178 case R_AARCH64_LDST16_ABS_LO12_NC: 179 case R_AARCH64_LDST32_ABS_LO12_NC: 180 case R_AARCH64_LDST64_ABS_LO12_NC: 181 case R_AARCH64_LDST8_ABS_LO12_NC: 182 case R_AARCH64_TLSDESC_ADD_LO12: 183 case R_AARCH64_TLSDESC_LD64_LO12: 184 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 185 return true; 186 } 187 } 188 189 RelType AArch64::getDynRel(RelType type) const { 190 if (type == R_AARCH64_ABS64) 191 return type; 192 return R_AARCH64_NONE; 193 } 194 195 int64_t AArch64::getImplicitAddend(const uint8_t *buf, RelType type) const { 196 switch (type) { 197 case R_AARCH64_TLSDESC: 198 return read64(buf + 8); 199 case R_AARCH64_NONE: 200 return 0; 201 case R_AARCH64_PREL32: 202 return SignExtend64<32>(read32(buf)); 203 case R_AARCH64_ABS64: 204 case R_AARCH64_PREL64: 205 return read64(buf); 206 default: 207 internalLinkerError(getErrorLocation(buf), 208 "cannot read addend for relocation " + toString(type)); 209 return 0; 210 } 211 } 212 213 void AArch64::writeGotPlt(uint8_t *buf, const Symbol &) const { 214 write64(buf, in.plt->getVA()); 215 } 216 217 void AArch64::writePltHeader(uint8_t *buf) const { 218 const uint8_t pltData[] = { 219 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]! 220 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2])) 221 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))] 222 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[2])) 223 0x20, 0x02, 0x1f, 0xd6, // br x17 224 0x1f, 0x20, 0x03, 0xd5, // nop 225 0x1f, 0x20, 0x03, 0xd5, // nop 226 0x1f, 0x20, 0x03, 0xd5 // nop 227 }; 228 memcpy(buf, pltData, sizeof(pltData)); 229 230 uint64_t got = in.gotPlt->getVA(); 231 uint64_t plt = in.plt->getVA(); 232 relocateNoSym(buf + 4, R_AARCH64_ADR_PREL_PG_HI21, 233 getAArch64Page(got + 16) - getAArch64Page(plt + 4)); 234 relocateNoSym(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16); 235 relocateNoSym(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16); 236 } 237 238 void AArch64::writePlt(uint8_t *buf, const Symbol &sym, 239 uint64_t pltEntryAddr) const { 240 const uint8_t inst[] = { 241 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n])) 242 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))] 243 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[n])) 244 0x20, 0x02, 0x1f, 0xd6 // br x17 245 }; 246 memcpy(buf, inst, sizeof(inst)); 247 248 uint64_t gotPltEntryAddr = sym.getGotPltVA(); 249 relocateNoSym(buf, R_AARCH64_ADR_PREL_PG_HI21, 250 getAArch64Page(gotPltEntryAddr) - getAArch64Page(pltEntryAddr)); 251 relocateNoSym(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr); 252 relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr); 253 } 254 255 bool AArch64::needsThunk(RelExpr expr, RelType type, const InputFile *file, 256 uint64_t branchAddr, const Symbol &s, 257 int64_t a) const { 258 // If s is an undefined weak symbol and does not have a PLT entry then it 259 // will be resolved as a branch to the next instruction. 260 if (s.isUndefWeak() && !s.isInPlt()) 261 return false; 262 // ELF for the ARM 64-bit architecture, section Call and Jump relocations 263 // only permits range extension thunks for R_AARCH64_CALL26 and 264 // R_AARCH64_JUMP26 relocation types. 265 if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26 && 266 type != R_AARCH64_PLT32) 267 return false; 268 uint64_t dst = expr == R_PLT_PC ? s.getPltVA() : s.getVA(a); 269 return !inBranchRange(type, branchAddr, dst); 270 } 271 272 uint32_t AArch64::getThunkSectionSpacing() const { 273 // See comment in Arch/ARM.cpp for a more detailed explanation of 274 // getThunkSectionSpacing(). For AArch64 the only branches we are permitted to 275 // Thunk have a range of +/- 128 MiB 276 return (128 * 1024 * 1024) - 0x30000; 277 } 278 279 bool AArch64::inBranchRange(RelType type, uint64_t src, uint64_t dst) const { 280 if (type != R_AARCH64_CALL26 && type != R_AARCH64_JUMP26 && 281 type != R_AARCH64_PLT32) 282 return true; 283 // The AArch64 call and unconditional branch instructions have a range of 284 // +/- 128 MiB. The PLT32 relocation supports a range up to +/- 2 GiB. 285 uint64_t range = 286 type == R_AARCH64_PLT32 ? (UINT64_C(1) << 31) : (128 * 1024 * 1024); 287 if (dst > src) { 288 // Immediate of branch is signed. 289 range -= 4; 290 return dst - src <= range; 291 } 292 return src - dst <= range; 293 } 294 295 static void write32AArch64Addr(uint8_t *l, uint64_t imm) { 296 uint32_t immLo = (imm & 0x3) << 29; 297 uint32_t immHi = (imm & 0x1FFFFC) << 3; 298 uint64_t mask = (0x3 << 29) | (0x1FFFFC << 3); 299 write32le(l, (read32le(l) & ~mask) | immLo | immHi); 300 } 301 302 // Return the bits [Start, End] from Val shifted Start bits. 303 // For instance, getBits(0xF0, 4, 8) returns 0xF. 304 static uint64_t getBits(uint64_t val, int start, int end) { 305 uint64_t mask = ((uint64_t)1 << (end + 1 - start)) - 1; 306 return (val >> start) & mask; 307 } 308 309 static void or32le(uint8_t *p, int32_t v) { write32le(p, read32le(p) | v); } 310 311 // Update the immediate field in a AARCH64 ldr, str, and add instruction. 312 static void or32AArch64Imm(uint8_t *l, uint64_t imm) { 313 or32le(l, (imm & 0xFFF) << 10); 314 } 315 316 // Update the immediate field in an AArch64 movk, movn or movz instruction 317 // for a signed relocation, and update the opcode of a movn or movz instruction 318 // to match the sign of the operand. 319 static void writeSMovWImm(uint8_t *loc, uint32_t imm) { 320 uint32_t inst = read32le(loc); 321 // Opcode field is bits 30, 29, with 10 = movz, 00 = movn and 11 = movk. 322 if (!(inst & (1 << 29))) { 323 // movn or movz. 324 if (imm & 0x10000) { 325 // Change opcode to movn, which takes an inverted operand. 326 imm ^= 0xFFFF; 327 inst &= ~(1 << 30); 328 } else { 329 // Change opcode to movz. 330 inst |= 1 << 30; 331 } 332 } 333 write32le(loc, inst | ((imm & 0xFFFF) << 5)); 334 } 335 336 void AArch64::relocate(uint8_t *loc, const Relocation &rel, 337 uint64_t val) const { 338 switch (rel.type) { 339 case R_AARCH64_ABS16: 340 case R_AARCH64_PREL16: 341 checkIntUInt(loc, val, 16, rel); 342 write16(loc, val); 343 break; 344 case R_AARCH64_ABS32: 345 case R_AARCH64_PREL32: 346 checkIntUInt(loc, val, 32, rel); 347 write32(loc, val); 348 break; 349 case R_AARCH64_PLT32: 350 checkInt(loc, val, 32, rel); 351 write32(loc, val); 352 break; 353 case R_AARCH64_ABS64: 354 case R_AARCH64_PREL64: 355 write64(loc, val); 356 break; 357 case R_AARCH64_ADD_ABS_LO12_NC: 358 or32AArch64Imm(loc, val); 359 break; 360 case R_AARCH64_ADR_GOT_PAGE: 361 case R_AARCH64_ADR_PREL_PG_HI21: 362 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 363 case R_AARCH64_TLSDESC_ADR_PAGE21: 364 checkInt(loc, val, 33, rel); 365 LLVM_FALLTHROUGH; 366 case R_AARCH64_ADR_PREL_PG_HI21_NC: 367 write32AArch64Addr(loc, val >> 12); 368 break; 369 case R_AARCH64_ADR_PREL_LO21: 370 checkInt(loc, val, 21, rel); 371 write32AArch64Addr(loc, val); 372 break; 373 case R_AARCH64_JUMP26: 374 // Normally we would just write the bits of the immediate field, however 375 // when patching instructions for the cpu errata fix -fix-cortex-a53-843419 376 // we want to replace a non-branch instruction with a branch immediate 377 // instruction. By writing all the bits of the instruction including the 378 // opcode and the immediate (0 001 | 01 imm26) we can do this 379 // transformation by placing a R_AARCH64_JUMP26 relocation at the offset of 380 // the instruction we want to patch. 381 write32le(loc, 0x14000000); 382 LLVM_FALLTHROUGH; 383 case R_AARCH64_CALL26: 384 checkInt(loc, val, 28, rel); 385 or32le(loc, (val & 0x0FFFFFFC) >> 2); 386 break; 387 case R_AARCH64_CONDBR19: 388 case R_AARCH64_LD_PREL_LO19: 389 checkAlignment(loc, val, 4, rel); 390 checkInt(loc, val, 21, rel); 391 or32le(loc, (val & 0x1FFFFC) << 3); 392 break; 393 case R_AARCH64_LDST8_ABS_LO12_NC: 394 case R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC: 395 or32AArch64Imm(loc, getBits(val, 0, 11)); 396 break; 397 case R_AARCH64_LDST16_ABS_LO12_NC: 398 case R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC: 399 checkAlignment(loc, val, 2, rel); 400 or32AArch64Imm(loc, getBits(val, 1, 11)); 401 break; 402 case R_AARCH64_LDST32_ABS_LO12_NC: 403 case R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC: 404 checkAlignment(loc, val, 4, rel); 405 or32AArch64Imm(loc, getBits(val, 2, 11)); 406 break; 407 case R_AARCH64_LDST64_ABS_LO12_NC: 408 case R_AARCH64_LD64_GOT_LO12_NC: 409 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 410 case R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC: 411 case R_AARCH64_TLSDESC_LD64_LO12: 412 checkAlignment(loc, val, 8, rel); 413 or32AArch64Imm(loc, getBits(val, 3, 11)); 414 break; 415 case R_AARCH64_LDST128_ABS_LO12_NC: 416 case R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC: 417 checkAlignment(loc, val, 16, rel); 418 or32AArch64Imm(loc, getBits(val, 4, 11)); 419 break; 420 case R_AARCH64_LD64_GOTPAGE_LO15: 421 checkAlignment(loc, val, 8, rel); 422 or32AArch64Imm(loc, getBits(val, 3, 14)); 423 break; 424 case R_AARCH64_MOVW_UABS_G0: 425 checkUInt(loc, val, 16, rel); 426 LLVM_FALLTHROUGH; 427 case R_AARCH64_MOVW_UABS_G0_NC: 428 or32le(loc, (val & 0xFFFF) << 5); 429 break; 430 case R_AARCH64_MOVW_UABS_G1: 431 checkUInt(loc, val, 32, rel); 432 LLVM_FALLTHROUGH; 433 case R_AARCH64_MOVW_UABS_G1_NC: 434 or32le(loc, (val & 0xFFFF0000) >> 11); 435 break; 436 case R_AARCH64_MOVW_UABS_G2: 437 checkUInt(loc, val, 48, rel); 438 LLVM_FALLTHROUGH; 439 case R_AARCH64_MOVW_UABS_G2_NC: 440 or32le(loc, (val & 0xFFFF00000000) >> 27); 441 break; 442 case R_AARCH64_MOVW_UABS_G3: 443 or32le(loc, (val & 0xFFFF000000000000) >> 43); 444 break; 445 case R_AARCH64_MOVW_PREL_G0: 446 case R_AARCH64_MOVW_SABS_G0: 447 case R_AARCH64_TLSLE_MOVW_TPREL_G0: 448 checkInt(loc, val, 17, rel); 449 LLVM_FALLTHROUGH; 450 case R_AARCH64_MOVW_PREL_G0_NC: 451 case R_AARCH64_TLSLE_MOVW_TPREL_G0_NC: 452 writeSMovWImm(loc, val); 453 break; 454 case R_AARCH64_MOVW_PREL_G1: 455 case R_AARCH64_MOVW_SABS_G1: 456 case R_AARCH64_TLSLE_MOVW_TPREL_G1: 457 checkInt(loc, val, 33, rel); 458 LLVM_FALLTHROUGH; 459 case R_AARCH64_MOVW_PREL_G1_NC: 460 case R_AARCH64_TLSLE_MOVW_TPREL_G1_NC: 461 writeSMovWImm(loc, val >> 16); 462 break; 463 case R_AARCH64_MOVW_PREL_G2: 464 case R_AARCH64_MOVW_SABS_G2: 465 case R_AARCH64_TLSLE_MOVW_TPREL_G2: 466 checkInt(loc, val, 49, rel); 467 LLVM_FALLTHROUGH; 468 case R_AARCH64_MOVW_PREL_G2_NC: 469 writeSMovWImm(loc, val >> 32); 470 break; 471 case R_AARCH64_MOVW_PREL_G3: 472 writeSMovWImm(loc, val >> 48); 473 break; 474 case R_AARCH64_TSTBR14: 475 checkInt(loc, val, 16, rel); 476 or32le(loc, (val & 0xFFFC) << 3); 477 break; 478 case R_AARCH64_TLSLE_ADD_TPREL_HI12: 479 checkUInt(loc, val, 24, rel); 480 or32AArch64Imm(loc, val >> 12); 481 break; 482 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 483 case R_AARCH64_TLSDESC_ADD_LO12: 484 or32AArch64Imm(loc, val); 485 break; 486 case R_AARCH64_TLSDESC: 487 // For R_AARCH64_TLSDESC the addend is stored in the second 64-bit word. 488 write64(loc + 8, val); 489 break; 490 default: 491 llvm_unreachable("unknown relocation"); 492 } 493 } 494 495 void AArch64::relaxTlsGdToLe(uint8_t *loc, const Relocation &rel, 496 uint64_t val) const { 497 // TLSDESC Global-Dynamic relocation are in the form: 498 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21] 499 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12] 500 // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12] 501 // .tlsdesccall [R_AARCH64_TLSDESC_CALL] 502 // blr x1 503 // And it can optimized to: 504 // movz x0, #0x0, lsl #16 505 // movk x0, #0x10 506 // nop 507 // nop 508 checkUInt(loc, val, 32, rel); 509 510 switch (rel.type) { 511 case R_AARCH64_TLSDESC_ADD_LO12: 512 case R_AARCH64_TLSDESC_CALL: 513 write32le(loc, 0xd503201f); // nop 514 return; 515 case R_AARCH64_TLSDESC_ADR_PAGE21: 516 write32le(loc, 0xd2a00000 | (((val >> 16) & 0xffff) << 5)); // movz 517 return; 518 case R_AARCH64_TLSDESC_LD64_LO12: 519 write32le(loc, 0xf2800000 | ((val & 0xffff) << 5)); // movk 520 return; 521 default: 522 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation"); 523 } 524 } 525 526 void AArch64::relaxTlsGdToIe(uint8_t *loc, const Relocation &rel, 527 uint64_t val) const { 528 // TLSDESC Global-Dynamic relocation are in the form: 529 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21] 530 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12] 531 // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12] 532 // .tlsdesccall [R_AARCH64_TLSDESC_CALL] 533 // blr x1 534 // And it can optimized to: 535 // adrp x0, :gottprel:v 536 // ldr x0, [x0, :gottprel_lo12:v] 537 // nop 538 // nop 539 540 switch (rel.type) { 541 case R_AARCH64_TLSDESC_ADD_LO12: 542 case R_AARCH64_TLSDESC_CALL: 543 write32le(loc, 0xd503201f); // nop 544 break; 545 case R_AARCH64_TLSDESC_ADR_PAGE21: 546 write32le(loc, 0x90000000); // adrp 547 relocateNoSym(loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, val); 548 break; 549 case R_AARCH64_TLSDESC_LD64_LO12: 550 write32le(loc, 0xf9400000); // ldr 551 relocateNoSym(loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, val); 552 break; 553 default: 554 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation"); 555 } 556 } 557 558 void AArch64::relaxTlsIeToLe(uint8_t *loc, const Relocation &rel, 559 uint64_t val) const { 560 checkUInt(loc, val, 32, rel); 561 562 if (rel.type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) { 563 // Generate MOVZ. 564 uint32_t regNo = read32le(loc) & 0x1f; 565 write32le(loc, (0xd2a00000 | regNo) | (((val >> 16) & 0xffff) << 5)); 566 return; 567 } 568 if (rel.type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) { 569 // Generate MOVK. 570 uint32_t regNo = read32le(loc) & 0x1f; 571 write32le(loc, (0xf2800000 | regNo) | ((val & 0xffff) << 5)); 572 return; 573 } 574 llvm_unreachable("invalid relocation for TLS IE to LE relaxation"); 575 } 576 577 AArch64Relaxer::AArch64Relaxer(ArrayRef<Relocation> relocs) { 578 if (!config->relax || config->emachine != EM_AARCH64) { 579 safeToRelaxAdrpLdr = false; 580 return; 581 } 582 // Check if R_AARCH64_ADR_GOT_PAGE and R_AARCH64_LD64_GOT_LO12_NC 583 // always appear in pairs. 584 size_t i = 0; 585 const size_t size = relocs.size(); 586 for (; i != size; ++i) { 587 if (relocs[i].type == R_AARCH64_ADR_GOT_PAGE) { 588 if (i + 1 < size && relocs[i + 1].type == R_AARCH64_LD64_GOT_LO12_NC) { 589 ++i; 590 continue; 591 } 592 break; 593 } else if (relocs[i].type == R_AARCH64_LD64_GOT_LO12_NC) { 594 break; 595 } 596 } 597 safeToRelaxAdrpLdr = i == size; 598 } 599 600 bool AArch64Relaxer::tryRelaxAdrpAdd(const Relocation &adrpRel, 601 const Relocation &addRel, uint64_t secAddr, 602 uint8_t *buf) const { 603 // When the address of sym is within the range of ADR then 604 // we may relax 605 // ADRP xn, sym 606 // ADD xn, xn, :lo12: sym 607 // to 608 // NOP 609 // ADR xn, sym 610 if (!config->relax || adrpRel.type != R_AARCH64_ADR_PREL_PG_HI21 || 611 addRel.type != R_AARCH64_ADD_ABS_LO12_NC) 612 return false; 613 // Check if the relocations apply to consecutive instructions. 614 if (adrpRel.offset + 4 != addRel.offset) 615 return false; 616 if (adrpRel.sym != addRel.sym) 617 return false; 618 if (adrpRel.addend != 0 || addRel.addend != 0) 619 return false; 620 621 uint32_t adrpInstr = read32le(buf + adrpRel.offset); 622 uint32_t addInstr = read32le(buf + addRel.offset); 623 // Check if the first instruction is ADRP and the second instruction is ADD. 624 if ((adrpInstr & 0x9f000000) != 0x90000000 || 625 (addInstr & 0xffc00000) != 0x91000000) 626 return false; 627 uint32_t adrpDestReg = adrpInstr & 0x1f; 628 uint32_t addDestReg = addInstr & 0x1f; 629 uint32_t addSrcReg = (addInstr >> 5) & 0x1f; 630 if (adrpDestReg != addDestReg || adrpDestReg != addSrcReg) 631 return false; 632 633 Symbol &sym = *adrpRel.sym; 634 // Check if the address difference is within 1MiB range. 635 int64_t val = sym.getVA() - (secAddr + addRel.offset); 636 if (val < -1024 * 1024 || val >= 1024 * 1024) 637 return false; 638 639 Relocation adrRel = {R_ABS, R_AARCH64_ADR_PREL_LO21, addRel.offset, 640 /*addend=*/0, &sym}; 641 // nop 642 write32le(buf + adrpRel.offset, 0xd503201f); 643 // adr x_<dest_reg> 644 write32le(buf + adrRel.offset, 0x10000000 | adrpDestReg); 645 target->relocate(buf + adrRel.offset, adrRel, val); 646 return true; 647 } 648 649 bool AArch64Relaxer::tryRelaxAdrpLdr(const Relocation &adrpRel, 650 const Relocation &ldrRel, uint64_t secAddr, 651 uint8_t *buf) const { 652 if (!safeToRelaxAdrpLdr) 653 return false; 654 655 // When the definition of sym is not preemptible then we may 656 // be able to relax 657 // ADRP xn, :got: sym 658 // LDR xn, [ xn :got_lo12: sym] 659 // to 660 // ADRP xn, sym 661 // ADD xn, xn, :lo_12: sym 662 663 if (adrpRel.type != R_AARCH64_ADR_GOT_PAGE || 664 ldrRel.type != R_AARCH64_LD64_GOT_LO12_NC) 665 return false; 666 // Check if the relocations apply to consecutive instructions. 667 if (adrpRel.offset + 4 != ldrRel.offset) 668 return false; 669 // Check if the relocations reference the same symbol and 670 // skip undefined, preemptible and STT_GNU_IFUNC symbols. 671 if (!adrpRel.sym || adrpRel.sym != ldrRel.sym || !adrpRel.sym->isDefined() || 672 adrpRel.sym->isPreemptible || adrpRel.sym->isGnuIFunc()) 673 return false; 674 // Check if the addends of the both relocations are zero. 675 if (adrpRel.addend != 0 || ldrRel.addend != 0) 676 return false; 677 uint32_t adrpInstr = read32le(buf + adrpRel.offset); 678 uint32_t ldrInstr = read32le(buf + ldrRel.offset); 679 // Check if the first instruction is ADRP and the second instruction is LDR. 680 if ((adrpInstr & 0x9f000000) != 0x90000000 || 681 (ldrInstr & 0x3b000000) != 0x39000000) 682 return false; 683 // Check the value of the sf bit. 684 if (!(ldrInstr >> 31)) 685 return false; 686 uint32_t adrpDestReg = adrpInstr & 0x1f; 687 uint32_t ldrDestReg = ldrInstr & 0x1f; 688 uint32_t ldrSrcReg = (ldrInstr >> 5) & 0x1f; 689 // Check if ADPR and LDR use the same register. 690 if (adrpDestReg != ldrDestReg || adrpDestReg != ldrSrcReg) 691 return false; 692 693 Symbol &sym = *adrpRel.sym; 694 // Check if the address difference is within 4GB range. 695 int64_t val = 696 getAArch64Page(sym.getVA()) - getAArch64Page(secAddr + adrpRel.offset); 697 if (val != llvm::SignExtend64(val, 33)) 698 return false; 699 700 Relocation adrpSymRel = {R_AARCH64_PAGE_PC, R_AARCH64_ADR_PREL_PG_HI21, 701 adrpRel.offset, /*addend=*/0, &sym}; 702 Relocation addRel = {R_ABS, R_AARCH64_ADD_ABS_LO12_NC, ldrRel.offset, 703 /*addend=*/0, &sym}; 704 705 // adrp x_<dest_reg> 706 write32le(buf + adrpSymRel.offset, 0x90000000 | adrpDestReg); 707 // add x_<dest reg>, x_<dest reg> 708 write32le(buf + addRel.offset, 0x91000000 | adrpDestReg | (adrpDestReg << 5)); 709 710 target->relocate(buf + adrpSymRel.offset, adrpSymRel, 711 SignExtend64(getAArch64Page(sym.getVA()) - 712 getAArch64Page(secAddr + adrpSymRel.offset), 713 64)); 714 target->relocate(buf + addRel.offset, addRel, SignExtend64(sym.getVA(), 64)); 715 tryRelaxAdrpAdd(adrpSymRel, addRel, secAddr, buf); 716 return true; 717 } 718 719 // AArch64 may use security features in variant PLT sequences. These are: 720 // Pointer Authentication (PAC), introduced in armv8.3-a and Branch Target 721 // Indicator (BTI) introduced in armv8.5-a. The additional instructions used 722 // in the variant Plt sequences are encoded in the Hint space so they can be 723 // deployed on older architectures, which treat the instructions as a nop. 724 // PAC and BTI can be combined leading to the following combinations: 725 // writePltHeader 726 // writePltHeaderBti (no PAC Header needed) 727 // writePlt 728 // writePltBti (BTI only) 729 // writePltPac (PAC only) 730 // writePltBtiPac (BTI and PAC) 731 // 732 // When PAC is enabled the dynamic loader encrypts the address that it places 733 // in the .got.plt using the pacia1716 instruction which encrypts the value in 734 // x17 using the modifier in x16. The static linker places autia1716 before the 735 // indirect branch to x17 to authenticate the address in x17 with the modifier 736 // in x16. This makes it more difficult for an attacker to modify the value in 737 // the .got.plt. 738 // 739 // When BTI is enabled all indirect branches must land on a bti instruction. 740 // The static linker must place a bti instruction at the start of any PLT entry 741 // that may be the target of an indirect branch. As the PLT entries call the 742 // lazy resolver indirectly this must have a bti instruction at start. In 743 // general a bti instruction is not needed for a PLT entry as indirect calls 744 // are resolved to the function address and not the PLT entry for the function. 745 // There are a small number of cases where the PLT address can escape, such as 746 // taking the address of a function or ifunc via a non got-generating 747 // relocation, and a shared library refers to that symbol. 748 // 749 // We use the bti c variant of the instruction which permits indirect branches 750 // (br) via x16/x17 and indirect function calls (blr) via any register. The ABI 751 // guarantees that all indirect branches from code requiring BTI protection 752 // will go via x16/x17 753 754 namespace { 755 class AArch64BtiPac final : public AArch64 { 756 public: 757 AArch64BtiPac(); 758 void writePltHeader(uint8_t *buf) const override; 759 void writePlt(uint8_t *buf, const Symbol &sym, 760 uint64_t pltEntryAddr) const override; 761 762 private: 763 bool btiHeader; // bti instruction needed in PLT Header and Entry 764 bool pacEntry; // autia1716 instruction needed in PLT Entry 765 }; 766 } // namespace 767 768 AArch64BtiPac::AArch64BtiPac() { 769 btiHeader = (config->andFeatures & GNU_PROPERTY_AARCH64_FEATURE_1_BTI); 770 // A BTI (Branch Target Indicator) Plt Entry is only required if the 771 // address of the PLT entry can be taken by the program, which permits an 772 // indirect jump to the PLT entry. This can happen when the address 773 // of the PLT entry for a function is canonicalised due to the address of 774 // the function in an executable being taken by a shared library, or 775 // non-preemptible ifunc referenced by non-GOT-generating, non-PLT-generating 776 // relocations. 777 // The PAC PLT entries require dynamic loader support and this isn't known 778 // from properties in the objects, so we use the command line flag. 779 pacEntry = config->zPacPlt; 780 781 if (btiHeader || pacEntry) { 782 pltEntrySize = 24; 783 ipltEntrySize = 24; 784 } 785 } 786 787 void AArch64BtiPac::writePltHeader(uint8_t *buf) const { 788 const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c 789 const uint8_t pltData[] = { 790 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]! 791 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2])) 792 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))] 793 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[2])) 794 0x20, 0x02, 0x1f, 0xd6, // br x17 795 0x1f, 0x20, 0x03, 0xd5, // nop 796 0x1f, 0x20, 0x03, 0xd5 // nop 797 }; 798 const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop 799 800 uint64_t got = in.gotPlt->getVA(); 801 uint64_t plt = in.plt->getVA(); 802 803 if (btiHeader) { 804 // PltHeader is called indirectly by plt[N]. Prefix pltData with a BTI C 805 // instruction. 806 memcpy(buf, btiData, sizeof(btiData)); 807 buf += sizeof(btiData); 808 plt += sizeof(btiData); 809 } 810 memcpy(buf, pltData, sizeof(pltData)); 811 812 relocateNoSym(buf + 4, R_AARCH64_ADR_PREL_PG_HI21, 813 getAArch64Page(got + 16) - getAArch64Page(plt + 8)); 814 relocateNoSym(buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, got + 16); 815 relocateNoSym(buf + 12, R_AARCH64_ADD_ABS_LO12_NC, got + 16); 816 if (!btiHeader) 817 // We didn't add the BTI c instruction so round out size with NOP. 818 memcpy(buf + sizeof(pltData), nopData, sizeof(nopData)); 819 } 820 821 void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym, 822 uint64_t pltEntryAddr) const { 823 // The PLT entry is of the form: 824 // [btiData] addrInst (pacBr | stdBr) [nopData] 825 const uint8_t btiData[] = { 0x5f, 0x24, 0x03, 0xd5 }; // bti c 826 const uint8_t addrInst[] = { 827 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n])) 828 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))] 829 0x10, 0x02, 0x00, 0x91 // add x16, x16, Offset(&(.plt.got[n])) 830 }; 831 const uint8_t pacBr[] = { 832 0x9f, 0x21, 0x03, 0xd5, // autia1716 833 0x20, 0x02, 0x1f, 0xd6 // br x17 834 }; 835 const uint8_t stdBr[] = { 836 0x20, 0x02, 0x1f, 0xd6, // br x17 837 0x1f, 0x20, 0x03, 0xd5 // nop 838 }; 839 const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop 840 841 // needsCopy indicates a non-ifunc canonical PLT entry whose address may 842 // escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its 843 // address may escape if referenced by a direct relocation. The condition is 844 // conservative. 845 bool hasBti = btiHeader && (sym.needsCopy || sym.isInIplt); 846 if (hasBti) { 847 memcpy(buf, btiData, sizeof(btiData)); 848 buf += sizeof(btiData); 849 pltEntryAddr += sizeof(btiData); 850 } 851 852 uint64_t gotPltEntryAddr = sym.getGotPltVA(); 853 memcpy(buf, addrInst, sizeof(addrInst)); 854 relocateNoSym(buf, R_AARCH64_ADR_PREL_PG_HI21, 855 getAArch64Page(gotPltEntryAddr) - getAArch64Page(pltEntryAddr)); 856 relocateNoSym(buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, gotPltEntryAddr); 857 relocateNoSym(buf + 8, R_AARCH64_ADD_ABS_LO12_NC, gotPltEntryAddr); 858 859 if (pacEntry) 860 memcpy(buf + sizeof(addrInst), pacBr, sizeof(pacBr)); 861 else 862 memcpy(buf + sizeof(addrInst), stdBr, sizeof(stdBr)); 863 if (!hasBti) 864 // We didn't add the BTI c instruction so round out size with NOP. 865 memcpy(buf + sizeof(addrInst) + sizeof(stdBr), nopData, sizeof(nopData)); 866 } 867 868 static TargetInfo *getTargetInfo() { 869 if (config->andFeatures & (GNU_PROPERTY_AARCH64_FEATURE_1_BTI | 870 GNU_PROPERTY_AARCH64_FEATURE_1_PAC)) { 871 static AArch64BtiPac t; 872 return &t; 873 } 874 static AArch64 t; 875 return &t; 876 } 877 878 TargetInfo *elf::getAArch64TargetInfo() { return getTargetInfo(); } 879