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