1 //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===// 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 assembles .s files and emits ARM ELF .o object files. Different 11 // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to 12 // delimit regions of data and code. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "ARMRegisterInfo.h" 17 #include "ARMUnwindOp.h" 18 #include "ARMUnwindOpAsm.h" 19 #include "llvm/ADT/SmallPtrSet.h" 20 #include "llvm/ADT/Twine.h" 21 #include "llvm/MC/MCAsmBackend.h" 22 #include "llvm/MC/MCAssembler.h" 23 #include "llvm/MC/MCCodeEmitter.h" 24 #include "llvm/MC/MCContext.h" 25 #include "llvm/MC/MCELF.h" 26 #include "llvm/MC/MCELFStreamer.h" 27 #include "llvm/MC/MCELFSymbolFlags.h" 28 #include "llvm/MC/MCExpr.h" 29 #include "llvm/MC/MCInst.h" 30 #include "llvm/MC/MCObjectStreamer.h" 31 #include "llvm/MC/MCRegisterInfo.h" 32 #include "llvm/MC/MCSection.h" 33 #include "llvm/MC/MCSectionELF.h" 34 #include "llvm/MC/MCStreamer.h" 35 #include "llvm/MC/MCSymbol.h" 36 #include "llvm/MC/MCValue.h" 37 #include "llvm/Support/Debug.h" 38 #include "llvm/Support/ELF.h" 39 #include "llvm/Support/raw_ostream.h" 40 41 using namespace llvm; 42 43 static std::string GetAEABIUnwindPersonalityName(unsigned Index) { 44 assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index"); 45 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 46 } 47 48 namespace { 49 50 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at 51 /// the appropriate points in the object files. These symbols are defined in the 52 /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 53 /// 54 /// In brief: $a, $t or $d should be emitted at the start of each contiguous 55 /// region of ARM code, Thumb code or data in a section. In practice, this 56 /// emission does not rely on explicit assembler directives but on inherent 57 /// properties of the directives doing the emission (e.g. ".byte" is data, "add 58 /// r0, r0, r0" an instruction). 59 /// 60 /// As a result this system is orthogonal to the DataRegion infrastructure used 61 /// by MachO. Beware! 62 class ARMELFStreamer : public MCELFStreamer { 63 public: 64 ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, 65 MCCodeEmitter *Emitter, bool IsThumb) 66 : MCELFStreamer(SK_ARMELFStreamer, Context, TAB, OS, Emitter), 67 IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) { 68 Reset(); 69 } 70 71 ~ARMELFStreamer() {} 72 73 // ARM exception handling directives 74 virtual void EmitFnStart(); 75 virtual void EmitFnEnd(); 76 virtual void EmitCantUnwind(); 77 virtual void EmitPersonality(const MCSymbol *Per); 78 virtual void EmitHandlerData(); 79 virtual void EmitSetFP(unsigned NewFpReg, 80 unsigned NewSpReg, 81 int64_t Offset = 0); 82 virtual void EmitPad(int64_t Offset); 83 virtual void EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 84 bool isVector); 85 86 virtual void ChangeSection(const MCSection *Section, 87 const MCExpr *Subsection) { 88 // We have to keep track of the mapping symbol state of any sections we 89 // use. Each one should start off as EMS_None, which is provided as the 90 // default constructor by DenseMap::lookup. 91 LastMappingSymbols[getPreviousSection().first] = LastEMS; 92 LastEMS = LastMappingSymbols.lookup(Section); 93 94 MCELFStreamer::ChangeSection(Section, Subsection); 95 } 96 97 /// This function is the one used to emit instruction data into the ELF 98 /// streamer. We override it to add the appropriate mapping symbol if 99 /// necessary. 100 virtual void EmitInstruction(const MCInst& Inst) { 101 if (IsThumb) 102 EmitThumbMappingSymbol(); 103 else 104 EmitARMMappingSymbol(); 105 106 MCELFStreamer::EmitInstruction(Inst); 107 } 108 109 /// This is one of the functions used to emit data into an ELF section, so the 110 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 111 /// necessary. 112 virtual void EmitBytes(StringRef Data, unsigned AddrSpace) { 113 EmitDataMappingSymbol(); 114 MCELFStreamer::EmitBytes(Data, AddrSpace); 115 } 116 117 /// This is one of the functions used to emit data into an ELF section, so the 118 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 119 /// necessary. 120 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size, 121 unsigned AddrSpace) { 122 EmitDataMappingSymbol(); 123 MCELFStreamer::EmitValueImpl(Value, Size, AddrSpace); 124 } 125 126 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) { 127 MCELFStreamer::EmitAssemblerFlag(Flag); 128 129 switch (Flag) { 130 case MCAF_SyntaxUnified: 131 return; // no-op here. 132 case MCAF_Code16: 133 IsThumb = true; 134 return; // Change to Thumb mode 135 case MCAF_Code32: 136 IsThumb = false; 137 return; // Change to ARM mode 138 case MCAF_Code64: 139 return; 140 case MCAF_SubsectionsViaSymbols: 141 return; 142 } 143 } 144 145 static bool classof(const MCStreamer *S) { 146 return S->getKind() == SK_ARMELFStreamer; 147 } 148 149 private: 150 enum ElfMappingSymbol { 151 EMS_None, 152 EMS_ARM, 153 EMS_Thumb, 154 EMS_Data 155 }; 156 157 void EmitDataMappingSymbol() { 158 if (LastEMS == EMS_Data) return; 159 EmitMappingSymbol("$d"); 160 LastEMS = EMS_Data; 161 } 162 163 void EmitThumbMappingSymbol() { 164 if (LastEMS == EMS_Thumb) return; 165 EmitMappingSymbol("$t"); 166 LastEMS = EMS_Thumb; 167 } 168 169 void EmitARMMappingSymbol() { 170 if (LastEMS == EMS_ARM) return; 171 EmitMappingSymbol("$a"); 172 LastEMS = EMS_ARM; 173 } 174 175 void EmitMappingSymbol(StringRef Name) { 176 MCSymbol *Start = getContext().CreateTempSymbol(); 177 EmitLabel(Start); 178 179 MCSymbol *Symbol = 180 getContext().GetOrCreateSymbol(Name + "." + 181 Twine(MappingSymbolCounter++)); 182 183 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 184 MCELF::SetType(SD, ELF::STT_NOTYPE); 185 MCELF::SetBinding(SD, ELF::STB_LOCAL); 186 SD.setExternal(false); 187 Symbol->setSection(*getCurrentSection().first); 188 189 const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext()); 190 Symbol->setVariableValue(Value); 191 } 192 193 void EmitThumbFunc(MCSymbol *Func) { 194 // FIXME: Anything needed here to flag the function as thumb? 195 196 getAssembler().setIsThumbFunc(Func); 197 198 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); 199 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); 200 } 201 202 // Helper functions for ARM exception handling directives 203 void Reset(); 204 205 void EmitPersonalityFixup(StringRef Name); 206 void CollectUnwindOpcodes(); 207 208 void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, 209 SectionKind Kind, const MCSymbol &Fn); 210 void SwitchToExTabSection(const MCSymbol &FnStart); 211 void SwitchToExIdxSection(const MCSymbol &FnStart); 212 213 bool IsThumb; 214 int64_t MappingSymbolCounter; 215 216 DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols; 217 ElfMappingSymbol LastEMS; 218 219 // ARM Exception Handling Frame Information 220 MCSymbol *ExTab; 221 MCSymbol *FnStart; 222 const MCSymbol *Personality; 223 uint32_t VFPRegSave; // Register mask for {d31-d0} 224 uint32_t RegSave; // Register mask for {r15-r0} 225 int64_t SPOffset; 226 uint16_t FPReg; 227 int64_t FPOffset; 228 bool UsedFP; 229 bool CantUnwind; 230 UnwindOpcodeAssembler UnwindOpAsm; 231 }; 232 } // end anonymous namespace 233 234 inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, 235 unsigned Type, 236 unsigned Flags, 237 SectionKind Kind, 238 const MCSymbol &Fn) { 239 const MCSectionELF &FnSection = 240 static_cast<const MCSectionELF &>(Fn.getSection()); 241 242 // Create the name for new section 243 StringRef FnSecName(FnSection.getSectionName()); 244 SmallString<128> EHSecName(Prefix); 245 if (FnSecName != ".text") { 246 EHSecName += FnSecName; 247 } 248 249 // Get .ARM.extab or .ARM.exidx section 250 const MCSectionELF *EHSection = NULL; 251 if (const MCSymbol *Group = FnSection.getGroup()) { 252 EHSection = getContext().getELFSection( 253 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind, 254 FnSection.getEntrySize(), Group->getName()); 255 } else { 256 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind); 257 } 258 assert(EHSection && "Failed to get the required EH section"); 259 260 // Switch to .ARM.extab or .ARM.exidx section 261 SwitchSection(EHSection); 262 EmitCodeAlignment(4, 0); 263 } 264 265 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 266 SwitchToEHSection(".ARM.extab", 267 ELF::SHT_PROGBITS, 268 ELF::SHF_ALLOC, 269 SectionKind::getDataRel(), 270 FnStart); 271 } 272 273 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 274 SwitchToEHSection(".ARM.exidx", 275 ELF::SHT_ARM_EXIDX, 276 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 277 SectionKind::getDataRel(), 278 FnStart); 279 } 280 281 void ARMELFStreamer::Reset() { 282 const MCRegisterInfo &MRI = getContext().getRegisterInfo(); 283 284 ExTab = NULL; 285 FnStart = NULL; 286 Personality = NULL; 287 VFPRegSave = 0; 288 RegSave = 0; 289 FPReg = MRI.getEncodingValue(ARM::SP); 290 FPOffset = 0; 291 SPOffset = 0; 292 UsedFP = false; 293 CantUnwind = false; 294 295 UnwindOpAsm.Reset(); 296 } 297 298 // Add the R_ARM_NONE fixup at the same position 299 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 300 const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name); 301 302 const MCSymbolRefExpr *PersonalityRef = 303 MCSymbolRefExpr::Create(PersonalitySym, 304 MCSymbolRefExpr::VK_ARM_NONE, 305 getContext()); 306 307 AddValueSymbols(PersonalityRef); 308 MCDataFragment *DF = getOrCreateDataFragment(); 309 DF->getFixups().push_back( 310 MCFixup::Create(DF->getContents().size(), PersonalityRef, 311 MCFixup::getKindForSize(4, false))); 312 } 313 314 void ARMELFStreamer::CollectUnwindOpcodes() { 315 if (UsedFP) { 316 UnwindOpAsm.EmitSetFP(FPReg); 317 UnwindOpAsm.EmitSPOffset(-FPOffset); 318 } else { 319 UnwindOpAsm.EmitSPOffset(SPOffset); 320 } 321 UnwindOpAsm.EmitVFPRegSave(VFPRegSave); 322 UnwindOpAsm.EmitRegSave(RegSave); 323 UnwindOpAsm.Finalize(); 324 } 325 326 void ARMELFStreamer::EmitFnStart() { 327 assert(FnStart == 0); 328 FnStart = getContext().CreateTempSymbol(); 329 EmitLabel(FnStart); 330 } 331 332 void ARMELFStreamer::EmitFnEnd() { 333 assert(FnStart && ".fnstart must preceeds .fnend"); 334 335 // Emit unwind opcodes if there is no .handlerdata directive 336 if (!ExTab && !CantUnwind) { 337 CollectUnwindOpcodes(); 338 339 unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex(); 340 if (PersonalityIndex == AEABI_UNWIND_CPP_PR1 || 341 PersonalityIndex == AEABI_UNWIND_CPP_PR2) { 342 // For the __aeabi_unwind_cpp_pr1 and __aeabi_unwind_cpp_pr2, we have to 343 // emit the unwind opcodes in the corresponding ".ARM.extab" section, and 344 // then emit a reference to these unwind opcodes in the second word of 345 // the exception index table entry. 346 SwitchToExTabSection(*FnStart); 347 ExTab = getContext().CreateTempSymbol(); 348 EmitLabel(ExTab); 349 EmitBytes(UnwindOpAsm.data(), 0); 350 } 351 } 352 353 // Emit the exception index table entry 354 SwitchToExIdxSection(*FnStart); 355 356 unsigned PersonalityIndex = UnwindOpAsm.getPersonalityIndex(); 357 if (PersonalityIndex < NUM_PERSONALITY_INDEX) 358 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 359 360 const MCSymbolRefExpr *FnStartRef = 361 MCSymbolRefExpr::Create(FnStart, 362 MCSymbolRefExpr::VK_ARM_PREL31, 363 getContext()); 364 365 EmitValue(FnStartRef, 4, 0); 366 367 if (CantUnwind) { 368 EmitIntValue(EXIDX_CANTUNWIND, 4, 0); 369 } else if (ExTab) { 370 // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 371 const MCSymbolRefExpr *ExTabEntryRef = 372 MCSymbolRefExpr::Create(ExTab, 373 MCSymbolRefExpr::VK_ARM_PREL31, 374 getContext()); 375 EmitValue(ExTabEntryRef, 4, 0); 376 } else { 377 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 378 // the second word of exception index table entry. The size of the unwind 379 // opcodes should always be 4 bytes. 380 assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 && 381 "Compact model must use __aeabi_cpp_unwind_pr0 as personality"); 382 assert(UnwindOpAsm.size() == 4u && 383 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4"); 384 EmitBytes(UnwindOpAsm.data(), 0); 385 } 386 387 // Clean exception handling frame information 388 Reset(); 389 } 390 391 void ARMELFStreamer::EmitCantUnwind() { 392 CantUnwind = true; 393 } 394 395 void ARMELFStreamer::EmitHandlerData() { 396 SwitchToExTabSection(*FnStart); 397 398 // Create .ARM.extab label for offset in .ARM.exidx 399 assert(!ExTab); 400 ExTab = getContext().CreateTempSymbol(); 401 EmitLabel(ExTab); 402 403 // Emit Personality 404 assert(Personality && ".personality directive must preceed .handlerdata"); 405 406 const MCSymbolRefExpr *PersonalityRef = 407 MCSymbolRefExpr::Create(Personality, 408 MCSymbolRefExpr::VK_ARM_PREL31, 409 getContext()); 410 411 EmitValue(PersonalityRef, 4, 0); 412 413 // Emit unwind opcodes 414 CollectUnwindOpcodes(); 415 EmitBytes(UnwindOpAsm.data(), 0); 416 } 417 418 void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) { 419 Personality = Per; 420 UnwindOpAsm.setPersonality(Per); 421 } 422 423 void ARMELFStreamer::EmitSetFP(unsigned NewFPReg, 424 unsigned NewSPReg, 425 int64_t Offset) { 426 assert(SPOffset == 0 && 427 "Current implementation assumes .setfp precedes .pad"); 428 429 const MCRegisterInfo &MRI = getContext().getRegisterInfo(); 430 431 uint16_t NewFPRegEncVal = MRI.getEncodingValue(NewFPReg); 432 #ifndef NDEBUG 433 uint16_t NewSPRegEncVal = MRI.getEncodingValue(NewSPReg); 434 #endif 435 436 assert((NewSPReg == ARM::SP || NewSPRegEncVal == FPReg) && 437 "the operand of .setfp directive should be either $sp or $fp"); 438 439 UsedFP = true; 440 FPReg = NewFPRegEncVal; 441 FPOffset = Offset; 442 } 443 444 void ARMELFStreamer::EmitPad(int64_t Offset) { 445 SPOffset += Offset; 446 } 447 448 void ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 449 bool IsVector) { 450 const MCRegisterInfo &MRI = getContext().getRegisterInfo(); 451 452 #ifndef NDEBUG 453 unsigned Max = IsVector ? 32 : 16; 454 #endif 455 uint32_t &RegMask = IsVector ? VFPRegSave : RegSave; 456 457 for (size_t i = 0; i < RegList.size(); ++i) { 458 unsigned Reg = MRI.getEncodingValue(RegList[i]); 459 assert(Reg < Max && "Register encoded value out of range"); 460 RegMask |= 1u << Reg; 461 } 462 } 463 464 namespace llvm { 465 MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 466 raw_ostream &OS, MCCodeEmitter *Emitter, 467 bool RelaxAll, bool NoExecStack, 468 bool IsThumb) { 469 ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); 470 if (RelaxAll) 471 S->getAssembler().setRelaxAll(true); 472 if (NoExecStack) 473 S->getAssembler().setNoExecStack(true); 474 return S; 475 } 476 477 } 478 479 480