1//===-- AArch64ELFObjectWriter.cpp - AArch64 ELF Writer -------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file handles ELF-specific object emission, converting LLVM's internal 11// fixups into the appropriate relocations. 12// 13//===----------------------------------------------------------------------===// 14 15#include "MCTargetDesc/AArch64FixupKinds.h" 16#include "MCTargetDesc/AArch64MCTargetDesc.h" 17#include "llvm/MC/MCELFObjectWriter.h" 18#include "llvm/MC/MCValue.h" 19#include "llvm/Support/ErrorHandling.h" 20 21using namespace llvm; 22 23namespace { 24class AArch64ELFObjectWriter : public MCELFObjectTargetWriter { 25public: 26 AArch64ELFObjectWriter(uint8_t OSABI); 27 28 virtual ~AArch64ELFObjectWriter(); 29 30protected: 31 virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 32 bool IsPCRel, bool IsRelocWithSymbol, 33 int64_t Addend) const; 34private: 35}; 36} 37 38AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI) 39 : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64, 40 /*HasRelocationAddend*/ true) 41{} 42 43AArch64ELFObjectWriter::~AArch64ELFObjectWriter() 44{} 45 46unsigned AArch64ELFObjectWriter::GetRelocType(const MCValue &Target, 47 const MCFixup &Fixup, 48 bool IsPCRel, 49 bool IsRelocWithSymbol, 50 int64_t Addend) const { 51 unsigned Type; 52 if (IsPCRel) { 53 switch ((unsigned)Fixup.getKind()) { 54 default: 55 llvm_unreachable("Unimplemented fixup -> relocation"); 56 case FK_Data_8: 57 return ELF::R_AARCH64_PREL64; 58 case FK_Data_4: 59 return ELF::R_AARCH64_PREL32; 60 case FK_Data_2: 61 return ELF::R_AARCH64_PREL16; 62 case AArch64::fixup_a64_ld_prel: 63 Type = ELF::R_AARCH64_LD_PREL_LO19; 64 break; 65 case AArch64::fixup_a64_adr_prel: 66 Type = ELF::R_AARCH64_ADR_PREL_LO21; 67 break; 68 case AArch64::fixup_a64_adr_prel_page: 69 Type = ELF::R_AARCH64_ADR_PREL_PG_HI21; 70 break; 71 case AArch64::fixup_a64_adr_prel_got_page: 72 Type = ELF::R_AARCH64_ADR_GOT_PAGE; 73 break; 74 case AArch64::fixup_a64_tstbr: 75 Type = ELF::R_AARCH64_TSTBR14; 76 break; 77 case AArch64::fixup_a64_condbr: 78 Type = ELF::R_AARCH64_CONDBR19; 79 break; 80 case AArch64::fixup_a64_uncondbr: 81 Type = ELF::R_AARCH64_JUMP26; 82 break; 83 case AArch64::fixup_a64_call: 84 Type = ELF::R_AARCH64_CALL26; 85 break; 86 case AArch64::fixup_a64_adr_gottprel_page: 87 Type = ELF::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21; 88 break; 89 case AArch64::fixup_a64_ld_gottprel_prel19: 90 Type = ELF::R_AARCH64_TLSIE_LD_GOTTPREL_PREL19; 91 break; 92 case AArch64::fixup_a64_tlsdesc_adr_page: 93 Type = ELF::R_AARCH64_TLSDESC_ADR_PAGE; 94 break; 95 } 96 } else { 97 switch ((unsigned)Fixup.getKind()) { 98 default: 99 llvm_unreachable("Unimplemented fixup -> relocation"); 100 case FK_Data_8: 101 return ELF::R_AARCH64_ABS64; 102 case FK_Data_4: 103 return ELF::R_AARCH64_ABS32; 104 case FK_Data_2: 105 return ELF::R_AARCH64_ABS16; 106 case AArch64::fixup_a64_add_lo12: 107 Type = ELF::R_AARCH64_ADD_ABS_LO12_NC; 108 break; 109 case AArch64::fixup_a64_ld64_got_lo12_nc: 110 Type = ELF::R_AARCH64_LD64_GOT_LO12_NC; 111 break; 112 case AArch64::fixup_a64_ldst8_lo12: 113 Type = ELF::R_AARCH64_LDST8_ABS_LO12_NC; 114 break; 115 case AArch64::fixup_a64_ldst16_lo12: 116 Type = ELF::R_AARCH64_LDST16_ABS_LO12_NC; 117 break; 118 case AArch64::fixup_a64_ldst32_lo12: 119 Type = ELF::R_AARCH64_LDST32_ABS_LO12_NC; 120 break; 121 case AArch64::fixup_a64_ldst64_lo12: 122 Type = ELF::R_AARCH64_LDST64_ABS_LO12_NC; 123 break; 124 case AArch64::fixup_a64_ldst128_lo12: 125 Type = ELF::R_AARCH64_LDST128_ABS_LO12_NC; 126 break; 127 case AArch64::fixup_a64_movw_uabs_g0: 128 Type = ELF::R_AARCH64_MOVW_UABS_G0; 129 break; 130 case AArch64::fixup_a64_movw_uabs_g0_nc: 131 Type = ELF::R_AARCH64_MOVW_UABS_G0_NC; 132 break; 133 case AArch64::fixup_a64_movw_uabs_g1: 134 Type = ELF::R_AARCH64_MOVW_UABS_G1; 135 break; 136 case AArch64::fixup_a64_movw_uabs_g1_nc: 137 Type = ELF::R_AARCH64_MOVW_UABS_G1_NC; 138 break; 139 case AArch64::fixup_a64_movw_uabs_g2: 140 Type = ELF::R_AARCH64_MOVW_UABS_G2; 141 break; 142 case AArch64::fixup_a64_movw_uabs_g2_nc: 143 Type = ELF::R_AARCH64_MOVW_UABS_G2_NC; 144 break; 145 case AArch64::fixup_a64_movw_uabs_g3: 146 Type = ELF::R_AARCH64_MOVW_UABS_G3; 147 break; 148 case AArch64::fixup_a64_movw_sabs_g0: 149 Type = ELF::R_AARCH64_MOVW_SABS_G0; 150 break; 151 case AArch64::fixup_a64_movw_sabs_g1: 152 Type = ELF::R_AARCH64_MOVW_SABS_G1; 153 break; 154 case AArch64::fixup_a64_movw_sabs_g2: 155 Type = ELF::R_AARCH64_MOVW_SABS_G2; 156 break; 157 158 // TLS Local-dynamic block 159 case AArch64::fixup_a64_movw_dtprel_g2: 160 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; 161 break; 162 case AArch64::fixup_a64_movw_dtprel_g1: 163 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1; 164 break; 165 case AArch64::fixup_a64_movw_dtprel_g1_nc: 166 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; 167 break; 168 case AArch64::fixup_a64_movw_dtprel_g0: 169 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0; 170 break; 171 case AArch64::fixup_a64_movw_dtprel_g0_nc: 172 Type = ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC; 173 break; 174 case AArch64::fixup_a64_add_dtprel_hi12: 175 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_HI12; 176 break; 177 case AArch64::fixup_a64_add_dtprel_lo12: 178 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12; 179 break; 180 case AArch64::fixup_a64_add_dtprel_lo12_nc: 181 Type = ELF::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC; 182 break; 183 case AArch64::fixup_a64_ldst8_dtprel_lo12: 184 Type = ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12; 185 break; 186 case AArch64::fixup_a64_ldst8_dtprel_lo12_nc: 187 Type = ELF::R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC; 188 break; 189 case AArch64::fixup_a64_ldst16_dtprel_lo12: 190 Type = ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12; 191 break; 192 case AArch64::fixup_a64_ldst16_dtprel_lo12_nc: 193 Type = ELF::R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC; 194 break; 195 case AArch64::fixup_a64_ldst32_dtprel_lo12: 196 Type = ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12; 197 break; 198 case AArch64::fixup_a64_ldst32_dtprel_lo12_nc: 199 Type = ELF::R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC; 200 break; 201 case AArch64::fixup_a64_ldst64_dtprel_lo12: 202 Type = ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12; 203 break; 204 case AArch64::fixup_a64_ldst64_dtprel_lo12_nc: 205 Type = ELF::R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC; 206 break; 207 208 // TLS initial-exec block 209 case AArch64::fixup_a64_movw_gottprel_g1: 210 Type = ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; 211 break; 212 case AArch64::fixup_a64_movw_gottprel_g0_nc: 213 Type = ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; 214 break; 215 case AArch64::fixup_a64_ld64_gottprel_lo12_nc: 216 Type = ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 217 break; 218 219 // TLS local-exec block 220 case AArch64::fixup_a64_movw_tprel_g2: 221 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; 222 break; 223 case AArch64::fixup_a64_movw_tprel_g1: 224 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1; 225 break; 226 case AArch64::fixup_a64_movw_tprel_g1_nc: 227 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; 228 break; 229 case AArch64::fixup_a64_movw_tprel_g0: 230 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0; 231 break; 232 case AArch64::fixup_a64_movw_tprel_g0_nc: 233 Type = ELF::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC; 234 break; 235 case AArch64::fixup_a64_add_tprel_hi12: 236 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_HI12; 237 break; 238 case AArch64::fixup_a64_add_tprel_lo12: 239 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12; 240 break; 241 case AArch64::fixup_a64_add_tprel_lo12_nc: 242 Type = ELF::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC; 243 break; 244 case AArch64::fixup_a64_ldst8_tprel_lo12: 245 Type = ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12; 246 break; 247 case AArch64::fixup_a64_ldst8_tprel_lo12_nc: 248 Type = ELF::R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC; 249 break; 250 case AArch64::fixup_a64_ldst16_tprel_lo12: 251 Type = ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12; 252 break; 253 case AArch64::fixup_a64_ldst16_tprel_lo12_nc: 254 Type = ELF::R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC; 255 break; 256 case AArch64::fixup_a64_ldst32_tprel_lo12: 257 Type = ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12; 258 break; 259 case AArch64::fixup_a64_ldst32_tprel_lo12_nc: 260 Type = ELF::R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC; 261 break; 262 case AArch64::fixup_a64_ldst64_tprel_lo12: 263 Type = ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12; 264 break; 265 case AArch64::fixup_a64_ldst64_tprel_lo12_nc: 266 Type = ELF::R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC; 267 break; 268 269 // TLS general-dynamic block 270 case AArch64::fixup_a64_tlsdesc_adr_page: 271 Type = ELF::R_AARCH64_TLSDESC_ADR_PAGE; 272 break; 273 case AArch64::fixup_a64_tlsdesc_ld64_lo12_nc: 274 Type = ELF::R_AARCH64_TLSDESC_LD64_LO12_NC; 275 break; 276 case AArch64::fixup_a64_tlsdesc_add_lo12_nc: 277 Type = ELF::R_AARCH64_TLSDESC_ADD_LO12_NC; 278 break; 279 case AArch64::fixup_a64_tlsdesc_call: 280 Type = ELF::R_AARCH64_TLSDESC_CALL; 281 break; 282 } 283 } 284 285 return Type; 286} 287 288MCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_ostream &OS, 289 uint8_t OSABI) { 290 MCELFObjectTargetWriter *MOTW = new AArch64ELFObjectWriter(OSABI); 291 return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true); 292} 293