Home | History | Annotate | Download | only in MCTargetDesc
      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