50 return (
Twine(
"__aeabi_unwind_cpp_pr") +
Twine(Index)).str();
58 #define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME;
59 #include "ARMFPUName.def"
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);
82 virtual void switchVendor(
StringRef Vendor);
85 virtual void emitFPU(
unsigned FPU);
86 virtual void finishAttributeSection();
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';
101 void ARMTargetAsmStreamer::emitHandlerData() { OS <<
"\t.handlerdata\n"; }
102 void ARMTargetAsmStreamer::emitSetFP(
unsigned FpReg,
unsigned SpReg,
105 InstPrinter.printRegName(OS, FpReg);
107 InstPrinter.printRegName(OS, SpReg);
109 OS <<
", #" << Offset;
112 void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
113 OS <<
"\t.pad\t#" << Offset <<
'\n';
117 assert(RegList.
size() &&
"RegList should not be empty");
123 InstPrinter.printRegName(OS, RegList[0]);
125 for (
unsigned i = 1, e = RegList.
size(); i != e; ++i) {
127 InstPrinter.printRegName(OS, RegList[i]);
132 void ARMTargetAsmStreamer::switchVendor(
StringRef Vendor) {
134 void ARMTargetAsmStreamer::emitAttribute(
unsigned Attribute,
unsigned Value) {
135 OS <<
"\t.eabi_attribute\t" << Attribute <<
", " <<
Twine(Value) <<
"\n";
137 void ARMTargetAsmStreamer::emitTextAttribute(
unsigned Attribute,
142 OS <<
"\t.cpu\t" << String.
lower() <<
"\n";
146 void ARMTargetAsmStreamer::emitFPU(
unsigned FPU) {
149 void ARMTargetAsmStreamer::finishAttributeSection() {
157 struct AttributeItem {
167 static bool LessTag(
const AttributeItem &LHS,
const AttributeItem &RHS) {
168 return (LHS.Tag < RHS.Tag);
180 static size_t getULEBSize(
int Value) {
184 Size +=
sizeof(int8_t);
189 AttributeItem *getAttributeItem(
unsigned Attribute) {
190 for (
size_t i = 0; i < Contents.size(); ++i)
191 if (Contents[i].Tag == Attribute)
196 void setAttributeItem(
unsigned Attribute,
unsigned Value,
197 bool OverwriteExisting) {
199 if (AttributeItem *Item = getAttributeItem(Attribute)) {
200 if (!OverwriteExisting)
202 Item->IntValue = Value;
207 AttributeItem Item = {
208 AttributeItem::NumericAttribute,
213 Contents.push_back(Item);
216 void setAttributeItem(
unsigned Attribute,
StringRef Value,
217 bool OverwriteExisting) {
219 if (AttributeItem *Item = getAttributeItem(Attribute)) {
220 if (!OverwriteExisting)
222 Item->StringValue = Value;
227 AttributeItem Item = {
228 AttributeItem::TextAttribute,
233 Contents.push_back(Item);
236 void emitFPUDefaultAttributes();
238 ARMELFStreamer &getStreamer();
245 virtual void emitSetFP(
unsigned FpReg,
unsigned SpReg, int64_t Offset = 0);
246 virtual void emitPad(int64_t Offset);
251 virtual void emitAttribute(
unsigned Attribute,
unsigned Value);
253 virtual void emitFPU(
unsigned FPU);
256 size_t calculateContentSize()
const;
259 ARMTargetELFStreamer()
261 AttributeSection(0) {
279 friend class ARMTargetELFStreamer;
285 IsThumb(IsThumb), MappingSymbolCounter(0), LastEMS(EMS_None) {
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);
304 const MCExpr *Subsection) {
309 LastEMS = LastMappingSymbols.lookup(Section);
319 EmitThumbMappingSymbol();
321 EmitARMMappingSymbol();
330 EmitDataMappingSymbol();
338 EmitDataMappingSymbol();
362 enum ElfMappingSymbol {
369 void EmitDataMappingSymbol() {
370 if (LastEMS == EMS_Data)
return;
371 EmitMappingSymbol(
"$d");
375 void EmitThumbMappingSymbol() {
376 if (LastEMS == EMS_Thumb)
return;
377 EmitMappingSymbol(
"$t");
381 void EmitARMMappingSymbol() {
382 if (LastEMS == EMS_ARM)
return;
383 EmitMappingSymbol(
"$a");
393 Twine(MappingSymbolCounter++));
417 void EmitPersonalityFixup(
StringRef Name);
418 void FlushPendingOffset();
419 void FlushUnwindOpcodes(
bool NoHandlerData);
421 void SwitchToEHSection(
const char *
Prefix,
unsigned Type,
unsigned Flags,
423 void SwitchToExTabSection(
const MCSymbol &FnStart);
424 void SwitchToExIdxSection(
const MCSymbol &FnStart);
427 int64_t MappingSymbolCounter;
430 ElfMappingSymbol LastEMS;
436 unsigned PersonalityIndex;
440 int64_t PendingOffset;
448 ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
449 ARMELFStreamer *S =
static_cast<ARMELFStreamer *
>(Streamer);
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);
459 void ARMTargetELFStreamer::emitHandlerData() {
460 getStreamer().emitHandlerData();
462 void ARMTargetELFStreamer::emitSetFP(
unsigned FpReg,
unsigned SpReg,
464 getStreamer().emitSetFP(FpReg, SpReg, Offset);
466 void ARMTargetELFStreamer::emitPad(int64_t Offset) {
467 getStreamer().emitPad(Offset);
471 getStreamer().emitRegSave(RegList, isVector);
473 void ARMTargetELFStreamer::switchVendor(
StringRef Vendor) {
474 assert(!Vendor.
empty() &&
"Vendor cannot be empty.");
476 if (CurrentVendor == Vendor)
479 if (!CurrentVendor.empty())
480 finishAttributeSection();
482 assert(Contents.empty() &&
483 ".ARM.attributes should be flushed before changing vendor");
484 CurrentVendor = Vendor;
487 void ARMTargetELFStreamer::emitAttribute(
unsigned Attribute,
unsigned Value) {
488 setAttributeItem(Attribute, Value,
true);
490 void ARMTargetELFStreamer::emitTextAttribute(
unsigned Attribute,
492 setAttributeItem(Attribute, Value,
true);
494 void ARMTargetELFStreamer::emitFPU(
unsigned Value) {
497 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
545 case ARM::NEON_VFPV4:
554 case ARM::NEON_FP_ARMV8:
555 case ARM::CRYPTO_NEON_FP_ARMV8:
569 size_t ARMTargetELFStreamer::calculateContentSize()
const {
571 for (
size_t i = 0; i < Contents.size(); ++i) {
572 AttributeItem item = Contents[i];
574 case AttributeItem::HiddenAttribute:
576 case AttributeItem::NumericAttribute:
577 Result += getULEBSize(item.Tag);
578 Result += getULEBSize(item.IntValue);
580 case AttributeItem::TextAttribute:
581 Result += getULEBSize(item.Tag);
582 Result += item.StringValue.size() + 1;
588 void ARMTargetELFStreamer::finishAttributeSection() {
598 emitFPUDefaultAttributes();
600 if (Contents.empty())
603 std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag);
605 ARMELFStreamer &Streamer = getStreamer();
608 if (AttributeSection) {
609 Streamer.SwitchSection(AttributeSection);
612 Streamer.getContext().getELFSection(
".ARM.attributes",
613 ELF::SHT_ARM_ATTRIBUTES,
615 SectionKind::getMetadata());
616 Streamer.SwitchSection(AttributeSection);
619 Streamer.EmitIntValue(0x41, 1);
623 const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
626 const size_t TagHeaderSize = 1 + 4;
628 const size_t ContentsSize = calculateContentSize();
630 Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4);
631 Streamer.EmitBytes(CurrentVendor);
632 Streamer.EmitIntValue(0, 1);
635 Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4);
639 for (
size_t i = 0; i < Contents.size(); ++i) {
640 AttributeItem item = Contents[i];
641 Streamer.EmitULEB128IntValue(item.Tag);
644 case AttributeItem::NumericAttribute:
645 Streamer.EmitULEB128IntValue(item.IntValue);
647 case AttributeItem::TextAttribute:
648 Streamer.EmitBytes(item.StringValue.upper());
649 Streamer.EmitIntValue(0, 1);
658 void ARMELFStreamer::FinishImpl() {
663 MCELFStreamer::FinishImpl();
666 inline void ARMELFStreamer::SwitchToEHSection(
const char *
Prefix,
677 if (FnSecName !=
".text") {
678 EHSecName += FnSecName;
684 EHSection = getContext().getELFSection(
685 EHSecName, Type, Flags | ELF::SHF_GROUP, Kind,
688 EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind);
690 assert(EHSection &&
"Failed to get the required EH section");
693 SwitchSection(EHSection);
694 EmitCodeAlignment(4, 0);
697 inline void ARMELFStreamer::SwitchToExTabSection(
const MCSymbol &FnStart) {
698 SwitchToEHSection(
".ARM.extab",
701 SectionKind::getDataRel(),
705 inline void ARMELFStreamer::SwitchToExIdxSection(
const MCSymbol &FnStart) {
706 SwitchToEHSection(
".ARM.exidx",
708 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
709 SectionKind::getDataRel(),
713 void ARMELFStreamer::Reset() {
729 void ARMELFStreamer::emitFnStart() {
730 assert(FnStart == 0);
731 FnStart = getContext().CreateTempSymbol();
735 void ARMELFStreamer::emitFnEnd() {
736 assert(FnStart &&
".fnstart must preceeds .fnend");
739 if (!ExTab && !CantUnwind)
740 FlushUnwindOpcodes(
true);
743 SwitchToExIdxSection(*FnStart);
749 MCSymbolRefExpr::Create(FnStart,
750 MCSymbolRefExpr::VK_ARM_PREL31,
753 EmitValue(FnStartRef, 4);
760 MCSymbolRefExpr::Create(ExTab,
761 MCSymbolRefExpr::VK_ARM_PREL31,
763 EmitValue(ExTabEntryRef, 4);
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()),
783 void ARMELFStreamer::emitCantUnwind() { CantUnwind =
true; }
786 void ARMELFStreamer::EmitPersonalityFixup(
StringRef Name) {
787 const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name);
790 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
792 AddValueSymbols(PersonalityRef);
796 MCFixup::getKindForSize(4,
false)));
799 void ARMELFStreamer::FlushPendingOffset() {
800 if (PendingOffset != 0) {
801 UnwindOpAsm.EmitSPOffset(-PendingOffset);
806 void ARMELFStreamer::FlushUnwindOpcodes(
bool NoHandlerData) {
810 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
811 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
814 FlushPendingOffset();
818 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
827 SwitchToExTabSection(*FnStart);
831 ExTab = getContext().CreateTempSymbol();
837 MCSymbolRefExpr::Create(Personality,
838 MCSymbolRefExpr::VK_ARM_PREL31,
841 EmitValue(PersonalityRef, 4);
845 EmitBytes(
StringRef(reinterpret_cast<const char *>(Opcodes.data()),
855 if (NoHandlerData && !Personality)
859 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(
false); }
861 void ARMELFStreamer::emitPersonality(
const MCSymbol *Per) {
863 UnwindOpAsm.setPersonality(Per);
866 void ARMELFStreamer::emitSetFP(
unsigned NewFPReg,
unsigned NewSPReg,
868 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
869 "the operand of .setfp directive should be either $sp or $fp");
874 if (NewSPReg == ARM::SP)
875 FPOffset = SPOffset + Offset;
880 void ARMELFStreamer::emitPad(int64_t Offset) {
886 PendingOffset -= Offset;
895 for (
size_t i = 0; i < RegList.
size(); ++i) {
897 assert(Reg < (IsVector ? 32U : 16U) &&
"Register out of range");
898 unsigned Bit = (1u <<
Reg);
899 if ((Mask & Bit) == 0) {
909 SPOffset -= Count * (IsVector ? 8 : 4);
912 FlushPendingOffset();
914 UnwindOpAsm.EmitVFPRegSave(Mask);
916 UnwindOpAsm.EmitRegSave(Mask);
922 bool isVerboseAsm,
bool useLoc,
bool useCFI,
923 bool useDwarfDirectory,
926 ARMTargetAsmStreamer *S =
new ARMTargetAsmStreamer(OS, *InstPrint);
929 useDwarfDirectory, InstPrint, CE, TAB,
937 ARMTargetELFStreamer *TS =
new ARMTargetELFStreamer();
939 new ARMELFStreamer(Context, TS, TAB, OS, Emitter, IsThumb);
943 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
946 S->getAssembler().setRelaxAll(
true);
948 S->getAssembler().setNoExecStack(
true);
void setIsThumbFunc(const MCSymbol *Func)
Flag a function symbol as the target of a .thumb_func directive.
COFF::RelocationTypeX86 Type
void setExternal(bool Value)
MCSectionSubPair getPreviousSection() const
StringRef getSectionName() const
void setFlags(uint32_t Value)
setFlags - Set the (implementation defined) symbol flags.
virtual void switchVendor(StringRef Vendor)=0
virtual void emitPersonality(const MCSymbol *Personality)=0
const MCSymbol * getGroup() const
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
virtual SmallVectorImpl< char > & getContents()
static void SetType(MCSymbolData &SD, unsigned Type)
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()
MCSymbol * GetOrCreateSymbol(StringRef Name)
MCSymbol * CreateTempSymbol()
const MCSection & getSection() const
virtual void FinishImpl()
FinishImpl - Streamer specific finalization.
#define llvm_unreachable(msg)
Special entry for the function never unwind.
MCSectionSubPair getCurrentSection() const
void AssignSection(MCSymbol *Symbol, const MCSection *Section)
virtual void emitFnEnd()=0
ID
LLVM Calling Convention Representation.
MCContext & getContext() const
virtual void EmitAssemblerFlag(MCAssemblerFlag Flag)
EmitAssemblerFlag - Note in the output the specified Flag.
virtual void emitFnStart()=0
.code16 (X86) / .code 16 (ARM)
virtual void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset=0)=0
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
static void SetBinding(MCSymbolData &SD, unsigned Binding)
virtual void emitRegSave(const SmallVectorImpl< unsigned > &RegList, bool isVector)=0
MCAssembler & getAssembler()
uint32_t getFlags() const
getFlags - Get the (implementation defined) symbol flags.
MCCodeEmitter - Generic instruction encoding interface.
virtual void EmitInstruction(const MCInst &Inst)
.subsections_via_symbols (MachO)
MCSymbolData & getOrCreateSymbolData(const MCSymbol &Symbol, bool *Created=0)
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)
virtual void EmitLabel(MCSymbol *Symbol)
static const char * GetFPUName(unsigned ID)
.code32 (X86) / .code 32 (ARM)
virtual void emitCantUnwind()=0
StringRef getName() const
getName - Get the symbol name.
virtual void emitPad(int64_t Offset)=0
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.
MCAsmBackend - Generic interface to target specific assembler backends.
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
bool empty() const
empty - Check if the string is empty.