LLVM API Documentation

AArch64ELFObjectWriter.cpp
Go to the documentation of this file.
00001 //===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file handles ELF-specific object emission, converting LLVM's internal
00011 // fixups into the appropriate relocations.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "MCTargetDesc/AArch64FixupKinds.h"
00016 #include "MCTargetDesc/AArch64MCExpr.h"
00017 #include "MCTargetDesc/AArch64MCTargetDesc.h"
00018 #include "llvm/MC/MCELFObjectWriter.h"
00019 #include "llvm/MC/MCValue.h"
00020 #include "llvm/Support/ErrorHandling.h"
00021 
00022 using namespace llvm;
00023 
00024 namespace {
00025 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter {
00026 public:
00027   AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian);
00028 
00029   virtual ~AArch64ELFObjectWriter();
00030 
00031 protected:
00032   unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
00033                         bool IsPCRel) const override;
00034 
00035 private:
00036 };
00037 }
00038 
00039 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI,
00040                                                bool IsLittleEndian)
00041     : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64,
00042                               /*HasRelocationAddend*/ true) {}
00043 
00044 AArch64ELFObjectWriter::~AArch64ELFObjectWriter() {}
00045 
00046 unsigned AArch64ELFObjectWriter::GetRelocType(const MCValue &Target,
00047                                             const MCFixup &Fixup,
00048                                             bool IsPCRel) const {
00049   AArch64MCExpr::VariantKind RefKind =
00050       static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind());
00051   AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind);
00052   bool IsNC = AArch64MCExpr::isNotChecked(RefKind);
00053 
00054   assert((!Target.getSymA() ||
00055           Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) &&
00056          "Should only be expression-level modifiers here");
00057 
00058   assert((!Target.getSymB() ||
00059           Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) &&
00060          "Should only be expression-level modifiers here");
00061 
00062   if (IsPCRel) {
00063     switch ((unsigned)Fixup.getKind()) {
00064     case FK_Data_2:
00065       return ELF::R_AARCH64_PREL16;
00066     case FK_Data_4:
00067       return ELF::R_AARCH64_PREL32;
00068     case FK_Data_8:
00069       return ELF::R_AARCH64_PREL64;
00070     case AArch64::fixup_aarch64_pcrel_adr_imm21:
00071       assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation");
00072       return ELF::R_AARCH64_ADR_PREL_LO21;
00073     case AArch64::fixup_aarch64_pcrel_adrp_imm21:
00074       if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC)
00075         return ELF::R_AARCH64_ADR_PREL_PG_HI21;
00076       if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC)
00077         return ELF::R_AARCH64_ADR_GOT_PAGE;
00078       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC)
00079         return ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21;
00080       if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC)
00081         return ELF::R_AARCH64_TLSDESC_ADR_PAGE;
00082       llvm_unreachable("invalid symbol kind for ADRP relocation");
00083     case AArch64::fixup_aarch64_pcrel_branch26:
00084       return ELF::R_AARCH64_JUMP26;
00085     case AArch64::fixup_aarch64_pcrel_call26:
00086       return ELF::R_AARCH64_CALL26;
00087     case AArch64::fixup_aarch64_ldr_pcrel_imm19:
00088       if (SymLoc == AArch64MCExpr::VK_GOTTPREL)
00089         return ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19;
00090       return ELF::R_AARCH64_LD_PREL_LO19;
00091     case AArch64::fixup_aarch64_pcrel_branch14:
00092       return ELF::R_AARCH64_TSTBR14;
00093     case AArch64::fixup_aarch64_pcrel_branch19:
00094       return ELF::R_AARCH64_CONDBR19;
00095     default:
00096       llvm_unreachable("Unsupported pc-relative fixup kind");
00097     }
00098   } else {
00099     switch ((unsigned)Fixup.getKind()) {
00100     case FK_Data_2:
00101       return ELF::R_AARCH64_ABS16;
00102     case FK_Data_4:
00103       return ELF::R_AARCH64_ABS32;
00104     case FK_Data_8:
00105       return ELF::R_AARCH64_ABS64;
00106     case AArch64::fixup_aarch64_add_imm12:
00107       if (RefKind == AArch64MCExpr::VK_DTPREL_HI12)
00108         return ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12;
00109       if (RefKind == AArch64MCExpr::VK_TPREL_HI12)
00110         return ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12;
00111       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC)
00112         return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC;
00113       if (RefKind == AArch64MCExpr::VK_DTPREL_LO12)
00114         return ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12;
00115       if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC)
00116         return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC;
00117       if (RefKind == AArch64MCExpr::VK_TPREL_LO12)
00118         return ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12;
00119       if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12)
00120         return ELF::R_AARCH64_TLSDESC_ADD_LO12_NC;
00121       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00122         return ELF::R_AARCH64_ADD_ABS_LO12_NC;
00123 
00124       report_fatal_error("invalid fixup for add (uimm12) instruction");
00125       return 0;
00126     case AArch64::fixup_aarch64_ldst_imm12_scale1:
00127       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00128         return ELF::R_AARCH64_LDST8_ABS_LO12_NC;
00129       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
00130         return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12;
00131       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
00132         return ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC;
00133       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
00134         return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12;
00135       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
00136         return ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC;
00137 
00138       report_fatal_error("invalid fixup for 8-bit load/store instruction");
00139       return 0;
00140     case AArch64::fixup_aarch64_ldst_imm12_scale2:
00141       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00142         return ELF::R_AARCH64_LDST16_ABS_LO12_NC;
00143       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
00144         return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12;
00145       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
00146         return ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC;
00147       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
00148         return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12;
00149       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
00150         return ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC;
00151 
00152       report_fatal_error("invalid fixup for 16-bit load/store instruction");
00153       return 0;
00154     case AArch64::fixup_aarch64_ldst_imm12_scale4:
00155       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00156         return ELF::R_AARCH64_LDST32_ABS_LO12_NC;
00157       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
00158         return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12;
00159       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
00160         return ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC;
00161       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
00162         return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12;
00163       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
00164         return ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC;
00165 
00166       report_fatal_error("invalid fixup for 32-bit load/store instruction");
00167       return 0;
00168     case AArch64::fixup_aarch64_ldst_imm12_scale8:
00169       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00170         return ELF::R_AARCH64_LDST64_ABS_LO12_NC;
00171       if (SymLoc == AArch64MCExpr::VK_GOT && IsNC)
00172         return ELF::R_AARCH64_LD64_GOT_LO12_NC;
00173       if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC)
00174         return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12;
00175       if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC)
00176         return ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC;
00177       if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC)
00178         return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12;
00179       if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC)
00180         return ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC;
00181       if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC)
00182         return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC;
00183       if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC)
00184         return ELF::R_AARCH64_TLSDESC_LD64_LO12_NC;
00185 
00186       report_fatal_error("invalid fixup for 64-bit load/store instruction");
00187       return 0;
00188     case AArch64::fixup_aarch64_ldst_imm12_scale16:
00189       if (SymLoc == AArch64MCExpr::VK_ABS && IsNC)
00190         return ELF::R_AARCH64_LDST128_ABS_LO12_NC;
00191 
00192       report_fatal_error("invalid fixup for 128-bit load/store instruction");
00193       return 0;
00194     case AArch64::fixup_aarch64_movw:
00195       if (RefKind == AArch64MCExpr::VK_ABS_G3)
00196         return ELF::R_AARCH64_MOVW_UABS_G3;
00197       if (RefKind == AArch64MCExpr::VK_ABS_G2)
00198         return ELF::R_AARCH64_MOVW_UABS_G2;
00199       if (RefKind == AArch64MCExpr::VK_ABS_G2_S)
00200         return ELF::R_AARCH64_MOVW_SABS_G2;
00201       if (RefKind == AArch64MCExpr::VK_ABS_G2_NC)
00202         return ELF::R_AARCH64_MOVW_UABS_G2_NC;
00203       if (RefKind == AArch64MCExpr::VK_ABS_G1)
00204         return ELF::R_AARCH64_MOVW_UABS_G1;
00205       if (RefKind == AArch64MCExpr::VK_ABS_G1_S)
00206         return ELF::R_AARCH64_MOVW_SABS_G1;
00207       if (RefKind == AArch64MCExpr::VK_ABS_G1_NC)
00208         return ELF::R_AARCH64_MOVW_UABS_G1_NC;
00209       if (RefKind == AArch64MCExpr::VK_ABS_G0)
00210         return ELF::R_AARCH64_MOVW_UABS_G0;
00211       if (RefKind == AArch64MCExpr::VK_ABS_G0_S)
00212         return ELF::R_AARCH64_MOVW_SABS_G0;
00213       if (RefKind == AArch64MCExpr::VK_ABS_G0_NC)
00214         return ELF::R_AARCH64_MOVW_UABS_G0_NC;
00215       if (RefKind == AArch64MCExpr::VK_DTPREL_G2)
00216         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2;
00217       if (RefKind == AArch64MCExpr::VK_DTPREL_G1)
00218         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1;
00219       if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC)
00220         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC;
00221       if (RefKind == AArch64MCExpr::VK_DTPREL_G0)
00222         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0;
00223       if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC)
00224         return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC;
00225       if (RefKind == AArch64MCExpr::VK_TPREL_G2)
00226         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2;
00227       if (RefKind == AArch64MCExpr::VK_TPREL_G1)
00228         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1;
00229       if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC)
00230         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC;
00231       if (RefKind == AArch64MCExpr::VK_TPREL_G0)
00232         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0;
00233       if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC)
00234         return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC;
00235       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1)
00236         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1;
00237       if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC)
00238         return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC;
00239       report_fatal_error("invalid fixup for movz/movk instruction");
00240       return 0;
00241     case AArch64::fixup_aarch64_tlsdesc_call:
00242       return ELF::R_AARCH64_TLSDESC_CALL;
00243     default:
00244       llvm_unreachable("Unknown ELF relocation type");
00245     }
00246   }
00247 
00248   llvm_unreachable("Unimplemented fixup -> relocation");
00249 }
00250 
00251 MCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_ostream &OS,
00252                                                  uint8_t OSABI,
00253                                                  bool IsLittleEndian) {
00254   MCELFObjectTargetWriter *MOTW =
00255       new AArch64ELFObjectWriter(OSABI, IsLittleEndian);
00256   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
00257 }