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