1 //===- bolt/Core/Relocation.cpp - Object file relocations -----------------===// 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 // This file implements the Relocation class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "bolt/Core/Relocation.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCStreamer.h" 17 #include "llvm/MC/MCSymbol.h" 18 #include "llvm/Object/ELF.h" 19 20 using namespace llvm; 21 using namespace bolt; 22 23 Triple::ArchType Relocation::Arch; 24 25 static bool isSupportedX86(uint64_t Type) { 26 switch (Type) { 27 default: 28 return false; 29 case ELF::R_X86_64_8: 30 case ELF::R_X86_64_16: 31 case ELF::R_X86_64_32: 32 case ELF::R_X86_64_32S: 33 case ELF::R_X86_64_64: 34 case ELF::R_X86_64_PC8: 35 case ELF::R_X86_64_PC32: 36 case ELF::R_X86_64_PC64: 37 case ELF::R_X86_64_PLT32: 38 case ELF::R_X86_64_GOTPCREL: 39 case ELF::R_X86_64_GOTTPOFF: 40 case ELF::R_X86_64_TPOFF32: 41 case ELF::R_X86_64_GOTPCRELX: 42 case ELF::R_X86_64_REX_GOTPCRELX: 43 return true; 44 } 45 } 46 47 static bool isSupportedAArch64(uint64_t Type) { 48 switch (Type) { 49 default: 50 return false; 51 case ELF::R_AARCH64_CALL26: 52 case ELF::R_AARCH64_JUMP26: 53 case ELF::R_AARCH64_TSTBR14: 54 case ELF::R_AARCH64_CONDBR19: 55 case ELF::R_AARCH64_ADR_PREL_LO21: 56 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 57 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 58 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 59 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 60 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 61 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 62 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 63 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 64 case ELF::R_AARCH64_ADR_GOT_PAGE: 65 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 66 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 67 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 68 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 69 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 70 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 71 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 72 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 73 case ELF::R_AARCH64_TLSDESC_CALL: 74 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 75 case ELF::R_AARCH64_PREL16: 76 case ELF::R_AARCH64_PREL32: 77 case ELF::R_AARCH64_PREL64: 78 case ELF::R_AARCH64_ABS16: 79 case ELF::R_AARCH64_ABS32: 80 case ELF::R_AARCH64_ABS64: 81 case ELF::R_AARCH64_MOVW_UABS_G0: 82 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 83 case ELF::R_AARCH64_MOVW_UABS_G1: 84 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 85 case ELF::R_AARCH64_MOVW_UABS_G2: 86 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 87 case ELF::R_AARCH64_MOVW_UABS_G3: 88 return true; 89 } 90 } 91 92 static size_t getSizeForTypeX86(uint64_t Type) { 93 switch (Type) { 94 default: 95 errs() << object::getELFRelocationTypeName(ELF::EM_X86_64, Type) << '\n'; 96 llvm_unreachable("unsupported relocation type"); 97 case ELF::R_X86_64_8: 98 case ELF::R_X86_64_PC8: 99 return 1; 100 case ELF::R_X86_64_16: 101 return 2; 102 case ELF::R_X86_64_PLT32: 103 case ELF::R_X86_64_PC32: 104 case ELF::R_X86_64_32S: 105 case ELF::R_X86_64_32: 106 case ELF::R_X86_64_GOTPCREL: 107 case ELF::R_X86_64_GOTTPOFF: 108 case ELF::R_X86_64_TPOFF32: 109 case ELF::R_X86_64_GOTPCRELX: 110 case ELF::R_X86_64_REX_GOTPCRELX: 111 return 4; 112 case ELF::R_X86_64_PC64: 113 case ELF::R_X86_64_64: 114 return 8; 115 } 116 } 117 118 static size_t getSizeForTypeAArch64(uint64_t Type) { 119 switch (Type) { 120 default: 121 errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n'; 122 llvm_unreachable("unsupported relocation type"); 123 case ELF::R_AARCH64_ABS16: 124 case ELF::R_AARCH64_PREL16: 125 return 2; 126 case ELF::R_AARCH64_CALL26: 127 case ELF::R_AARCH64_JUMP26: 128 case ELF::R_AARCH64_TSTBR14: 129 case ELF::R_AARCH64_CONDBR19: 130 case ELF::R_AARCH64_ADR_PREL_LO21: 131 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 132 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 133 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 134 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 135 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 136 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 137 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 138 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 139 case ELF::R_AARCH64_ADR_GOT_PAGE: 140 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 141 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 142 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 143 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 144 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 145 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 146 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 147 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 148 case ELF::R_AARCH64_TLSDESC_CALL: 149 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 150 case ELF::R_AARCH64_PREL32: 151 case ELF::R_AARCH64_MOVW_UABS_G0: 152 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 153 case ELF::R_AARCH64_MOVW_UABS_G1: 154 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 155 case ELF::R_AARCH64_MOVW_UABS_G2: 156 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 157 case ELF::R_AARCH64_MOVW_UABS_G3: 158 case ELF::R_AARCH64_ABS32: 159 return 4; 160 case ELF::R_AARCH64_ABS64: 161 case ELF::R_AARCH64_PREL64: 162 return 8; 163 } 164 } 165 166 static bool skipRelocationTypeX86(uint64_t Type) { 167 return Type == ELF::R_X86_64_NONE; 168 } 169 170 static bool skipRelocationTypeAArch64(uint64_t Type) { 171 return Type == ELF::R_AARCH64_NONE || Type == ELF::R_AARCH64_LD_PREL_LO19; 172 } 173 174 static bool skipRelocationProcessX86(uint64_t &Type, uint64_t Contents) { 175 return false; 176 } 177 178 static bool skipRelocationProcessAArch64(uint64_t &Type, uint64_t Contents) { 179 auto IsMov = [](uint64_t Contents) -> bool { 180 // The bits 28-23 are 0b100101 181 return (Contents & 0x1f800000) == 0x12800000; 182 }; 183 184 auto IsB = [](uint64_t Contents) -> bool { 185 // The bits 31-26 are 0b000101 186 return (Contents & 0xfc000000) == 0x14000000; 187 }; 188 189 auto IsAdr = [](uint64_t Contents) -> bool { 190 // The bits 31-24 are 0b0xx10000 191 return (Contents & 0x9f000000) == 0x10000000; 192 }; 193 194 auto IsAddImm = [](uint64_t Contents) -> bool { 195 // The bits 30-23 are 0b00100010 196 return (Contents & 0x7F800000) == 0x11000000; 197 }; 198 199 auto IsNop = [](uint64_t Contents) -> bool { return Contents == 0xd503201f; }; 200 201 // The linker might eliminate the instruction and replace it with NOP, ignore 202 if (IsNop(Contents)) 203 return true; 204 205 // The linker might relax ADRP+LDR instruction sequence for loading symbol 206 // address from GOT table to ADRP+ADD sequence that would point to the 207 // binary-local symbol. Change relocation type in order to process it right. 208 if (Type == ELF::R_AARCH64_LD64_GOT_LO12_NC && IsAddImm(Contents)) { 209 Type = ELF::R_AARCH64_ADD_ABS_LO12_NC; 210 return false; 211 } 212 213 // The linker might perform TLS relocations relaxations, such as 214 // changed TLS access model (e.g. changed global dynamic model 215 // to initial exec), thus changing the instructions. The static 216 // relocations might be invalid at this point and we might no 217 // need to proccess these relocations anymore. 218 // More information could be found by searching 219 // elfNN_aarch64_tls_relax in bfd 220 switch (Type) { 221 default: 222 break; 223 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 224 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 225 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 226 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: { 227 if (IsMov(Contents)) 228 return true; 229 } 230 } 231 232 // The linker might replace load/store instruction with jump and 233 // veneer due to errata 843419 234 // https://documentation-service.arm.com/static/5fa29fddb209f547eebd361d 235 // Thus load/store relocations for these instructions must be ignored 236 // NOTE: We only process GOT and TLS relocations this way since the 237 // addend used in load/store instructions won't change after bolt 238 // (it is important since the instruction in veneer won't have relocation) 239 switch (Type) { 240 default: 241 break; 242 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 243 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 244 case ELF::R_AARCH64_TLSDESC_LD64_LO12: { 245 if (IsB(Contents)) 246 return true; 247 } 248 } 249 250 // The linker might relax ADRP+ADD or ADRP+LDR sequences to the ADR+NOP 251 switch (Type) { 252 default: 253 break; 254 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 255 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 256 case ELF::R_AARCH64_ADR_GOT_PAGE: 257 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 258 if (IsAdr(Contents)) 259 return true; 260 } 261 262 return false; 263 } 264 265 static uint64_t adjustValueX86(uint64_t Type, uint64_t Value, uint64_t PC) { 266 switch (Type) { 267 default: 268 llvm_unreachable("not supported relocation"); 269 case ELF::R_X86_64_32: 270 break; 271 case ELF::R_X86_64_PC32: 272 Value -= PC; 273 break; 274 } 275 return Value; 276 } 277 278 static uint64_t adjustValueAArch64(uint64_t Type, uint64_t Value, uint64_t PC) { 279 switch (Type) { 280 default: 281 llvm_unreachable("not supported relocation"); 282 case ELF::R_AARCH64_ABS32: 283 break; 284 case ELF::R_AARCH64_PREL16: 285 case ELF::R_AARCH64_PREL32: 286 case ELF::R_AARCH64_PREL64: 287 Value -= PC; 288 break; 289 } 290 return Value; 291 } 292 293 static uint64_t extractValueX86(uint64_t Type, uint64_t Contents, uint64_t PC) { 294 if (Type == ELF::R_X86_64_32S) 295 return SignExtend64<32>(Contents); 296 if (Relocation::isPCRelative(Type)) 297 return SignExtend64(Contents, 8 * Relocation::getSizeForType(Type)); 298 return Contents; 299 } 300 301 static uint64_t extractValueAArch64(uint64_t Type, uint64_t Contents, 302 uint64_t PC) { 303 switch (Type) { 304 default: 305 errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n'; 306 llvm_unreachable("unsupported relocation type"); 307 case ELF::R_AARCH64_ABS16: 308 case ELF::R_AARCH64_ABS32: 309 case ELF::R_AARCH64_ABS64: 310 return Contents; 311 case ELF::R_AARCH64_PREL16: 312 return static_cast<int64_t>(PC) + SignExtend64<16>(Contents & 0xffff); 313 case ELF::R_AARCH64_PREL32: 314 return static_cast<int64_t>(PC) + SignExtend64<32>(Contents & 0xffffffff); 315 case ELF::R_AARCH64_PREL64: 316 return static_cast<int64_t>(PC) + Contents; 317 case ELF::R_AARCH64_TLSDESC_CALL: 318 case ELF::R_AARCH64_JUMP26: 319 case ELF::R_AARCH64_CALL26: 320 // Immediate goes in bits 25:0 of B and BL. 321 Contents &= ~0xfffffffffc000000ULL; 322 return static_cast<int64_t>(PC) + SignExtend64<28>(Contents << 2); 323 case ELF::R_AARCH64_TSTBR14: 324 // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ 325 Contents &= ~0xfffffffffff8001fULL; 326 return static_cast<int64_t>(PC) + SignExtend64<16>(Contents >> 3); 327 case ELF::R_AARCH64_CONDBR19: 328 // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ 329 Contents &= ~0xffffffffff00001fULL; 330 return static_cast<int64_t>(PC) + SignExtend64<21>(Contents >> 3); 331 case ELF::R_AARCH64_ADR_GOT_PAGE: 332 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 333 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 334 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 335 case ELF::R_AARCH64_ADR_PREL_LO21: 336 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 337 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: { 338 // Bits 32:12 of Symbol address goes in bits 30:29 + 23:5 of ADRP 339 // and ADR instructions 340 bool IsAdr = !!(((Contents >> 31) & 0x1) == 0); 341 Contents &= ~0xffffffff9f00001fUll; 342 uint64_t LowBits = (Contents >> 29) & 0x3; 343 uint64_t HighBits = (Contents >> 5) & 0x7ffff; 344 Contents = LowBits | (HighBits << 2); 345 if (IsAdr) 346 return static_cast<int64_t>(PC) + SignExtend64<21>(Contents); 347 348 // ADRP instruction 349 Contents = static_cast<int64_t>(PC) + SignExtend64<33>(Contents << 12); 350 Contents &= ~0xfffUll; 351 return Contents; 352 } 353 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 354 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 355 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 356 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: { 357 // Immediate goes in bits 21:10 of LD/ST instruction, taken 358 // from bits 11:3 of Symbol address 359 Contents &= ~0xffffffffffc003ffU; 360 return Contents >> (10 - 3); 361 } 362 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 363 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 364 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 365 case ELF::R_AARCH64_ADD_ABS_LO12_NC: { 366 // Immediate goes in bits 21:10 of ADD instruction 367 Contents &= ~0xffffffffffc003ffU; 368 return Contents >> (10 - 0); 369 } 370 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: { 371 // Immediate goes in bits 21:10 of ADD instruction, taken 372 // from bits 11:4 of Symbol address 373 Contents &= ~0xffffffffffc003ffU; 374 return Contents >> (10 - 4); 375 } 376 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: { 377 // Immediate goes in bits 21:10 of ADD instruction, taken 378 // from bits 11:2 of Symbol address 379 Contents &= ~0xffffffffffc003ffU; 380 return Contents >> (10 - 2); 381 } 382 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: { 383 // Immediate goes in bits 21:10 of ADD instruction, taken 384 // from bits 11:1 of Symbol address 385 Contents &= ~0xffffffffffc003ffU; 386 return Contents >> (10 - 1); 387 } 388 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: { 389 // Immediate goes in bits 21:10 of ADD instruction, taken 390 // from bits 11:0 of Symbol address 391 Contents &= ~0xffffffffffc003ffU; 392 return Contents >> (10 - 0); 393 } 394 case ELF::R_AARCH64_MOVW_UABS_G3: 395 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 396 case ELF::R_AARCH64_MOVW_UABS_G2: 397 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 398 case ELF::R_AARCH64_MOVW_UABS_G1: 399 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 400 case ELF::R_AARCH64_MOVW_UABS_G0: 401 // The shift goest in bits 22:21 of MOV* instructions 402 uint8_t Shift = (Contents >> 21) & 0x3; 403 // Immediate goes in bits 20:5 404 Contents = (Contents >> 5) & 0xffff; 405 return Contents << (16 * Shift); 406 } 407 } 408 409 static bool isGOTX86(uint64_t Type) { 410 switch (Type) { 411 default: 412 return false; 413 case ELF::R_X86_64_GOT32: 414 case ELF::R_X86_64_GOTPCREL: 415 case ELF::R_X86_64_GOTTPOFF: 416 case ELF::R_X86_64_GOTOFF64: 417 case ELF::R_X86_64_GOTPC32: 418 case ELF::R_X86_64_GOT64: 419 case ELF::R_X86_64_GOTPCREL64: 420 case ELF::R_X86_64_GOTPC64: 421 case ELF::R_X86_64_GOTPLT64: 422 case ELF::R_X86_64_GOTPC32_TLSDESC: 423 case ELF::R_X86_64_GOTPCRELX: 424 case ELF::R_X86_64_REX_GOTPCRELX: 425 return true; 426 } 427 } 428 429 static bool isGOTAArch64(uint64_t Type) { 430 switch (Type) { 431 default: 432 return false; 433 case ELF::R_AARCH64_ADR_GOT_PAGE: 434 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 435 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 436 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 437 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 438 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 439 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 440 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 441 case ELF::R_AARCH64_TLSDESC_CALL: 442 return true; 443 } 444 } 445 446 static bool isTLSX86(uint64_t Type) { 447 switch (Type) { 448 default: 449 return false; 450 case ELF::R_X86_64_TPOFF32: 451 case ELF::R_X86_64_TPOFF64: 452 case ELF::R_X86_64_GOTTPOFF: 453 return true; 454 } 455 } 456 457 static bool isTLSAArch64(uint64_t Type) { 458 switch (Type) { 459 default: 460 return false; 461 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 462 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 463 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 464 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 465 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 466 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 467 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 468 case ELF::R_AARCH64_TLSDESC_CALL: 469 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 470 return true; 471 } 472 } 473 474 static bool isPCRelativeX86(uint64_t Type) { 475 switch (Type) { 476 default: 477 llvm_unreachable("Unknown relocation type"); 478 case ELF::R_X86_64_64: 479 case ELF::R_X86_64_32: 480 case ELF::R_X86_64_32S: 481 case ELF::R_X86_64_16: 482 case ELF::R_X86_64_8: 483 case ELF::R_X86_64_TPOFF32: 484 return false; 485 case ELF::R_X86_64_PC8: 486 case ELF::R_X86_64_PC32: 487 case ELF::R_X86_64_PC64: 488 case ELF::R_X86_64_GOTPCREL: 489 case ELF::R_X86_64_PLT32: 490 case ELF::R_X86_64_GOTOFF64: 491 case ELF::R_X86_64_GOTPC32: 492 case ELF::R_X86_64_GOTTPOFF: 493 case ELF::R_X86_64_GOTPCRELX: 494 case ELF::R_X86_64_REX_GOTPCRELX: 495 return true; 496 } 497 } 498 499 static bool isPCRelativeAArch64(uint64_t Type) { 500 switch (Type) { 501 default: 502 llvm_unreachable("Unknown relocation type"); 503 case ELF::R_AARCH64_ABS16: 504 case ELF::R_AARCH64_ABS32: 505 case ELF::R_AARCH64_ABS64: 506 case ELF::R_AARCH64_LDST64_ABS_LO12_NC: 507 case ELF::R_AARCH64_ADD_ABS_LO12_NC: 508 case ELF::R_AARCH64_LDST128_ABS_LO12_NC: 509 case ELF::R_AARCH64_LDST32_ABS_LO12_NC: 510 case ELF::R_AARCH64_LDST16_ABS_LO12_NC: 511 case ELF::R_AARCH64_LDST8_ABS_LO12_NC: 512 case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC: 513 case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12: 514 case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC: 515 case ELF::R_AARCH64_LD64_GOT_LO12_NC: 516 case ELF::R_AARCH64_TLSDESC_LD64_LO12: 517 case ELF::R_AARCH64_TLSDESC_ADD_LO12: 518 case ELF::R_AARCH64_MOVW_UABS_G0: 519 case ELF::R_AARCH64_MOVW_UABS_G0_NC: 520 case ELF::R_AARCH64_MOVW_UABS_G1: 521 case ELF::R_AARCH64_MOVW_UABS_G1_NC: 522 case ELF::R_AARCH64_MOVW_UABS_G2: 523 case ELF::R_AARCH64_MOVW_UABS_G2_NC: 524 case ELF::R_AARCH64_MOVW_UABS_G3: 525 return false; 526 case ELF::R_AARCH64_TLSDESC_CALL: 527 case ELF::R_AARCH64_CALL26: 528 case ELF::R_AARCH64_JUMP26: 529 case ELF::R_AARCH64_TSTBR14: 530 case ELF::R_AARCH64_CONDBR19: 531 case ELF::R_AARCH64_ADR_PREL_LO21: 532 case ELF::R_AARCH64_ADR_PREL_PG_HI21: 533 case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: 534 case ELF::R_AARCH64_ADR_GOT_PAGE: 535 case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21: 536 case ELF::R_AARCH64_TLSDESC_ADR_PREL21: 537 case ELF::R_AARCH64_TLSDESC_ADR_PAGE21: 538 case ELF::R_AARCH64_PREL16: 539 case ELF::R_AARCH64_PREL32: 540 case ELF::R_AARCH64_PREL64: 541 return true; 542 } 543 } 544 545 bool Relocation::isSupported(uint64_t Type) { 546 if (Arch == Triple::aarch64) 547 return isSupportedAArch64(Type); 548 return isSupportedX86(Type); 549 } 550 551 size_t Relocation::getSizeForType(uint64_t Type) { 552 if (Arch == Triple::aarch64) 553 return getSizeForTypeAArch64(Type); 554 return getSizeForTypeX86(Type); 555 } 556 557 bool Relocation::skipRelocationType(uint64_t Type) { 558 if (Arch == Triple::aarch64) 559 return skipRelocationTypeAArch64(Type); 560 return skipRelocationTypeX86(Type); 561 } 562 563 bool Relocation::skipRelocationProcess(uint64_t &Type, uint64_t Contents) { 564 if (Arch == Triple::aarch64) 565 return skipRelocationProcessAArch64(Type, Contents); 566 return skipRelocationProcessX86(Type, Contents); 567 } 568 569 uint64_t Relocation::adjustValue(uint64_t Type, uint64_t Value, 570 uint64_t PC) { 571 if (Arch == Triple::aarch64) 572 return adjustValueAArch64(Type, Value, PC); 573 return adjustValueX86(Type, Value, PC); 574 } 575 576 uint64_t Relocation::extractValue(uint64_t Type, uint64_t Contents, 577 uint64_t PC) { 578 if (Arch == Triple::aarch64) 579 return extractValueAArch64(Type, Contents, PC); 580 return extractValueX86(Type, Contents, PC); 581 } 582 583 bool Relocation::isGOT(uint64_t Type) { 584 if (Arch == Triple::aarch64) 585 return isGOTAArch64(Type); 586 return isGOTX86(Type); 587 } 588 589 bool Relocation::isX86GOTPCRELX(uint64_t Type) { 590 if (Arch != Triple::x86_64) 591 return false; 592 return Type == ELF::R_X86_64_GOTPCRELX || Type == ELF::R_X86_64_REX_GOTPCRELX; 593 } 594 595 bool Relocation::isNone(uint64_t Type) { return Type == getNone(); } 596 597 bool Relocation::isRelative(uint64_t Type) { 598 if (Arch == Triple::aarch64) 599 return Type == ELF::R_AARCH64_RELATIVE; 600 return Type == ELF::R_X86_64_RELATIVE; 601 } 602 603 bool Relocation::isIRelative(uint64_t Type) { 604 if (Arch == Triple::aarch64) 605 return Type == ELF::R_AARCH64_IRELATIVE; 606 return Type == ELF::R_X86_64_IRELATIVE; 607 } 608 609 bool Relocation::isTLS(uint64_t Type) { 610 if (Arch == Triple::aarch64) 611 return isTLSAArch64(Type); 612 return isTLSX86(Type); 613 } 614 615 uint64_t Relocation::getNone() { 616 if (Arch == Triple::aarch64) 617 return ELF::R_AARCH64_NONE; 618 return ELF::R_X86_64_NONE; 619 } 620 621 uint64_t Relocation::getPC32() { 622 if (Arch == Triple::aarch64) 623 return ELF::R_AARCH64_PREL32; 624 return ELF::R_X86_64_PC32; 625 } 626 627 uint64_t Relocation::getPC64() { 628 if (Arch == Triple::aarch64) 629 return ELF::R_AARCH64_PREL64; 630 return ELF::R_X86_64_PC64; 631 } 632 633 bool Relocation::isPCRelative(uint64_t Type) { 634 if (Arch == Triple::aarch64) 635 return isPCRelativeAArch64(Type); 636 return isPCRelativeX86(Type); 637 } 638 639 uint64_t Relocation::getAbs64() { 640 if (Arch == Triple::aarch64) 641 return ELF::R_AARCH64_ABS64; 642 return ELF::R_X86_64_64; 643 } 644 645 size_t Relocation::emit(MCStreamer *Streamer) const { 646 const size_t Size = getSizeForType(Type); 647 MCContext &Ctx = Streamer->getContext(); 648 if (isPCRelative(Type)) { 649 MCSymbol *TempLabel = Ctx.createNamedTempSymbol(); 650 Streamer->emitLabel(TempLabel); 651 const MCExpr *Value = nullptr; 652 if (Symbol) { 653 Value = MCSymbolRefExpr::create(Symbol, Ctx); 654 if (Addend) { 655 Value = MCBinaryExpr::createAdd( 656 Value, MCConstantExpr::create(Addend, Ctx), Ctx); 657 } 658 } else { 659 Value = MCConstantExpr::create(Addend, Ctx); 660 } 661 Value = MCBinaryExpr::createSub( 662 Value, MCSymbolRefExpr::create(TempLabel, Ctx), Ctx); 663 Streamer->emitValue(Value, Size); 664 665 return Size; 666 } 667 668 if (Symbol && Addend) { 669 auto Value = 670 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, Ctx), 671 MCConstantExpr::create(Addend, Ctx), Ctx); 672 Streamer->emitValue(Value, Size); 673 } else if (Symbol) { 674 Streamer->emitSymbolValue(Symbol, Size); 675 } else { 676 Streamer->emitIntValue(Addend, Size); 677 } 678 679 return Size; 680 } 681 682 #define ELF_RELOC(name, value) #name, 683 684 void Relocation::print(raw_ostream &OS) const { 685 static const char *X86RelocNames[] = { 686 #include "llvm/BinaryFormat/ELFRelocs/x86_64.def" 687 }; 688 static const char *AArch64RelocNames[] = { 689 #include "llvm/BinaryFormat/ELFRelocs/AArch64.def" 690 }; 691 if (Arch == Triple::aarch64) 692 OS << AArch64RelocNames[Type]; 693 else 694 OS << X86RelocNames[Type]; 695 OS << ", 0x" << Twine::utohexstr(Offset); 696 if (Symbol) { 697 OS << ", " << Symbol->getName(); 698 } 699 if (int64_t(Addend) < 0) 700 OS << ", -0x" << Twine::utohexstr(-int64_t(Addend)); 701 else 702 OS << ", 0x" << Twine::utohexstr(Addend); 703 OS << ", 0x" << Twine::utohexstr(Value); 704 } 705