ARMELFStreamer.cpp revision 276479
1249259Sdim//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===// 2249259Sdim// 3249259Sdim// The LLVM Compiler Infrastructure 4249259Sdim// 5249259Sdim// This file is distributed under the University of Illinois Open Source 6249259Sdim// License. See LICENSE.TXT for details. 7249259Sdim// 8249259Sdim//===----------------------------------------------------------------------===// 9249259Sdim// 10249259Sdim// This file assembles .s files and emits ARM ELF .o object files. Different 11249259Sdim// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to 12249259Sdim// delimit regions of data and code. 13249259Sdim// 14249259Sdim//===----------------------------------------------------------------------===// 15249259Sdim 16276479Sdim#include "ARMArchName.h" 17261991Sdim#include "ARMFPUName.h" 18251662Sdim#include "ARMRegisterInfo.h" 19251662Sdim#include "ARMUnwindOpAsm.h" 20276479Sdim#include "llvm/ADT/StringExtras.h" 21249259Sdim#include "llvm/ADT/Twine.h" 22249259Sdim#include "llvm/MC/MCAsmBackend.h" 23276479Sdim#include "llvm/MC/MCAsmInfo.h" 24249259Sdim#include "llvm/MC/MCAssembler.h" 25249259Sdim#include "llvm/MC/MCCodeEmitter.h" 26249259Sdim#include "llvm/MC/MCContext.h" 27249259Sdim#include "llvm/MC/MCELF.h" 28249259Sdim#include "llvm/MC/MCELFStreamer.h" 29249259Sdim#include "llvm/MC/MCELFSymbolFlags.h" 30249259Sdim#include "llvm/MC/MCExpr.h" 31249259Sdim#include "llvm/MC/MCInst.h" 32261991Sdim#include "llvm/MC/MCInstPrinter.h" 33276479Sdim#include "llvm/MC/MCObjectFileInfo.h" 34249259Sdim#include "llvm/MC/MCObjectStreamer.h" 35251662Sdim#include "llvm/MC/MCRegisterInfo.h" 36249259Sdim#include "llvm/MC/MCSection.h" 37249259Sdim#include "llvm/MC/MCSectionELF.h" 38249259Sdim#include "llvm/MC/MCStreamer.h" 39249259Sdim#include "llvm/MC/MCSymbol.h" 40249259Sdim#include "llvm/MC/MCValue.h" 41276479Sdim#include "llvm/Support/ARMBuildAttributes.h" 42276479Sdim#include "llvm/Support/ARMEHABI.h" 43249259Sdim#include "llvm/Support/Debug.h" 44249259Sdim#include "llvm/Support/ELF.h" 45261991Sdim#include "llvm/Support/FormattedStream.h" 46276479Sdim#include "llvm/Support/LEB128.h" 47249259Sdim#include "llvm/Support/raw_ostream.h" 48261991Sdim#include <algorithm> 49249259Sdim 50249259Sdimusing namespace llvm; 51249259Sdim 52251662Sdimstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) { 53276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && 54276479Sdim "Invalid personality index"); 55251662Sdim return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 56251662Sdim} 57251662Sdim 58261991Sdimstatic const char *GetFPUName(unsigned ID) { 59261991Sdim switch (ID) { 60261991Sdim default: 61261991Sdim llvm_unreachable("Unknown FPU kind"); 62261991Sdim break; 63261991Sdim#define ARM_FPU_NAME(NAME, ID) case ARM::ID: return NAME; 64261991Sdim#include "ARMFPUName.def" 65261991Sdim } 66276479Sdim return nullptr; 67261991Sdim} 68261991Sdim 69276479Sdimstatic const char *GetArchName(unsigned ID) { 70276479Sdim switch (ID) { 71276479Sdim default: 72276479Sdim llvm_unreachable("Unknown ARCH kind"); 73276479Sdim break; 74276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ 75276479Sdim case ARM::ID: return NAME; 76276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */ 77276479Sdim#include "ARMArchName.def" 78276479Sdim } 79276479Sdim return nullptr; 80276479Sdim} 81276479Sdim 82276479Sdimstatic const char *GetArchDefaultCPUName(unsigned ID) { 83276479Sdim switch (ID) { 84276479Sdim default: 85276479Sdim llvm_unreachable("Unknown ARCH kind"); 86276479Sdim break; 87276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ 88276479Sdim case ARM::ID: return DEFAULT_CPU_NAME; 89276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */ 90276479Sdim#include "ARMArchName.def" 91276479Sdim } 92276479Sdim return nullptr; 93276479Sdim} 94276479Sdim 95276479Sdimstatic unsigned GetArchDefaultCPUArch(unsigned ID) { 96276479Sdim switch (ID) { 97276479Sdim default: 98276479Sdim llvm_unreachable("Unknown ARCH kind"); 99276479Sdim break; 100276479Sdim#define ARM_ARCH_NAME(NAME, ID, DEFAULT_CPU_NAME, DEFAULT_CPU_ARCH) \ 101276479Sdim case ARM::ID: return ARMBuildAttrs::DEFAULT_CPU_ARCH; 102276479Sdim#define ARM_ARCH_ALIAS(NAME, ID) /* empty */ 103276479Sdim#include "ARMArchName.def" 104276479Sdim } 105276479Sdim return 0; 106276479Sdim} 107276479Sdim 108249259Sdimnamespace { 109249259Sdim 110261991Sdimclass ARMELFStreamer; 111261991Sdim 112261991Sdimclass ARMTargetAsmStreamer : public ARMTargetStreamer { 113261991Sdim formatted_raw_ostream &OS; 114261991Sdim MCInstPrinter &InstPrinter; 115276479Sdim bool IsVerboseAsm; 116261991Sdim 117276479Sdim void emitFnStart() override; 118276479Sdim void emitFnEnd() override; 119276479Sdim void emitCantUnwind() override; 120276479Sdim void emitPersonality(const MCSymbol *Personality) override; 121276479Sdim void emitPersonalityIndex(unsigned Index) override; 122276479Sdim void emitHandlerData() override; 123276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 124276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 125276479Sdim void emitPad(int64_t Offset) override; 126276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 127276479Sdim bool isVector) override; 128276479Sdim void emitUnwindRaw(int64_t Offset, 129276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 130261991Sdim 131276479Sdim void switchVendor(StringRef Vendor) override; 132276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 133276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 134276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 135276479Sdim StringRef StrinValue) override; 136276479Sdim void emitArch(unsigned Arch) override; 137276479Sdim void emitObjectArch(unsigned Arch) override; 138276479Sdim void emitFPU(unsigned FPU) override; 139276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 140276479Sdim void finishAttributeSection() override; 141261991Sdim 142276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 143276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 144276479Sdim 145261991Sdimpublic: 146276479Sdim ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, 147276479Sdim MCInstPrinter &InstPrinter, bool VerboseAsm); 148261991Sdim}; 149261991Sdim 150276479SdimARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S, 151276479Sdim formatted_raw_ostream &OS, 152276479Sdim MCInstPrinter &InstPrinter, 153276479Sdim bool VerboseAsm) 154276479Sdim : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter), 155276479Sdim IsVerboseAsm(VerboseAsm) {} 156261991Sdimvoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } 157261991Sdimvoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } 158261991Sdimvoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } 159261991Sdimvoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { 160261991Sdim OS << "\t.personality " << Personality->getName() << '\n'; 161261991Sdim} 162276479Sdimvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) { 163276479Sdim OS << "\t.personalityindex " << Index << '\n'; 164276479Sdim} 165261991Sdimvoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } 166261991Sdimvoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 167261991Sdim int64_t Offset) { 168261991Sdim OS << "\t.setfp\t"; 169261991Sdim InstPrinter.printRegName(OS, FpReg); 170261991Sdim OS << ", "; 171261991Sdim InstPrinter.printRegName(OS, SpReg); 172261991Sdim if (Offset) 173261991Sdim OS << ", #" << Offset; 174261991Sdim OS << '\n'; 175261991Sdim} 176276479Sdimvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 177276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 178276479Sdim "the operand of .movsp cannot be either sp or pc"); 179276479Sdim 180276479Sdim OS << "\t.movsp\t"; 181276479Sdim InstPrinter.printRegName(OS, Reg); 182276479Sdim if (Offset) 183276479Sdim OS << ", #" << Offset; 184276479Sdim OS << '\n'; 185276479Sdim} 186261991Sdimvoid ARMTargetAsmStreamer::emitPad(int64_t Offset) { 187261991Sdim OS << "\t.pad\t#" << Offset << '\n'; 188261991Sdim} 189261991Sdimvoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 190261991Sdim bool isVector) { 191261991Sdim assert(RegList.size() && "RegList should not be empty"); 192261991Sdim if (isVector) 193261991Sdim OS << "\t.vsave\t{"; 194261991Sdim else 195261991Sdim OS << "\t.save\t{"; 196261991Sdim 197261991Sdim InstPrinter.printRegName(OS, RegList[0]); 198261991Sdim 199261991Sdim for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 200261991Sdim OS << ", "; 201261991Sdim InstPrinter.printRegName(OS, RegList[i]); 202261991Sdim } 203261991Sdim 204261991Sdim OS << "}\n"; 205261991Sdim} 206261991Sdimvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) { 207261991Sdim} 208261991Sdimvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 209276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); 210276479Sdim if (IsVerboseAsm) { 211276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 212276479Sdim if (!Name.empty()) 213276479Sdim OS << "\t@ " << Name; 214276479Sdim } 215276479Sdim OS << "\n"; 216261991Sdim} 217261991Sdimvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 218261991Sdim StringRef String) { 219261991Sdim switch (Attribute) { 220261991Sdim case ARMBuildAttrs::CPU_name: 221276479Sdim OS << "\t.cpu\t" << String.lower(); 222261991Sdim break; 223276479Sdim default: 224276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; 225276479Sdim if (IsVerboseAsm) { 226276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 227276479Sdim if (!Name.empty()) 228276479Sdim OS << "\t@ " << Name; 229276479Sdim } 230276479Sdim break; 231261991Sdim } 232276479Sdim OS << "\n"; 233261991Sdim} 234276479Sdimvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, 235276479Sdim unsigned IntValue, 236276479Sdim StringRef StringValue) { 237276479Sdim switch (Attribute) { 238276479Sdim default: llvm_unreachable("unsupported multi-value attribute in asm mode"); 239276479Sdim case ARMBuildAttrs::compatibility: 240276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue; 241276479Sdim if (!StringValue.empty()) 242276479Sdim OS << ", \"" << StringValue << "\""; 243276479Sdim if (IsVerboseAsm) 244276479Sdim OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute); 245276479Sdim break; 246276479Sdim } 247276479Sdim OS << "\n"; 248276479Sdim} 249276479Sdimvoid ARMTargetAsmStreamer::emitArch(unsigned Arch) { 250276479Sdim OS << "\t.arch\t" << GetArchName(Arch) << "\n"; 251276479Sdim} 252276479Sdimvoid ARMTargetAsmStreamer::emitObjectArch(unsigned Arch) { 253276479Sdim OS << "\t.object_arch\t" << GetArchName(Arch) << '\n'; 254276479Sdim} 255261991Sdimvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) { 256261991Sdim OS << "\t.fpu\t" << GetFPUName(FPU) << "\n"; 257261991Sdim} 258261991Sdimvoid ARMTargetAsmStreamer::finishAttributeSection() { 259261991Sdim} 260276479Sdimvoid 261276479SdimARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 262276479Sdim OS << "\t.tlsdescseq\t" << S->getSymbol().getName(); 263276479Sdim} 264261991Sdim 265276479Sdimvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 266276479Sdim OS << "\t.thumb_set\t" << *Symbol << ", " << *Value << '\n'; 267276479Sdim} 268276479Sdim 269276479Sdimvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) { 270276479Sdim OS << "\t.inst"; 271276479Sdim if (Suffix) 272276479Sdim OS << "." << Suffix; 273276479Sdim OS << "\t0x" << utohexstr(Inst) << "\n"; 274276479Sdim} 275276479Sdim 276276479Sdimvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset, 277276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 278276479Sdim OS << "\t.unwind_raw " << Offset; 279276479Sdim for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(), 280276479Sdim OCE = Opcodes.end(); 281276479Sdim OCI != OCE; ++OCI) 282276479Sdim OS << ", 0x" << utohexstr(*OCI); 283276479Sdim OS << '\n'; 284276479Sdim} 285276479Sdim 286261991Sdimclass ARMTargetELFStreamer : public ARMTargetStreamer { 287261991Sdimprivate: 288261991Sdim // This structure holds all attributes, accounting for 289261991Sdim // their string/numeric value, so we can later emmit them 290261991Sdim // in declaration order, keeping all in the same vector 291261991Sdim struct AttributeItem { 292261991Sdim enum { 293261991Sdim HiddenAttribute = 0, 294261991Sdim NumericAttribute, 295276479Sdim TextAttribute, 296276479Sdim NumericAndTextAttributes 297261991Sdim } Type; 298261991Sdim unsigned Tag; 299261991Sdim unsigned IntValue; 300261991Sdim StringRef StringValue; 301261991Sdim 302261991Sdim static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { 303261991Sdim return (LHS.Tag < RHS.Tag); 304261991Sdim } 305261991Sdim }; 306261991Sdim 307261991Sdim StringRef CurrentVendor; 308261991Sdim unsigned FPU; 309276479Sdim unsigned Arch; 310276479Sdim unsigned EmittedArch; 311261991Sdim SmallVector<AttributeItem, 64> Contents; 312261991Sdim 313261991Sdim const MCSection *AttributeSection; 314261991Sdim 315261991Sdim AttributeItem *getAttributeItem(unsigned Attribute) { 316261991Sdim for (size_t i = 0; i < Contents.size(); ++i) 317261991Sdim if (Contents[i].Tag == Attribute) 318261991Sdim return &Contents[i]; 319276479Sdim return nullptr; 320261991Sdim } 321261991Sdim 322261991Sdim void setAttributeItem(unsigned Attribute, unsigned Value, 323261991Sdim bool OverwriteExisting) { 324261991Sdim // Look for existing attribute item 325261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 326261991Sdim if (!OverwriteExisting) 327261991Sdim return; 328276479Sdim Item->Type = AttributeItem::NumericAttribute; 329261991Sdim Item->IntValue = Value; 330261991Sdim return; 331261991Sdim } 332261991Sdim 333261991Sdim // Create new attribute item 334261991Sdim AttributeItem Item = { 335261991Sdim AttributeItem::NumericAttribute, 336261991Sdim Attribute, 337261991Sdim Value, 338261991Sdim StringRef("") 339261991Sdim }; 340261991Sdim Contents.push_back(Item); 341261991Sdim } 342261991Sdim 343261991Sdim void setAttributeItem(unsigned Attribute, StringRef Value, 344261991Sdim bool OverwriteExisting) { 345261991Sdim // Look for existing attribute item 346261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 347261991Sdim if (!OverwriteExisting) 348261991Sdim return; 349276479Sdim Item->Type = AttributeItem::TextAttribute; 350261991Sdim Item->StringValue = Value; 351261991Sdim return; 352261991Sdim } 353261991Sdim 354261991Sdim // Create new attribute item 355261991Sdim AttributeItem Item = { 356261991Sdim AttributeItem::TextAttribute, 357261991Sdim Attribute, 358261991Sdim 0, 359261991Sdim Value 360261991Sdim }; 361261991Sdim Contents.push_back(Item); 362261991Sdim } 363261991Sdim 364276479Sdim void setAttributeItems(unsigned Attribute, unsigned IntValue, 365276479Sdim StringRef StringValue, bool OverwriteExisting) { 366276479Sdim // Look for existing attribute item 367276479Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 368276479Sdim if (!OverwriteExisting) 369276479Sdim return; 370276479Sdim Item->Type = AttributeItem::NumericAndTextAttributes; 371276479Sdim Item->IntValue = IntValue; 372276479Sdim Item->StringValue = StringValue; 373276479Sdim return; 374276479Sdim } 375276479Sdim 376276479Sdim // Create new attribute item 377276479Sdim AttributeItem Item = { 378276479Sdim AttributeItem::NumericAndTextAttributes, 379276479Sdim Attribute, 380276479Sdim IntValue, 381276479Sdim StringValue 382276479Sdim }; 383276479Sdim Contents.push_back(Item); 384276479Sdim } 385276479Sdim 386276479Sdim void emitArchDefaultAttributes(); 387261991Sdim void emitFPUDefaultAttributes(); 388261991Sdim 389261991Sdim ARMELFStreamer &getStreamer(); 390261991Sdim 391276479Sdim void emitFnStart() override; 392276479Sdim void emitFnEnd() override; 393276479Sdim void emitCantUnwind() override; 394276479Sdim void emitPersonality(const MCSymbol *Personality) override; 395276479Sdim void emitPersonalityIndex(unsigned Index) override; 396276479Sdim void emitHandlerData() override; 397276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 398276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 399276479Sdim void emitPad(int64_t Offset) override; 400276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 401276479Sdim bool isVector) override; 402276479Sdim void emitUnwindRaw(int64_t Offset, 403276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 404261991Sdim 405276479Sdim void switchVendor(StringRef Vendor) override; 406276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 407276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 408276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 409276479Sdim StringRef StringValue) override; 410276479Sdim void emitArch(unsigned Arch) override; 411276479Sdim void emitObjectArch(unsigned Arch) override; 412276479Sdim void emitFPU(unsigned FPU) override; 413276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 414276479Sdim void finishAttributeSection() override; 415276479Sdim void emitLabel(MCSymbol *Symbol) override; 416261991Sdim 417276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 418276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 419276479Sdim 420261991Sdim size_t calculateContentSize() const; 421261991Sdim 422261991Sdimpublic: 423276479Sdim ARMTargetELFStreamer(MCStreamer &S) 424276479Sdim : ARMTargetStreamer(S), CurrentVendor("aeabi"), FPU(ARM::INVALID_FPU), 425276479Sdim Arch(ARM::INVALID_ARCH), EmittedArch(ARM::INVALID_ARCH), 426276479Sdim AttributeSection(nullptr) {} 427261991Sdim}; 428261991Sdim 429249259Sdim/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 430249259Sdim/// the appropriate points in the object files. These symbols are defined in the 431249259Sdim/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 432249259Sdim/// 433249259Sdim/// In brief: $a, $t or $d should be emitted at the start of each contiguous 434249259Sdim/// region of ARM code, Thumb code or data in a section. In practice, this 435249259Sdim/// emission does not rely on explicit assembler directives but on inherent 436249259Sdim/// properties of the directives doing the emission (e.g. ".byte" is data, "add 437249259Sdim/// r0, r0, r0" an instruction). 438249259Sdim/// 439249259Sdim/// As a result this system is orthogonal to the DataRegion infrastructure used 440249259Sdim/// by MachO. Beware! 441249259Sdimclass ARMELFStreamer : public MCELFStreamer { 442249259Sdimpublic: 443261991Sdim friend class ARMTargetELFStreamer; 444261991Sdim 445276479Sdim ARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, raw_ostream &OS, 446276479Sdim MCCodeEmitter *Emitter, bool IsThumb) 447276479Sdim : MCELFStreamer(Context, TAB, OS, Emitter), IsThumb(IsThumb), 448276479Sdim MappingSymbolCounter(0), LastEMS(EMS_None) { 449251662Sdim Reset(); 450251662Sdim } 451249259Sdim 452249259Sdim ~ARMELFStreamer() {} 453249259Sdim 454276479Sdim void FinishImpl() override; 455261991Sdim 456249259Sdim // ARM exception handling directives 457261991Sdim void emitFnStart(); 458261991Sdim void emitFnEnd(); 459261991Sdim void emitCantUnwind(); 460261991Sdim void emitPersonality(const MCSymbol *Per); 461276479Sdim void emitPersonalityIndex(unsigned index); 462261991Sdim void emitHandlerData(); 463261991Sdim void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); 464276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0); 465261991Sdim void emitPad(int64_t Offset); 466261991Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); 467276479Sdim void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes); 468249259Sdim 469276479Sdim void ChangeSection(const MCSection *Section, 470276479Sdim const MCExpr *Subsection) override { 471249259Sdim // We have to keep track of the mapping symbol state of any sections we 472249259Sdim // use. Each one should start off as EMS_None, which is provided as the 473249259Sdim // default constructor by DenseMap::lookup. 474251662Sdim LastMappingSymbols[getPreviousSection().first] = LastEMS; 475249259Sdim LastEMS = LastMappingSymbols.lookup(Section); 476249259Sdim 477251662Sdim MCELFStreamer::ChangeSection(Section, Subsection); 478249259Sdim } 479249259Sdim 480249259Sdim /// This function is the one used to emit instruction data into the ELF 481249259Sdim /// streamer. We override it to add the appropriate mapping symbol if 482249259Sdim /// necessary. 483276479Sdim void EmitInstruction(const MCInst& Inst, 484276479Sdim const MCSubtargetInfo &STI) override { 485249259Sdim if (IsThumb) 486249259Sdim EmitThumbMappingSymbol(); 487249259Sdim else 488249259Sdim EmitARMMappingSymbol(); 489249259Sdim 490276479Sdim MCELFStreamer::EmitInstruction(Inst, STI); 491249259Sdim } 492249259Sdim 493276479Sdim void emitInst(uint32_t Inst, char Suffix) { 494276479Sdim unsigned Size; 495276479Sdim char Buffer[4]; 496276479Sdim const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian(); 497276479Sdim 498276479Sdim switch (Suffix) { 499276479Sdim case '\0': 500276479Sdim Size = 4; 501276479Sdim 502276479Sdim assert(!IsThumb); 503276479Sdim EmitARMMappingSymbol(); 504276479Sdim for (unsigned II = 0, IE = Size; II != IE; II++) { 505276479Sdim const unsigned I = LittleEndian ? (Size - II - 1) : II; 506276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT); 507276479Sdim } 508276479Sdim 509276479Sdim break; 510276479Sdim case 'n': 511276479Sdim case 'w': 512276479Sdim Size = (Suffix == 'n' ? 2 : 4); 513276479Sdim 514276479Sdim assert(IsThumb); 515276479Sdim EmitThumbMappingSymbol(); 516276479Sdim for (unsigned II = 0, IE = Size; II != IE; II = II + 2) { 517276479Sdim const unsigned I0 = LittleEndian ? II + 0 : (Size - II - 1); 518276479Sdim const unsigned I1 = LittleEndian ? II + 1 : (Size - II - 2); 519276479Sdim Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT); 520276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT); 521276479Sdim } 522276479Sdim 523276479Sdim break; 524276479Sdim default: 525276479Sdim llvm_unreachable("Invalid Suffix"); 526276479Sdim } 527276479Sdim 528276479Sdim MCELFStreamer::EmitBytes(StringRef(Buffer, Size)); 529276479Sdim } 530276479Sdim 531249259Sdim /// This is one of the functions used to emit data into an ELF section, so the 532249259Sdim /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 533249259Sdim /// necessary. 534276479Sdim void EmitBytes(StringRef Data) override { 535249259Sdim EmitDataMappingSymbol(); 536261991Sdim MCELFStreamer::EmitBytes(Data); 537249259Sdim } 538249259Sdim 539249259Sdim /// This is one of the functions used to emit data into an ELF section, so the 540249259Sdim /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 541249259Sdim /// necessary. 542276479Sdim void EmitValueImpl(const MCExpr *Value, unsigned Size, 543276479Sdim const SMLoc &Loc) override { 544249259Sdim EmitDataMappingSymbol(); 545261991Sdim MCELFStreamer::EmitValueImpl(Value, Size); 546249259Sdim } 547249259Sdim 548276479Sdim void EmitAssemblerFlag(MCAssemblerFlag Flag) override { 549249259Sdim MCELFStreamer::EmitAssemblerFlag(Flag); 550249259Sdim 551249259Sdim switch (Flag) { 552249259Sdim case MCAF_SyntaxUnified: 553249259Sdim return; // no-op here. 554249259Sdim case MCAF_Code16: 555249259Sdim IsThumb = true; 556249259Sdim return; // Change to Thumb mode 557249259Sdim case MCAF_Code32: 558249259Sdim IsThumb = false; 559249259Sdim return; // Change to ARM mode 560249259Sdim case MCAF_Code64: 561249259Sdim return; 562249259Sdim case MCAF_SubsectionsViaSymbols: 563249259Sdim return; 564249259Sdim } 565249259Sdim } 566249259Sdim 567249259Sdimprivate: 568249259Sdim enum ElfMappingSymbol { 569249259Sdim EMS_None, 570249259Sdim EMS_ARM, 571249259Sdim EMS_Thumb, 572249259Sdim EMS_Data 573249259Sdim }; 574249259Sdim 575249259Sdim void EmitDataMappingSymbol() { 576249259Sdim if (LastEMS == EMS_Data) return; 577249259Sdim EmitMappingSymbol("$d"); 578249259Sdim LastEMS = EMS_Data; 579249259Sdim } 580249259Sdim 581249259Sdim void EmitThumbMappingSymbol() { 582249259Sdim if (LastEMS == EMS_Thumb) return; 583249259Sdim EmitMappingSymbol("$t"); 584249259Sdim LastEMS = EMS_Thumb; 585249259Sdim } 586249259Sdim 587249259Sdim void EmitARMMappingSymbol() { 588249259Sdim if (LastEMS == EMS_ARM) return; 589249259Sdim EmitMappingSymbol("$a"); 590249259Sdim LastEMS = EMS_ARM; 591249259Sdim } 592249259Sdim 593249259Sdim void EmitMappingSymbol(StringRef Name) { 594249259Sdim MCSymbol *Start = getContext().CreateTempSymbol(); 595249259Sdim EmitLabel(Start); 596249259Sdim 597249259Sdim MCSymbol *Symbol = 598249259Sdim getContext().GetOrCreateSymbol(Name + "." + 599249259Sdim Twine(MappingSymbolCounter++)); 600249259Sdim 601249259Sdim MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); 602249259Sdim MCELF::SetType(SD, ELF::STT_NOTYPE); 603249259Sdim MCELF::SetBinding(SD, ELF::STB_LOCAL); 604249259Sdim SD.setExternal(false); 605261991Sdim AssignSection(Symbol, getCurrentSection().first); 606249259Sdim 607249259Sdim const MCExpr *Value = MCSymbolRefExpr::Create(Start, getContext()); 608249259Sdim Symbol->setVariableValue(Value); 609249259Sdim } 610249259Sdim 611276479Sdim void EmitThumbFunc(MCSymbol *Func) override { 612249259Sdim getAssembler().setIsThumbFunc(Func); 613276479Sdim EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction); 614249259Sdim } 615249259Sdim 616249259Sdim // Helper functions for ARM exception handling directives 617249259Sdim void Reset(); 618249259Sdim 619249259Sdim void EmitPersonalityFixup(StringRef Name); 620261991Sdim void FlushPendingOffset(); 621261991Sdim void FlushUnwindOpcodes(bool NoHandlerData); 622249259Sdim 623249259Sdim void SwitchToEHSection(const char *Prefix, unsigned Type, unsigned Flags, 624249259Sdim SectionKind Kind, const MCSymbol &Fn); 625249259Sdim void SwitchToExTabSection(const MCSymbol &FnStart); 626249259Sdim void SwitchToExIdxSection(const MCSymbol &FnStart); 627249259Sdim 628276479Sdim void EmitFixup(const MCExpr *Expr, MCFixupKind Kind); 629276479Sdim 630249259Sdim bool IsThumb; 631249259Sdim int64_t MappingSymbolCounter; 632249259Sdim 633249259Sdim DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols; 634249259Sdim ElfMappingSymbol LastEMS; 635249259Sdim 636249259Sdim // ARM Exception Handling Frame Information 637249259Sdim MCSymbol *ExTab; 638249259Sdim MCSymbol *FnStart; 639249259Sdim const MCSymbol *Personality; 640261991Sdim unsigned PersonalityIndex; 641261991Sdim unsigned FPReg; // Frame pointer register 642261991Sdim int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 643261991Sdim int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 644261991Sdim int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 645251662Sdim bool UsedFP; 646249259Sdim bool CantUnwind; 647261991Sdim SmallVector<uint8_t, 64> Opcodes; 648251662Sdim UnwindOpcodeAssembler UnwindOpAsm; 649249259Sdim}; 650251662Sdim} // end anonymous namespace 651249259Sdim 652261991SdimARMELFStreamer &ARMTargetELFStreamer::getStreamer() { 653276479Sdim return static_cast<ARMELFStreamer &>(Streamer); 654261991Sdim} 655261991Sdim 656261991Sdimvoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } 657261991Sdimvoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } 658261991Sdimvoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } 659261991Sdimvoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { 660261991Sdim getStreamer().emitPersonality(Personality); 661261991Sdim} 662276479Sdimvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) { 663276479Sdim getStreamer().emitPersonalityIndex(Index); 664276479Sdim} 665261991Sdimvoid ARMTargetELFStreamer::emitHandlerData() { 666261991Sdim getStreamer().emitHandlerData(); 667261991Sdim} 668261991Sdimvoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 669261991Sdim int64_t Offset) { 670261991Sdim getStreamer().emitSetFP(FpReg, SpReg, Offset); 671261991Sdim} 672276479Sdimvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 673276479Sdim getStreamer().emitMovSP(Reg, Offset); 674276479Sdim} 675261991Sdimvoid ARMTargetELFStreamer::emitPad(int64_t Offset) { 676261991Sdim getStreamer().emitPad(Offset); 677261991Sdim} 678261991Sdimvoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 679261991Sdim bool isVector) { 680261991Sdim getStreamer().emitRegSave(RegList, isVector); 681261991Sdim} 682276479Sdimvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset, 683276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 684276479Sdim getStreamer().emitUnwindRaw(Offset, Opcodes); 685276479Sdim} 686261991Sdimvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) { 687261991Sdim assert(!Vendor.empty() && "Vendor cannot be empty."); 688261991Sdim 689261991Sdim if (CurrentVendor == Vendor) 690261991Sdim return; 691261991Sdim 692261991Sdim if (!CurrentVendor.empty()) 693261991Sdim finishAttributeSection(); 694261991Sdim 695261991Sdim assert(Contents.empty() && 696261991Sdim ".ARM.attributes should be flushed before changing vendor"); 697261991Sdim CurrentVendor = Vendor; 698261991Sdim 699261991Sdim} 700261991Sdimvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 701261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 702261991Sdim} 703261991Sdimvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, 704261991Sdim StringRef Value) { 705261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 706261991Sdim} 707276479Sdimvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 708276479Sdim unsigned IntValue, 709276479Sdim StringRef StringValue) { 710276479Sdim setAttributeItems(Attribute, IntValue, StringValue, 711276479Sdim /* OverwriteExisting= */ true); 712276479Sdim} 713276479Sdimvoid ARMTargetELFStreamer::emitArch(unsigned Value) { 714276479Sdim Arch = Value; 715276479Sdim} 716276479Sdimvoid ARMTargetELFStreamer::emitObjectArch(unsigned Value) { 717276479Sdim EmittedArch = Value; 718276479Sdim} 719276479Sdimvoid ARMTargetELFStreamer::emitArchDefaultAttributes() { 720276479Sdim using namespace ARMBuildAttrs; 721276479Sdim 722276479Sdim setAttributeItem(CPU_name, GetArchDefaultCPUName(Arch), false); 723276479Sdim if (EmittedArch == ARM::INVALID_ARCH) 724276479Sdim setAttributeItem(CPU_arch, GetArchDefaultCPUArch(Arch), false); 725276479Sdim else 726276479Sdim setAttributeItem(CPU_arch, GetArchDefaultCPUArch(EmittedArch), false); 727276479Sdim 728276479Sdim switch (Arch) { 729276479Sdim case ARM::ARMV2: 730276479Sdim case ARM::ARMV2A: 731276479Sdim case ARM::ARMV3: 732276479Sdim case ARM::ARMV3M: 733276479Sdim case ARM::ARMV4: 734276479Sdim case ARM::ARMV5: 735276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 736276479Sdim break; 737276479Sdim 738276479Sdim case ARM::ARMV4T: 739276479Sdim case ARM::ARMV5T: 740276479Sdim case ARM::ARMV5TE: 741276479Sdim case ARM::ARMV6: 742276479Sdim case ARM::ARMV6J: 743276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 744276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 745276479Sdim break; 746276479Sdim 747276479Sdim case ARM::ARMV6T2: 748276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 749276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 750276479Sdim break; 751276479Sdim 752276479Sdim case ARM::ARMV6Z: 753276479Sdim case ARM::ARMV6ZK: 754276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 755276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 756276479Sdim setAttributeItem(Virtualization_use, AllowTZ, false); 757276479Sdim break; 758276479Sdim 759276479Sdim case ARM::ARMV6M: 760276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 761276479Sdim break; 762276479Sdim 763276479Sdim case ARM::ARMV7: 764276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 765276479Sdim break; 766276479Sdim 767276479Sdim case ARM::ARMV7A: 768276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 769276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 770276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 771276479Sdim break; 772276479Sdim 773276479Sdim case ARM::ARMV7R: 774276479Sdim setAttributeItem(CPU_arch_profile, RealTimeProfile, false); 775276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 776276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 777276479Sdim break; 778276479Sdim 779276479Sdim case ARM::ARMV7M: 780276479Sdim setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 781276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 782276479Sdim break; 783276479Sdim 784276479Sdim case ARM::ARMV8A: 785276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 786276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 787276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 788276479Sdim setAttributeItem(MPextension_use, Allowed, false); 789276479Sdim setAttributeItem(Virtualization_use, AllowTZVirtualization, false); 790276479Sdim break; 791276479Sdim 792276479Sdim case ARM::IWMMXT: 793276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 794276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 795276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv1, false); 796276479Sdim break; 797276479Sdim 798276479Sdim case ARM::IWMMXT2: 799276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 800276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 801276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv2, false); 802276479Sdim break; 803276479Sdim 804276479Sdim default: 805276479Sdim report_fatal_error("Unknown Arch: " + Twine(Arch)); 806276479Sdim break; 807276479Sdim } 808276479Sdim} 809261991Sdimvoid ARMTargetELFStreamer::emitFPU(unsigned Value) { 810261991Sdim FPU = Value; 811261991Sdim} 812261991Sdimvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() { 813261991Sdim switch (FPU) { 814261991Sdim case ARM::VFP: 815261991Sdim case ARM::VFPV2: 816276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 817261991Sdim ARMBuildAttrs::AllowFPv2, 818261991Sdim /* OverwriteExisting= */ false); 819261991Sdim break; 820261991Sdim 821261991Sdim case ARM::VFPV3: 822276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 823261991Sdim ARMBuildAttrs::AllowFPv3A, 824261991Sdim /* OverwriteExisting= */ false); 825261991Sdim break; 826261991Sdim 827261991Sdim case ARM::VFPV3_D16: 828276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 829261991Sdim ARMBuildAttrs::AllowFPv3B, 830261991Sdim /* OverwriteExisting= */ false); 831261991Sdim break; 832261991Sdim 833261991Sdim case ARM::VFPV4: 834276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 835261991Sdim ARMBuildAttrs::AllowFPv4A, 836261991Sdim /* OverwriteExisting= */ false); 837261991Sdim break; 838261991Sdim 839261991Sdim case ARM::VFPV4_D16: 840276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 841261991Sdim ARMBuildAttrs::AllowFPv4B, 842261991Sdim /* OverwriteExisting= */ false); 843261991Sdim break; 844261991Sdim 845261991Sdim case ARM::FP_ARMV8: 846276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 847261991Sdim ARMBuildAttrs::AllowFPARMv8A, 848261991Sdim /* OverwriteExisting= */ false); 849261991Sdim break; 850261991Sdim 851261991Sdim case ARM::NEON: 852276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 853261991Sdim ARMBuildAttrs::AllowFPv3A, 854261991Sdim /* OverwriteExisting= */ false); 855261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 856261991Sdim ARMBuildAttrs::AllowNeon, 857261991Sdim /* OverwriteExisting= */ false); 858261991Sdim break; 859261991Sdim 860261991Sdim case ARM::NEON_VFPV4: 861276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 862261991Sdim ARMBuildAttrs::AllowFPv4A, 863261991Sdim /* OverwriteExisting= */ false); 864261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 865261991Sdim ARMBuildAttrs::AllowNeon2, 866261991Sdim /* OverwriteExisting= */ false); 867261991Sdim break; 868261991Sdim 869261991Sdim case ARM::NEON_FP_ARMV8: 870261991Sdim case ARM::CRYPTO_NEON_FP_ARMV8: 871276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 872261991Sdim ARMBuildAttrs::AllowFPARMv8A, 873261991Sdim /* OverwriteExisting= */ false); 874261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 875261991Sdim ARMBuildAttrs::AllowNeonARMv8, 876261991Sdim /* OverwriteExisting= */ false); 877261991Sdim break; 878261991Sdim 879276479Sdim case ARM::SOFTVFP: 880276479Sdim break; 881276479Sdim 882261991Sdim default: 883261991Sdim report_fatal_error("Unknown FPU: " + Twine(FPU)); 884261991Sdim break; 885261991Sdim } 886261991Sdim} 887261991Sdimsize_t ARMTargetELFStreamer::calculateContentSize() const { 888261991Sdim size_t Result = 0; 889261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 890261991Sdim AttributeItem item = Contents[i]; 891261991Sdim switch (item.Type) { 892261991Sdim case AttributeItem::HiddenAttribute: 893261991Sdim break; 894261991Sdim case AttributeItem::NumericAttribute: 895276479Sdim Result += getULEB128Size(item.Tag); 896276479Sdim Result += getULEB128Size(item.IntValue); 897261991Sdim break; 898261991Sdim case AttributeItem::TextAttribute: 899276479Sdim Result += getULEB128Size(item.Tag); 900261991Sdim Result += item.StringValue.size() + 1; // string + '\0' 901261991Sdim break; 902276479Sdim case AttributeItem::NumericAndTextAttributes: 903276479Sdim Result += getULEB128Size(item.Tag); 904276479Sdim Result += getULEB128Size(item.IntValue); 905276479Sdim Result += item.StringValue.size() + 1; // string + '\0'; 906276479Sdim break; 907261991Sdim } 908261991Sdim } 909261991Sdim return Result; 910261991Sdim} 911261991Sdimvoid ARMTargetELFStreamer::finishAttributeSection() { 912261991Sdim // <format-version> 913261991Sdim // [ <section-length> "vendor-name" 914261991Sdim // [ <file-tag> <size> <attribute>* 915261991Sdim // | <section-tag> <size> <section-number>* 0 <attribute>* 916261991Sdim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 917261991Sdim // ]+ 918261991Sdim // ]* 919261991Sdim 920261991Sdim if (FPU != ARM::INVALID_FPU) 921261991Sdim emitFPUDefaultAttributes(); 922261991Sdim 923276479Sdim if (Arch != ARM::INVALID_ARCH) 924276479Sdim emitArchDefaultAttributes(); 925276479Sdim 926261991Sdim if (Contents.empty()) 927261991Sdim return; 928261991Sdim 929261991Sdim std::sort(Contents.begin(), Contents.end(), AttributeItem::LessTag); 930261991Sdim 931261991Sdim ARMELFStreamer &Streamer = getStreamer(); 932261991Sdim 933261991Sdim // Switch to .ARM.attributes section 934261991Sdim if (AttributeSection) { 935261991Sdim Streamer.SwitchSection(AttributeSection); 936261991Sdim } else { 937261991Sdim AttributeSection = 938261991Sdim Streamer.getContext().getELFSection(".ARM.attributes", 939261991Sdim ELF::SHT_ARM_ATTRIBUTES, 940261991Sdim 0, 941261991Sdim SectionKind::getMetadata()); 942261991Sdim Streamer.SwitchSection(AttributeSection); 943261991Sdim 944261991Sdim // Format version 945261991Sdim Streamer.EmitIntValue(0x41, 1); 946261991Sdim } 947261991Sdim 948261991Sdim // Vendor size + Vendor name + '\0' 949261991Sdim const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 950261991Sdim 951261991Sdim // Tag + Tag Size 952261991Sdim const size_t TagHeaderSize = 1 + 4; 953261991Sdim 954261991Sdim const size_t ContentsSize = calculateContentSize(); 955261991Sdim 956261991Sdim Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 957261991Sdim Streamer.EmitBytes(CurrentVendor); 958261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 959261991Sdim 960261991Sdim Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 961261991Sdim Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 962261991Sdim 963261991Sdim // Size should have been accounted for already, now 964261991Sdim // emit each field as its type (ULEB or String) 965261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 966261991Sdim AttributeItem item = Contents[i]; 967261991Sdim Streamer.EmitULEB128IntValue(item.Tag); 968261991Sdim switch (item.Type) { 969261991Sdim default: llvm_unreachable("Invalid attribute type"); 970261991Sdim case AttributeItem::NumericAttribute: 971261991Sdim Streamer.EmitULEB128IntValue(item.IntValue); 972261991Sdim break; 973261991Sdim case AttributeItem::TextAttribute: 974261991Sdim Streamer.EmitBytes(item.StringValue.upper()); 975261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 976261991Sdim break; 977276479Sdim case AttributeItem::NumericAndTextAttributes: 978276479Sdim Streamer.EmitULEB128IntValue(item.IntValue); 979276479Sdim Streamer.EmitBytes(item.StringValue.upper()); 980276479Sdim Streamer.EmitIntValue(0, 1); // '\0' 981276479Sdim break; 982261991Sdim } 983261991Sdim } 984261991Sdim 985261991Sdim Contents.clear(); 986261991Sdim FPU = ARM::INVALID_FPU; 987261991Sdim} 988261991Sdim 989276479Sdimvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 990276479Sdim ARMELFStreamer &Streamer = getStreamer(); 991276479Sdim if (!Streamer.IsThumb) 992276479Sdim return; 993276479Sdim 994276479Sdim const MCSymbolData &SD = Streamer.getOrCreateSymbolData(Symbol); 995276479Sdim unsigned Type = MCELF::GetType(SD); 996276479Sdim if (Type == ELF_STT_Func || Type == ELF_STT_GnuIFunc) 997276479Sdim Streamer.EmitThumbFunc(Symbol); 998276479Sdim} 999276479Sdim 1000276479Sdimvoid 1001276479SdimARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 1002276479Sdim getStreamer().EmitFixup(S, FK_Data_4); 1003276479Sdim} 1004276479Sdim 1005276479Sdimvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 1006276479Sdim if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) { 1007276479Sdim const MCSymbol &Sym = SRE->getSymbol(); 1008276479Sdim if (!Sym.isDefined()) { 1009276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1010276479Sdim return; 1011276479Sdim } 1012276479Sdim } 1013276479Sdim 1014276479Sdim getStreamer().EmitThumbFunc(Symbol); 1015276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1016276479Sdim} 1017276479Sdim 1018276479Sdimvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) { 1019276479Sdim getStreamer().emitInst(Inst, Suffix); 1020276479Sdim} 1021276479Sdim 1022261991Sdimvoid ARMELFStreamer::FinishImpl() { 1023276479Sdim MCTargetStreamer &TS = *getTargetStreamer(); 1024261991Sdim ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1025261991Sdim ATS.finishAttributeSection(); 1026261991Sdim 1027261991Sdim MCELFStreamer::FinishImpl(); 1028261991Sdim} 1029261991Sdim 1030249259Sdiminline void ARMELFStreamer::SwitchToEHSection(const char *Prefix, 1031249259Sdim unsigned Type, 1032249259Sdim unsigned Flags, 1033249259Sdim SectionKind Kind, 1034249259Sdim const MCSymbol &Fn) { 1035249259Sdim const MCSectionELF &FnSection = 1036249259Sdim static_cast<const MCSectionELF &>(Fn.getSection()); 1037249259Sdim 1038249259Sdim // Create the name for new section 1039249259Sdim StringRef FnSecName(FnSection.getSectionName()); 1040249259Sdim SmallString<128> EHSecName(Prefix); 1041249259Sdim if (FnSecName != ".text") { 1042249259Sdim EHSecName += FnSecName; 1043249259Sdim } 1044249259Sdim 1045249259Sdim // Get .ARM.extab or .ARM.exidx section 1046276479Sdim const MCSectionELF *EHSection = nullptr; 1047249259Sdim if (const MCSymbol *Group = FnSection.getGroup()) { 1048249259Sdim EHSection = getContext().getELFSection( 1049249259Sdim EHSecName, Type, Flags | ELF::SHF_GROUP, Kind, 1050249259Sdim FnSection.getEntrySize(), Group->getName()); 1051249259Sdim } else { 1052249259Sdim EHSection = getContext().getELFSection(EHSecName, Type, Flags, Kind); 1053249259Sdim } 1054251662Sdim assert(EHSection && "Failed to get the required EH section"); 1055249259Sdim 1056249259Sdim // Switch to .ARM.extab or .ARM.exidx section 1057249259Sdim SwitchSection(EHSection); 1058276479Sdim EmitCodeAlignment(4); 1059249259Sdim} 1060249259Sdim 1061249259Sdiminline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 1062249259Sdim SwitchToEHSection(".ARM.extab", 1063249259Sdim ELF::SHT_PROGBITS, 1064249259Sdim ELF::SHF_ALLOC, 1065249259Sdim SectionKind::getDataRel(), 1066249259Sdim FnStart); 1067249259Sdim} 1068249259Sdim 1069249259Sdiminline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 1070249259Sdim SwitchToEHSection(".ARM.exidx", 1071249259Sdim ELF::SHT_ARM_EXIDX, 1072249259Sdim ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 1073249259Sdim SectionKind::getDataRel(), 1074249259Sdim FnStart); 1075249259Sdim} 1076276479Sdimvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) { 1077276479Sdim MCDataFragment *Frag = getOrCreateDataFragment(); 1078276479Sdim Frag->getFixups().push_back(MCFixup::Create(Frag->getContents().size(), Expr, 1079276479Sdim Kind)); 1080276479Sdim} 1081249259Sdim 1082249259Sdimvoid ARMELFStreamer::Reset() { 1083276479Sdim ExTab = nullptr; 1084276479Sdim FnStart = nullptr; 1085276479Sdim Personality = nullptr; 1086276479Sdim PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX; 1087261991Sdim FPReg = ARM::SP; 1088251662Sdim FPOffset = 0; 1089251662Sdim SPOffset = 0; 1090261991Sdim PendingOffset = 0; 1091251662Sdim UsedFP = false; 1092249259Sdim CantUnwind = false; 1093251662Sdim 1094261991Sdim Opcodes.clear(); 1095251662Sdim UnwindOpAsm.Reset(); 1096249259Sdim} 1097249259Sdim 1098261991Sdimvoid ARMELFStreamer::emitFnStart() { 1099276479Sdim assert(FnStart == nullptr); 1100249259Sdim FnStart = getContext().CreateTempSymbol(); 1101249259Sdim EmitLabel(FnStart); 1102249259Sdim} 1103249259Sdim 1104261991Sdimvoid ARMELFStreamer::emitFnEnd() { 1105276479Sdim assert(FnStart && ".fnstart must precedes .fnend"); 1106249259Sdim 1107249259Sdim // Emit unwind opcodes if there is no .handlerdata directive 1108261991Sdim if (!ExTab && !CantUnwind) 1109261991Sdim FlushUnwindOpcodes(true); 1110249259Sdim 1111249259Sdim // Emit the exception index table entry 1112249259Sdim SwitchToExIdxSection(*FnStart); 1113249259Sdim 1114276479Sdim if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX) 1115251662Sdim EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 1116249259Sdim 1117249259Sdim const MCSymbolRefExpr *FnStartRef = 1118249259Sdim MCSymbolRefExpr::Create(FnStart, 1119249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1120249259Sdim getContext()); 1121249259Sdim 1122261991Sdim EmitValue(FnStartRef, 4); 1123249259Sdim 1124249259Sdim if (CantUnwind) { 1125276479Sdim EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4); 1126251662Sdim } else if (ExTab) { 1127251662Sdim // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 1128249259Sdim const MCSymbolRefExpr *ExTabEntryRef = 1129249259Sdim MCSymbolRefExpr::Create(ExTab, 1130249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1131249259Sdim getContext()); 1132261991Sdim EmitValue(ExTabEntryRef, 4); 1133251662Sdim } else { 1134251662Sdim // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 1135251662Sdim // the second word of exception index table entry. The size of the unwind 1136251662Sdim // opcodes should always be 4 bytes. 1137276479Sdim assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 && 1138276479Sdim "Compact model must use __aeabi_unwind_cpp_pr0 as personality"); 1139261991Sdim assert(Opcodes.size() == 4u && 1140276479Sdim "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4"); 1141276479Sdim uint64_t Intval = Opcodes[0] | 1142276479Sdim Opcodes[1] << 8 | 1143276479Sdim Opcodes[2] << 16 | 1144276479Sdim Opcodes[3] << 24; 1145276479Sdim EmitIntValue(Intval, Opcodes.size()); 1146249259Sdim } 1147249259Sdim 1148261991Sdim // Switch to the section containing FnStart 1149261991Sdim SwitchSection(&FnStart->getSection()); 1150261991Sdim 1151249259Sdim // Clean exception handling frame information 1152249259Sdim Reset(); 1153249259Sdim} 1154249259Sdim 1155261991Sdimvoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } 1156261991Sdim 1157261991Sdim// Add the R_ARM_NONE fixup at the same position 1158261991Sdimvoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 1159261991Sdim const MCSymbol *PersonalitySym = getContext().GetOrCreateSymbol(Name); 1160261991Sdim 1161261991Sdim const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::Create( 1162261991Sdim PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); 1163261991Sdim 1164276479Sdim visitUsedExpr(*PersonalityRef); 1165261991Sdim MCDataFragment *DF = getOrCreateDataFragment(); 1166261991Sdim DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), 1167261991Sdim PersonalityRef, 1168261991Sdim MCFixup::getKindForSize(4, false))); 1169249259Sdim} 1170249259Sdim 1171261991Sdimvoid ARMELFStreamer::FlushPendingOffset() { 1172261991Sdim if (PendingOffset != 0) { 1173261991Sdim UnwindOpAsm.EmitSPOffset(-PendingOffset); 1174261991Sdim PendingOffset = 0; 1175261991Sdim } 1176261991Sdim} 1177261991Sdim 1178261991Sdimvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 1179261991Sdim // Emit the unwind opcode to restore $sp. 1180261991Sdim if (UsedFP) { 1181261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1182261991Sdim int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 1183261991Sdim UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 1184261991Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1185261991Sdim } else { 1186261991Sdim FlushPendingOffset(); 1187261991Sdim } 1188261991Sdim 1189261991Sdim // Finalize the unwind opcode sequence 1190261991Sdim UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 1191261991Sdim 1192261991Sdim // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 1193261991Sdim // section. Thus, we don't have to create an entry in the .ARM.extab 1194261991Sdim // section. 1195276479Sdim if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0) 1196261991Sdim return; 1197261991Sdim 1198261991Sdim // Switch to .ARM.extab section. 1199249259Sdim SwitchToExTabSection(*FnStart); 1200249259Sdim 1201249259Sdim // Create .ARM.extab label for offset in .ARM.exidx 1202249259Sdim assert(!ExTab); 1203249259Sdim ExTab = getContext().CreateTempSymbol(); 1204249259Sdim EmitLabel(ExTab); 1205249259Sdim 1206261991Sdim // Emit personality 1207261991Sdim if (Personality) { 1208261991Sdim const MCSymbolRefExpr *PersonalityRef = 1209261991Sdim MCSymbolRefExpr::Create(Personality, 1210261991Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1211261991Sdim getContext()); 1212249259Sdim 1213261991Sdim EmitValue(PersonalityRef, 4); 1214261991Sdim } 1215249259Sdim 1216261991Sdim // Emit unwind opcodes 1217276479Sdim assert((Opcodes.size() % 4) == 0 && 1218276479Sdim "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4"); 1219276479Sdim for (unsigned I = 0; I != Opcodes.size(); I += 4) { 1220276479Sdim uint64_t Intval = Opcodes[I] | 1221276479Sdim Opcodes[I + 1] << 8 | 1222276479Sdim Opcodes[I + 2] << 16 | 1223276479Sdim Opcodes[I + 3] << 24; 1224276479Sdim EmitIntValue(Intval, 4); 1225276479Sdim } 1226249259Sdim 1227261991Sdim // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 1228261991Sdim // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 1229261991Sdim // after the unwind opcodes. The handler data consists of several 32-bit 1230261991Sdim // words, and should be terminated by zero. 1231261991Sdim // 1232261991Sdim // In case that the .handlerdata directive is not specified by the 1233261991Sdim // programmer, we should emit zero to terminate the handler data. 1234261991Sdim if (NoHandlerData && !Personality) 1235261991Sdim EmitIntValue(0, 4); 1236249259Sdim} 1237249259Sdim 1238261991Sdimvoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } 1239261991Sdim 1240261991Sdimvoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) { 1241249259Sdim Personality = Per; 1242251662Sdim UnwindOpAsm.setPersonality(Per); 1243249259Sdim} 1244249259Sdim 1245276479Sdimvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) { 1246276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index"); 1247276479Sdim PersonalityIndex = Index; 1248276479Sdim} 1249276479Sdim 1250261991Sdimvoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, 1251249259Sdim int64_t Offset) { 1252261991Sdim assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 1253251662Sdim "the operand of .setfp directive should be either $sp or $fp"); 1254251662Sdim 1255251662Sdim UsedFP = true; 1256261991Sdim FPReg = NewFPReg; 1257261991Sdim 1258261991Sdim if (NewSPReg == ARM::SP) 1259261991Sdim FPOffset = SPOffset + Offset; 1260261991Sdim else 1261261991Sdim FPOffset += Offset; 1262249259Sdim} 1263249259Sdim 1264276479Sdimvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 1265276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 1266276479Sdim "the operand of .movsp cannot be either sp or pc"); 1267276479Sdim assert(FPReg == ARM::SP && "current FP must be SP"); 1268276479Sdim 1269276479Sdim FlushPendingOffset(); 1270276479Sdim 1271276479Sdim FPReg = Reg; 1272276479Sdim FPOffset = SPOffset + Offset; 1273276479Sdim 1274276479Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1275276479Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1276276479Sdim} 1277276479Sdim 1278261991Sdimvoid ARMELFStreamer::emitPad(int64_t Offset) { 1279261991Sdim // Track the change of the $sp offset 1280261991Sdim SPOffset -= Offset; 1281261991Sdim 1282261991Sdim // To squash multiple .pad directives, we should delay the unwind opcode 1283261991Sdim // until the .save, .vsave, .handlerdata, or .fnend directives. 1284261991Sdim PendingOffset -= Offset; 1285249259Sdim} 1286249259Sdim 1287261991Sdimvoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 1288249259Sdim bool IsVector) { 1289261991Sdim // Collect the registers in the register list 1290261991Sdim unsigned Count = 0; 1291261991Sdim uint32_t Mask = 0; 1292261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1293261991Sdim for (size_t i = 0; i < RegList.size(); ++i) { 1294261991Sdim unsigned Reg = MRI->getEncodingValue(RegList[i]); 1295261991Sdim assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 1296261991Sdim unsigned Bit = (1u << Reg); 1297261991Sdim if ((Mask & Bit) == 0) { 1298261991Sdim Mask |= Bit; 1299261991Sdim ++Count; 1300261991Sdim } 1301261991Sdim } 1302251662Sdim 1303261991Sdim // Track the change the $sp offset: For the .save directive, the 1304261991Sdim // corresponding push instruction will decrease the $sp by (4 * Count). 1305261991Sdim // For the .vsave directive, the corresponding vpush instruction will 1306261991Sdim // decrease $sp by (8 * Count). 1307261991Sdim SPOffset -= Count * (IsVector ? 8 : 4); 1308251662Sdim 1309261991Sdim // Emit the opcode 1310261991Sdim FlushPendingOffset(); 1311261991Sdim if (IsVector) 1312261991Sdim UnwindOpAsm.EmitVFPRegSave(Mask); 1313261991Sdim else 1314261991Sdim UnwindOpAsm.EmitRegSave(Mask); 1315249259Sdim} 1316249259Sdim 1317276479Sdimvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset, 1318276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 1319276479Sdim FlushPendingOffset(); 1320276479Sdim SPOffset = SPOffset - Offset; 1321276479Sdim UnwindOpAsm.EmitRaw(Opcodes); 1322276479Sdim} 1323276479Sdim 1324249259Sdimnamespace llvm { 1325261991Sdim 1326261991SdimMCStreamer *createMCAsmStreamer(MCContext &Ctx, formatted_raw_ostream &OS, 1327276479Sdim bool isVerboseAsm, bool useDwarfDirectory, 1328261991Sdim MCInstPrinter *InstPrint, MCCodeEmitter *CE, 1329261991Sdim MCAsmBackend *TAB, bool ShowInst) { 1330276479Sdim MCStreamer *S = llvm::createAsmStreamer( 1331276479Sdim Ctx, OS, isVerboseAsm, useDwarfDirectory, InstPrint, CE, TAB, ShowInst); 1332276479Sdim new ARMTargetAsmStreamer(*S, OS, *InstPrint, isVerboseAsm); 1333276479Sdim return S; 1334276479Sdim} 1335261991Sdim 1336276479SdimMCStreamer *createARMNullStreamer(MCContext &Ctx) { 1337276479Sdim MCStreamer *S = llvm::createNullStreamer(Ctx); 1338276479Sdim new ARMTargetStreamer(*S); 1339276479Sdim return S; 1340261991Sdim} 1341261991Sdim 1342249259Sdim MCELFStreamer* createARMELFStreamer(MCContext &Context, MCAsmBackend &TAB, 1343249259Sdim raw_ostream &OS, MCCodeEmitter *Emitter, 1344249259Sdim bool RelaxAll, bool NoExecStack, 1345249259Sdim bool IsThumb) { 1346276479Sdim ARMELFStreamer *S = new ARMELFStreamer(Context, TAB, OS, Emitter, IsThumb); 1347276479Sdim new ARMTargetELFStreamer(*S); 1348261991Sdim // FIXME: This should eventually end up somewhere else where more 1349261991Sdim // intelligent flag decisions can be made. For now we are just maintaining 1350261991Sdim // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 1351261991Sdim S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1352261991Sdim 1353249259Sdim if (RelaxAll) 1354249259Sdim S->getAssembler().setRelaxAll(true); 1355249259Sdim if (NoExecStack) 1356249259Sdim S->getAssembler().setNoExecStack(true); 1357249259Sdim return S; 1358249259Sdim } 1359249259Sdim 1360249259Sdim} 1361249259Sdim 1362249259Sdim 1363