1 //===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "MCTargetDesc/ARMFixupKinds.h" 10 #include "MCTargetDesc/ARMMCAsmInfo.h" 11 #include "MCTargetDesc/ARMMCTargetDesc.h" 12 #include "llvm/BinaryFormat/ELF.h" 13 #include "llvm/MC/MCAssembler.h" 14 #include "llvm/MC/MCContext.h" 15 #include "llvm/MC/MCELFObjectWriter.h" 16 #include "llvm/MC/MCExpr.h" 17 #include "llvm/MC/MCFixup.h" 18 #include "llvm/MC/MCObjectWriter.h" 19 #include "llvm/MC/MCValue.h" 20 #include "llvm/Object/ELF.h" 21 #include "llvm/Support/ErrorHandling.h" 22 #include <cstdint> 23 24 using namespace llvm; 25 26 namespace { 27 28 class ARMELFObjectWriter : public MCELFObjectTargetWriter { 29 enum { DefaultEABIVersion = 0x05000000U }; 30 31 public: 32 ARMELFObjectWriter(uint8_t OSABI); 33 34 ~ARMELFObjectWriter() override = default; 35 36 unsigned getRelocType(const MCFixup &, const MCValue &, 37 bool IsPCRel) const override; 38 39 bool needsRelocateWithSymbol(const MCValue &Val, 40 unsigned Type) const override; 41 }; 42 43 } // end anonymous namespace 44 45 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI) 46 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, 47 ELF::EM_ARM, 48 /*HasRelocationAddend*/ false) {} 49 50 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCValue &V, 51 unsigned Type) const { 52 // If the symbol is a thumb function the final relocation must set the lowest 53 // bit. With a symbol that is done by just having the symbol have that bit 54 // set, so we would lose the bit if we relocated with the section. 55 // We could use the section but add the bit to the relocation value. 56 if (Asm->isThumbFunc(V.getAddSym())) 57 return true; 58 59 // FIXME: This is extremely conservative. This really needs to use an 60 // explicit list with a clear explanation for why each realocation needs to 61 // point to the symbol, not to the section. 62 switch (Type) { 63 default: 64 return true; 65 66 case ELF::R_ARM_PREL31: 67 case ELF::R_ARM_ABS32: 68 return false; 69 } 70 } 71 72 // Need to examine the Fixup when determining whether to 73 // emit the relocation as an explicit symbol or as a section relative 74 // offset 75 unsigned ARMELFObjectWriter::getRelocType(const MCFixup &Fixup, 76 const MCValue &Target, 77 bool IsPCRel) const { 78 auto Kind = Fixup.getKind(); 79 uint8_t Specifier = Target.getSpecifier(); 80 auto CheckFDPIC = [&](uint32_t Type) { 81 if (getOSABI() != ELF::ELFOSABI_ARM_FDPIC) 82 reportError(Fixup.getLoc(), 83 "relocation " + 84 object::getELFRelocationTypeName(ELF::EM_ARM, Type) + 85 " only supported in FDPIC mode"); 86 return Type; 87 }; 88 89 switch (Specifier) { 90 case ARM::S_GOTTPOFF: 91 case ARM::S_GOTTPOFF_FDPIC: 92 case ARM::S_TLSCALL: 93 case ARM::S_TLSDESC: 94 case ARM::S_TLSGD: 95 case ARM::S_TLSGD_FDPIC: 96 case ARM::S_TLSLDM: 97 case ARM::S_TLSLDM_FDPIC: 98 case ARM::S_TLSLDO: 99 case ARM::S_TPOFF: 100 if (auto *SA = Target.getAddSym()) 101 cast<MCSymbolELF>(SA)->setType(ELF::STT_TLS); 102 break; 103 default: 104 break; 105 } 106 107 if (IsPCRel) { 108 switch (Fixup.getKind()) { 109 default: 110 reportError(Fixup.getLoc(), "unsupported relocation type"); 111 return ELF::R_ARM_NONE; 112 case FK_Data_4: 113 switch (Specifier) { 114 default: 115 reportError(Fixup.getLoc(), 116 "invalid fixup for 4-byte pc-relative data relocation"); 117 return ELF::R_ARM_NONE; 118 case ARM::S_None: { 119 if (const auto *SA = Target.getAddSym()) { 120 // For GNU AS compatibility expressions such as 121 // _GLOBAL_OFFSET_TABLE_ - label emit a R_ARM_BASE_PREL relocation. 122 if (SA->getName() == "_GLOBAL_OFFSET_TABLE_") 123 return ELF::R_ARM_BASE_PREL; 124 } 125 return ELF::R_ARM_REL32; 126 } 127 case ARM::S_GOTTPOFF: 128 return ELF::R_ARM_TLS_IE32; 129 case ARM::S_GOT_PREL: 130 return ELF::R_ARM_GOT_PREL; 131 case ARM::S_PREL31: 132 return ELF::R_ARM_PREL31; 133 } 134 case ARM::fixup_arm_blx: 135 case ARM::fixup_arm_uncondbl: 136 switch (Specifier) { 137 case ARM::S_PLT: 138 return ELF::R_ARM_CALL; 139 case ARM::S_TLSCALL: 140 return ELF::R_ARM_TLS_CALL; 141 default: 142 return ELF::R_ARM_CALL; 143 } 144 case ARM::fixup_arm_condbl: 145 case ARM::fixup_arm_condbranch: 146 case ARM::fixup_arm_uncondbranch: 147 return ELF::R_ARM_JUMP24; 148 case ARM::fixup_t2_condbranch: 149 return ELF::R_ARM_THM_JUMP19; 150 case ARM::fixup_t2_uncondbranch: 151 return ELF::R_ARM_THM_JUMP24; 152 case ARM::fixup_arm_movt_hi16: 153 return ELF::R_ARM_MOVT_PREL; 154 case ARM::fixup_arm_movw_lo16: 155 return ELF::R_ARM_MOVW_PREL_NC; 156 case ARM::fixup_t2_movt_hi16: 157 return ELF::R_ARM_THM_MOVT_PREL; 158 case ARM::fixup_t2_movw_lo16: 159 return ELF::R_ARM_THM_MOVW_PREL_NC; 160 case ARM::fixup_arm_thumb_upper_8_15: 161 return ELF::R_ARM_THM_ALU_ABS_G3; 162 case ARM::fixup_arm_thumb_upper_0_7: 163 return ELF::R_ARM_THM_ALU_ABS_G2_NC; 164 case ARM::fixup_arm_thumb_lower_8_15: 165 return ELF::R_ARM_THM_ALU_ABS_G1_NC; 166 case ARM::fixup_arm_thumb_lower_0_7: 167 return ELF::R_ARM_THM_ALU_ABS_G0_NC; 168 case ARM::fixup_arm_thumb_br: 169 return ELF::R_ARM_THM_JUMP11; 170 case ARM::fixup_arm_thumb_bcc: 171 return ELF::R_ARM_THM_JUMP8; 172 case ARM::fixup_arm_thumb_bl: 173 case ARM::fixup_arm_thumb_blx: 174 switch (Specifier) { 175 case ARM::S_TLSCALL: 176 return ELF::R_ARM_THM_TLS_CALL; 177 default: 178 return ELF::R_ARM_THM_CALL; 179 } 180 case ARM::fixup_arm_ldst_pcrel_12: 181 return ELF::R_ARM_LDR_PC_G0; 182 case ARM::fixup_arm_pcrel_10_unscaled: 183 return ELF::R_ARM_LDRS_PC_G0; 184 case ARM::fixup_t2_ldst_pcrel_12: 185 return ELF::R_ARM_THM_PC12; 186 case ARM::fixup_arm_adr_pcrel_12: 187 return ELF::R_ARM_ALU_PC_G0; 188 case ARM::fixup_thumb_adr_pcrel_10: 189 return ELF::R_ARM_THM_PC8; 190 case ARM::fixup_t2_adr_pcrel_12: 191 return ELF::R_ARM_THM_ALU_PREL_11_0; 192 case ARM::fixup_bf_target: 193 return ELF::R_ARM_THM_BF16; 194 case ARM::fixup_bfc_target: 195 return ELF::R_ARM_THM_BF12; 196 case ARM::fixup_bfl_target: 197 return ELF::R_ARM_THM_BF18; 198 } 199 } 200 switch (Kind) { 201 default: 202 reportError(Fixup.getLoc(), "unsupported relocation type"); 203 return ELF::R_ARM_NONE; 204 case FK_Data_1: 205 switch (Specifier) { 206 default: 207 reportError(Fixup.getLoc(), "invalid fixup for 1-byte data relocation"); 208 return ELF::R_ARM_NONE; 209 case ARM::S_None: 210 return ELF::R_ARM_ABS8; 211 } 212 case FK_Data_2: 213 switch (Specifier) { 214 default: 215 reportError(Fixup.getLoc(), "invalid fixup for 2-byte data relocation"); 216 return ELF::R_ARM_NONE; 217 case ARM::S_None: 218 return ELF::R_ARM_ABS16; 219 } 220 case FK_Data_4: 221 switch (Specifier) { 222 default: 223 reportError(Fixup.getLoc(), "invalid fixup for 4-byte data relocation"); 224 return ELF::R_ARM_NONE; 225 case ARM::S_ARM_NONE: 226 return ELF::R_ARM_NONE; 227 case ARM::S_GOT: 228 return ELF::R_ARM_GOT_BREL; 229 case ARM::S_TLSGD: 230 return ELF::R_ARM_TLS_GD32; 231 case ARM::S_TPOFF: 232 return ELF::R_ARM_TLS_LE32; 233 case ARM::S_GOTTPOFF: 234 return ELF::R_ARM_TLS_IE32; 235 case ARM::S_None: 236 return ELF::R_ARM_ABS32; 237 case ARM::S_GOTOFF: 238 return ELF::R_ARM_GOTOFF32; 239 case ARM::S_GOT_PREL: 240 return ELF::R_ARM_GOT_PREL; 241 case ARM::S_TARGET1: 242 return ELF::R_ARM_TARGET1; 243 case ARM::S_TARGET2: 244 return ELF::R_ARM_TARGET2; 245 case ARM::S_PREL31: 246 return ELF::R_ARM_PREL31; 247 case ARM::S_SBREL: 248 return ELF::R_ARM_SBREL32; 249 case ARM::S_TLSLDO: 250 return ELF::R_ARM_TLS_LDO32; 251 case ARM::S_TLSCALL: 252 return ELF::R_ARM_TLS_CALL; 253 case ARM::S_TLSDESC: 254 return ELF::R_ARM_TLS_GOTDESC; 255 case ARM::S_TLSLDM: 256 return ELF::R_ARM_TLS_LDM32; 257 case ARM::S_TLSDESCSEQ: 258 return ELF::R_ARM_TLS_DESCSEQ; 259 case ARM::S_FUNCDESC: 260 return CheckFDPIC(ELF::R_ARM_FUNCDESC); 261 case ARM::S_GOTFUNCDESC: 262 return CheckFDPIC(ELF::R_ARM_GOTFUNCDESC); 263 case ARM::S_GOTOFFFUNCDESC: 264 return CheckFDPIC(ELF::R_ARM_GOTOFFFUNCDESC); 265 case ARM::S_TLSGD_FDPIC: 266 return CheckFDPIC(ELF::R_ARM_TLS_GD32_FDPIC); 267 case ARM::S_TLSLDM_FDPIC: 268 return CheckFDPIC(ELF::R_ARM_TLS_LDM32_FDPIC); 269 case ARM::S_GOTTPOFF_FDPIC: 270 return CheckFDPIC(ELF::R_ARM_TLS_IE32_FDPIC); 271 } 272 case ARM::fixup_arm_condbranch: 273 case ARM::fixup_arm_uncondbranch: 274 return ELF::R_ARM_JUMP24; 275 case ARM::fixup_arm_movt_hi16: 276 switch (Specifier) { 277 default: 278 reportError(Fixup.getLoc(), "invalid fixup for ARM MOVT instruction"); 279 return ELF::R_ARM_NONE; 280 case ARM::S_None: 281 return ELF::R_ARM_MOVT_ABS; 282 case ARM::S_SBREL: 283 return ELF::R_ARM_MOVT_BREL; 284 } 285 case ARM::fixup_arm_movw_lo16: 286 switch (Specifier) { 287 default: 288 reportError(Fixup.getLoc(), "invalid fixup for ARM MOVW instruction"); 289 return ELF::R_ARM_NONE; 290 case ARM::S_None: 291 return ELF::R_ARM_MOVW_ABS_NC; 292 case ARM::S_SBREL: 293 return ELF::R_ARM_MOVW_BREL_NC; 294 } 295 case ARM::fixup_t2_movt_hi16: 296 switch (Specifier) { 297 default: 298 reportError(Fixup.getLoc(), "invalid fixup for Thumb MOVT instruction"); 299 return ELF::R_ARM_NONE; 300 case ARM::S_None: 301 return ELF::R_ARM_THM_MOVT_ABS; 302 case ARM::S_SBREL: 303 return ELF::R_ARM_THM_MOVT_BREL; 304 } 305 case ARM::fixup_t2_movw_lo16: 306 switch (Specifier) { 307 default: 308 reportError(Fixup.getLoc(), "invalid fixup for Thumb MOVW instruction"); 309 return ELF::R_ARM_NONE; 310 case ARM::S_None: 311 return ELF::R_ARM_THM_MOVW_ABS_NC; 312 case ARM::S_SBREL: 313 return ELF::R_ARM_THM_MOVW_BREL_NC; 314 } 315 316 case ARM::fixup_arm_thumb_upper_8_15: 317 return ELF::R_ARM_THM_ALU_ABS_G3; 318 case ARM::fixup_arm_thumb_upper_0_7: 319 return ELF::R_ARM_THM_ALU_ABS_G2_NC; 320 case ARM::fixup_arm_thumb_lower_8_15: 321 return ELF::R_ARM_THM_ALU_ABS_G1_NC; 322 case ARM::fixup_arm_thumb_lower_0_7: 323 return ELF::R_ARM_THM_ALU_ABS_G0_NC; 324 } 325 } 326 327 std::unique_ptr<MCObjectTargetWriter> 328 llvm::createARMELFObjectWriter(uint8_t OSABI) { 329 return std::make_unique<ARMELFObjectWriter>(OSABI); 330 } 331