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/AArch64MCExpr.h" 17 #include "MCTargetDesc/AArch64MCTargetDesc.h" 18 #include "llvm/BinaryFormat/ELF.h" 19 #include "llvm/MC/MCContext.h" 20 #include "llvm/MC/MCELFObjectWriter.h" 21 #include "llvm/MC/MCFixup.h" 22 #include "llvm/MC/MCObjectWriter.h" 23 #include "llvm/MC/MCValue.h" 24 #include "llvm/Support/ErrorHandling.h" 25 #include <cassert> 26 #include <cstdint> 27 28 using namespace llvm; 29 30 namespace { 31 32 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter { 33 public: 34 AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32); 35 36 ~AArch64ELFObjectWriter() override = default; 37 38 protected: 39 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 40 const MCFixup &Fixup, bool IsPCRel) const override; 41 bool IsILP32; 42 }; 43 44 } // end anonymous namespace 45 46 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) 47 : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64, 48 /*HasRelocationAddend*/ true), 49 IsILP32(IsILP32) {} 50 51 #define R_CLS(rtype) \ 52 IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype 53 #define BAD_ILP32_MOV(lp64rtype) \ 54 "ILP32 absolute MOV relocation not " \ 55 "supported (LP64 eqv: " #lp64rtype ")" 56 57 // assumes IsILP32 is true 58 static bool isNonILP32reloc(const MCFixup &Fixup, 59 AArch64MCExpr::VariantKind RefKind, 60 MCContext &Ctx) { 61 if ((unsigned)Fixup.getKind() != AArch64::fixup_aarch64_movw) 62 return false; 63 switch (RefKind) { 64 case AArch64MCExpr::VK_ABS_G3: 65 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G3)); 66 return true; 67 case AArch64MCExpr::VK_ABS_G2: 68 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2)); 69 return true; 70 case AArch64MCExpr::VK_ABS_G2_S: 71 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G2)); 72 return true; 73 case AArch64MCExpr::VK_ABS_G2_NC: 74 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC)); 75 return true; 76 case AArch64MCExpr::VK_ABS_G1_S: 77 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1)); 78 return true; 79 case AArch64MCExpr::VK_ABS_G1_NC: 80 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC)); 81 return true; 82 case AArch64MCExpr::VK_DTPREL_G2: 83 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2)); 84 return true; 85 case AArch64MCExpr::VK_DTPREL_G1_NC: 86 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC)); 87 return true; 88 case AArch64MCExpr::VK_TPREL_G2: 89 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2)); 90 return true; 91 case AArch64MCExpr::VK_TPREL_G1_NC: 92 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC)); 93 return true; 94 case AArch64MCExpr::VK_GOTTPREL_G1: 95 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1)); 96 return true; 97 case AArch64MCExpr::VK_GOTTPREL_G0_NC: 98 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC)); 99 return true; 100 default: 101 return false; 102 } 103 return false; 104 } 105 106 unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, 107 const MCValue &Target, 108 const MCFixup &Fixup, 109 bool IsPCRel) const { 110 AArch64MCExpr::VariantKind RefKind = 111 static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind()); 112 AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); 113 bool IsNC = AArch64MCExpr::isNotChecked(RefKind); 114 115 assert((!Target.getSymA() || 116 Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && 117 "Should only be expression-level modifiers here"); 118 119 assert((!Target.getSymB() || 120 Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) && 121 "Should only be expression-level modifiers here"); 122 123 if (IsPCRel) { 124 switch ((unsigned)Fixup.getKind()) { 125 case FK_Data_1: 126 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 127 return ELF::R_AARCH64_NONE; 128 case FK_Data_2: 129 return R_CLS(PREL16); 130 case FK_Data_4: 131 return R_CLS(PREL32); 132 case FK_Data_8: 133 if (IsILP32) { 134 Ctx.reportError(Fixup.getLoc(), 135 "ILP32 8 byte PC relative data " 136 "relocation not supported (LP64 eqv: PREL64)"); 137 return ELF::R_AARCH64_NONE; 138 } else 139 return ELF::R_AARCH64_PREL64; 140 case AArch64::fixup_aarch64_pcrel_adr_imm21: 141 if (SymLoc != AArch64MCExpr::VK_ABS) 142 Ctx.reportError(Fixup.getLoc(), 143 "invalid symbol kind for ADR relocation"); 144 return R_CLS(ADR_PREL_LO21); 145 case AArch64::fixup_aarch64_pcrel_adrp_imm21: 146 if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC) 147 return R_CLS(ADR_PREL_PG_HI21); 148 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) { 149 if (IsILP32) { 150 Ctx.reportError(Fixup.getLoc(), 151 "invalid fixup for 32-bit pcrel ADRP instruction " 152 "VK_ABS VK_NC"); 153 return ELF::R_AARCH64_NONE; 154 } else { 155 return ELF::R_AARCH64_ADR_PREL_PG_HI21_NC; 156 } 157 } 158 if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) 159 return R_CLS(ADR_GOT_PAGE); 160 if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC) 161 return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21); 162 if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) 163 return R_CLS(TLSDESC_ADR_PAGE21); 164 Ctx.reportError(Fixup.getLoc(), 165 "invalid symbol kind for ADRP relocation"); 166 return ELF::R_AARCH64_NONE; 167 case AArch64::fixup_aarch64_pcrel_branch26: 168 return R_CLS(JUMP26); 169 case AArch64::fixup_aarch64_pcrel_call26: 170 return R_CLS(CALL26); 171 case AArch64::fixup_aarch64_ldr_pcrel_imm19: 172 if (SymLoc == AArch64MCExpr::VK_GOTTPREL) 173 return R_CLS(TLSIE_LD_GOTTPREL_PREL19); 174 if (SymLoc == AArch64MCExpr::VK_GOT) 175 return R_CLS(GOT_LD_PREL19); 176 return R_CLS(LD_PREL_LO19); 177 case AArch64::fixup_aarch64_pcrel_branch14: 178 return R_CLS(TSTBR14); 179 case AArch64::fixup_aarch64_pcrel_branch19: 180 return R_CLS(CONDBR19); 181 default: 182 Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind"); 183 return ELF::R_AARCH64_NONE; 184 } 185 } else { 186 if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx)) 187 return ELF::R_AARCH64_NONE; 188 switch ((unsigned)Fixup.getKind()) { 189 case FK_Data_1: 190 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 191 return ELF::R_AARCH64_NONE; 192 case FK_Data_2: 193 return R_CLS(ABS16); 194 case FK_Data_4: 195 return R_CLS(ABS32); 196 case FK_Data_8: 197 if (IsILP32) { 198 Ctx.reportError(Fixup.getLoc(), 199 "ILP32 8 byte absolute data " 200 "relocation not supported (LP64 eqv: ABS64)"); 201 return ELF::R_AARCH64_NONE; 202 } else 203 return ELF::R_AARCH64_ABS64; 204 case AArch64::fixup_aarch64_add_imm12: 205 if (RefKind == AArch64MCExpr::VK_DTPREL_HI12) 206 return R_CLS(TLSLD_ADD_DTPREL_HI12); 207 if (RefKind == AArch64MCExpr::VK_TPREL_HI12) 208 return R_CLS(TLSLE_ADD_TPREL_HI12); 209 if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC) 210 return R_CLS(TLSLD_ADD_DTPREL_LO12_NC); 211 if (RefKind == AArch64MCExpr::VK_DTPREL_LO12) 212 return R_CLS(TLSLD_ADD_DTPREL_LO12); 213 if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC) 214 return R_CLS(TLSLE_ADD_TPREL_LO12_NC); 215 if (RefKind == AArch64MCExpr::VK_TPREL_LO12) 216 return R_CLS(TLSLE_ADD_TPREL_LO12); 217 if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12) 218 return R_CLS(TLSDESC_ADD_LO12); 219 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 220 return R_CLS(ADD_ABS_LO12_NC); 221 222 Ctx.reportError(Fixup.getLoc(), 223 "invalid fixup for add (uimm12) instruction"); 224 return ELF::R_AARCH64_NONE; 225 case AArch64::fixup_aarch64_ldst_imm12_scale1: 226 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 227 return R_CLS(LDST8_ABS_LO12_NC); 228 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 229 return R_CLS(TLSLD_LDST8_DTPREL_LO12); 230 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 231 return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC); 232 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 233 return R_CLS(TLSLE_LDST8_TPREL_LO12); 234 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 235 return R_CLS(TLSLE_LDST8_TPREL_LO12_NC); 236 237 Ctx.reportError(Fixup.getLoc(), 238 "invalid fixup for 8-bit load/store instruction"); 239 return ELF::R_AARCH64_NONE; 240 case AArch64::fixup_aarch64_ldst_imm12_scale2: 241 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 242 return R_CLS(LDST16_ABS_LO12_NC); 243 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 244 return R_CLS(TLSLD_LDST16_DTPREL_LO12); 245 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 246 return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC); 247 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 248 return R_CLS(TLSLE_LDST16_TPREL_LO12); 249 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 250 return R_CLS(TLSLE_LDST16_TPREL_LO12_NC); 251 252 Ctx.reportError(Fixup.getLoc(), 253 "invalid fixup for 16-bit load/store instruction"); 254 return ELF::R_AARCH64_NONE; 255 case AArch64::fixup_aarch64_ldst_imm12_scale4: 256 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 257 return R_CLS(LDST32_ABS_LO12_NC); 258 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 259 return R_CLS(TLSLD_LDST32_DTPREL_LO12); 260 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 261 return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC); 262 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 263 return R_CLS(TLSLE_LDST32_TPREL_LO12); 264 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 265 return R_CLS(TLSLE_LDST32_TPREL_LO12_NC); 266 if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) { 267 if (IsILP32) { 268 return ELF::R_AARCH64_P32_LD32_GOT_LO12_NC; 269 } else { 270 Ctx.reportError(Fixup.getLoc(), 271 "LP64 4 byte unchecked GOT load/store relocation " 272 "not supported (ILP32 eqv: LD32_GOT_LO12_NC"); 273 return ELF::R_AARCH64_NONE; 274 } 275 } 276 if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) { 277 if (IsILP32) { 278 Ctx.reportError(Fixup.getLoc(), 279 "ILP32 4 byte checked GOT load/store relocation " 280 "not supported (unchecked eqv: LD32_GOT_LO12_NC)"); 281 } else { 282 Ctx.reportError(Fixup.getLoc(), 283 "LP64 4 byte checked GOT load/store relocation " 284 "not supported (unchecked/ILP32 eqv: " 285 "LD32_GOT_LO12_NC)"); 286 } 287 return ELF::R_AARCH64_NONE; 288 } 289 if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) { 290 if (IsILP32) { 291 return ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC; 292 } else { 293 Ctx.reportError(Fixup.getLoc(), 294 "LP64 32-bit load/store " 295 "relocation not supported (ILP32 eqv: " 296 "TLSIE_LD32_GOTTPREL_LO12_NC)"); 297 return ELF::R_AARCH64_NONE; 298 } 299 } 300 if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) { 301 if (IsILP32) { 302 return ELF::R_AARCH64_P32_TLSDESC_LD32_LO12; 303 } else { 304 Ctx.reportError(Fixup.getLoc(), 305 "LP64 4 byte TLSDESC load/store relocation " 306 "not supported (ILP32 eqv: TLSDESC_LD64_LO12)"); 307 return ELF::R_AARCH64_NONE; 308 } 309 } 310 311 Ctx.reportError(Fixup.getLoc(), 312 "invalid fixup for 32-bit load/store instruction " 313 "fixup_aarch64_ldst_imm12_scale4"); 314 return ELF::R_AARCH64_NONE; 315 case AArch64::fixup_aarch64_ldst_imm12_scale8: 316 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 317 return R_CLS(LDST64_ABS_LO12_NC); 318 if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) { 319 if (!IsILP32) { 320 return ELF::R_AARCH64_LD64_GOT_LO12_NC; 321 } else { 322 Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " 323 "relocation not supported (LP64 eqv: " 324 "LD64_GOT_LO12_NC)"); 325 return ELF::R_AARCH64_NONE; 326 } 327 } 328 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 329 return R_CLS(TLSLD_LDST64_DTPREL_LO12); 330 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 331 return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC); 332 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 333 return R_CLS(TLSLE_LDST64_TPREL_LO12); 334 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 335 return R_CLS(TLSLE_LDST64_TPREL_LO12_NC); 336 if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) { 337 if (!IsILP32) { 338 return ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 339 } else { 340 Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " 341 "relocation not supported (LP64 eqv: " 342 "TLSIE_LD64_GOTTPREL_LO12_NC)"); 343 return ELF::R_AARCH64_NONE; 344 } 345 } 346 if (SymLoc == AArch64MCExpr::VK_TLSDESC) { 347 if (!IsILP32) { 348 return ELF::R_AARCH64_TLSDESC_LD64_LO12; 349 } else { 350 Ctx.reportError(Fixup.getLoc(), "ILP32 64-bit load/store " 351 "relocation not supported (LP64 eqv: " 352 "TLSDESC_LD64_LO12)"); 353 return ELF::R_AARCH64_NONE; 354 } 355 } 356 Ctx.reportError(Fixup.getLoc(), 357 "invalid fixup for 64-bit load/store instruction"); 358 return ELF::R_AARCH64_NONE; 359 case AArch64::fixup_aarch64_ldst_imm12_scale16: 360 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 361 return R_CLS(LDST128_ABS_LO12_NC); 362 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 363 return R_CLS(TLSLD_LDST128_DTPREL_LO12); 364 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 365 return R_CLS(TLSLD_LDST128_DTPREL_LO12_NC); 366 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 367 return R_CLS(TLSLE_LDST128_TPREL_LO12); 368 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 369 return R_CLS(TLSLE_LDST128_TPREL_LO12_NC); 370 371 Ctx.reportError(Fixup.getLoc(), 372 "invalid fixup for 128-bit load/store instruction"); 373 return ELF::R_AARCH64_NONE; 374 // ILP32 case not reached here, tested with isNonILP32reloc 375 case AArch64::fixup_aarch64_movw: 376 if (RefKind == AArch64MCExpr::VK_ABS_G3) 377 return ELF::R_AARCH64_MOVW_UABS_G3; 378 if (RefKind == AArch64MCExpr::VK_ABS_G2) 379 return ELF::R_AARCH64_MOVW_UABS_G2; 380 if (RefKind == AArch64MCExpr::VK_ABS_G2_S) 381 return ELF::R_AARCH64_MOVW_SABS_G2; 382 if (RefKind == AArch64MCExpr::VK_ABS_G2_NC) 383 return ELF::R_AARCH64_MOVW_UABS_G2_NC; 384 if (RefKind == AArch64MCExpr::VK_ABS_G1) 385 return R_CLS(MOVW_UABS_G1); 386 if (RefKind == AArch64MCExpr::VK_ABS_G1_S) 387 return ELF::R_AARCH64_MOVW_SABS_G1; 388 if (RefKind == AArch64MCExpr::VK_ABS_G1_NC) 389 return ELF::R_AARCH64_MOVW_UABS_G1_NC; 390 if (RefKind == AArch64MCExpr::VK_ABS_G0) 391 return R_CLS(MOVW_UABS_G0); 392 if (RefKind == AArch64MCExpr::VK_ABS_G0_S) 393 return R_CLS(MOVW_SABS_G0); 394 if (RefKind == AArch64MCExpr::VK_ABS_G0_NC) 395 return R_CLS(MOVW_UABS_G0_NC); 396 if (RefKind == AArch64MCExpr::VK_DTPREL_G2) 397 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; 398 if (RefKind == AArch64MCExpr::VK_DTPREL_G1) 399 return R_CLS(TLSLD_MOVW_DTPREL_G1); 400 if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC) 401 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; 402 if (RefKind == AArch64MCExpr::VK_DTPREL_G0) 403 return R_CLS(TLSLD_MOVW_DTPREL_G0); 404 if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC) 405 return R_CLS(TLSLD_MOVW_DTPREL_G0_NC); 406 if (RefKind == AArch64MCExpr::VK_TPREL_G2) 407 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; 408 if (RefKind == AArch64MCExpr::VK_TPREL_G1) 409 return R_CLS(TLSLE_MOVW_TPREL_G1); 410 if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC) 411 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; 412 if (RefKind == AArch64MCExpr::VK_TPREL_G0) 413 return R_CLS(TLSLE_MOVW_TPREL_G0); 414 if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC) 415 return R_CLS(TLSLE_MOVW_TPREL_G0_NC); 416 if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1) 417 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; 418 if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC) 419 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; 420 Ctx.reportError(Fixup.getLoc(), 421 "invalid fixup for movz/movk instruction"); 422 return ELF::R_AARCH64_NONE; 423 case AArch64::fixup_aarch64_tlsdesc_call: 424 return R_CLS(TLSDESC_CALL); 425 default: 426 Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); 427 return ELF::R_AARCH64_NONE; 428 } 429 } 430 431 llvm_unreachable("Unimplemented fixup -> relocation"); 432 } 433 434 std::unique_ptr<MCObjectTargetWriter> 435 llvm::createAArch64ELFObjectWriter(uint8_t OSABI, bool IsILP32) { 436 return llvm::make_unique<AArch64ELFObjectWriter>(OSABI, IsILP32); 437 } 438