1 //===-- ARMELFObjectWriter.cpp - ARM 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 #include "MCTargetDesc/ARMFixupKinds.h" 11 #include "MCTargetDesc/ARMMCTargetDesc.h" 12 #include "llvm/BinaryFormat/ELF.h" 13 #include "llvm/MC/MCContext.h" 14 #include "llvm/MC/MCELFObjectWriter.h" 15 #include "llvm/MC/MCExpr.h" 16 #include "llvm/MC/MCFixup.h" 17 #include "llvm/MC/MCObjectFileInfo.h" 18 #include "llvm/MC/MCObjectWriter.h" 19 #include "llvm/MC/MCValue.h" 20 #include "llvm/Support/ErrorHandling.h" 21 #include "llvm/Support/raw_ostream.h" 22 #include <cstdint> 23 24 using namespace llvm; 25 26 namespace { 27 28 class ARMELFObjectWriter : public MCELFObjectTargetWriter { 29 enum { DefaultEABIVersion = 0x05000000U }; 30 31 unsigned GetRelocTypeInner(const MCValue &Target, const MCFixup &Fixup, 32 bool IsPCRel, MCContext &Ctx) const; 33 34 public: 35 ARMELFObjectWriter(uint8_t OSABI); 36 37 ~ARMELFObjectWriter() override = default; 38 39 unsigned getRelocType(MCContext &Ctx, const MCValue &Target, 40 const MCFixup &Fixup, bool IsPCRel) const override; 41 42 bool needsRelocateWithSymbol(const MCSymbol &Sym, 43 unsigned Type) const override; 44 45 void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override; 46 }; 47 48 } // end anonymous namespace 49 50 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI) 51 : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI, 52 ELF::EM_ARM, 53 /*HasRelocationAddend*/ false) {} 54 55 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym, 56 unsigned Type) const { 57 // FIXME: This is extremely conservative. This really needs to use a 58 // whitelist with a clear explanation for why each realocation needs to 59 // point to the symbol, not to the section. 60 switch (Type) { 61 default: 62 return true; 63 64 case ELF::R_ARM_PREL31: 65 case ELF::R_ARM_ABS32: 66 return false; 67 } 68 } 69 70 // Need to examine the Fixup when determining whether to 71 // emit the relocation as an explicit symbol or as a section relative 72 // offset 73 unsigned ARMELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target, 74 const MCFixup &Fixup, 75 bool IsPCRel) const { 76 return GetRelocTypeInner(Target, Fixup, IsPCRel, Ctx); 77 } 78 79 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, 80 const MCFixup &Fixup, 81 bool IsPCRel, 82 MCContext &Ctx) const { 83 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 84 85 if (IsPCRel) { 86 switch ((unsigned)Fixup.getKind()) { 87 default: 88 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); 89 return ELF::R_ARM_NONE; 90 case FK_Data_4: 91 switch (Modifier) { 92 default: 93 llvm_unreachable("Unsupported Modifier"); 94 case MCSymbolRefExpr::VK_None: 95 return ELF::R_ARM_REL32; 96 case MCSymbolRefExpr::VK_GOTTPOFF: 97 return ELF::R_ARM_TLS_IE32; 98 case MCSymbolRefExpr::VK_ARM_GOT_PREL: 99 return ELF::R_ARM_GOT_PREL; 100 case MCSymbolRefExpr::VK_ARM_PREL31: 101 return ELF::R_ARM_PREL31; 102 } 103 case ARM::fixup_arm_blx: 104 case ARM::fixup_arm_uncondbl: 105 switch (Modifier) { 106 case MCSymbolRefExpr::VK_PLT: 107 return ELF::R_ARM_CALL; 108 case MCSymbolRefExpr::VK_TLSCALL: 109 return ELF::R_ARM_TLS_CALL; 110 default: 111 return ELF::R_ARM_CALL; 112 } 113 case ARM::fixup_arm_condbl: 114 case ARM::fixup_arm_condbranch: 115 case ARM::fixup_arm_uncondbranch: 116 return ELF::R_ARM_JUMP24; 117 case ARM::fixup_t2_condbranch: 118 return ELF::R_ARM_THM_JUMP19; 119 case ARM::fixup_t2_uncondbranch: 120 return ELF::R_ARM_THM_JUMP24; 121 case ARM::fixup_arm_movt_hi16: 122 return ELF::R_ARM_MOVT_PREL; 123 case ARM::fixup_arm_movw_lo16: 124 return ELF::R_ARM_MOVW_PREL_NC; 125 case ARM::fixup_t2_movt_hi16: 126 return ELF::R_ARM_THM_MOVT_PREL; 127 case ARM::fixup_t2_movw_lo16: 128 return ELF::R_ARM_THM_MOVW_PREL_NC; 129 case ARM::fixup_arm_thumb_br: 130 return ELF::R_ARM_THM_JUMP11; 131 case ARM::fixup_arm_thumb_bcc: 132 return ELF::R_ARM_THM_JUMP8; 133 case ARM::fixup_arm_thumb_bl: 134 case ARM::fixup_arm_thumb_blx: 135 switch (Modifier) { 136 case MCSymbolRefExpr::VK_TLSCALL: 137 return ELF::R_ARM_THM_TLS_CALL; 138 default: 139 return ELF::R_ARM_THM_CALL; 140 } 141 } 142 } 143 switch ((unsigned)Fixup.getKind()) { 144 default: 145 Ctx.reportFatalError(Fixup.getLoc(), "unsupported relocation on symbol"); 146 return ELF::R_ARM_NONE; 147 case FK_Data_1: 148 switch (Modifier) { 149 default: 150 llvm_unreachable("unsupported Modifier"); 151 case MCSymbolRefExpr::VK_None: 152 return ELF::R_ARM_ABS8; 153 } 154 case FK_Data_2: 155 switch (Modifier) { 156 default: 157 llvm_unreachable("unsupported modifier"); 158 case MCSymbolRefExpr::VK_None: 159 return ELF::R_ARM_ABS16; 160 } 161 case FK_Data_4: 162 switch (Modifier) { 163 default: 164 llvm_unreachable("Unsupported Modifier"); 165 case MCSymbolRefExpr::VK_ARM_NONE: 166 return ELF::R_ARM_NONE; 167 case MCSymbolRefExpr::VK_GOT: 168 return ELF::R_ARM_GOT_BREL; 169 case MCSymbolRefExpr::VK_TLSGD: 170 return ELF::R_ARM_TLS_GD32; 171 case MCSymbolRefExpr::VK_TPOFF: 172 return ELF::R_ARM_TLS_LE32; 173 case MCSymbolRefExpr::VK_GOTTPOFF: 174 return ELF::R_ARM_TLS_IE32; 175 case MCSymbolRefExpr::VK_None: 176 return ELF::R_ARM_ABS32; 177 case MCSymbolRefExpr::VK_GOTOFF: 178 return ELF::R_ARM_GOTOFF32; 179 case MCSymbolRefExpr::VK_ARM_GOT_PREL: 180 return ELF::R_ARM_GOT_PREL; 181 case MCSymbolRefExpr::VK_ARM_TARGET1: 182 return ELF::R_ARM_TARGET1; 183 case MCSymbolRefExpr::VK_ARM_TARGET2: 184 return ELF::R_ARM_TARGET2; 185 case MCSymbolRefExpr::VK_ARM_PREL31: 186 return ELF::R_ARM_PREL31; 187 case MCSymbolRefExpr::VK_ARM_SBREL: 188 return ELF::R_ARM_SBREL32; 189 case MCSymbolRefExpr::VK_ARM_TLSLDO: 190 return ELF::R_ARM_TLS_LDO32; 191 case MCSymbolRefExpr::VK_TLSCALL: 192 return ELF::R_ARM_TLS_CALL; 193 case MCSymbolRefExpr::VK_TLSDESC: 194 return ELF::R_ARM_TLS_GOTDESC; 195 case MCSymbolRefExpr::VK_TLSLDM: 196 return ELF::R_ARM_TLS_LDM32; 197 case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ: 198 return ELF::R_ARM_TLS_DESCSEQ; 199 } 200 case ARM::fixup_arm_condbranch: 201 case ARM::fixup_arm_uncondbranch: 202 return ELF::R_ARM_JUMP24; 203 case ARM::fixup_arm_movt_hi16: 204 switch (Modifier) { 205 default: 206 llvm_unreachable("Unsupported Modifier"); 207 case MCSymbolRefExpr::VK_None: 208 return ELF::R_ARM_MOVT_ABS; 209 case MCSymbolRefExpr::VK_ARM_SBREL: 210 return ELF::R_ARM_MOVT_BREL; 211 } 212 case ARM::fixup_arm_movw_lo16: 213 switch (Modifier) { 214 default: 215 llvm_unreachable("Unsupported Modifier"); 216 case MCSymbolRefExpr::VK_None: 217 return ELF::R_ARM_MOVW_ABS_NC; 218 case MCSymbolRefExpr::VK_ARM_SBREL: 219 return ELF::R_ARM_MOVW_BREL_NC; 220 } 221 case ARM::fixup_t2_movt_hi16: 222 switch (Modifier) { 223 default: 224 llvm_unreachable("Unsupported Modifier"); 225 case MCSymbolRefExpr::VK_None: 226 return ELF::R_ARM_THM_MOVT_ABS; 227 case MCSymbolRefExpr::VK_ARM_SBREL: 228 return ELF::R_ARM_THM_MOVT_BREL; 229 } 230 case ARM::fixup_t2_movw_lo16: 231 switch (Modifier) { 232 default: 233 llvm_unreachable("Unsupported Modifier"); 234 case MCSymbolRefExpr::VK_None: 235 return ELF::R_ARM_THM_MOVW_ABS_NC; 236 case MCSymbolRefExpr::VK_ARM_SBREL: 237 return ELF::R_ARM_THM_MOVW_BREL_NC; 238 } 239 } 240 } 241 242 void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx, 243 MCSectionELF &Sec) { 244 // The mix of execute-only and non-execute-only at link time is 245 // non-execute-only. To avoid the empty implicitly created .text 246 // section from making the whole .text section non-execute-only, we 247 // mark it execute-only if it is empty and there is at least one 248 // execute-only section in the object. 249 MCSectionELF *TextSection = 250 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection()); 251 if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() && 252 !TextSection->hasData()) { 253 TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE); 254 } 255 } 256 257 std::unique_ptr<MCObjectTargetWriter> 258 llvm::createARMELFObjectWriter(uint8_t OSABI) { 259 return llvm::make_unique<ARMELFObjectWriter>(OSABI); 260 } 261