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