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) { 113 EmitDataMappingSymbol(); 114 MCELFStreamer::EmitBytes(Data); 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 EmitDataMappingSymbol(); 122 MCELFStreamer::EmitValueImpl(Value, Size); 123 } 124 125 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) { 126 MCELFStreamer::EmitAssemblerFlag(Flag); 127 128 switch (Flag) { 129 case MCAF_SyntaxUnified: 130 return; // no-op here. 131 case MCAF_Code16: 132 IsThumb = true; 133 return; // Change to Thumb mode 134 case MCAF_Code32: 135 IsThumb = false; 136 return; // Change to ARM mode 137 case MCAF_Code64: 138 return; 139 case MCAF_SubsectionsViaSymbols: 140 return; 141 } 142 } 143 144 static bool classof(const MCStreamer *S) { 145 return S->getKind() == SK_ARMELFStreamer; 146 } 147 148 private: 149 enum ElfMappingSymbol { 150 EMS_None, 151 EMS_ARM, 152 EMS_Thumb, 153 EMS_Data 154 }; 155 156 void EmitDataMappingSymbol() { 157 if (LastEMS == EMS_Data) return; 158 EmitMappingSymbol("$d"); 159 LastEMS = EMS_Data; 160 } 161 162 void EmitThumbMappingSymbol() { 163 if (LastEMS == EMS_Thumb) return; 164 EmitMappingSymbol("$t"); 165 LastEMS = EMS_Thumb; 166 } 167 168 void EmitARMMappingSymbol() { 169 if (LastEMS == EMS_ARM) return; 170 EmitMappingSymbol("$a"); 171 LastEMS = EMS_ARM; 172 } 173 174 void EmitMappingSymbol(StringRef Name) { 175 MCSymbol *Start = getContext().CreateTempSymbol(); 176 EmitLabel(Start); 177 178 MCSymbol *Symbol = 179 getContext().GetOrCreateSymbol(Name + "." + 180 Twine(MappingSymbolCounter++)); 181 182 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 183 MCELF::SetType(SD, ELF::STT_NOTYPE); 184 MCELF::SetBinding(SD, ELF::STB_LOCAL); 185 SD.setExternal(false); 186 Symbol->setSection(*getCurrentSection().first); 187 188 const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext()); 189 Symbol->setVariableValue(Value); 190 } 191 192 void EmitThumbFunc(MCSymbol *Func) { 193 // FIXME: Anything needed here to flag the function as thumb? 194 195 getAssembler().setIsThumbFunc(Func); 196 197 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); 198 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); 199 } 200 201 // Helper functions for ARM exception handling directives 202 void Reset(); 203 204 void EmitPersonalityFixup(StringRef Name); 205 void FlushPendingOffset(); 206 void FlushUnwindOpcodes(bool NoHandlerData); 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 unsigned PersonalityIndex; 224 unsigned FPReg; // Frame pointer register 225 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 226 int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 227 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 228 bool UsedFP; 229 bool CantUnwind; 230 SmallVector<uint8_t, 64> Opcodes; 231 UnwindOpcodeAssembler UnwindOpAsm; 232 }; 233 } // end anonymous namespace 234 235 inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, 236 unsigned Type, 237 unsigned Flags, 238 SectionKind Kind, 239 const MCSymbol &Fn) { 240 const MCSectionELF &FnSection = 241 static_cast<const MCSectionELF &>(Fn.getSection()); 242 243 // Create the name for new section 244 StringRef FnSecName(FnSection.getSectionName()); 245 SmallString<128> EHSecName(Prefix); 246 if (FnSecName != ".text") { 247 EHSecName += FnSecName; 248 } 249 250 // Get .ARM.extab or .ARM.exidx section 251 const MCSectionELF *EHSection = NULL; 252 if (const MCSymbol *Group = FnSection.getGroup()) { 253 EHSection = getContext().getELFSection( 254 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind, 255 FnSection.getEntrySize(), Group->getName()); 256 } else { 257 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind); 258 } 259 assert(EHSection && "Failed to get the required EH section"); 260 261 // Switch to .ARM.extab or .ARM.exidx section 262 SwitchSection(EHSection); 263 EmitCodeAlignment(4, 0); 264 } 265 266 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 267 SwitchToEHSection(".ARM.extab", 268 ELF::SHT_PROGBITS, 269 ELF::SHF_ALLOC, 270 SectionKind::getDataRel(), 271 FnStart); 272 } 273 274 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 275 SwitchToEHSection(".ARM.exidx", 276 ELF::SHT_ARM_EXIDX, 277 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 278 SectionKind::getDataRel(), 279 FnStart); 280 } 281 282 void ARMELFStreamer::Reset() { 283 ExTab = NULL; 284 FnStart = NULL; 285 Personality = NULL; 286 PersonalityIndex = NUM_PERSONALITY_INDEX; 287 FPReg = ARM::SP; 288 FPOffset = 0; 289 SPOffset = 0; 290 PendingOffset = 0; 291 UsedFP = false; 292 CantUnwind = false; 293 294 Opcodes.clear(); 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::EmitFnStart() { 315 assert(FnStart == 0); 316 FnStart = getContext().CreateTempSymbol(); 317 EmitLabel(FnStart); 318 } 319 320 void ARMELFStreamer::EmitFnEnd() { 321 assert(FnStart && ".fnstart must preceeds .fnend"); 322 323 // Emit unwind opcodes if there is no .handlerdata directive 324 if (!ExTab && !CantUnwind) 325 FlushUnwindOpcodes(true); 326 327 // Emit the exception index table entry 328 SwitchToExIdxSection(*FnStart); 329 330 if (PersonalityIndex < NUM_PERSONALITY_INDEX) 331 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 332 333 const MCSymbolRefExpr *FnStartRef = 334 MCSymbolRefExpr::Create(FnStart, 335 MCSymbolRefExpr::VK_ARM_PREL31, 336 getContext()); 337 338 EmitValue(FnStartRef, 4); 339 340 if (CantUnwind) { 341 EmitIntValue(EXIDX_CANTUNWIND, 4); 342 } else if (ExTab) { 343 // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 344 const MCSymbolRefExpr *ExTabEntryRef = 345 MCSymbolRefExpr::Create(ExTab, 346 MCSymbolRefExpr::VK_ARM_PREL31, 347 getContext()); 348 EmitValue(ExTabEntryRef, 4); 349 } else { 350 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 351 // the second word of exception index table entry. The size of the unwind 352 // opcodes should always be 4 bytes. 353 assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 && 354 "Compact model must use __aeabi_cpp_unwind_pr0 as personality"); 355 assert(Opcodes.size() == 4u && 356 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4"); 357 EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()), 358 Opcodes.size())); 359 } 360 361 // Switch to the section containing FnStart 362 SwitchSection(&FnStart->getSection()); 363 364 // Clean exception handling frame information 365 Reset(); 366 } 367 368 void ARMELFStreamer::EmitCantUnwind() { 369 CantUnwind = true; 370 } 371 372 void ARMELFStreamer::FlushPendingOffset() { 373 if (PendingOffset != 0) { 374 UnwindOpAsm.EmitSPOffset(-PendingOffset); 375 PendingOffset = 0; 376 } 377 } 378 379 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 380 // Emit the unwind opcode to restore $sp. 381 if (UsedFP) { 382 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 383 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 384 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 385 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 386 } else { 387 FlushPendingOffset(); 388 } 389 390 // Finalize the unwind opcode sequence 391 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 392 393 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 394 // section. Thus, we don't have to create an entry in the .ARM.extab 395 // section. 396 if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0) 397 return; 398 399 // Switch to .ARM.extab section. 400 SwitchToExTabSection(*FnStart); 401 402 // Create .ARM.extab label for offset in .ARM.exidx 403 assert(!ExTab); 404 ExTab = getContext().CreateTempSymbol(); 405 EmitLabel(ExTab); 406 407 // Emit personality 408 if (Personality) { 409 const MCSymbolRefExpr *PersonalityRef = 410 MCSymbolRefExpr::Create(Personality, 411 MCSymbolRefExpr::VK_ARM_PREL31, 412 getContext()); 413 414 EmitValue(PersonalityRef, 4); 415 } 416 417 // Emit unwind opcodes 418 EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()), 419 Opcodes.size())); 420 421 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 422 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 423 // after the unwind opcodes. The handler data consists of several 32-bit 424 // words, and should be terminated by zero. 425 // 426 // In case that the .handlerdata directive is not specified by the 427 // programmer, we should emit zero to terminate the handler data. 428 if (NoHandlerData && !Personality) 429 EmitIntValue(0, 4); 430 } 431 432 void ARMELFStreamer::EmitHandlerData() { 433 FlushUnwindOpcodes(false); 434 } 435 436 void ARMELFStreamer::EmitPersonality(const MCSymbol *Per) { 437 Personality = Per; 438 UnwindOpAsm.setPersonality(Per); 439 } 440 441 void ARMELFStreamer::EmitSetFP(unsigned NewFPReg, 442 unsigned NewSPReg, 443 int64_t Offset) { 444 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 445 "the operand of .setfp directive should be either $sp or $fp"); 446 447 UsedFP = true; 448 FPReg = NewFPReg; 449 450 if (NewSPReg == ARM::SP) 451 FPOffset = SPOffset + Offset; 452 else 453 FPOffset += Offset; 454 } 455 456 void ARMELFStreamer::EmitPad(int64_t Offset) { 457 // Track the change of the $sp offset 458 SPOffset -= Offset; 459 460 // To squash multiple .pad directives, we should delay the unwind opcode 461 // until the .save, .vsave, .handlerdata, or .fnend directives. 462 PendingOffset -= Offset; 463 } 464 465 void ARMELFStreamer::EmitRegSave(const SmallVectorImpl<unsigned> &RegList, 466 bool IsVector) { 467 // Collect the registers in the register list 468 unsigned Count = 0; 469 uint32_t Mask = 0; 470 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 471 for (size_t i = 0; i < RegList.size(); ++i) { 472 unsigned Reg = MRI->getEncodingValue(RegList[i]); 473 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 474 unsigned Bit = (1u << Reg); 475 if ((Mask & Bit) == 0) { 476 Mask |= Bit; 477 ++Count; 478 } 479 } 480 481 // Track the change the $sp offset: For the .save directive, the 482 // corresponding push instruction will decrease the $sp by (4 * Count). 483 // For the .vsave directive, the corresponding vpush instruction will 484 // decrease $sp by (8 * Count). 485 SPOffset -= Count * (IsVector ? 8 : 4); 486 487 // Emit the opcode 488 FlushPendingOffset(); 489 if (IsVector) 490 UnwindOpAsm.EmitVFPRegSave(Mask); 491 else 492 UnwindOpAsm.EmitRegSave(Mask); 493 } 494 495 namespace llvm { 496 MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 497 raw_ostream &OS, MCCodeEmitter *Emitter, 498 bool RelaxAll, bool NoExecStack, 499 bool IsThumb) { 500 ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); 501 if (RelaxAll) 502 S->getAssembler().setRelaxAll(true); 503 if (NoExecStack) 504 S->getAssembler().setNoExecStack(true); 505 return S; 506 } 507 508 } 509 510 511