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/MC/MCContext.h" 19 #include "llvm/MC/MCELFObjectWriter.h" 20 #include "llvm/MC/MCFixup.h" 21 #include "llvm/MC/MCValue.h" 22 #include "llvm/Support/ELF.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include <cassert> 25 #include <cstdint> 26 27 using namespace llvm; 28 29 namespace { 30 31 class AArch64ELFObjectWriter : public MCELFObjectTargetWriter { 32 public: 33 AArch64ELFObjectWriter(uint8_t OSABI, bool IsLittleEndian, bool IsILP32); 34 35 ~AArch64ELFObjectWriter() override = default; 36 37 protected: 38 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 39 const MCFixup &Fixup, bool IsPCRel) const override; 40 bool IsILP32; 41 }; 42 43 } // end anonymous namespace 44 45 AArch64ELFObjectWriter::AArch64ELFObjectWriter(uint8_t OSABI, 46 bool IsLittleEndian, 47 bool IsILP32) 48 : MCELFObjectTargetWriter(/*Is64Bit*/ true, OSABI, ELF::EM_AARCH64, 49 /*HasRelocationAddend*/ true), 50 IsILP32(IsILP32) {} 51 52 #define R_CLS(rtype) \ 53 IsILP32 ? ELF::R_AARCH64_P32_##rtype : ELF::R_AARCH64_##rtype 54 #define BAD_ILP32_MOV(lp64rtype) "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 ELF::R_AARCH64_NONE; 73 case AArch64MCExpr::VK_ABS_G2_NC: 74 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G2_NC)); 75 return ELF::R_AARCH64_NONE; 76 case AArch64MCExpr::VK_ABS_G1_S: 77 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_SABS_G1)); 78 return ELF::R_AARCH64_NONE; 79 case AArch64MCExpr::VK_ABS_G1_NC: 80 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(MOVW_UABS_G1_NC)); 81 return ELF::R_AARCH64_NONE; 82 case AArch64MCExpr::VK_DTPREL_G2: 83 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G2)); 84 return ELF::R_AARCH64_NONE; 85 case AArch64MCExpr::VK_DTPREL_G1_NC: 86 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLD_MOVW_DTPREL_G1_NC)); 87 return ELF::R_AARCH64_NONE; 88 case AArch64MCExpr::VK_TPREL_G2: 89 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G2)); 90 return ELF::R_AARCH64_NONE; 91 case AArch64MCExpr::VK_TPREL_G1_NC: 92 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSLE_MOVW_TPREL_G1_NC)); 93 return ELF::R_AARCH64_NONE; 94 case AArch64MCExpr::VK_GOTTPREL_G1: 95 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G1)); 96 return ELF::R_AARCH64_NONE; 97 case AArch64MCExpr::VK_GOTTPREL_G0_NC: 98 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(TLSIE_MOVW_GOTTPREL_G0_NC)); 99 return ELF::R_AARCH64_NONE; 100 default: return false; 101 } 102 return false; 103 } 104 105 unsigned AArch64ELFObjectWriter::getRelocType(MCContext &Ctx, 106 const MCValue &Target, 107 const MCFixup &Fixup, 108 bool IsPCRel) const { 109 AArch64MCExpr::VariantKind RefKind = 110 static_cast<AArch64MCExpr::VariantKind>(Target.getRefKind()); 111 AArch64MCExpr::VariantKind SymLoc = AArch64MCExpr::getSymbolLoc(RefKind); 112 bool IsNC = AArch64MCExpr::isNotChecked(RefKind); 113 114 assert((!Target.getSymA() || 115 Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None) && 116 "Should only be expression-level modifiers here"); 117 118 assert((!Target.getSymB() || 119 Target.getSymB()->getKind() == MCSymbolRefExpr::VK_None) && 120 "Should only be expression-level modifiers here"); 121 122 if (IsPCRel) { 123 switch ((unsigned)Fixup.getKind()) { 124 case FK_Data_1: 125 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 126 return ELF::R_AARCH64_NONE; 127 case FK_Data_2: 128 return R_CLS(PREL16); 129 case FK_Data_4: 130 return R_CLS(PREL32); 131 case FK_Data_8: 132 if (IsILP32) { 133 Ctx.reportError(Fixup.getLoc(), "ILP32 8 byte PC relative data " 134 "relocation not supported (LP64 eqv: PREL64)"); 135 return ELF::R_AARCH64_NONE; 136 } else 137 return ELF::R_AARCH64_PREL64; 138 case AArch64::fixup_aarch64_pcrel_adr_imm21: 139 assert(SymLoc == AArch64MCExpr::VK_NONE && "unexpected ADR relocation"); 140 return R_CLS(ADR_PREL_LO21); 141 case AArch64::fixup_aarch64_pcrel_adrp_imm21: 142 if (SymLoc == AArch64MCExpr::VK_ABS && !IsNC) 143 return R_CLS(ADR_PREL_PG_HI21); 144 if (SymLoc == AArch64MCExpr::VK_GOT && !IsNC) 145 return R_CLS(ADR_GOT_PAGE); 146 if (SymLoc == AArch64MCExpr::VK_GOTTPREL && !IsNC) 147 return R_CLS(TLSIE_ADR_GOTTPREL_PAGE21); 148 if (SymLoc == AArch64MCExpr::VK_TLSDESC && !IsNC) 149 return R_CLS(TLSDESC_ADR_PAGE21); 150 Ctx.reportError(Fixup.getLoc(), 151 "invalid symbol kind for ADRP relocation"); 152 return ELF::R_AARCH64_NONE; 153 case AArch64::fixup_aarch64_pcrel_branch26: 154 return R_CLS(JUMP26); 155 case AArch64::fixup_aarch64_pcrel_call26: 156 return R_CLS(CALL26); 157 case AArch64::fixup_aarch64_ldr_pcrel_imm19: 158 if (SymLoc == AArch64MCExpr::VK_GOTTPREL) 159 return R_CLS(TLSIE_LD_GOTTPREL_PREL19); 160 return R_CLS(LD_PREL_LO19); 161 case AArch64::fixup_aarch64_pcrel_branch14: 162 return R_CLS(TSTBR14); 163 case AArch64::fixup_aarch64_pcrel_branch19: 164 return R_CLS(CONDBR19); 165 default: 166 Ctx.reportError(Fixup.getLoc(), "Unsupported pc-relative fixup kind"); 167 return ELF::R_AARCH64_NONE; 168 } 169 } else { 170 if (IsILP32 && isNonILP32reloc(Fixup, RefKind, Ctx)) 171 return ELF::R_AARCH64_NONE; 172 switch ((unsigned)Fixup.getKind()) { 173 case FK_Data_1: 174 Ctx.reportError(Fixup.getLoc(), "1-byte data relocations not supported"); 175 return ELF::R_AARCH64_NONE; 176 case FK_Data_2: 177 return R_CLS(ABS16); 178 case FK_Data_4: 179 return R_CLS(ABS32); 180 case FK_Data_8: 181 if (IsILP32) { 182 Ctx.reportError(Fixup.getLoc(), BAD_ILP32_MOV(ABS64)); 183 return ELF::R_AARCH64_NONE; 184 } else 185 return ELF::R_AARCH64_ABS64; 186 case AArch64::fixup_aarch64_add_imm12: 187 if (RefKind == AArch64MCExpr::VK_DTPREL_HI12) 188 return R_CLS(TLSLD_ADD_DTPREL_HI12); 189 if (RefKind == AArch64MCExpr::VK_TPREL_HI12) 190 return R_CLS(TLSLE_ADD_TPREL_HI12); 191 if (RefKind == AArch64MCExpr::VK_DTPREL_LO12_NC) 192 return R_CLS(TLSLD_ADD_DTPREL_LO12_NC); 193 if (RefKind == AArch64MCExpr::VK_DTPREL_LO12) 194 return R_CLS(TLSLD_ADD_DTPREL_LO12); 195 if (RefKind == AArch64MCExpr::VK_TPREL_LO12_NC) 196 return R_CLS(TLSLE_ADD_TPREL_LO12_NC); 197 if (RefKind == AArch64MCExpr::VK_TPREL_LO12) 198 return R_CLS(TLSLE_ADD_TPREL_LO12); 199 if (RefKind == AArch64MCExpr::VK_TLSDESC_LO12) 200 return R_CLS(TLSDESC_ADD_LO12_NC); 201 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 202 return R_CLS(ADD_ABS_LO12_NC); 203 204 Ctx.reportError(Fixup.getLoc(), 205 "invalid fixup for add (uimm12) instruction"); 206 return ELF::R_AARCH64_NONE; 207 case AArch64::fixup_aarch64_ldst_imm12_scale1: 208 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 209 return R_CLS(LDST8_ABS_LO12_NC); 210 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 211 return R_CLS(TLSLD_LDST8_DTPREL_LO12); 212 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 213 return R_CLS(TLSLD_LDST8_DTPREL_LO12_NC); 214 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 215 return R_CLS(TLSLE_LDST8_TPREL_LO12); 216 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 217 return R_CLS(TLSLE_LDST8_TPREL_LO12_NC); 218 219 Ctx.reportError(Fixup.getLoc(), 220 "invalid fixup for 8-bit load/store instruction"); 221 return ELF::R_AARCH64_NONE; 222 case AArch64::fixup_aarch64_ldst_imm12_scale2: 223 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 224 return R_CLS(LDST16_ABS_LO12_NC); 225 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 226 return R_CLS(TLSLD_LDST16_DTPREL_LO12); 227 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 228 return R_CLS(TLSLD_LDST16_DTPREL_LO12_NC); 229 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 230 return R_CLS(TLSLE_LDST16_TPREL_LO12); 231 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 232 return R_CLS(TLSLE_LDST16_TPREL_LO12_NC); 233 234 Ctx.reportError(Fixup.getLoc(), 235 "invalid fixup for 16-bit load/store instruction"); 236 return ELF::R_AARCH64_NONE; 237 case AArch64::fixup_aarch64_ldst_imm12_scale4: 238 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 239 return R_CLS(LDST32_ABS_LO12_NC); 240 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 241 return R_CLS(TLSLD_LDST32_DTPREL_LO12); 242 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 243 return R_CLS(TLSLD_LDST32_DTPREL_LO12_NC); 244 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 245 return R_CLS(TLSLE_LDST32_TPREL_LO12); 246 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 247 return R_CLS(TLSLE_LDST32_TPREL_LO12_NC); 248 249 Ctx.reportError(Fixup.getLoc(), 250 "invalid fixup for 32-bit load/store instruction"); 251 return ELF::R_AARCH64_NONE; 252 case AArch64::fixup_aarch64_ldst_imm12_scale8: 253 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 254 return R_CLS(LDST64_ABS_LO12_NC); 255 if (SymLoc == AArch64MCExpr::VK_GOT && IsNC) 256 return R_CLS(LD64_GOT_LO12_NC); 257 if (SymLoc == AArch64MCExpr::VK_DTPREL && !IsNC) 258 return R_CLS(TLSLD_LDST64_DTPREL_LO12); 259 if (SymLoc == AArch64MCExpr::VK_DTPREL && IsNC) 260 return R_CLS(TLSLD_LDST64_DTPREL_LO12_NC); 261 if (SymLoc == AArch64MCExpr::VK_TPREL && !IsNC) 262 return R_CLS(TLSLE_LDST64_TPREL_LO12); 263 if (SymLoc == AArch64MCExpr::VK_TPREL && IsNC) 264 return R_CLS(TLSLE_LDST64_TPREL_LO12_NC); 265 if (SymLoc == AArch64MCExpr::VK_GOTTPREL && IsNC) 266 return IsILP32 ? ELF::R_AARCH64_P32_TLSIE_LD32_GOTTPREL_LO12_NC 267 : ELF::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC; 268 if (SymLoc == AArch64MCExpr::VK_TLSDESC && IsNC) 269 return IsILP32 ? ELF::R_AARCH64_P32_TLSDESC_LD32_LO12_NC 270 : ELF::R_AARCH64_TLSDESC_LD64_LO12_NC; 271 272 Ctx.reportError(Fixup.getLoc(), 273 "invalid fixup for 64-bit load/store instruction"); 274 return ELF::R_AARCH64_NONE; 275 case AArch64::fixup_aarch64_ldst_imm12_scale16: 276 if (SymLoc == AArch64MCExpr::VK_ABS && IsNC) 277 return R_CLS(LDST128_ABS_LO12_NC); 278 279 Ctx.reportError(Fixup.getLoc(), 280 "invalid fixup for 128-bit load/store instruction"); 281 return ELF::R_AARCH64_NONE; 282 // ILP32 case not reached here, tested with isNonILP32reloc 283 case AArch64::fixup_aarch64_movw: 284 if (RefKind == AArch64MCExpr::VK_ABS_G3) 285 return ELF::R_AARCH64_MOVW_UABS_G3; 286 if (RefKind == AArch64MCExpr::VK_ABS_G2) 287 return ELF::R_AARCH64_MOVW_UABS_G2; 288 if (RefKind == AArch64MCExpr::VK_ABS_G2_S) 289 return ELF::R_AARCH64_MOVW_SABS_G2; 290 if (RefKind == AArch64MCExpr::VK_ABS_G2_NC) 291 return ELF::R_AARCH64_MOVW_UABS_G2_NC; 292 if (RefKind == AArch64MCExpr::VK_ABS_G1) 293 return R_CLS(MOVW_UABS_G1); 294 if (RefKind == AArch64MCExpr::VK_ABS_G1_S) 295 return ELF::R_AARCH64_MOVW_SABS_G1; 296 if (RefKind == AArch64MCExpr::VK_ABS_G1_NC) 297 return ELF::R_AARCH64_MOVW_UABS_G1_NC; 298 if (RefKind == AArch64MCExpr::VK_ABS_G0) 299 return R_CLS(MOVW_UABS_G0); 300 if (RefKind == AArch64MCExpr::VK_ABS_G0_S) 301 return R_CLS(MOVW_SABS_G0); 302 if (RefKind == AArch64MCExpr::VK_ABS_G0_NC) 303 return R_CLS(MOVW_UABS_G0_NC); 304 if (RefKind == AArch64MCExpr::VK_DTPREL_G2) 305 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G2; 306 if (RefKind == AArch64MCExpr::VK_DTPREL_G1) 307 return R_CLS(TLSLD_MOVW_DTPREL_G1); 308 if (RefKind == AArch64MCExpr::VK_DTPREL_G1_NC) 309 return ELF::R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC; 310 if (RefKind == AArch64MCExpr::VK_DTPREL_G0) 311 return R_CLS(TLSLD_MOVW_DTPREL_G0); 312 if (RefKind == AArch64MCExpr::VK_DTPREL_G0_NC) 313 return R_CLS(TLSLD_MOVW_DTPREL_G0_NC); 314 if (RefKind == AArch64MCExpr::VK_TPREL_G2) 315 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G2; 316 if (RefKind == AArch64MCExpr::VK_TPREL_G1) 317 return R_CLS(TLSLE_MOVW_TPREL_G1); 318 if (RefKind == AArch64MCExpr::VK_TPREL_G1_NC) 319 return ELF::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC; 320 if (RefKind == AArch64MCExpr::VK_TPREL_G0) 321 return R_CLS(TLSLE_MOVW_TPREL_G0); 322 if (RefKind == AArch64MCExpr::VK_TPREL_G0_NC) 323 return R_CLS(TLSLE_MOVW_TPREL_G0_NC); 324 if (RefKind == AArch64MCExpr::VK_GOTTPREL_G1) 325 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G1; 326 if (RefKind == AArch64MCExpr::VK_GOTTPREL_G0_NC) 327 return ELF::R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC; 328 Ctx.reportError(Fixup.getLoc(), 329 "invalid fixup for movz/movk instruction"); 330 return ELF::R_AARCH64_NONE; 331 case AArch64::fixup_aarch64_tlsdesc_call: 332 return R_CLS(TLSDESC_CALL); 333 default: 334 Ctx.reportError(Fixup.getLoc(), "Unknown ELF relocation type"); 335 return ELF::R_AARCH64_NONE; 336 } 337 } 338 339 llvm_unreachable("Unimplemented fixup -> relocation"); 340 } 341 342 MCObjectWriter *llvm::createAArch64ELFObjectWriter(raw_pwrite_stream &OS, 343 uint8_t OSABI, 344 bool IsLittleEndian, 345 bool IsILP32) { 346 MCELFObjectTargetWriter *MOTW = 347 new AArch64ELFObjectWriter(OSABI, IsLittleEndian, IsILP32); 348 return createELFObjectWriter(MOTW, OS, IsLittleEndian); 349 } 350