ARMELFStreamer.cpp revision 263508
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 "ARMBuildAttrs.h" 17#include "ARMFPUName.h" 18#include "ARMRegisterInfo.h" 19#include "ARMUnwindOp.h" 20#include "ARMUnwindOpAsm.h" 21#include "llvm/ADT/SmallPtrSet.h" 22#include "llvm/ADT/Twine.h" 23#include "llvm/MC/MCAsmBackend.h" 24#include "llvm/MC/MCAssembler.h" 25#include "llvm/MC/MCCodeEmitter.h" 26#include "llvm/MC/MCContext.h" 27#include "llvm/MC/MCELF.h" 28#include "llvm/MC/MCELFStreamer.h" 29#include "llvm/MC/MCELFSymbolFlags.h" 30#include "llvm/MC/MCExpr.h" 31#include "llvm/MC/MCInst.h" 32#include "llvm/MC/MCInstPrinter.h" 33#include "llvm/MC/MCObjectStreamer.h" 34#include "llvm/MC/MCRegisterInfo.h" 35#include "llvm/MC/MCSection.h" 36#include "llvm/MC/MCSectionELF.h" 37#include "llvm/MC/MCStreamer.h" 38#include "llvm/MC/MCSymbol.h" 39#include "llvm/MC/MCValue.h" 40#include "llvm/Support/Debug.h" 41#include "llvm/Support/ELF.h" 42#include "llvm/Support/FormattedStream.h" 43#include "llvm/Support/raw_ostream.h" 44#include <algorithm> 45 46using namespace llvm; 47 48static std::string GetAEABIUnwindPersonalityName(unsigned Index) { 49 assert(Index < NUM_PERSONALITY_INDEX && "Invalid personality index"); 50 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 51} 52 53static const char *GetFPUName(unsigned ID) { 54 switch (ID) { 55 default: 56 llvm_unreachable("Unknown FPU kind"); 57 break; 58#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME; 59#include "ARMFPUName.def" 60 } 61 return NULL; 62} 63 64namespace { 65 66class ARMELFStreamer; 67 68class ARMTargetAsmStreamer : public ARMTargetStreamer { 69 formatted_raw_ostream &OS; 70 MCInstPrinter &InstPrinter; 71 72 virtual void emitFnStart(); 73 virtual void emitFnEnd(); 74 virtual void emitCantUnwind(); 75 virtual void emitPersonality(const MCSymbol *Personality); 76 virtual void emitHandlerData(); 77 virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); 78 virtual void emitPad(int64_t Offset); 79 virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 80 bool isVector); 81 82 virtual void switchVendor(StringRef Vendor); 83 virtual void emitAttribute(unsigned Attribute, unsigned Value); 84 virtual void emitTextAttribute(unsigned Attribute, StringRef String); 85 virtual void emitFPU(unsigned FPU); 86 virtual void finishAttributeSection(); 87 88public: 89 ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter); 90}; 91 92ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS, 93 MCInstPrinter &InstPrinter) 94 : OS(OS), InstPrinter(InstPrinter) {} 95void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } 96void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } 97void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } 98void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { 99 OS << "\t.personality " << Personality->getName() << '\n'; 100} 101void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } 102void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 103 int64_t Offset) { 104 OS << "\t.setfp\t"; 105 InstPrinter.printRegName(OS, FpReg); 106 OS << ", "; 107 InstPrinter.printRegName(OS, SpReg); 108 if (Offset) 109 OS << ", #" << Offset; 110 OS << '\n'; 111} 112void ARMTargetAsmStreamer::emitPad(int64_t Offset) { 113 OS << "\t.pad\t#" << Offset << '\n'; 114} 115void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 116 bool isVector) { 117 assert(RegList.size() && "RegList should not be empty"); 118 if (isVector) 119 OS << "\t.vsave\t{"; 120 else 121 OS << "\t.save\t{"; 122 123 InstPrinter.printRegName(OS, RegList[0]); 124 125 for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 126 OS << ", "; 127 InstPrinter.printRegName(OS, RegList[i]); 128 } 129 130 OS << "}\n"; 131} 132void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) { 133} 134void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 135 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value) << "\n"; 136} 137void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 138 StringRef String) { 139 switch (Attribute) { 140 default: llvm_unreachable("Unsupported Text attribute in ASM Mode"); 141 case ARMBuildAttrs::CPU_name: 142 OS << "\t.cpu\t" << String.lower() << "\n"; 143 break; 144 } 145} 146void ARMTargetAsmStreamer::emitFPU(unsigned FPU) { 147 OS << "\t.fpu\t" << GetFPUName(FPU) << "\n"; 148} 149void ARMTargetAsmStreamer::finishAttributeSection() { 150} 151 152class ARMTargetELFStreamer : public ARMTargetStreamer { 153private: 154 // This structure holds all attributes, accounting for 155 // their string/numeric value, so we can later emmit them 156 // in declaration order, keeping all in the same vector 157 struct AttributeItem { 158 enum { 159 HiddenAttribute = 0, 160 NumericAttribute, 161 TextAttribute 162 } Type; 163 unsigned Tag; 164 unsigned IntValue; 165 StringRef StringValue; 166 167 static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { 168 return (LHS.Tag < RHS.Tag); 169 } 170 }; 171 172 StringRef CurrentVendor; 173 unsigned FPU; 174 SmallVector<AttributeItem, 64> Contents; 175 176 const MCSection *AttributeSection; 177 178 // FIXME: this should be in a more generic place, but 179 // getULEBSize() is in MCAsmInfo and will be moved to MCDwarf 180 static size_t getULEBSize(int Value) { 181 size_t Size = 0; 182 do { 183 Value >>= 7; 184 Size += sizeof(int8_t); // Is this really necessary? 185 } while (Value); 186 return Size; 187 } 188 189 AttributeItem *getAttributeItem(unsigned Attribute) { 190 for (size_t i = 0; i < Contents.size(); ++i) 191 if (Contents[i].Tag == Attribute) 192 return &Contents[i]; 193 return 0; 194 } 195 196 void setAttributeItem(unsigned Attribute, unsigned Value, 197 bool OverwriteExisting) { 198 // Look for existing attribute item 199 if (AttributeItem *Item = getAttributeItem(Attribute)) { 200 if (!OverwriteExisting) 201 return; 202 Item->IntValue = Value; 203 return; 204 } 205 206 // Create new attribute item 207 AttributeItem Item = { 208 AttributeItem::NumericAttribute, 209 Attribute, 210 Value, 211 StringRef("") 212 }; 213 Contents.push_back(Item); 214 } 215 216 void setAttributeItem(unsigned Attribute, StringRef Value, 217 bool OverwriteExisting) { 218 // Look for existing attribute item 219 if (AttributeItem *Item = getAttributeItem(Attribute)) { 220 if (!OverwriteExisting) 221 return; 222 Item->StringValue = Value; 223 return; 224 } 225 226 // Create new attribute item 227 AttributeItem Item = { 228 AttributeItem::TextAttribute, 229 Attribute, 230 0, 231 Value 232 }; 233 Contents.push_back(Item); 234 } 235 236 void emitFPUDefaultAttributes(); 237 238 ARMELFStreamer &getStreamer(); 239 240 virtual void emitFnStart(); 241 virtual void emitFnEnd(); 242 virtual void emitCantUnwind(); 243 virtual void emitPersonality(const MCSymbol *Personality); 244 virtual void emitHandlerData(); 245 virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0); 246 virtual void emitPad(int64_t Offset); 247 virtual void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 248 bool isVector); 249 250 virtual void switchVendor(StringRef Vendor); 251 virtual void emitAttribute(unsigned Attribute, unsigned Value); 252 virtual void emitTextAttribute(unsigned Attribute, StringRef String); 253 virtual void emitFPU(unsigned FPU); 254 virtual void finishAttributeSection(); 255 256 size_t calculateContentSize() const; 257 258public: 259 ARMTargetELFStreamer() 260 : ARMTargetStreamer(), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU), 261 AttributeSection(0) { 262 } 263}; 264 265/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 266/// the appropriate points in the object files. These symbols are defined in the 267/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 268/// 269/// In brief: $a, $t or $d should be emitted at the start of each contiguous 270/// region of ARM code, Thumb code or data in a section. In practice, this 271/// emission does not rely on explicit assembler directives but on inherent 272/// properties of the directives doing the emission (e.g. ".byte" is data, "add 273/// r0, r0, r0" an instruction). 274/// 275/// As a result this system is orthogonal to the DataRegion infrastructure used 276/// by MachO. Beware! 277class ARMELFStreamer : public MCELFStreamer { 278public: 279 friend class ARMTargetELFStreamer; 280 281 ARMELFStreamer(MCContext &Context, MCTargetStreamer *TargetStreamer, 282 MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, 283 bool IsThumb) 284 : MCELFStreamer(Context, TargetStreamer, TAB, OS, Emitter), 285 IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) { 286 Reset(); 287 } 288 289 ~ARMELFStreamer() {} 290 291 virtual void FinishImpl(); 292 293 // ARM exception handling directives 294 void emitFnStart(); 295 void emitFnEnd(); 296 void emitCantUnwind(); 297 void emitPersonality(const MCSymbol *Per); 298 void emitHandlerData(); 299 void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); 300 void emitPad(int64_t Offset); 301 void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); 302 303 virtual void ChangeSection(const MCSection *Section, 304 const MCExpr *Subsection) { 305 // We have to keep track of the mapping symbol state of any sections we 306 // use. Each one should start off as EMS_None, which is provided as the 307 // default constructor by DenseMap::lookup. 308 LastMappingSymbols[getPreviousSection().first] = LastEMS; 309 LastEMS = LastMappingSymbols.lookup(Section); 310 311 MCELFStreamer::ChangeSection(Section, Subsection); 312 } 313 314 /// This function is the one used to emit instruction data into the ELF 315 /// streamer. We override it to add the appropriate mapping symbol if 316 /// necessary. 317 virtual void EmitInstruction(const MCInst& Inst) { 318 if (IsThumb) 319 EmitThumbMappingSymbol(); 320 else 321 EmitARMMappingSymbol(); 322 323 MCELFStreamer::EmitInstruction(Inst); 324 } 325 326 /// This is one of the functions used to emit data into an ELF section, so the 327 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 328 /// necessary. 329 virtual void EmitBytes(StringRef Data) { 330 EmitDataMappingSymbol(); 331 MCELFStreamer::EmitBytes(Data); 332 } 333 334 /// This is one of the functions used to emit data into an ELF section, so the 335 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 336 /// necessary. 337 virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) { 338 EmitDataMappingSymbol(); 339 MCELFStreamer::EmitValueImpl(Value, Size); 340 } 341 342 virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) { 343 MCELFStreamer::EmitAssemblerFlag(Flag); 344 345 switch (Flag) { 346 case MCAF_SyntaxUnified: 347 return; // no-op here. 348 case MCAF_Code16: 349 IsThumb = true; 350 return; // Change to Thumb mode 351 case MCAF_Code32: 352 IsThumb = false; 353 return; // Change to ARM mode 354 case MCAF_Code64: 355 return; 356 case MCAF_SubsectionsViaSymbols: 357 return; 358 } 359 } 360 361private: 362 enum ElfMappingSymbol { 363 EMS_None, 364 EMS_ARM, 365 EMS_Thumb, 366 EMS_Data 367 }; 368 369 void EmitDataMappingSymbol() { 370 if (LastEMS == EMS_Data) return; 371 EmitMappingSymbol("$d"); 372 LastEMS = EMS_Data; 373 } 374 375 void EmitThumbMappingSymbol() { 376 if (LastEMS == EMS_Thumb) return; 377 EmitMappingSymbol("$t"); 378 LastEMS = EMS_Thumb; 379 } 380 381 void EmitARMMappingSymbol() { 382 if (LastEMS == EMS_ARM) return; 383 EmitMappingSymbol("$a"); 384 LastEMS = EMS_ARM; 385 } 386 387 void EmitMappingSymbol(StringRef Name) { 388 MCSymbol *Start = getContext().CreateTempSymbol(); 389 EmitLabel(Start); 390 391 MCSymbol *Symbol = 392 getContext().GetOrCreateSymbol(Name + "." + 393 Twine(MappingSymbolCounter++)); 394 395 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 396 MCELF::SetType(SD, ELF::STT_NOTYPE); 397 MCELF::SetBinding(SD, ELF::STB_LOCAL); 398 SD.setExternal(false); 399 AssignSection(Symbol, getCurrentSection().first); 400 401 const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext()); 402 Symbol->setVariableValue(Value); 403 } 404 405 void EmitThumbFunc(MCSymbol *Func) { 406 // FIXME: Anything needed here to flag the function as thumb? 407 408 getAssembler().setIsThumbFunc(Func); 409 410 MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Func); 411 SD.setFlags(SD.getFlags() | ELF_Other_ThumbFunc); 412 } 413 414 // Helper functions for ARM exception handling directives 415 void Reset(); 416 417 void EmitPersonalityFixup(StringRef Name); 418 void FlushPendingOffset(); 419 void FlushUnwindOpcodes(bool NoHandlerData); 420 421 void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, 422 SectionKind Kind, const MCSymbol &Fn); 423 void SwitchToExTabSection(const MCSymbol &FnStart); 424 void SwitchToExIdxSection(const MCSymbol &FnStart); 425 426 bool IsThumb; 427 int64_t MappingSymbolCounter; 428 429 DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols; 430 ElfMappingSymbol LastEMS; 431 432 // ARM Exception Handling Frame Information 433 MCSymbol *ExTab; 434 MCSymbol *FnStart; 435 const MCSymbol *Personality; 436 unsigned PersonalityIndex; 437 unsigned FPReg; // Frame pointer register 438 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 439 int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 440 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 441 bool UsedFP; 442 bool CantUnwind; 443 SmallVector<uint8_t, 64> Opcodes; 444 UnwindOpcodeAssembler UnwindOpAsm; 445}; 446} // end anonymous namespace 447 448ARMELFStreamer &ARMTargetELFStreamer::getStreamer() { 449 ARMELFStreamer *S = static_cast<ARMELFStreamer *>(Streamer); 450 return *S; 451} 452 453void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } 454void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } 455void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } 456void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { 457 getStreamer().emitPersonality(Personality); 458} 459void ARMTargetELFStreamer::emitHandlerData() { 460 getStreamer().emitHandlerData(); 461} 462void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 463 int64_t Offset) { 464 getStreamer().emitSetFP(FpReg, SpReg, Offset); 465} 466void ARMTargetELFStreamer::emitPad(int64_t Offset) { 467 getStreamer().emitPad(Offset); 468} 469void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 470 bool isVector) { 471 getStreamer().emitRegSave(RegList, isVector); 472} 473void ARMTargetELFStreamer::switchVendor(StringRef Vendor) { 474 assert(!Vendor.empty() && "Vendor cannot be empty."); 475 476 if (CurrentVendor == Vendor) 477 return; 478 479 if (!CurrentVendor.empty()) 480 finishAttributeSection(); 481 482 assert(Contents.empty() && 483 ".ARM.attributes should be flushed before changing vendor"); 484 CurrentVendor = Vendor; 485 486} 487void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 488 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 489} 490void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, 491 StringRef Value) { 492 setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 493} 494void ARMTargetELFStreamer::emitFPU(unsigned Value) { 495 FPU = Value; 496} 497void ARMTargetELFStreamer::emitFPUDefaultAttributes() { 498 switch (FPU) { 499 case ARM::VFP: 500 case ARM::VFPV2: 501 setAttributeItem(ARMBuildAttrs::VFP_arch, 502 ARMBuildAttrs::AllowFPv2, 503 /* OverwriteExisting= */ false); 504 break; 505 506 case ARM::VFPV3: 507 setAttributeItem(ARMBuildAttrs::VFP_arch, 508 ARMBuildAttrs::AllowFPv3A, 509 /* OverwriteExisting= */ false); 510 break; 511 512 case ARM::VFPV3_D16: 513 setAttributeItem(ARMBuildAttrs::VFP_arch, 514 ARMBuildAttrs::AllowFPv3B, 515 /* OverwriteExisting= */ false); 516 break; 517 518 case ARM::VFPV4: 519 setAttributeItem(ARMBuildAttrs::VFP_arch, 520 ARMBuildAttrs::AllowFPv4A, 521 /* OverwriteExisting= */ false); 522 break; 523 524 case ARM::VFPV4_D16: 525 setAttributeItem(ARMBuildAttrs::VFP_arch, 526 ARMBuildAttrs::AllowFPv4B, 527 /* OverwriteExisting= */ false); 528 break; 529 530 case ARM::FP_ARMV8: 531 setAttributeItem(ARMBuildAttrs::VFP_arch, 532 ARMBuildAttrs::AllowFPARMv8A, 533 /* OverwriteExisting= */ false); 534 break; 535 536 case ARM::NEON: 537 setAttributeItem(ARMBuildAttrs::VFP_arch, 538 ARMBuildAttrs::AllowFPv3A, 539 /* OverwriteExisting= */ false); 540 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 541 ARMBuildAttrs::AllowNeon, 542 /* OverwriteExisting= */ false); 543 break; 544 545 case ARM::NEON_VFPV4: 546 setAttributeItem(ARMBuildAttrs::VFP_arch, 547 ARMBuildAttrs::AllowFPv4A, 548 /* OverwriteExisting= */ false); 549 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 550 ARMBuildAttrs::AllowNeon2, 551 /* OverwriteExisting= */ false); 552 break; 553 554 case ARM::NEON_FP_ARMV8: 555 case ARM::CRYPTO_NEON_FP_ARMV8: 556 setAttributeItem(ARMBuildAttrs::VFP_arch, 557 ARMBuildAttrs::AllowFPARMv8A, 558 /* OverwriteExisting= */ false); 559 setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 560 ARMBuildAttrs::AllowNeonARMv8, 561 /* OverwriteExisting= */ false); 562 break; 563 564 default: 565 report_fatal_error("Unknown FPU: " + Twine(FPU)); 566 break; 567 } 568} 569size_t ARMTargetELFStreamer::calculateContentSize() const { 570 size_t Result = 0; 571 for (size_t i = 0; i < Contents.size(); ++i) { 572 AttributeItem item = Contents[i]; 573 switch (item.Type) { 574 case AttributeItem::HiddenAttribute: 575 break; 576 case AttributeItem::NumericAttribute: 577 Result += getULEBSize(item.Tag); 578 Result += getULEBSize(item.IntValue); 579 break; 580 case AttributeItem::TextAttribute: 581 Result += getULEBSize(item.Tag); 582 Result += item.StringValue.size() + 1; // string + '\0' 583 break; 584 } 585 } 586 return Result; 587} 588void ARMTargetELFStreamer::finishAttributeSection() { 589 // <format-version> 590 // [ <section-length> "vendor-name" 591 // [ <file-tag> <size> <attribute>* 592 // | <section-tag> <size> <section-number>* 0 <attribute>* 593 // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 594 // ]+ 595 // ]* 596 597 if (FPU != ARM::INVALID_FPU) 598 emitFPUDefaultAttributes(); 599 600 if (Contents.empty()) 601 return; 602 603 std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag); 604 605 ARMELFStreamer &Streamer = getStreamer(); 606 607 // Switch to .ARM.attributes section 608 if (AttributeSection) { 609 Streamer.SwitchSection(AttributeSection); 610 } else { 611 AttributeSection = 612 Streamer.getContext().getELFSection(".ARM.attributes", 613 ELF::SHT_ARM_ATTRIBUTES, 614 0, 615 SectionKind::getMetadata()); 616 Streamer.SwitchSection(AttributeSection); 617 618 // Format version 619 Streamer.EmitIntValue(0x41, 1); 620 } 621 622 // Vendor size + Vendor name + '\0' 623 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 624 625 // Tag + Tag Size 626 const size_t TagHeaderSize = 1 + 4; 627 628 const size_t ContentsSize = calculateContentSize(); 629 630 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 631 Streamer.EmitBytes(CurrentVendor); 632 Streamer.EmitIntValue(0, 1); // '\0' 633 634 Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 635 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 636 637 // Size should have been accounted for already, now 638 // emit each field as its type (ULEB or String) 639 for (size_t i = 0; i < Contents.size(); ++i) { 640 AttributeItem item = Contents[i]; 641 Streamer.EmitULEB128IntValue(item.Tag); 642 switch (item.Type) { 643 default: llvm_unreachable("Invalid attribute type"); 644 case AttributeItem::NumericAttribute: 645 Streamer.EmitULEB128IntValue(item.IntValue); 646 break; 647 case AttributeItem::TextAttribute: 648 Streamer.EmitBytes(item.StringValue.upper()); 649 Streamer.EmitIntValue(0, 1); // '\0' 650 break; 651 } 652 } 653 654 Contents.clear(); 655 FPU = ARM::INVALID_FPU; 656} 657 658void ARMELFStreamer::FinishImpl() { 659 MCTargetStreamer &TS = getTargetStreamer(); 660 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 661 ATS.finishAttributeSection(); 662 663 MCELFStreamer::FinishImpl(); 664} 665 666inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, 667 unsigned Type, 668 unsigned Flags, 669 SectionKind Kind, 670 const MCSymbol &Fn) { 671 const MCSectionELF &FnSection = 672 static_cast<const MCSectionELF &>(Fn.getSection()); 673 674 // Create the name for new section 675 StringRef FnSecName(FnSection.getSectionName()); 676 SmallString<128> EHSecName(Prefix); 677 if (FnSecName != ".text") { 678 EHSecName += FnSecName; 679 } 680 681 // Get .ARM.extab or .ARM.exidx section 682 const MCSectionELF *EHSection = NULL; 683 if (const MCSymbol *Group = FnSection.getGroup()) { 684 EHSection = getContext().getELFSection( 685 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind, 686 FnSection.getEntrySize(), Group->getName()); 687 } else { 688 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind); 689 } 690 assert(EHSection && "Failed to get the required EH section"); 691 692 // Switch to .ARM.extab or .ARM.exidx section 693 SwitchSection(EHSection); 694 EmitCodeAlignment(4, 0); 695} 696 697inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 698 SwitchToEHSection(".ARM.extab", 699 ELF::SHT_PROGBITS, 700 ELF::SHF_ALLOC, 701 SectionKind::getDataRel(), 702 FnStart); 703} 704 705inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 706 SwitchToEHSection(".ARM.exidx", 707 ELF::SHT_ARM_EXIDX, 708 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 709 SectionKind::getDataRel(), 710 FnStart); 711} 712 713void ARMELFStreamer::Reset() { 714 ExTab = NULL; 715 FnStart = NULL; 716 Personality = NULL; 717 PersonalityIndex = NUM_PERSONALITY_INDEX; 718 FPReg = ARM::SP; 719 FPOffset = 0; 720 SPOffset = 0; 721 PendingOffset = 0; 722 UsedFP = false; 723 CantUnwind = false; 724 725 Opcodes.clear(); 726 UnwindOpAsm.Reset(); 727} 728 729void ARMELFStreamer::emitFnStart() { 730 assert(FnStart == 0); 731 FnStart = getContext().CreateTempSymbol(); 732 EmitLabel(FnStart); 733} 734 735void ARMELFStreamer::emitFnEnd() { 736 assert(FnStart && ".fnstart must preceeds .fnend"); 737 738 // Emit unwind opcodes if there is no .handlerdata directive 739 if (!ExTab && !CantUnwind) 740 FlushUnwindOpcodes(true); 741 742 // Emit the exception index table entry 743 SwitchToExIdxSection(*FnStart); 744 745 if (PersonalityIndex < NUM_PERSONALITY_INDEX) 746 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 747 748 const MCSymbolRefExpr *FnStartRef = 749 MCSymbolRefExpr::Create(FnStart, 750 MCSymbolRefExpr::VK_ARM_PREL31, 751 getContext()); 752 753 EmitValue(FnStartRef, 4); 754 755 if (CantUnwind) { 756 EmitIntValue(EXIDX_CANTUNWIND, 4); 757 } else if (ExTab) { 758 // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 759 const MCSymbolRefExpr *ExTabEntryRef = 760 MCSymbolRefExpr::Create(ExTab, 761 MCSymbolRefExpr::VK_ARM_PREL31, 762 getContext()); 763 EmitValue(ExTabEntryRef, 4); 764 } else { 765 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 766 // the second word of exception index table entry. The size of the unwind 767 // opcodes should always be 4 bytes. 768 assert(PersonalityIndex == AEABI_UNWIND_CPP_PR0 && 769 "Compact model must use __aeabi_cpp_unwind_pr0 as personality"); 770 assert(Opcodes.size() == 4u && 771 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be equal to 4"); 772 EmitBytes(StringRef(reinterpret_cast<const char*>(Opcodes.data()), 773 Opcodes.size())); 774 } 775 776 // Switch to the section containing FnStart 777 SwitchSection(&FnStart->getSection()); 778 779 // Clean exception handling frame information 780 Reset(); 781} 782 783void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } 784 785// Add the R_ARM_NONE fixup at the same position 786void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 787 const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name); 788 789 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create( 790 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); 791 792 AddValueSymbols(PersonalityRef); 793 MCDataFragment *DF = getOrCreateDataFragment(); 794 DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 795 PersonalityRef, 796 MCFixup::getKindForSize(4, false))); 797} 798 799void ARMELFStreamer::FlushPendingOffset() { 800 if (PendingOffset != 0) { 801 UnwindOpAsm.EmitSPOffset(-PendingOffset); 802 PendingOffset = 0; 803 } 804} 805 806void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 807 // Emit the unwind opcode to restore $sp. 808 if (UsedFP) { 809 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 810 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 811 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 812 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 813 } else { 814 FlushPendingOffset(); 815 } 816 817 // Finalize the unwind opcode sequence 818 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 819 820 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 821 // section. Thus, we don't have to create an entry in the .ARM.extab 822 // section. 823 if (NoHandlerData && PersonalityIndex == AEABI_UNWIND_CPP_PR0) 824 return; 825 826 // Switch to .ARM.extab section. 827 SwitchToExTabSection(*FnStart); 828 829 // Create .ARM.extab label for offset in .ARM.exidx 830 assert(!ExTab); 831 ExTab = getContext().CreateTempSymbol(); 832 EmitLabel(ExTab); 833 834 // Emit personality 835 if (Personality) { 836 const MCSymbolRefExpr *PersonalityRef = 837 MCSymbolRefExpr::Create(Personality, 838 MCSymbolRefExpr::VK_ARM_PREL31, 839 getContext()); 840 841 EmitValue(PersonalityRef, 4); 842 } 843 844 // Emit unwind opcodes 845 EmitBytes(StringRef(reinterpret_cast<const char *>(Opcodes.data()), 846 Opcodes.size())); 847 848 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 849 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 850 // after the unwind opcodes. The handler data consists of several 32-bit 851 // words, and should be terminated by zero. 852 // 853 // In case that the .handlerdata directive is not specified by the 854 // programmer, we should emit zero to terminate the handler data. 855 if (NoHandlerData && !Personality) 856 EmitIntValue(0, 4); 857} 858 859void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } 860 861void ARMELFStreamer::emitPersonality(const MCSymbol *Per) { 862 Personality = Per; 863 UnwindOpAsm.setPersonality(Per); 864} 865 866void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, 867 int64_t Offset) { 868 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 869 "the operand of .setfp directive should be either $sp or $fp"); 870 871 UsedFP = true; 872 FPReg = NewFPReg; 873 874 if (NewSPReg == ARM::SP) 875 FPOffset = SPOffset + Offset; 876 else 877 FPOffset += Offset; 878} 879 880void ARMELFStreamer::emitPad(int64_t Offset) { 881 // Track the change of the $sp offset 882 SPOffset -= Offset; 883 884 // To squash multiple .pad directives, we should delay the unwind opcode 885 // until the .save, .vsave, .handlerdata, or .fnend directives. 886 PendingOffset -= Offset; 887} 888 889void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 890 bool IsVector) { 891 // Collect the registers in the register list 892 unsigned Count = 0; 893 uint32_t Mask = 0; 894 const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 895 for (size_t i = 0; i < RegList.size(); ++i) { 896 unsigned Reg = MRI->getEncodingValue(RegList[i]); 897 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 898 unsigned Bit = (1u << Reg); 899 if ((Mask & Bit) == 0) { 900 Mask |= Bit; 901 ++Count; 902 } 903 } 904 905 // Track the change the $sp offset: For the .save directive, the 906 // corresponding push instruction will decrease the $sp by (4 * Count). 907 // For the .vsave directive, the corresponding vpush instruction will 908 // decrease $sp by (8 * Count). 909 SPOffset -= Count * (IsVector ? 8 : 4); 910 911 // Emit the opcode 912 FlushPendingOffset(); 913 if (IsVector) 914 UnwindOpAsm.EmitVFPRegSave(Mask); 915 else 916 UnwindOpAsm.EmitRegSave(Mask); 917} 918 919namespace llvm { 920 921MCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, 922 bool isVerboseAsm, bool useLoc, bool useCFI, 923 bool useDwarfDirectory, 924 MCInstPrinter *InstPrint, MCCodeEmitter *CE, 925 MCAsmBackend *TAB, bool ShowInst) { 926 ARMTargetAsmStreamer *S = new ARMTargetAsmStreamer(OS, *InstPrint); 927 928 return llvm::createAsmStreamer(Ctx, S, OS, isVerboseAsm, useLoc, useCFI, 929 useDwarfDirectory, InstPrint, CE, TAB, 930 ShowInst); 931} 932 933 MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 934 raw_ostream &OS, MCCodeEmitter *Emitter, 935 bool RelaxAll, bool NoExecStack, 936 bool IsThumb) { 937 ARMTargetELFStreamer *TS = new ARMTargetELFStreamer(); 938 ARMELFStreamer *S = 939 new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb); 940 // FIXME: This should eventually end up somewhere else where more 941 // intelligent flag decisions can be made. For now we are just maintaining 942 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 943 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 944 945 if (RelaxAll) 946 S->getAssembler().setRelaxAll(true); 947 if (NoExecStack) 948 S->getAssembler().setNoExecStack(true); 949 return S; 950 } 951 952} 953 954 955