LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMELFStreamer.cpp
Go to the documentation of this file.
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"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCInst.h"
32 #include "llvm/MC/MCInstPrinter.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"
44 #include <algorithm>
45 
46 using namespace llvm;
47 
48 static 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 
53 static 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 
64 namespace {
65 
66 class ARMELFStreamer;
67 
68 class ARMTargetAsmStreamer : public ARMTargetStreamer {
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 
88 public:
89  ARMTargetAsmStreamer(formatted_raw_ostream &OS, MCInstPrinter &InstPrinter);
90 };
91 
92 ARMTargetAsmStreamer::ARMTargetAsmStreamer(formatted_raw_ostream &OS,
93  MCInstPrinter &InstPrinter)
94  : OS(OS), InstPrinter(InstPrinter) {}
95 void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
96 void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
97 void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
98 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
99  OS << "\t.personality " << Personality->getName() << '\n';
100 }
101 void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
102 void 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 }
112 void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
113  OS << "\t.pad\t#" << Offset << '\n';
114 }
115 void 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 }
132 void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {
133 }
134 void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
135  OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value) << "\n";
136 }
137 void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
138  StringRef String) {
139  switch (Attribute) {
140  default: llvm_unreachable("Unsupported Text attribute in ASM Mode");
142  OS << "\t.cpu\t" << String.lower() << "\n";
143  break;
144  }
145 }
146 void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
147  OS << "\t.fpu\t" << GetFPUName(FPU) << "\n";
148 }
149 void ARMTargetAsmStreamer::finishAttributeSection() {
150 }
151 
152 class ARMTargetELFStreamer : public ARMTargetStreamer {
153 private:
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;
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 
258 public:
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!
277 class ARMELFStreamer : public MCELFStreamer {
278 public:
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 
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();
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) {
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;
357  return;
358  }
359  }
360 
361 private:
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 
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 
409 
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 
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 
448 ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
449  ARMELFStreamer *S = static_cast<ARMELFStreamer *>(Streamer);
450  return *S;
451 }
452 
453 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
454 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
455 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
456 void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
457  getStreamer().emitPersonality(Personality);
458 }
459 void ARMTargetELFStreamer::emitHandlerData() {
460  getStreamer().emitHandlerData();
461 }
462 void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
463  int64_t Offset) {
464  getStreamer().emitSetFP(FpReg, SpReg, Offset);
465 }
466 void ARMTargetELFStreamer::emitPad(int64_t Offset) {
467  getStreamer().emitPad(Offset);
468 }
469 void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
470  bool isVector) {
471  getStreamer().emitRegSave(RegList, isVector);
472 }
473 void 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 }
487 void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
488  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
489 }
490 void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
491  StringRef Value) {
492  setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
493 }
494 void ARMTargetELFStreamer::emitFPU(unsigned Value) {
495  FPU = Value;
496 }
497 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
498  switch (FPU) {
499  case ARM::VFP:
500  case ARM::VFPV2:
501  setAttributeItem(ARMBuildAttrs::VFP_arch,
503  /* OverwriteExisting= */ false);
504  break;
505 
506  case ARM::VFPV3:
507  setAttributeItem(ARMBuildAttrs::VFP_arch,
509  /* OverwriteExisting= */ false);
510  break;
511 
512  case ARM::VFPV3_D16:
513  setAttributeItem(ARMBuildAttrs::VFP_arch,
515  /* OverwriteExisting= */ false);
516  break;
517 
518  case ARM::VFPV4:
519  setAttributeItem(ARMBuildAttrs::VFP_arch,
521  /* OverwriteExisting= */ false);
522  break;
523 
524  case ARM::VFPV4_D16:
525  setAttributeItem(ARMBuildAttrs::VFP_arch,
527  /* OverwriteExisting= */ false);
528  break;
529 
530  case ARM::FP_ARMV8:
531  setAttributeItem(ARMBuildAttrs::VFP_arch,
533  /* OverwriteExisting= */ false);
534  break;
535 
536  case ARM::NEON:
537  setAttributeItem(ARMBuildAttrs::VFP_arch,
539  /* OverwriteExisting= */ false);
540  setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
542  /* OverwriteExisting= */ false);
543  break;
544 
545  case ARM::NEON_VFPV4:
546  setAttributeItem(ARMBuildAttrs::VFP_arch,
548  /* OverwriteExisting= */ false);
549  setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
551  /* OverwriteExisting= */ false);
552  break;
553 
554  case ARM::NEON_FP_ARMV8:
555  case ARM::CRYPTO_NEON_FP_ARMV8:
556  setAttributeItem(ARMBuildAttrs::VFP_arch,
558  /* OverwriteExisting= */ false);
559  setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
561  /* OverwriteExisting= */ false);
562  break;
563 
564  default:
565  report_fatal_error("Unknown FPU: " + Twine(FPU));
566  break;
567  }
568 }
569 size_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 }
588 void 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 
658 void ARMELFStreamer::FinishImpl() {
659  MCTargetStreamer &TS = getTargetStreamer();
660  ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
662 
663  MCELFStreamer::FinishImpl();
664 }
665 
666 inline void ARMELFStreamer::SwitchToEHSection(const char *Prefix,
667  unsigned Type,
668  unsigned Flags,
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 
697 inline 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 
705 inline 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 
713 void 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 
729 void ARMELFStreamer::emitFnStart() {
730  assert(FnStart == 0);
731  FnStart = getContext().CreateTempSymbol();
732  EmitLabel(FnStart);
733 }
734 
735 void 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 
783 void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
784 
785 // Add the R_ARM_NONE fixup at the same position
786 void 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 
799 void ARMELFStreamer::FlushPendingOffset() {
800  if (PendingOffset != 0) {
801  UnwindOpAsm.EmitSPOffset(-PendingOffset);
802  PendingOffset = 0;
803  }
804 }
805 
806 void 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 
859 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
860 
861 void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
862  Personality = Per;
863  UnwindOpAsm.setPersonality(Per);
864 }
865 
866 void 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 
880 void 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 
889 void 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 
919 namespace llvm {
920 
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 
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 
void setIsThumbFunc(const MCSymbol *Func)
Flag a function symbol as the target of a .thumb_func directive.
Definition: MCAssembler.h:968
COFF::RelocationTypeX86 Type
Definition: COFFYAML.cpp:227
void setExternal(bool Value)
Definition: MCAssembler.h:731
MCSectionSubPair getPreviousSection() const
Definition: MCStreamer.h:232
StringRef getSectionName() const
Definition: MCSectionELF.h:61
void setFlags(uint32_t Value)
setFlags - Set the (implementation defined) symbol flags.
Definition: MCAssembler.h:773
virtual void switchVendor(StringRef Vendor)=0
virtual void emitPersonality(const MCSymbol *Personality)=0
const MCSymbol * getGroup() const
Definition: MCSectionELF.h:70
MCStreamer * createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint, MCCodeEmitter *CE, MCAsmBackend *TAB, bool ShowInst)
unsigned getEntrySize() const
Definition: MCSectionELF.h:69
virtual SmallVectorImpl< char > & getContents()
Definition: MCAssembler.h:221
static void SetType(MCSymbolData &SD, unsigned Type)
Definition: MCELF.cpp:36
virtual void ChangeSection(const MCSection *Section, const MCExpr *Subsection)
virtual void finishAttributeSection()=0
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
virtual void EmitValueImpl(const MCExpr *Value, unsigned Size)
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCAssembler.h:224
MCSymbol * GetOrCreateSymbol(StringRef Name)
Definition: MCContext.cpp:118
MCSymbol * CreateTempSymbol()
Definition: MCContext.cpp:165
const MCSection & getSection() const
Definition: MCSymbol.h:111
virtual void FinishImpl()
FinishImpl - Streamer specific finalization.
#define llvm_unreachable(msg)
Special entry for the function never unwind.
Definition: ARMUnwindOp.h:28
MCSectionSubPair getCurrentSection() const
Definition: MCStreamer.h:224
void AssignSection(MCSymbol *Symbol, const MCSection *Section)
Definition: MCStreamer.cpp:201
virtual void emitFnEnd()=0
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
MCContext & getContext() const
Definition: MCStreamer.h:168
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag)
EmitAssemblerFlag - Note in the output the specified Flag.
virtual void emitFnStart()=0
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:50
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)=0
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:270
static void SetBinding(MCSymbolData &SD, unsigned Binding)
Definition: MCELF.cpp:22
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)=0
MCAssembler & getAssembler()
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
Definition: MCAssembler.h:770
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
virtual void EmitInstruction(const MCInst &Inst)
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:49
MCSymbolData & getOrCreateSymbolData(const MCSymbol &Symbol, bool *Created=0)
Definition: MCAssembler.h:1151
virtual void EmitBytes(StringRef Data)
virtual void emitAttribute(unsigned Attribute, unsigned Value)=0
virtual void emitFPU(unsigned FPU)=0
MCStreamer * createAsmStreamer(MCContext &Ctx, MCTargetStreamer *TargetStreamer, formatted_raw_ostream &OS, bool isVerboseAsm, bool useLoc, bool useCFI, bool useDwarfDirectory, MCInstPrinter *InstPrint=0, MCCodeEmitter *CE=0, MCAsmBackend *TAB=0, bool ShowInst=false)
void setVariableValue(const MCExpr *Value)
Definition: MCSymbol.cpp:54
.syntax (ARM/ELF)
Definition: MCDirectives.h:48
virtual void EmitLabel(MCSymbol *Symbol)
static const char * GetFPUName(unsigned ID)
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:51
.code64 (X86)
Definition: MCDirectives.h:52
virtual void emitCantUnwind()=0
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:70
virtual void emitPad(int64_t Offset)=0
MCAssemblerFlag
Definition: MCDirectives.h:47
MCELFStreamer * createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, MCCodeEmitter *Emitter, bool RelaxAll, bool NoExecStack, bool IsThumb)
virtual void emitHandlerData()=0
uint16_t getEncodingValue(unsigned RegNo) const
Returns the encoding for RegNo.
LLVM Value Representation.
Definition: Value.h:66
MCAsmBackend - Generic interface to target specific assembler backends.
Definition: MCAsmBackend.h:34
virtual void emitTextAttribute(unsigned Attribute, StringRef String)=0
cl::opt< bool > RelaxAll("mc-relax-all", cl::desc("When used with filetype=obj, ""relax all fixups in the emitted object file"))
const MCRegisterInfo & MRI
virtual void EmitThumbFunc(MCSymbol *Func)
static std::string GetAEABIUnwindPersonalityName(unsigned Index)
std::string lower() const
Definition: StringRef.cpp:118
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110