brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.4 KiB · f872db2 Raw
1041 lines · cpp
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-exception6//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#include "llvm/Object/ObjectFile.h"20 21using namespace llvm;22using namespace bolt;23 24namespace ELFReserved {25enum {26  R_RISCV_TPREL_I = 49,27  R_RISCV_TPREL_S = 50,28};29} // namespace ELFReserved30 31Triple::ArchType Relocation::Arch;32 33static bool isSupportedX86(uint32_t Type) {34  switch (Type) {35  default:36    return false;37  case ELF::R_X86_64_8:38  case ELF::R_X86_64_16:39  case ELF::R_X86_64_32:40  case ELF::R_X86_64_32S:41  case ELF::R_X86_64_64:42  case ELF::R_X86_64_PC8:43  case ELF::R_X86_64_PC32:44  case ELF::R_X86_64_PC64:45  case ELF::R_X86_64_PLT32:46  case ELF::R_X86_64_GOTPC64:47  case ELF::R_X86_64_GOTPCREL:48  case ELF::R_X86_64_GOTTPOFF:49  case ELF::R_X86_64_TPOFF32:50  case ELF::R_X86_64_GOTPCRELX:51  case ELF::R_X86_64_REX_GOTPCRELX:52    return true;53  }54}55 56static bool isSupportedAArch64(uint32_t Type) {57  switch (Type) {58  default:59    return false;60  case ELF::R_AARCH64_CALL26:61  case ELF::R_AARCH64_JUMP26:62  case ELF::R_AARCH64_TSTBR14:63  case ELF::R_AARCH64_CONDBR19:64  case ELF::R_AARCH64_ADR_PREL_LO21:65  case ELF::R_AARCH64_ADR_PREL_PG_HI21:66  case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:67  case ELF::R_AARCH64_LDST64_ABS_LO12_NC:68  case ELF::R_AARCH64_ADD_ABS_LO12_NC:69  case ELF::R_AARCH64_LDST128_ABS_LO12_NC:70  case ELF::R_AARCH64_LDST32_ABS_LO12_NC:71  case ELF::R_AARCH64_LDST16_ABS_LO12_NC:72  case ELF::R_AARCH64_LDST8_ABS_LO12_NC:73  case ELF::R_AARCH64_ADR_GOT_PAGE:74  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:75  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:76  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:77  case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:78  case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:79  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:80  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:81  case ELF::R_AARCH64_LD64_GOT_LO12_NC:82  case ELF::R_AARCH64_TLSDESC_LD64_LO12:83  case ELF::R_AARCH64_TLSDESC_ADD_LO12:84  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:85  case ELF::R_AARCH64_PREL16:86  case ELF::R_AARCH64_PREL32:87  case ELF::R_AARCH64_PREL64:88  case ELF::R_AARCH64_ABS16:89  case ELF::R_AARCH64_ABS32:90  case ELF::R_AARCH64_ABS64:91  case ELF::R_AARCH64_MOVW_UABS_G0:92  case ELF::R_AARCH64_MOVW_UABS_G0_NC:93  case ELF::R_AARCH64_MOVW_UABS_G1:94  case ELF::R_AARCH64_MOVW_UABS_G1_NC:95  case ELF::R_AARCH64_MOVW_UABS_G2:96  case ELF::R_AARCH64_MOVW_UABS_G2_NC:97  case ELF::R_AARCH64_MOVW_UABS_G3:98  case ELF::R_AARCH64_PLT32:99    return true;100  }101}102 103static bool isSupportedRISCV(uint32_t Type) {104  switch (Type) {105  default:106    return false;107  case ELF::R_RISCV_JAL:108  case ELF::R_RISCV_CALL:109  case ELF::R_RISCV_CALL_PLT:110  case ELF::R_RISCV_BRANCH:111  case ELF::R_RISCV_RELAX:112  case ELF::R_RISCV_GOT_HI20:113  case ELF::R_RISCV_PCREL_HI20:114  case ELF::R_RISCV_PCREL_LO12_I:115  case ELF::R_RISCV_PCREL_LO12_S:116  case ELF::R_RISCV_RVC_JUMP:117  case ELF::R_RISCV_RVC_BRANCH:118  case ELF::R_RISCV_ADD32:119  case ELF::R_RISCV_SUB32:120  case ELF::R_RISCV_HI20:121  case ELF::R_RISCV_LO12_I:122  case ELF::R_RISCV_LO12_S:123  case ELF::R_RISCV_64:124  case ELF::R_RISCV_TLS_GOT_HI20:125  case ELF::R_RISCV_TLS_GD_HI20:126  case ELF::R_RISCV_TPREL_HI20:127  case ELF::R_RISCV_TPREL_ADD:128  case ELF::R_RISCV_TPREL_LO12_I:129  case ELF::R_RISCV_TPREL_LO12_S:130  case ELFReserved::R_RISCV_TPREL_I:131  case ELFReserved::R_RISCV_TPREL_S:132    return true;133  }134}135 136static size_t getSizeForTypeX86(uint32_t Type) {137  switch (Type) {138  default:139    errs() << object::getELFRelocationTypeName(ELF::EM_X86_64, Type) << '\n';140    llvm_unreachable("unsupported relocation type");141  case ELF::R_X86_64_8:142  case ELF::R_X86_64_PC8:143    return 1;144  case ELF::R_X86_64_16:145    return 2;146  case ELF::R_X86_64_PLT32:147  case ELF::R_X86_64_PC32:148  case ELF::R_X86_64_32S:149  case ELF::R_X86_64_32:150  case ELF::R_X86_64_GOTPCREL:151  case ELF::R_X86_64_GOTTPOFF:152  case ELF::R_X86_64_TPOFF32:153  case ELF::R_X86_64_GOTPCRELX:154  case ELF::R_X86_64_REX_GOTPCRELX:155    return 4;156  case ELF::R_X86_64_PC64:157  case ELF::R_X86_64_64:158  case ELF::R_X86_64_GOTPC64:159    return 8;160  }161}162 163static size_t getSizeForTypeAArch64(uint32_t Type) {164  switch (Type) {165  default:166    errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n';167    llvm_unreachable("unsupported relocation type");168  case ELF::R_AARCH64_ABS16:169  case ELF::R_AARCH64_PREL16:170    return 2;171  case ELF::R_AARCH64_CALL26:172  case ELF::R_AARCH64_JUMP26:173  case ELF::R_AARCH64_TSTBR14:174  case ELF::R_AARCH64_CONDBR19:175  case ELF::R_AARCH64_ADR_PREL_LO21:176  case ELF::R_AARCH64_ADR_PREL_PG_HI21:177  case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:178  case ELF::R_AARCH64_LDST64_ABS_LO12_NC:179  case ELF::R_AARCH64_ADD_ABS_LO12_NC:180  case ELF::R_AARCH64_LDST128_ABS_LO12_NC:181  case ELF::R_AARCH64_LDST32_ABS_LO12_NC:182  case ELF::R_AARCH64_LDST16_ABS_LO12_NC:183  case ELF::R_AARCH64_LDST8_ABS_LO12_NC:184  case ELF::R_AARCH64_ADR_GOT_PAGE:185  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:186  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:187  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:188  case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:189  case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:190  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:191  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:192  case ELF::R_AARCH64_LD64_GOT_LO12_NC:193  case ELF::R_AARCH64_TLSDESC_LD64_LO12:194  case ELF::R_AARCH64_TLSDESC_ADD_LO12:195  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:196  case ELF::R_AARCH64_PREL32:197  case ELF::R_AARCH64_MOVW_UABS_G0:198  case ELF::R_AARCH64_MOVW_UABS_G0_NC:199  case ELF::R_AARCH64_MOVW_UABS_G1:200  case ELF::R_AARCH64_MOVW_UABS_G1_NC:201  case ELF::R_AARCH64_MOVW_UABS_G2:202  case ELF::R_AARCH64_MOVW_UABS_G2_NC:203  case ELF::R_AARCH64_MOVW_UABS_G3:204  case ELF::R_AARCH64_ABS32:205  case ELF::R_AARCH64_PLT32:206    return 4;207  case ELF::R_AARCH64_ABS64:208  case ELF::R_AARCH64_PREL64:209    return 8;210  }211}212 213static size_t getSizeForTypeRISCV(uint32_t Type) {214  switch (Type) {215  default:216    errs() << object::getELFRelocationTypeName(ELF::EM_RISCV, Type) << '\n';217    llvm_unreachable("unsupported relocation type");218  case ELF::R_RISCV_RVC_JUMP:219  case ELF::R_RISCV_RVC_BRANCH:220    return 2;221  case ELF::R_RISCV_JAL:222  case ELF::R_RISCV_BRANCH:223  case ELF::R_RISCV_PCREL_HI20:224  case ELF::R_RISCV_PCREL_LO12_I:225  case ELF::R_RISCV_PCREL_LO12_S:226  case ELF::R_RISCV_32_PCREL:227  case ELF::R_RISCV_CALL:228  case ELF::R_RISCV_CALL_PLT:229  case ELF::R_RISCV_ADD32:230  case ELF::R_RISCV_SUB32:231  case ELF::R_RISCV_HI20:232  case ELF::R_RISCV_LO12_I:233  case ELF::R_RISCV_LO12_S:234    return 4;235  case ELF::R_RISCV_64:236  case ELF::R_RISCV_GOT_HI20:237  case ELF::R_RISCV_TLS_GOT_HI20:238  case ELF::R_RISCV_TLS_GD_HI20:239    // See extractValueRISCV for why this is necessary.240    return 8;241  }242}243 244static bool skipRelocationTypeX86(uint32_t Type) {245  return Type == ELF::R_X86_64_NONE;246}247 248static bool skipRelocationTypeAArch64(uint32_t Type) {249  switch (Type) {250  default:251    return false;252  case ELF::R_AARCH64_NONE:253  case ELF::R_AARCH64_LD_PREL_LO19:254  case ELF::R_AARCH64_TLSDESC_CALL:255    return true;256  }257}258 259static bool skipRelocationTypeRISCV(uint32_t Type) {260  switch (Type) {261  default:262    return false;263  case ELF::R_RISCV_NONE:264  case ELF::R_RISCV_RELAX:265    return true;266  }267}268 269static uint64_t encodeValueX86(uint32_t Type, uint64_t Value, uint64_t PC) {270  switch (Type) {271  default:272    llvm_unreachable("unsupported relocation");273  case ELF::R_X86_64_64:274  case ELF::R_X86_64_32:275    break;276  case ELF::R_X86_64_PC32:277    Value -= PC;278    break;279  }280  return Value;281}282 283static bool canEncodeValueAArch64(uint32_t Type, uint64_t Value, uint64_t PC) {284  switch (Type) {285  default:286    llvm_unreachable("unsupported relocation");287  case ELF::R_AARCH64_CALL26:288  case ELF::R_AARCH64_JUMP26:289    return isInt<28>(Value - PC);290  }291}292 293static uint64_t encodeValueAArch64(uint32_t Type, uint64_t Value, uint64_t PC) {294  switch (Type) {295  default:296    llvm_unreachable("unsupported relocation");297  case ELF::R_AARCH64_ABS16:298  case ELF::R_AARCH64_ABS32:299  case ELF::R_AARCH64_ABS64:300    break;301  case ELF::R_AARCH64_PREL16:302  case ELF::R_AARCH64_PREL32:303  case ELF::R_AARCH64_PREL64:304    Value -= PC;305    break;306  case ELF::R_AARCH64_CALL26:307    Value -= PC;308    assert(isInt<28>(Value) && "only PC +/- 128MB is allowed for direct call");309    // Immediate goes in bits 25:0 of BL.310    // OP 1001_01 goes in bits 31:26 of BL.311    Value = ((Value >> 2) & 0x3ffffff) | 0x94000000ULL;312    break;313  case ELF::R_AARCH64_JUMP26:314    Value -= PC;315    assert(isInt<28>(Value) &&316           "only PC +/- 128MB is allowed for direct branch");317    // Immediate goes in bits 25:0 of B.318    // OP 0001_01 goes in bits 31:26 of B.319    Value = ((Value >> 2) & 0x3ffffff) | 0x14000000ULL;320    break;321  }322  return Value;323}324 325static uint64_t canEncodeValueRISCV(uint32_t Type, uint64_t Value,326                                    uint64_t PC) {327  switch (Type) {328  default:329    llvm_unreachable("unsupported relocation");330  case ELF::R_RISCV_64:331    return true;332  }333}334 335static uint64_t encodeValueRISCV(uint32_t Type, uint64_t Value, uint64_t PC) {336  switch (Type) {337  default:338    llvm_unreachable("unsupported relocation");339  case ELF::R_RISCV_64:340    break;341  }342  return Value;343}344 345static uint64_t extractValueX86(uint32_t Type, uint64_t Contents, uint64_t PC) {346  if (Type == ELF::R_X86_64_32S)347    return SignExtend64<32>(Contents);348  if (Relocation::isPCRelative(Type))349    return SignExtend64(Contents, 8 * Relocation::getSizeForType(Type));350  return Contents;351}352 353static uint64_t extractValueAArch64(uint32_t Type, uint64_t Contents,354                                    uint64_t PC) {355  switch (Type) {356  default:357    errs() << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type) << '\n';358    llvm_unreachable("unsupported relocation type");359  case ELF::R_AARCH64_ABS16:360  case ELF::R_AARCH64_ABS32:361  case ELF::R_AARCH64_ABS64:362    return Contents;363  case ELF::R_AARCH64_PREL16:364    return static_cast<int64_t>(PC) + SignExtend64<16>(Contents & 0xffff);365  case ELF::R_AARCH64_PREL32:366  case ELF::R_AARCH64_PLT32:367    return static_cast<int64_t>(PC) + SignExtend64<32>(Contents & 0xffffffff);368  case ELF::R_AARCH64_PREL64:369    return static_cast<int64_t>(PC) + Contents;370  case ELF::R_AARCH64_JUMP26:371  case ELF::R_AARCH64_CALL26:372    // Immediate goes in bits 25:0 of B and BL.373    Contents &= ~0xfffffffffc000000ULL;374    return static_cast<int64_t>(PC) + SignExtend64<28>(Contents << 2);375  case ELF::R_AARCH64_TSTBR14:376    // Immediate:15:2 goes in bits 18:5 of TBZ, TBNZ377    Contents &= ~0xfffffffffff8001fULL;378    return static_cast<int64_t>(PC) + SignExtend64<16>(Contents >> 3);379  case ELF::R_AARCH64_CONDBR19:380    // Immediate:20:2 goes in bits 23:5 of Bcc, CBZ, CBNZ381    Contents &= ~0xffffffffff00001fULL;382    return static_cast<int64_t>(PC) + SignExtend64<21>(Contents >> 3);383  case ELF::R_AARCH64_ADR_GOT_PAGE:384  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:385  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:386  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:387  case ELF::R_AARCH64_ADR_PREL_LO21:388  case ELF::R_AARCH64_ADR_PREL_PG_HI21:389  case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC: {390    // Bits 32:12 of Symbol address goes in bits 30:29 + 23:5 of ADRP391    // and ADR instructions392    bool IsAdr = !!(((Contents >> 31) & 0x1) == 0);393    Contents &= ~0xffffffff9f00001fUll;394    uint64_t LowBits = (Contents >> 29) & 0x3;395    uint64_t HighBits = (Contents >> 5) & 0x7ffff;396    Contents = LowBits | (HighBits << 2);397    if (IsAdr)398      return static_cast<int64_t>(PC) + SignExtend64<21>(Contents);399 400    // ADRP instruction401    Contents = static_cast<int64_t>(PC) + SignExtend64<33>(Contents << 12);402    Contents &= ~0xfffUll;403    return Contents;404  }405  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:406  case ELF::R_AARCH64_TLSDESC_LD64_LO12:407  case ELF::R_AARCH64_LD64_GOT_LO12_NC:408  case ELF::R_AARCH64_LDST64_ABS_LO12_NC: {409    // Immediate goes in bits 21:10 of LD/ST instruction, taken410    // from bits 11:3 of Symbol address411    Contents &= ~0xffffffffffc003ffU;412    return Contents >> (10 - 3);413  }414  case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:415  case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:416  case ELF::R_AARCH64_TLSDESC_ADD_LO12:417  case ELF::R_AARCH64_ADD_ABS_LO12_NC: {418    // Immediate goes in bits 21:10 of ADD instruction419    Contents &= ~0xffffffffffc003ffU;420    return Contents >> (10 - 0);421  }422  case ELF::R_AARCH64_LDST128_ABS_LO12_NC: {423    // Immediate goes in bits 21:10 of ADD instruction, taken424    // from bits 11:4 of Symbol address425    Contents &= ~0xffffffffffc003ffU;426    return Contents >> (10 - 4);427  }428  case ELF::R_AARCH64_LDST32_ABS_LO12_NC: {429    // Immediate goes in bits 21:10 of ADD instruction, taken430    // from bits 11:2 of Symbol address431    Contents &= ~0xffffffffffc003ffU;432    return Contents >> (10 - 2);433  }434  case ELF::R_AARCH64_LDST16_ABS_LO12_NC: {435    // Immediate goes in bits 21:10 of ADD instruction, taken436    // from bits 11:1 of Symbol address437    Contents &= ~0xffffffffffc003ffU;438    return Contents >> (10 - 1);439  }440  case ELF::R_AARCH64_LDST8_ABS_LO12_NC: {441    // Immediate goes in bits 21:10 of ADD instruction, taken442    // from bits 11:0 of Symbol address443    Contents &= ~0xffffffffffc003ffU;444    return Contents >> (10 - 0);445  }446  case ELF::R_AARCH64_MOVW_UABS_G3:447  case ELF::R_AARCH64_MOVW_UABS_G2_NC:448  case ELF::R_AARCH64_MOVW_UABS_G2:449  case ELF::R_AARCH64_MOVW_UABS_G1_NC:450  case ELF::R_AARCH64_MOVW_UABS_G1:451  case ELF::R_AARCH64_MOVW_UABS_G0_NC:452  case ELF::R_AARCH64_MOVW_UABS_G0:453    // The shift goes in bits 22:21 of MOV* instructions454    uint8_t Shift = (Contents >> 21) & 0x3;455    // Immediate goes in bits 20:5456    Contents = (Contents >> 5) & 0xffff;457    return Contents << (16 * Shift);458  }459}460 461static uint64_t extractUImmRISCV(uint32_t Contents) {462  return SignExtend64<32>(Contents & 0xfffff000);463}464 465static uint64_t extractIImmRISCV(uint32_t Contents) {466  return SignExtend64<12>(Contents >> 20);467}468 469static uint64_t extractSImmRISCV(uint32_t Contents) {470  return SignExtend64<12>(((Contents >> 7) & 0x1f) | ((Contents >> 25) << 5));471}472 473static uint64_t extractJImmRISCV(uint32_t Contents) {474  return SignExtend64<21>(475      (((Contents >> 21) & 0x3ff) << 1) | (((Contents >> 20) & 0x1) << 11) |476      (((Contents >> 12) & 0xff) << 12) | (((Contents >> 31) & 0x1) << 20));477}478 479static uint64_t extractBImmRISCV(uint32_t Contents) {480  return SignExtend64<13>(481      (((Contents >> 8) & 0xf) << 1) | (((Contents >> 25) & 0x3f) << 5) |482      (((Contents >> 7) & 0x1) << 11) | (((Contents >> 31) & 0x1) << 12));483}484 485static uint64_t extractValueRISCV(uint32_t Type, uint64_t Contents,486                                  uint64_t PC) {487  switch (Type) {488  default:489    errs() << object::getELFRelocationTypeName(ELF::EM_RISCV, Type) << '\n';490    llvm_unreachable("unsupported relocation type");491  case ELF::R_RISCV_JAL:492    return extractJImmRISCV(Contents);493  case ELF::R_RISCV_CALL:494  case ELF::R_RISCV_CALL_PLT:495    return extractUImmRISCV(Contents);496  case ELF::R_RISCV_BRANCH:497    return extractBImmRISCV(Contents);498  case ELF::R_RISCV_GOT_HI20:499  case ELF::R_RISCV_TLS_GOT_HI20:500  case ELF::R_RISCV_TLS_GD_HI20:501    // We need to know the exact address of the GOT entry so we extract the502    // value from both the AUIPC and L[D|W]. We cannot rely on the symbol in the503    // relocation for this since it simply refers to the object that is stored504    // in the GOT entry, not to the entry itself.505    return extractUImmRISCV(Contents & 0xffffffff) +506           extractIImmRISCV(Contents >> 32);507  case ELF::R_RISCV_PCREL_HI20:508  case ELF::R_RISCV_HI20:509    return extractUImmRISCV(Contents);510  case ELF::R_RISCV_PCREL_LO12_I:511  case ELF::R_RISCV_LO12_I:512    return extractIImmRISCV(Contents);513  case ELF::R_RISCV_PCREL_LO12_S:514  case ELF::R_RISCV_LO12_S:515    return extractSImmRISCV(Contents);516  case ELF::R_RISCV_RVC_JUMP:517    return SignExtend64<11>(Contents >> 2);518  case ELF::R_RISCV_RVC_BRANCH:519    return SignExtend64<8>(((Contents >> 2) & 0x1f) | ((Contents >> 5) & 0xe0));520  case ELF::R_RISCV_ADD32:521  case ELF::R_RISCV_SUB32:522  case ELF::R_RISCV_64:523    return Contents;524  }525}526 527static bool isGOTX86(uint32_t Type) {528  switch (Type) {529  default:530    return false;531  case ELF::R_X86_64_GOT32:532  case ELF::R_X86_64_GOTPCREL:533  case ELF::R_X86_64_GOTTPOFF:534  case ELF::R_X86_64_GOTOFF64:535  case ELF::R_X86_64_GOTPC32:536  case ELF::R_X86_64_GOT64:537  case ELF::R_X86_64_GOTPCREL64:538  case ELF::R_X86_64_GOTPC64:539  case ELF::R_X86_64_GOTPLT64:540  case ELF::R_X86_64_GOTPC32_TLSDESC:541  case ELF::R_X86_64_GOTPCRELX:542  case ELF::R_X86_64_REX_GOTPCRELX:543    return true;544  }545}546 547static bool isGOTAArch64(uint32_t Type) {548  switch (Type) {549  default:550    return false;551  case ELF::R_AARCH64_ADR_GOT_PAGE:552  case ELF::R_AARCH64_LD64_GOT_LO12_NC:553  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:554  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:555  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:556  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:557  case ELF::R_AARCH64_TLSDESC_LD64_LO12:558  case ELF::R_AARCH64_TLSDESC_ADD_LO12:559    return true;560  }561}562 563static bool isGOTRISCV(uint32_t Type) {564  switch (Type) {565  default:566    return false;567  case ELF::R_RISCV_GOT_HI20:568  case ELF::R_RISCV_TLS_GOT_HI20:569    return true;570  }571}572 573static bool isTLSX86(uint32_t Type) {574  switch (Type) {575  default:576    return false;577  case ELF::R_X86_64_TPOFF32:578  case ELF::R_X86_64_TPOFF64:579  case ELF::R_X86_64_GOTTPOFF:580    return true;581  }582}583 584static bool isTLSAArch64(uint32_t Type) {585  switch (Type) {586  default:587    return false;588  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:589  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:590  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:591  case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:592  case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:593  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:594  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:595  case ELF::R_AARCH64_TLSDESC_LD64_LO12:596  case ELF::R_AARCH64_TLSDESC_ADD_LO12:597  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:598    return true;599  }600}601 602static bool isTLSRISCV(uint32_t Type) {603  switch (Type) {604  default:605    return false;606  case ELF::R_RISCV_TLS_GOT_HI20:607  case ELF::R_RISCV_TPREL_HI20:608  case ELF::R_RISCV_TPREL_ADD:609  case ELF::R_RISCV_TPREL_LO12_I:610  case ELF::R_RISCV_TPREL_LO12_S:611  case ELFReserved::R_RISCV_TPREL_I:612  case ELFReserved::R_RISCV_TPREL_S:613    return true;614  }615}616 617static bool isPCRelativeX86(uint32_t Type) {618  switch (Type) {619  default:620    llvm_unreachable("Unknown relocation type");621  case ELF::R_X86_64_64:622  case ELF::R_X86_64_32:623  case ELF::R_X86_64_32S:624  case ELF::R_X86_64_16:625  case ELF::R_X86_64_8:626  case ELF::R_X86_64_TPOFF32:627    return false;628  case ELF::R_X86_64_PC8:629  case ELF::R_X86_64_PC32:630  case ELF::R_X86_64_PC64:631  case ELF::R_X86_64_GOTPCREL:632  case ELF::R_X86_64_PLT32:633  case ELF::R_X86_64_GOTOFF64:634  case ELF::R_X86_64_GOTPC32:635  case ELF::R_X86_64_GOTPC64:636  case ELF::R_X86_64_GOTTPOFF:637  case ELF::R_X86_64_GOTPCRELX:638  case ELF::R_X86_64_REX_GOTPCRELX:639    return true;640  }641}642 643static bool isPCRelativeAArch64(uint32_t Type) {644  switch (Type) {645  default:646    llvm_unreachable("Unknown relocation type");647  case ELF::R_AARCH64_ABS16:648  case ELF::R_AARCH64_ABS32:649  case ELF::R_AARCH64_ABS64:650  case ELF::R_AARCH64_LDST64_ABS_LO12_NC:651  case ELF::R_AARCH64_ADD_ABS_LO12_NC:652  case ELF::R_AARCH64_LDST128_ABS_LO12_NC:653  case ELF::R_AARCH64_LDST32_ABS_LO12_NC:654  case ELF::R_AARCH64_LDST16_ABS_LO12_NC:655  case ELF::R_AARCH64_LDST8_ABS_LO12_NC:656  case ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:657  case ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12:658  case ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:659  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0:660  case ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:661  case ELF::R_AARCH64_LD64_GOT_LO12_NC:662  case ELF::R_AARCH64_TLSDESC_LD64_LO12:663  case ELF::R_AARCH64_TLSDESC_ADD_LO12:664  case ELF::R_AARCH64_MOVW_UABS_G0:665  case ELF::R_AARCH64_MOVW_UABS_G0_NC:666  case ELF::R_AARCH64_MOVW_UABS_G1:667  case ELF::R_AARCH64_MOVW_UABS_G1_NC:668  case ELF::R_AARCH64_MOVW_UABS_G2:669  case ELF::R_AARCH64_MOVW_UABS_G2_NC:670  case ELF::R_AARCH64_MOVW_UABS_G3:671    return false;672  case ELF::R_AARCH64_CALL26:673  case ELF::R_AARCH64_JUMP26:674  case ELF::R_AARCH64_TSTBR14:675  case ELF::R_AARCH64_CONDBR19:676  case ELF::R_AARCH64_ADR_PREL_LO21:677  case ELF::R_AARCH64_ADR_PREL_PG_HI21:678  case ELF::R_AARCH64_ADR_PREL_PG_HI21_NC:679  case ELF::R_AARCH64_ADR_GOT_PAGE:680  case ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:681  case ELF::R_AARCH64_TLSDESC_ADR_PREL21:682  case ELF::R_AARCH64_TLSDESC_ADR_PAGE21:683  case ELF::R_AARCH64_PREL16:684  case ELF::R_AARCH64_PREL32:685  case ELF::R_AARCH64_PREL64:686  case ELF::R_AARCH64_PLT32:687    return true;688  }689}690 691static bool isPCRelativeRISCV(uint32_t Type) {692  switch (Type) {693  default:694    llvm_unreachable("Unknown relocation type");695  case ELF::R_RISCV_ADD32:696  case ELF::R_RISCV_SUB32:697  case ELF::R_RISCV_HI20:698  case ELF::R_RISCV_LO12_I:699  case ELF::R_RISCV_LO12_S:700  case ELF::R_RISCV_64:701    return false;702  case ELF::R_RISCV_JAL:703  case ELF::R_RISCV_CALL:704  case ELF::R_RISCV_CALL_PLT:705  case ELF::R_RISCV_BRANCH:706  case ELF::R_RISCV_GOT_HI20:707  case ELF::R_RISCV_PCREL_HI20:708  case ELF::R_RISCV_PCREL_LO12_I:709  case ELF::R_RISCV_PCREL_LO12_S:710  case ELF::R_RISCV_RVC_JUMP:711  case ELF::R_RISCV_RVC_BRANCH:712  case ELF::R_RISCV_32_PCREL:713  case ELF::R_RISCV_TLS_GOT_HI20:714  case ELF::R_RISCV_TLS_GD_HI20:715    return true;716  }717}718 719bool Relocation::isSupported(uint32_t Type) {720  switch (Arch) {721  default:722    return false;723  case Triple::aarch64:724    return isSupportedAArch64(Type);725  case Triple::riscv64:726    return isSupportedRISCV(Type);727  case Triple::x86_64:728    return isSupportedX86(Type);729  }730}731 732size_t Relocation::getSizeForType(uint32_t Type) {733  switch (Arch) {734  default:735    llvm_unreachable("Unsupported architecture");736  case Triple::aarch64:737    return getSizeForTypeAArch64(Type);738  case Triple::riscv64:739    return getSizeForTypeRISCV(Type);740  case Triple::x86_64:741    return getSizeForTypeX86(Type);742  }743}744 745bool Relocation::skipRelocationType(uint32_t Type) {746  switch (Arch) {747  default:748    llvm_unreachable("Unsupported architecture");749  case Triple::aarch64:750    return skipRelocationTypeAArch64(Type);751  case Triple::riscv64:752    return skipRelocationTypeRISCV(Type);753  case Triple::x86_64:754    return skipRelocationTypeX86(Type);755  }756}757 758uint64_t Relocation::encodeValue(uint32_t Type, uint64_t Value, uint64_t PC) {759  switch (Arch) {760  default:761    llvm_unreachable("Unsupported architecture");762  case Triple::aarch64:763    return encodeValueAArch64(Type, Value, PC);764  case Triple::riscv64:765    return encodeValueRISCV(Type, Value, PC);766  case Triple::x86_64:767    return encodeValueX86(Type, Value, PC);768  }769}770 771bool Relocation::canEncodeValue(uint32_t Type, uint64_t Value, uint64_t PC) {772  switch (Arch) {773  default:774    llvm_unreachable("Unsupported architecture");775  case Triple::aarch64:776    return canEncodeValueAArch64(Type, Value, PC);777  case Triple::riscv64:778    return canEncodeValueRISCV(Type, Value, PC);779  case Triple::x86_64:780    return true;781  }782}783 784uint64_t Relocation::extractValue(uint32_t Type, uint64_t Contents,785                                  uint64_t PC) {786  switch (Arch) {787  default:788    llvm_unreachable("Unsupported architecture");789  case Triple::aarch64:790    return extractValueAArch64(Type, Contents, PC);791  case Triple::riscv64:792    return extractValueRISCV(Type, Contents, PC);793  case Triple::x86_64:794    return extractValueX86(Type, Contents, PC);795  }796}797 798bool Relocation::isGOT(uint32_t Type) {799  switch (Arch) {800  default:801    llvm_unreachable("Unsupported architecture");802  case Triple::aarch64:803    return isGOTAArch64(Type);804  case Triple::riscv64:805    return isGOTRISCV(Type);806  case Triple::x86_64:807    return isGOTX86(Type);808  }809}810 811bool Relocation::isX86GOTPCRELX(uint32_t Type) {812  if (Arch != Triple::x86_64)813    return false;814  return Type == ELF::R_X86_64_GOTPCRELX || Type == ELF::R_X86_64_REX_GOTPCRELX;815}816 817bool Relocation::isX86GOTPC64(uint32_t Type) {818  if (Arch != Triple::x86_64)819    return false;820  return Type == ELF::R_X86_64_GOTPC64;821}822 823bool Relocation::isNone(uint32_t Type) { return Type == getNone(); }824 825bool Relocation::isRelative(uint32_t Type) {826  switch (Arch) {827  default:828    llvm_unreachable("Unsupported architecture");829  case Triple::aarch64:830    return Type == ELF::R_AARCH64_RELATIVE;831  case Triple::riscv64:832    return Type == ELF::R_RISCV_RELATIVE;833  case Triple::x86_64:834    return Type == ELF::R_X86_64_RELATIVE;835  }836}837 838bool Relocation::isIRelative(uint32_t Type) {839  switch (Arch) {840  default:841    llvm_unreachable("Unsupported architecture");842  case Triple::aarch64:843    return Type == ELF::R_AARCH64_IRELATIVE;844  case Triple::riscv64:845    llvm_unreachable("not implemented");846  case Triple::x86_64:847    return Type == ELF::R_X86_64_IRELATIVE;848  }849}850 851bool Relocation::isTLS(uint32_t Type) {852  switch (Arch) {853  default:854    llvm_unreachable("Unsupported architecture");855  case Triple::aarch64:856    return isTLSAArch64(Type);857  case Triple::riscv64:858    return isTLSRISCV(Type);859  case Triple::x86_64:860    return isTLSX86(Type);861  }862}863 864bool Relocation::isInstructionReference(uint32_t Type) {865  if (Arch != Triple::riscv64)866    return false;867 868  switch (Type) {869  default:870    return false;871  case ELF::R_RISCV_PCREL_LO12_I:872  case ELF::R_RISCV_PCREL_LO12_S:873    return true;874  }875}876 877uint32_t Relocation::getNone() {878  switch (Arch) {879  default:880    llvm_unreachable("Unsupported architecture");881  case Triple::aarch64:882    return ELF::R_AARCH64_NONE;883  case Triple::riscv64:884    return ELF::R_RISCV_NONE;885  case Triple::x86_64:886    return ELF::R_X86_64_NONE;887  }888}889 890uint32_t Relocation::getPC32() {891  switch (Arch) {892  default:893    llvm_unreachable("Unsupported architecture");894  case Triple::aarch64:895    return ELF::R_AARCH64_PREL32;896  case Triple::riscv64:897    return ELF::R_RISCV_32_PCREL;898  case Triple::x86_64:899    return ELF::R_X86_64_PC32;900  }901}902 903uint32_t Relocation::getPC64() {904  switch (Arch) {905  default:906    llvm_unreachable("Unsupported architecture");907  case Triple::aarch64:908    return ELF::R_AARCH64_PREL64;909  case Triple::riscv64:910    llvm_unreachable("not implemented");911  case Triple::x86_64:912    return ELF::R_X86_64_PC64;913  }914}915 916uint32_t Relocation::getType(const object::RelocationRef &Rel) {917  uint64_t RelType = Rel.getType();918  assert(isUInt<32>(RelType) && "BOLT relocation types are 32 bits");919  return static_cast<uint32_t>(RelType);920}921 922bool Relocation::isPCRelative(uint32_t Type) {923  switch (Arch) {924  default:925    llvm_unreachable("Unsupported architecture");926  case Triple::aarch64:927    return isPCRelativeAArch64(Type);928  case Triple::riscv64:929    return isPCRelativeRISCV(Type);930  case Triple::x86_64:931    return isPCRelativeX86(Type);932  }933}934 935uint32_t Relocation::getAbs64() {936  switch (Arch) {937  default:938    llvm_unreachable("Unsupported architecture");939  case Triple::aarch64:940    return ELF::R_AARCH64_ABS64;941  case Triple::riscv64:942    return ELF::R_RISCV_64;943  case Triple::x86_64:944    return ELF::R_X86_64_64;945  }946}947 948uint32_t Relocation::getRelative() {949  switch (Arch) {950  default:951    llvm_unreachable("Unsupported architecture");952  case Triple::aarch64:953    return ELF::R_AARCH64_RELATIVE;954  case Triple::riscv64:955    llvm_unreachable("not implemented");956  case Triple::x86_64:957    return ELF::R_X86_64_RELATIVE;958  }959}960 961size_t Relocation::emit(MCStreamer *Streamer) const {962  const size_t Size = getSizeForType(Type);963  const auto *Value = createExpr(Streamer);964  Streamer->emitValue(Value, Size);965  return Size;966}967 968const MCExpr *Relocation::createExpr(MCStreamer *Streamer) const {969  MCContext &Ctx = Streamer->getContext();970  const MCExpr *Value = nullptr;971 972  if (Symbol && Addend) {973    Value = MCBinaryExpr::createAdd(MCSymbolRefExpr::create(Symbol, Ctx),974                                    MCConstantExpr::create(Addend, Ctx), Ctx);975  } else if (Symbol) {976    Value = MCSymbolRefExpr::create(Symbol, Ctx);977  } else {978    Value = MCConstantExpr::create(Addend, Ctx);979  }980 981  if (isPCRelative(Type)) {982    MCSymbol *TempLabel = Ctx.createNamedTempSymbol();983    Streamer->emitLabel(TempLabel);984    Value = MCBinaryExpr::createSub(985        Value, MCSymbolRefExpr::create(TempLabel, Ctx), Ctx);986  }987 988  return Value;989}990 991const MCExpr *Relocation::createExpr(MCStreamer *Streamer,992                                     const MCExpr *RetainedValue) const {993  const auto *Value = createExpr(Streamer);994 995  if (RetainedValue) {996    Value = MCBinaryExpr::create(getComposeOpcodeFor(Type), RetainedValue,997                                 Value, Streamer->getContext());998  }999 1000  return Value;1001}1002 1003MCBinaryExpr::Opcode Relocation::getComposeOpcodeFor(uint32_t Type) {1004  assert(Arch == Triple::riscv64 && "only implemented for RISC-V");1005 1006  switch (Type) {1007  default:1008    llvm_unreachable("not implemented");1009  case ELF::R_RISCV_ADD32:1010    return MCBinaryExpr::Add;1011  case ELF::R_RISCV_SUB32:1012    return MCBinaryExpr::Sub;1013  }1014}1015 1016void Relocation::print(raw_ostream &OS) const {1017  switch (Arch) {1018  default:1019    OS << "RType:" << Twine::utohexstr(Type);1020    break;1021  case Triple::aarch64:1022    OS << object::getELFRelocationTypeName(ELF::EM_AARCH64, Type);1023    break;1024  case Triple::riscv64:1025    OS << object::getELFRelocationTypeName(ELF::EM_RISCV, Type);1026    break;1027  case Triple::x86_64:1028    OS << object::getELFRelocationTypeName(ELF::EM_X86_64, Type);1029    break;1030  }1031  OS << ", 0x" << Twine::utohexstr(Offset);1032  if (Symbol) {1033    OS << ", " << Symbol->getName();1034  }1035  if (int64_t(Addend) < 0)1036    OS << ", -0x" << Twine::utohexstr(-int64_t(Addend));1037  else1038    OS << ", 0x" << Twine::utohexstr(Addend);1039  OS << ", 0x" << Twine::utohexstr(Value);1040}1041