1249259Sdim//===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===// 2249259Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6249259Sdim// 7249259Sdim//===----------------------------------------------------------------------===// 8249259Sdim// 9249259Sdim// This file assembles .s files and emits ARM ELF .o object files. Different 10249259Sdim// from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to 11249259Sdim// delimit regions of data and code. 12249259Sdim// 13249259Sdim//===----------------------------------------------------------------------===// 14249259Sdim 15251662Sdim#include "ARMRegisterInfo.h" 16251662Sdim#include "ARMUnwindOpAsm.h" 17321369Sdim#include "llvm/ADT/DenseMap.h" 18321369Sdim#include "llvm/ADT/SmallString.h" 19321369Sdim#include "llvm/ADT/SmallVector.h" 20321369Sdim#include "llvm/ADT/StringRef.h" 21321369Sdim#include "llvm/ADT/Triple.h" 22249259Sdim#include "llvm/ADT/Twine.h" 23321369Sdim#include "llvm/BinaryFormat/ELF.h" 24249259Sdim#include "llvm/MC/MCAsmBackend.h" 25276479Sdim#include "llvm/MC/MCAsmInfo.h" 26249259Sdim#include "llvm/MC/MCAssembler.h" 27249259Sdim#include "llvm/MC/MCCodeEmitter.h" 28249259Sdim#include "llvm/MC/MCContext.h" 29249259Sdim#include "llvm/MC/MCELFStreamer.h" 30249259Sdim#include "llvm/MC/MCExpr.h" 31321369Sdim#include "llvm/MC/MCFixup.h" 32321369Sdim#include "llvm/MC/MCFragment.h" 33249259Sdim#include "llvm/MC/MCInst.h" 34261991Sdim#include "llvm/MC/MCInstPrinter.h" 35341825Sdim#include "llvm/MC/MCObjectWriter.h" 36251662Sdim#include "llvm/MC/MCRegisterInfo.h" 37249259Sdim#include "llvm/MC/MCSection.h" 38249259Sdim#include "llvm/MC/MCSectionELF.h" 39249259Sdim#include "llvm/MC/MCStreamer.h" 40321369Sdim#include "llvm/MC/MCSubtargetInfo.h" 41321369Sdim#include "llvm/MC/MCSymbol.h" 42288943Sdim#include "llvm/MC/MCSymbolELF.h" 43321369Sdim#include "llvm/MC/SectionKind.h" 44276479Sdim#include "llvm/Support/ARMBuildAttributes.h" 45276479Sdim#include "llvm/Support/ARMEHABI.h" 46321369Sdim#include "llvm/Support/Casting.h" 47321369Sdim#include "llvm/Support/ErrorHandling.h" 48261991Sdim#include "llvm/Support/FormattedStream.h" 49276479Sdim#include "llvm/Support/LEB128.h" 50321369Sdim#include "llvm/Support/TargetParser.h" 51249259Sdim#include "llvm/Support/raw_ostream.h" 52261991Sdim#include <algorithm> 53321369Sdim#include <cassert> 54321369Sdim#include <climits> 55321369Sdim#include <cstddef> 56321369Sdim#include <cstdint> 57321369Sdim#include <string> 58249259Sdim 59249259Sdimusing namespace llvm; 60249259Sdim 61251662Sdimstatic std::string GetAEABIUnwindPersonalityName(unsigned Index) { 62276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && 63276479Sdim "Invalid personality index"); 64251662Sdim return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str(); 65251662Sdim} 66251662Sdim 67249259Sdimnamespace { 68249259Sdim 69261991Sdimclass ARMELFStreamer; 70261991Sdim 71261991Sdimclass ARMTargetAsmStreamer : public ARMTargetStreamer { 72261991Sdim formatted_raw_ostream &OS; 73261991Sdim MCInstPrinter &InstPrinter; 74276479Sdim bool IsVerboseAsm; 75261991Sdim 76276479Sdim void emitFnStart() override; 77276479Sdim void emitFnEnd() override; 78276479Sdim void emitCantUnwind() override; 79276479Sdim void emitPersonality(const MCSymbol *Personality) override; 80276479Sdim void emitPersonalityIndex(unsigned Index) override; 81276479Sdim void emitHandlerData() override; 82276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 83276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 84276479Sdim void emitPad(int64_t Offset) override; 85276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 86276479Sdim bool isVector) override; 87276479Sdim void emitUnwindRaw(int64_t Offset, 88276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 89261991Sdim 90276479Sdim void switchVendor(StringRef Vendor) override; 91276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 92276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 93276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 94296417Sdim StringRef StringValue) override; 95327952Sdim void emitArch(ARM::ArchKind Arch) override; 96288943Sdim void emitArchExtension(unsigned ArchExt) override; 97327952Sdim void emitObjectArch(ARM::ArchKind Arch) override; 98276479Sdim void emitFPU(unsigned FPU) override; 99276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 100276479Sdim void finishAttributeSection() override; 101261991Sdim 102276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 103276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 104276479Sdim 105261991Sdimpublic: 106276479Sdim ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, 107276479Sdim MCInstPrinter &InstPrinter, bool VerboseAsm); 108261991Sdim}; 109261991Sdim 110276479SdimARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S, 111276479Sdim formatted_raw_ostream &OS, 112276479Sdim MCInstPrinter &InstPrinter, 113276479Sdim bool VerboseAsm) 114276479Sdim : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter), 115276479Sdim IsVerboseAsm(VerboseAsm) {} 116321369Sdim 117261991Sdimvoid ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; } 118261991Sdimvoid ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; } 119261991Sdimvoid ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; } 120321369Sdim 121261991Sdimvoid ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) { 122261991Sdim OS << "\t.personality " << Personality->getName() << '\n'; 123261991Sdim} 124321369Sdim 125276479Sdimvoid ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) { 126276479Sdim OS << "\t.personalityindex " << Index << '\n'; 127276479Sdim} 128321369Sdim 129261991Sdimvoid ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; } 130321369Sdim 131261991Sdimvoid ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 132261991Sdim int64_t Offset) { 133261991Sdim OS << "\t.setfp\t"; 134261991Sdim InstPrinter.printRegName(OS, FpReg); 135261991Sdim OS << ", "; 136261991Sdim InstPrinter.printRegName(OS, SpReg); 137261991Sdim if (Offset) 138261991Sdim OS << ", #" << Offset; 139261991Sdim OS << '\n'; 140261991Sdim} 141321369Sdim 142276479Sdimvoid ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 143276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 144276479Sdim "the operand of .movsp cannot be either sp or pc"); 145276479Sdim 146276479Sdim OS << "\t.movsp\t"; 147276479Sdim InstPrinter.printRegName(OS, Reg); 148276479Sdim if (Offset) 149276479Sdim OS << ", #" << Offset; 150276479Sdim OS << '\n'; 151276479Sdim} 152321369Sdim 153261991Sdimvoid ARMTargetAsmStreamer::emitPad(int64_t Offset) { 154261991Sdim OS << "\t.pad\t#" << Offset << '\n'; 155261991Sdim} 156321369Sdim 157261991Sdimvoid ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 158261991Sdim bool isVector) { 159261991Sdim assert(RegList.size() && "RegList should not be empty"); 160261991Sdim if (isVector) 161261991Sdim OS << "\t.vsave\t{"; 162261991Sdim else 163261991Sdim OS << "\t.save\t{"; 164261991Sdim 165261991Sdim InstPrinter.printRegName(OS, RegList[0]); 166261991Sdim 167261991Sdim for (unsigned i = 1, e = RegList.size(); i != e; ++i) { 168261991Sdim OS << ", "; 169261991Sdim InstPrinter.printRegName(OS, RegList[i]); 170261991Sdim } 171261991Sdim 172261991Sdim OS << "}\n"; 173261991Sdim} 174321369Sdim 175321369Sdimvoid ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {} 176321369Sdim 177261991Sdimvoid ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 178276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value); 179276479Sdim if (IsVerboseAsm) { 180276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 181276479Sdim if (!Name.empty()) 182276479Sdim OS << "\t@ " << Name; 183276479Sdim } 184276479Sdim OS << "\n"; 185261991Sdim} 186321369Sdim 187261991Sdimvoid ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute, 188261991Sdim StringRef String) { 189261991Sdim switch (Attribute) { 190261991Sdim case ARMBuildAttrs::CPU_name: 191276479Sdim OS << "\t.cpu\t" << String.lower(); 192261991Sdim break; 193276479Sdim default: 194276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\""; 195276479Sdim if (IsVerboseAsm) { 196276479Sdim StringRef Name = ARMBuildAttrs::AttrTypeAsString(Attribute); 197276479Sdim if (!Name.empty()) 198276479Sdim OS << "\t@ " << Name; 199276479Sdim } 200276479Sdim break; 201261991Sdim } 202276479Sdim OS << "\n"; 203261991Sdim} 204321369Sdim 205276479Sdimvoid ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute, 206276479Sdim unsigned IntValue, 207276479Sdim StringRef StringValue) { 208276479Sdim switch (Attribute) { 209276479Sdim default: llvm_unreachable("unsupported multi-value attribute in asm mode"); 210276479Sdim case ARMBuildAttrs::compatibility: 211276479Sdim OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue; 212276479Sdim if (!StringValue.empty()) 213276479Sdim OS << ", \"" << StringValue << "\""; 214276479Sdim if (IsVerboseAsm) 215276479Sdim OS << "\t@ " << ARMBuildAttrs::AttrTypeAsString(Attribute); 216276479Sdim break; 217276479Sdim } 218276479Sdim OS << "\n"; 219276479Sdim} 220321369Sdim 221327952Sdimvoid ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) { 222296417Sdim OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n"; 223276479Sdim} 224321369Sdim 225288943Sdimvoid ARMTargetAsmStreamer::emitArchExtension(unsigned ArchExt) { 226296417Sdim OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n"; 227288943Sdim} 228321369Sdim 229327952Sdimvoid ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) { 230296417Sdim OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n'; 231276479Sdim} 232321369Sdim 233261991Sdimvoid ARMTargetAsmStreamer::emitFPU(unsigned FPU) { 234296417Sdim OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n"; 235261991Sdim} 236321369Sdim 237321369Sdimvoid ARMTargetAsmStreamer::finishAttributeSection() {} 238321369Sdim 239276479Sdimvoid 240276479SdimARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 241276479Sdim OS << "\t.tlsdescseq\t" << S->getSymbol().getName(); 242276479Sdim} 243261991Sdim 244276479Sdimvoid ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 245288943Sdim const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo(); 246288943Sdim 247288943Sdim OS << "\t.thumb_set\t"; 248288943Sdim Symbol->print(OS, MAI); 249288943Sdim OS << ", "; 250288943Sdim Value->print(OS, MAI); 251288943Sdim OS << '\n'; 252276479Sdim} 253276479Sdim 254276479Sdimvoid ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) { 255276479Sdim OS << "\t.inst"; 256276479Sdim if (Suffix) 257276479Sdim OS << "." << Suffix; 258288943Sdim OS << "\t0x" << Twine::utohexstr(Inst) << "\n"; 259276479Sdim} 260276479Sdim 261276479Sdimvoid ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset, 262276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 263276479Sdim OS << "\t.unwind_raw " << Offset; 264276479Sdim for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(), 265276479Sdim OCE = Opcodes.end(); 266276479Sdim OCI != OCE; ++OCI) 267288943Sdim OS << ", 0x" << Twine::utohexstr(*OCI); 268276479Sdim OS << '\n'; 269276479Sdim} 270276479Sdim 271261991Sdimclass ARMTargetELFStreamer : public ARMTargetStreamer { 272261991Sdimprivate: 273261991Sdim // This structure holds all attributes, accounting for 274296417Sdim // their string/numeric value, so we can later emit them 275261991Sdim // in declaration order, keeping all in the same vector 276261991Sdim struct AttributeItem { 277261991Sdim enum { 278261991Sdim HiddenAttribute = 0, 279261991Sdim NumericAttribute, 280276479Sdim TextAttribute, 281276479Sdim NumericAndTextAttributes 282261991Sdim } Type; 283261991Sdim unsigned Tag; 284261991Sdim unsigned IntValue; 285296417Sdim std::string StringValue; 286261991Sdim 287261991Sdim static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) { 288280031Sdim // The conformance tag must be emitted first when serialised 289280031Sdim // into an object file. Specifically, the addenda to the ARM ABI 290280031Sdim // states that (2.3.7.4): 291280031Sdim // 292280031Sdim // "To simplify recognition by consumers in the common case of 293280031Sdim // claiming conformity for the whole file, this tag should be 294280031Sdim // emitted first in a file-scope sub-subsection of the first 295280031Sdim // public subsection of the attributes section." 296280031Sdim // 297280031Sdim // So it is special-cased in this comparison predicate when the 298280031Sdim // attributes are sorted in finishAttributeSection(). 299280031Sdim return (RHS.Tag != ARMBuildAttrs::conformance) && 300280031Sdim ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag)); 301261991Sdim } 302261991Sdim }; 303261991Sdim 304261991Sdim StringRef CurrentVendor; 305321369Sdim unsigned FPU = ARM::FK_INVALID; 306327952Sdim ARM::ArchKind Arch = ARM::ArchKind::INVALID; 307327952Sdim ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID; 308261991Sdim SmallVector<AttributeItem, 64> Contents; 309261991Sdim 310321369Sdim MCSection *AttributeSection = nullptr; 311261991Sdim 312261991Sdim AttributeItem *getAttributeItem(unsigned Attribute) { 313261991Sdim for (size_t i = 0; i < Contents.size(); ++i) 314261991Sdim if (Contents[i].Tag == Attribute) 315261991Sdim return &Contents[i]; 316276479Sdim return nullptr; 317261991Sdim } 318261991Sdim 319261991Sdim void setAttributeItem(unsigned Attribute, unsigned Value, 320261991Sdim bool OverwriteExisting) { 321261991Sdim // Look for existing attribute item 322261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 323261991Sdim if (!OverwriteExisting) 324261991Sdim return; 325276479Sdim Item->Type = AttributeItem::NumericAttribute; 326261991Sdim Item->IntValue = Value; 327261991Sdim return; 328261991Sdim } 329261991Sdim 330261991Sdim // Create new attribute item 331261991Sdim AttributeItem Item = { 332261991Sdim AttributeItem::NumericAttribute, 333261991Sdim Attribute, 334261991Sdim Value, 335261991Sdim StringRef("") 336261991Sdim }; 337261991Sdim Contents.push_back(Item); 338261991Sdim } 339261991Sdim 340261991Sdim void setAttributeItem(unsigned Attribute, StringRef Value, 341261991Sdim bool OverwriteExisting) { 342261991Sdim // Look for existing attribute item 343261991Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 344261991Sdim if (!OverwriteExisting) 345261991Sdim return; 346276479Sdim Item->Type = AttributeItem::TextAttribute; 347261991Sdim Item->StringValue = Value; 348261991Sdim return; 349261991Sdim } 350261991Sdim 351261991Sdim // Create new attribute item 352261991Sdim AttributeItem Item = { 353261991Sdim AttributeItem::TextAttribute, 354261991Sdim Attribute, 355261991Sdim 0, 356261991Sdim Value 357261991Sdim }; 358261991Sdim Contents.push_back(Item); 359261991Sdim } 360261991Sdim 361276479Sdim void setAttributeItems(unsigned Attribute, unsigned IntValue, 362276479Sdim StringRef StringValue, bool OverwriteExisting) { 363276479Sdim // Look for existing attribute item 364276479Sdim if (AttributeItem *Item = getAttributeItem(Attribute)) { 365276479Sdim if (!OverwriteExisting) 366276479Sdim return; 367276479Sdim Item->Type = AttributeItem::NumericAndTextAttributes; 368276479Sdim Item->IntValue = IntValue; 369276479Sdim Item->StringValue = StringValue; 370276479Sdim return; 371276479Sdim } 372276479Sdim 373276479Sdim // Create new attribute item 374276479Sdim AttributeItem Item = { 375276479Sdim AttributeItem::NumericAndTextAttributes, 376276479Sdim Attribute, 377276479Sdim IntValue, 378276479Sdim StringValue 379276479Sdim }; 380276479Sdim Contents.push_back(Item); 381276479Sdim } 382276479Sdim 383276479Sdim void emitArchDefaultAttributes(); 384261991Sdim void emitFPUDefaultAttributes(); 385261991Sdim 386261991Sdim ARMELFStreamer &getStreamer(); 387261991Sdim 388276479Sdim void emitFnStart() override; 389276479Sdim void emitFnEnd() override; 390276479Sdim void emitCantUnwind() override; 391276479Sdim void emitPersonality(const MCSymbol *Personality) override; 392276479Sdim void emitPersonalityIndex(unsigned Index) override; 393276479Sdim void emitHandlerData() override; 394276479Sdim void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override; 395276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0) override; 396276479Sdim void emitPad(int64_t Offset) override; 397276479Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, 398276479Sdim bool isVector) override; 399276479Sdim void emitUnwindRaw(int64_t Offset, 400276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) override; 401261991Sdim 402276479Sdim void switchVendor(StringRef Vendor) override; 403276479Sdim void emitAttribute(unsigned Attribute, unsigned Value) override; 404276479Sdim void emitTextAttribute(unsigned Attribute, StringRef String) override; 405276479Sdim void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, 406276479Sdim StringRef StringValue) override; 407327952Sdim void emitArch(ARM::ArchKind Arch) override; 408327952Sdim void emitObjectArch(ARM::ArchKind Arch) override; 409276479Sdim void emitFPU(unsigned FPU) override; 410276479Sdim void emitInst(uint32_t Inst, char Suffix = '\0') override; 411276479Sdim void finishAttributeSection() override; 412276479Sdim void emitLabel(MCSymbol *Symbol) override; 413261991Sdim 414276479Sdim void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override; 415276479Sdim void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override; 416276479Sdim 417261991Sdim size_t calculateContentSize() const; 418261991Sdim 419296417Sdim // Reset state between object emissions 420296417Sdim void reset() override; 421296417Sdim 422261991Sdimpublic: 423276479Sdim ARMTargetELFStreamer(MCStreamer &S) 424321369Sdim : ARMTargetStreamer(S), CurrentVendor("aeabi") {} 425261991Sdim}; 426261991Sdim 427249259Sdim/// Extend the generic ELFStreamer class so that it can emit mapping symbols at 428249259Sdim/// the appropriate points in the object files. These symbols are defined in the 429249259Sdim/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf. 430249259Sdim/// 431249259Sdim/// In brief: $a, $t or $d should be emitted at the start of each contiguous 432249259Sdim/// region of ARM code, Thumb code or data in a section. In practice, this 433249259Sdim/// emission does not rely on explicit assembler directives but on inherent 434249259Sdim/// properties of the directives doing the emission (e.g. ".byte" is data, "add 435249259Sdim/// r0, r0, r0" an instruction). 436249259Sdim/// 437249259Sdim/// As a result this system is orthogonal to the DataRegion infrastructure used 438249259Sdim/// by MachO. Beware! 439249259Sdimclass ARMELFStreamer : public MCELFStreamer { 440249259Sdimpublic: 441261991Sdim friend class ARMTargetELFStreamer; 442261991Sdim 443327952Sdim ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB, 444360784Sdim std::unique_ptr<MCObjectWriter> OW, 445360784Sdim std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb, 446360784Sdim bool IsAndroid) 447360784Sdim : MCELFStreamer(Context, std::move(TAB), std::move(OW), 448360784Sdim std::move(Emitter)), 449360784Sdim IsThumb(IsThumb), IsAndroid(IsAndroid) { 450296417Sdim EHReset(); 451251662Sdim } 452249259Sdim 453321369Sdim ~ARMELFStreamer() override = default; 454249259Sdim 455276479Sdim void FinishImpl() override; 456261991Sdim 457249259Sdim // ARM exception handling directives 458261991Sdim void emitFnStart(); 459261991Sdim void emitFnEnd(); 460261991Sdim void emitCantUnwind(); 461261991Sdim void emitPersonality(const MCSymbol *Per); 462276479Sdim void emitPersonalityIndex(unsigned index); 463261991Sdim void emitHandlerData(); 464261991Sdim void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0); 465276479Sdim void emitMovSP(unsigned Reg, int64_t Offset = 0); 466261991Sdim void emitPad(int64_t Offset); 467261991Sdim void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector); 468276479Sdim void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes); 469344779Sdim void emitFill(const MCExpr &NumBytes, uint64_t FillValue, 470344779Sdim SMLoc Loc) override { 471344779Sdim EmitDataMappingSymbol(); 472344779Sdim MCObjectStreamer::emitFill(NumBytes, FillValue, Loc); 473344779Sdim } 474249259Sdim 475288943Sdim void ChangeSection(MCSection *Section, const MCExpr *Subsection) override { 476321369Sdim LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo); 477251662Sdim MCELFStreamer::ChangeSection(Section, Subsection); 478321369Sdim auto LastMappingSymbol = LastMappingSymbols.find(Section); 479321369Sdim if (LastMappingSymbol != LastMappingSymbols.end()) { 480321369Sdim LastEMSInfo = std::move(LastMappingSymbol->second); 481321369Sdim return; 482321369Sdim } 483321369Sdim LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0)); 484249259Sdim } 485249259Sdim 486249259Sdim /// This function is the one used to emit instruction data into the ELF 487249259Sdim /// streamer. We override it to add the appropriate mapping symbol if 488249259Sdim /// necessary. 489353358Sdim void EmitInstruction(const MCInst &Inst, 490353358Sdim const MCSubtargetInfo &STI) override { 491249259Sdim if (IsThumb) 492249259Sdim EmitThumbMappingSymbol(); 493249259Sdim else 494249259Sdim EmitARMMappingSymbol(); 495249259Sdim 496276479Sdim MCELFStreamer::EmitInstruction(Inst, STI); 497249259Sdim } 498249259Sdim 499276479Sdim void emitInst(uint32_t Inst, char Suffix) { 500276479Sdim unsigned Size; 501276479Sdim char Buffer[4]; 502276479Sdim const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian(); 503276479Sdim 504276479Sdim switch (Suffix) { 505276479Sdim case '\0': 506276479Sdim Size = 4; 507276479Sdim 508276479Sdim assert(!IsThumb); 509276479Sdim EmitARMMappingSymbol(); 510276479Sdim for (unsigned II = 0, IE = Size; II != IE; II++) { 511276479Sdim const unsigned I = LittleEndian ? (Size - II - 1) : II; 512276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT); 513276479Sdim } 514276479Sdim 515276479Sdim break; 516276479Sdim case 'n': 517276479Sdim case 'w': 518276479Sdim Size = (Suffix == 'n' ? 2 : 4); 519276479Sdim 520276479Sdim assert(IsThumb); 521276479Sdim EmitThumbMappingSymbol(); 522341825Sdim // Thumb wide instructions are emitted as a pair of 16-bit words of the 523341825Sdim // appropriate endianness. 524276479Sdim for (unsigned II = 0, IE = Size; II != IE; II = II + 2) { 525341825Sdim const unsigned I0 = LittleEndian ? II + 0 : II + 1; 526341825Sdim const unsigned I1 = LittleEndian ? II + 1 : II + 0; 527276479Sdim Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT); 528276479Sdim Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT); 529276479Sdim } 530276479Sdim 531276479Sdim break; 532276479Sdim default: 533276479Sdim llvm_unreachable("Invalid Suffix"); 534276479Sdim } 535276479Sdim 536276479Sdim MCELFStreamer::EmitBytes(StringRef(Buffer, Size)); 537276479Sdim } 538276479Sdim 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 EmitBytes(StringRef Data) override { 543249259Sdim EmitDataMappingSymbol(); 544261991Sdim MCELFStreamer::EmitBytes(Data); 545249259Sdim } 546249259Sdim 547321369Sdim void FlushPendingMappingSymbol() { 548321369Sdim if (!LastEMSInfo->hasInfo()) 549321369Sdim return; 550321369Sdim ElfMappingSymbolInfo *EMS = LastEMSInfo.get(); 551321369Sdim EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset); 552321369Sdim EMS->resetInfo(); 553321369Sdim } 554321369Sdim 555249259Sdim /// This is one of the functions used to emit data into an ELF section, so the 556249259Sdim /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if 557249259Sdim /// necessary. 558296417Sdim void EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override { 559321369Sdim if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) { 560296417Sdim if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) { 561296417Sdim getContext().reportError(Loc, "relocated expression must be 32-bit"); 562296417Sdim return; 563296417Sdim } 564321369Sdim getOrCreateDataFragment(); 565321369Sdim } 566280031Sdim 567249259Sdim EmitDataMappingSymbol(); 568296417Sdim MCELFStreamer::EmitValueImpl(Value, Size, Loc); 569249259Sdim } 570249259Sdim 571276479Sdim void EmitAssemblerFlag(MCAssemblerFlag Flag) override { 572249259Sdim MCELFStreamer::EmitAssemblerFlag(Flag); 573249259Sdim 574249259Sdim switch (Flag) { 575249259Sdim case MCAF_SyntaxUnified: 576249259Sdim return; // no-op here. 577249259Sdim case MCAF_Code16: 578249259Sdim IsThumb = true; 579249259Sdim return; // Change to Thumb mode 580249259Sdim case MCAF_Code32: 581249259Sdim IsThumb = false; 582249259Sdim return; // Change to ARM mode 583249259Sdim case MCAF_Code64: 584249259Sdim return; 585249259Sdim case MCAF_SubsectionsViaSymbols: 586249259Sdim return; 587249259Sdim } 588249259Sdim } 589249259Sdim 590249259Sdimprivate: 591249259Sdim enum ElfMappingSymbol { 592249259Sdim EMS_None, 593249259Sdim EMS_ARM, 594249259Sdim EMS_Thumb, 595249259Sdim EMS_Data 596249259Sdim }; 597249259Sdim 598321369Sdim struct ElfMappingSymbolInfo { 599321369Sdim explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O) 600321369Sdim : Loc(Loc), F(F), Offset(O), State(EMS_None) {} 601321369Sdim void resetInfo() { 602321369Sdim F = nullptr; 603321369Sdim Offset = 0; 604321369Sdim } 605321369Sdim bool hasInfo() { return F != nullptr; } 606321369Sdim SMLoc Loc; 607321369Sdim MCFragment *F; 608321369Sdim uint64_t Offset; 609321369Sdim ElfMappingSymbol State; 610321369Sdim }; 611321369Sdim 612249259Sdim void EmitDataMappingSymbol() { 613321369Sdim if (LastEMSInfo->State == EMS_Data) 614321369Sdim return; 615321369Sdim else if (LastEMSInfo->State == EMS_None) { 616321369Sdim // This is a tentative symbol, it won't really be emitted until it's 617321369Sdim // actually needed. 618321369Sdim ElfMappingSymbolInfo *EMS = LastEMSInfo.get(); 619321369Sdim auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment()); 620321369Sdim if (!DF) 621321369Sdim return; 622321369Sdim EMS->Loc = SMLoc(); 623321369Sdim EMS->F = getCurrentFragment(); 624321369Sdim EMS->Offset = DF->getContents().size(); 625321369Sdim LastEMSInfo->State = EMS_Data; 626321369Sdim return; 627321369Sdim } 628249259Sdim EmitMappingSymbol("$d"); 629321369Sdim LastEMSInfo->State = EMS_Data; 630249259Sdim } 631249259Sdim 632249259Sdim void EmitThumbMappingSymbol() { 633321369Sdim if (LastEMSInfo->State == EMS_Thumb) 634321369Sdim return; 635321369Sdim FlushPendingMappingSymbol(); 636249259Sdim EmitMappingSymbol("$t"); 637321369Sdim LastEMSInfo->State = EMS_Thumb; 638249259Sdim } 639249259Sdim 640249259Sdim void EmitARMMappingSymbol() { 641321369Sdim if (LastEMSInfo->State == EMS_ARM) 642321369Sdim return; 643321369Sdim FlushPendingMappingSymbol(); 644249259Sdim EmitMappingSymbol("$a"); 645321369Sdim LastEMSInfo->State = EMS_ARM; 646249259Sdim } 647249259Sdim 648249259Sdim void EmitMappingSymbol(StringRef Name) { 649288943Sdim auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 650288943Sdim Name + "." + Twine(MappingSymbolCounter++))); 651288943Sdim EmitLabel(Symbol); 652249259Sdim 653288943Sdim Symbol->setType(ELF::STT_NOTYPE); 654288943Sdim Symbol->setBinding(ELF::STB_LOCAL); 655288943Sdim Symbol->setExternal(false); 656249259Sdim } 657249259Sdim 658321369Sdim void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F, 659321369Sdim uint64_t Offset) { 660321369Sdim auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol( 661321369Sdim Name + "." + Twine(MappingSymbolCounter++))); 662360784Sdim EmitLabelAtPos(Symbol, Loc, F, Offset); 663321369Sdim Symbol->setType(ELF::STT_NOTYPE); 664321369Sdim Symbol->setBinding(ELF::STB_LOCAL); 665321369Sdim Symbol->setExternal(false); 666321369Sdim } 667321369Sdim 668276479Sdim void EmitThumbFunc(MCSymbol *Func) override { 669249259Sdim getAssembler().setIsThumbFunc(Func); 670276479Sdim EmitSymbolAttribute(Func, MCSA_ELF_TypeFunction); 671249259Sdim } 672249259Sdim 673249259Sdim // Helper functions for ARM exception handling directives 674296417Sdim void EHReset(); 675249259Sdim 676296417Sdim // Reset state between object emissions 677296417Sdim void reset() override; 678296417Sdim 679249259Sdim void EmitPersonalityFixup(StringRef Name); 680261991Sdim void FlushPendingOffset(); 681261991Sdim void FlushUnwindOpcodes(bool NoHandlerData); 682249259Sdim 683314564Sdim void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags, 684249259Sdim SectionKind Kind, const MCSymbol &Fn); 685249259Sdim void SwitchToExTabSection(const MCSymbol &FnStart); 686249259Sdim void SwitchToExIdxSection(const MCSymbol &FnStart); 687249259Sdim 688276479Sdim void EmitFixup(const MCExpr *Expr, MCFixupKind Kind); 689276479Sdim 690249259Sdim bool IsThumb; 691360784Sdim bool IsAndroid; 692321369Sdim int64_t MappingSymbolCounter = 0; 693249259Sdim 694321369Sdim DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>> 695321369Sdim LastMappingSymbols; 696249259Sdim 697321369Sdim std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo; 698321369Sdim 699249259Sdim // ARM Exception Handling Frame Information 700249259Sdim MCSymbol *ExTab; 701249259Sdim MCSymbol *FnStart; 702249259Sdim const MCSymbol *Personality; 703261991Sdim unsigned PersonalityIndex; 704261991Sdim unsigned FPReg; // Frame pointer register 705261991Sdim int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp) 706261991Sdim int64_t SPOffset; // Offset: (final $sp) - (initial $sp) 707261991Sdim int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp) 708251662Sdim bool UsedFP; 709249259Sdim bool CantUnwind; 710261991Sdim SmallVector<uint8_t, 64> Opcodes; 711251662Sdim UnwindOpcodeAssembler UnwindOpAsm; 712249259Sdim}; 713321369Sdim 714251662Sdim} // end anonymous namespace 715249259Sdim 716261991SdimARMELFStreamer &ARMTargetELFStreamer::getStreamer() { 717276479Sdim return static_cast<ARMELFStreamer &>(Streamer); 718261991Sdim} 719261991Sdim 720261991Sdimvoid ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); } 721261991Sdimvoid ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); } 722261991Sdimvoid ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); } 723321369Sdim 724261991Sdimvoid ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) { 725261991Sdim getStreamer().emitPersonality(Personality); 726261991Sdim} 727321369Sdim 728276479Sdimvoid ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) { 729276479Sdim getStreamer().emitPersonalityIndex(Index); 730276479Sdim} 731321369Sdim 732261991Sdimvoid ARMTargetELFStreamer::emitHandlerData() { 733261991Sdim getStreamer().emitHandlerData(); 734261991Sdim} 735321369Sdim 736261991Sdimvoid ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg, 737261991Sdim int64_t Offset) { 738261991Sdim getStreamer().emitSetFP(FpReg, SpReg, Offset); 739261991Sdim} 740321369Sdim 741276479Sdimvoid ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 742276479Sdim getStreamer().emitMovSP(Reg, Offset); 743276479Sdim} 744321369Sdim 745261991Sdimvoid ARMTargetELFStreamer::emitPad(int64_t Offset) { 746261991Sdim getStreamer().emitPad(Offset); 747261991Sdim} 748321369Sdim 749261991Sdimvoid ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 750261991Sdim bool isVector) { 751261991Sdim getStreamer().emitRegSave(RegList, isVector); 752261991Sdim} 753321369Sdim 754276479Sdimvoid ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset, 755276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 756276479Sdim getStreamer().emitUnwindRaw(Offset, Opcodes); 757276479Sdim} 758321369Sdim 759261991Sdimvoid ARMTargetELFStreamer::switchVendor(StringRef Vendor) { 760261991Sdim assert(!Vendor.empty() && "Vendor cannot be empty."); 761261991Sdim 762261991Sdim if (CurrentVendor == Vendor) 763261991Sdim return; 764261991Sdim 765261991Sdim if (!CurrentVendor.empty()) 766261991Sdim finishAttributeSection(); 767261991Sdim 768261991Sdim assert(Contents.empty() && 769261991Sdim ".ARM.attributes should be flushed before changing vendor"); 770261991Sdim CurrentVendor = Vendor; 771261991Sdim 772261991Sdim} 773321369Sdim 774261991Sdimvoid ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) { 775261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 776261991Sdim} 777321369Sdim 778261991Sdimvoid ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute, 779261991Sdim StringRef Value) { 780261991Sdim setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true); 781261991Sdim} 782321369Sdim 783276479Sdimvoid ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute, 784276479Sdim unsigned IntValue, 785276479Sdim StringRef StringValue) { 786276479Sdim setAttributeItems(Attribute, IntValue, StringValue, 787276479Sdim /* OverwriteExisting= */ true); 788276479Sdim} 789321369Sdim 790327952Sdimvoid ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) { 791276479Sdim Arch = Value; 792276479Sdim} 793321369Sdim 794327952Sdimvoid ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) { 795276479Sdim EmittedArch = Value; 796276479Sdim} 797321369Sdim 798276479Sdimvoid ARMTargetELFStreamer::emitArchDefaultAttributes() { 799276479Sdim using namespace ARMBuildAttrs; 800276479Sdim 801288943Sdim setAttributeItem(CPU_name, 802296417Sdim ARM::getCPUAttr(Arch), 803288943Sdim false); 804288943Sdim 805327952Sdim if (EmittedArch == ARM::ArchKind::INVALID) 806288943Sdim setAttributeItem(CPU_arch, 807296417Sdim ARM::getArchAttr(Arch), 808288943Sdim false); 809276479Sdim else 810288943Sdim setAttributeItem(CPU_arch, 811296417Sdim ARM::getArchAttr(EmittedArch), 812288943Sdim false); 813276479Sdim 814276479Sdim switch (Arch) { 815327952Sdim case ARM::ArchKind::ARMV2: 816327952Sdim case ARM::ArchKind::ARMV2A: 817327952Sdim case ARM::ArchKind::ARMV3: 818327952Sdim case ARM::ArchKind::ARMV3M: 819327952Sdim case ARM::ArchKind::ARMV4: 820276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 821276479Sdim break; 822276479Sdim 823327952Sdim case ARM::ArchKind::ARMV4T: 824327952Sdim case ARM::ArchKind::ARMV5T: 825327952Sdim case ARM::ArchKind::ARMV5TE: 826327952Sdim case ARM::ArchKind::ARMV6: 827276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 828276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 829276479Sdim break; 830276479Sdim 831327952Sdim case ARM::ArchKind::ARMV6T2: 832276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 833276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 834276479Sdim break; 835276479Sdim 836327952Sdim case ARM::ArchKind::ARMV6K: 837327952Sdim case ARM::ArchKind::ARMV6KZ: 838276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 839276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 840276479Sdim setAttributeItem(Virtualization_use, AllowTZ, false); 841276479Sdim break; 842276479Sdim 843327952Sdim case ARM::ArchKind::ARMV6M: 844276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 845276479Sdim break; 846276479Sdim 847327952Sdim case ARM::ArchKind::ARMV7A: 848276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 849276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 850276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 851276479Sdim break; 852276479Sdim 853327952Sdim case ARM::ArchKind::ARMV7R: 854276479Sdim setAttributeItem(CPU_arch_profile, RealTimeProfile, false); 855276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 856276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 857276479Sdim break; 858276479Sdim 859327952Sdim case ARM::ArchKind::ARMV7EM: 860327952Sdim case ARM::ArchKind::ARMV7M: 861276479Sdim setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 862276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 863276479Sdim break; 864276479Sdim 865327952Sdim case ARM::ArchKind::ARMV8A: 866327952Sdim case ARM::ArchKind::ARMV8_1A: 867327952Sdim case ARM::ArchKind::ARMV8_2A: 868341825Sdim case ARM::ArchKind::ARMV8_3A: 869341825Sdim case ARM::ArchKind::ARMV8_4A: 870344779Sdim case ARM::ArchKind::ARMV8_5A: 871276479Sdim setAttributeItem(CPU_arch_profile, ApplicationProfile, false); 872276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 873276479Sdim setAttributeItem(THUMB_ISA_use, AllowThumb32, false); 874276479Sdim setAttributeItem(MPextension_use, Allowed, false); 875276479Sdim setAttributeItem(Virtualization_use, AllowTZVirtualization, false); 876276479Sdim break; 877276479Sdim 878327952Sdim case ARM::ArchKind::ARMV8MBaseline: 879327952Sdim case ARM::ArchKind::ARMV8MMainline: 880309124Sdim setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false); 881309124Sdim setAttributeItem(CPU_arch_profile, MicroControllerProfile, false); 882309124Sdim break; 883309124Sdim 884327952Sdim case ARM::ArchKind::IWMMXT: 885276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 886276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 887276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv1, false); 888276479Sdim break; 889276479Sdim 890327952Sdim case ARM::ArchKind::IWMMXT2: 891276479Sdim setAttributeItem(ARM_ISA_use, Allowed, false); 892276479Sdim setAttributeItem(THUMB_ISA_use, Allowed, false); 893276479Sdim setAttributeItem(WMMX_arch, AllowWMMXv2, false); 894276479Sdim break; 895276479Sdim 896276479Sdim default: 897327952Sdim report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch))); 898276479Sdim break; 899276479Sdim } 900276479Sdim} 901321369Sdim 902261991Sdimvoid ARMTargetELFStreamer::emitFPU(unsigned Value) { 903261991Sdim FPU = Value; 904261991Sdim} 905321369Sdim 906261991Sdimvoid ARMTargetELFStreamer::emitFPUDefaultAttributes() { 907261991Sdim switch (FPU) { 908288943Sdim case ARM::FK_VFP: 909288943Sdim case ARM::FK_VFPV2: 910276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 911261991Sdim ARMBuildAttrs::AllowFPv2, 912261991Sdim /* OverwriteExisting= */ false); 913261991Sdim break; 914261991Sdim 915288943Sdim case ARM::FK_VFPV3: 916276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 917261991Sdim ARMBuildAttrs::AllowFPv3A, 918261991Sdim /* OverwriteExisting= */ false); 919261991Sdim break; 920261991Sdim 921288943Sdim case ARM::FK_VFPV3_FP16: 922276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 923288943Sdim ARMBuildAttrs::AllowFPv3A, 924288943Sdim /* OverwriteExisting= */ false); 925288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 926288943Sdim ARMBuildAttrs::AllowHPFP, 927288943Sdim /* OverwriteExisting= */ false); 928288943Sdim break; 929288943Sdim 930288943Sdim case ARM::FK_VFPV3_D16: 931288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 932261991Sdim ARMBuildAttrs::AllowFPv3B, 933261991Sdim /* OverwriteExisting= */ false); 934261991Sdim break; 935261991Sdim 936288943Sdim case ARM::FK_VFPV3_D16_FP16: 937276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 938288943Sdim ARMBuildAttrs::AllowFPv3B, 939288943Sdim /* OverwriteExisting= */ false); 940288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 941288943Sdim ARMBuildAttrs::AllowHPFP, 942288943Sdim /* OverwriteExisting= */ false); 943288943Sdim break; 944288943Sdim 945288943Sdim case ARM::FK_VFPV3XD: 946288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 947288943Sdim ARMBuildAttrs::AllowFPv3B, 948288943Sdim /* OverwriteExisting= */ false); 949288943Sdim break; 950288943Sdim case ARM::FK_VFPV3XD_FP16: 951288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 952288943Sdim ARMBuildAttrs::AllowFPv3B, 953288943Sdim /* OverwriteExisting= */ false); 954288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 955288943Sdim ARMBuildAttrs::AllowHPFP, 956288943Sdim /* OverwriteExisting= */ false); 957288943Sdim break; 958288943Sdim 959288943Sdim case ARM::FK_VFPV4: 960288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 961261991Sdim ARMBuildAttrs::AllowFPv4A, 962261991Sdim /* OverwriteExisting= */ false); 963261991Sdim break; 964261991Sdim 965288943Sdim // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same 966288943Sdim // as _D16 here. 967288943Sdim case ARM::FK_FPV4_SP_D16: 968288943Sdim case ARM::FK_VFPV4_D16: 969276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 970261991Sdim ARMBuildAttrs::AllowFPv4B, 971261991Sdim /* OverwriteExisting= */ false); 972261991Sdim break; 973261991Sdim 974288943Sdim case ARM::FK_FP_ARMV8: 975276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 976261991Sdim ARMBuildAttrs::AllowFPARMv8A, 977261991Sdim /* OverwriteExisting= */ false); 978261991Sdim break; 979261991Sdim 980280031Sdim // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so 981280031Sdim // uses the FP_ARMV8_D16 build attribute. 982288943Sdim case ARM::FK_FPV5_SP_D16: 983288943Sdim case ARM::FK_FPV5_D16: 984280031Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 985280031Sdim ARMBuildAttrs::AllowFPARMv8B, 986280031Sdim /* OverwriteExisting= */ false); 987280031Sdim break; 988280031Sdim 989288943Sdim case ARM::FK_NEON: 990276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 991261991Sdim ARMBuildAttrs::AllowFPv3A, 992261991Sdim /* OverwriteExisting= */ false); 993261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 994261991Sdim ARMBuildAttrs::AllowNeon, 995261991Sdim /* OverwriteExisting= */ false); 996261991Sdim break; 997261991Sdim 998288943Sdim case ARM::FK_NEON_FP16: 999276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 1000288943Sdim ARMBuildAttrs::AllowFPv3A, 1001288943Sdim /* OverwriteExisting= */ false); 1002288943Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 1003288943Sdim ARMBuildAttrs::AllowNeon, 1004288943Sdim /* OverwriteExisting= */ false); 1005288943Sdim setAttributeItem(ARMBuildAttrs::FP_HP_extension, 1006288943Sdim ARMBuildAttrs::AllowHPFP, 1007288943Sdim /* OverwriteExisting= */ false); 1008288943Sdim break; 1009288943Sdim 1010288943Sdim case ARM::FK_NEON_VFPV4: 1011288943Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 1012261991Sdim ARMBuildAttrs::AllowFPv4A, 1013261991Sdim /* OverwriteExisting= */ false); 1014261991Sdim setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch, 1015261991Sdim ARMBuildAttrs::AllowNeon2, 1016261991Sdim /* OverwriteExisting= */ false); 1017261991Sdim break; 1018261991Sdim 1019288943Sdim case ARM::FK_NEON_FP_ARMV8: 1020288943Sdim case ARM::FK_CRYPTO_NEON_FP_ARMV8: 1021276479Sdim setAttributeItem(ARMBuildAttrs::FP_arch, 1022261991Sdim ARMBuildAttrs::AllowFPARMv8A, 1023261991Sdim /* OverwriteExisting= */ false); 1024288943Sdim // 'Advanced_SIMD_arch' must be emitted not here, but within 1025288943Sdim // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a() 1026261991Sdim break; 1027261991Sdim 1028288943Sdim case ARM::FK_SOFTVFP: 1029288943Sdim case ARM::FK_NONE: 1030276479Sdim break; 1031276479Sdim 1032261991Sdim default: 1033261991Sdim report_fatal_error("Unknown FPU: " + Twine(FPU)); 1034261991Sdim break; 1035261991Sdim } 1036261991Sdim} 1037321369Sdim 1038261991Sdimsize_t ARMTargetELFStreamer::calculateContentSize() const { 1039261991Sdim size_t Result = 0; 1040261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 1041261991Sdim AttributeItem item = Contents[i]; 1042261991Sdim switch (item.Type) { 1043261991Sdim case AttributeItem::HiddenAttribute: 1044261991Sdim break; 1045261991Sdim case AttributeItem::NumericAttribute: 1046276479Sdim Result += getULEB128Size(item.Tag); 1047276479Sdim Result += getULEB128Size(item.IntValue); 1048261991Sdim break; 1049261991Sdim case AttributeItem::TextAttribute: 1050276479Sdim Result += getULEB128Size(item.Tag); 1051261991Sdim Result += item.StringValue.size() + 1; // string + '\0' 1052261991Sdim break; 1053276479Sdim case AttributeItem::NumericAndTextAttributes: 1054276479Sdim Result += getULEB128Size(item.Tag); 1055276479Sdim Result += getULEB128Size(item.IntValue); 1056276479Sdim Result += item.StringValue.size() + 1; // string + '\0'; 1057276479Sdim break; 1058261991Sdim } 1059261991Sdim } 1060261991Sdim return Result; 1061261991Sdim} 1062321369Sdim 1063261991Sdimvoid ARMTargetELFStreamer::finishAttributeSection() { 1064261991Sdim // <format-version> 1065261991Sdim // [ <section-length> "vendor-name" 1066261991Sdim // [ <file-tag> <size> <attribute>* 1067261991Sdim // | <section-tag> <size> <section-number>* 0 <attribute>* 1068261991Sdim // | <symbol-tag> <size> <symbol-number>* 0 <attribute>* 1069261991Sdim // ]+ 1070261991Sdim // ]* 1071261991Sdim 1072288943Sdim if (FPU != ARM::FK_INVALID) 1073261991Sdim emitFPUDefaultAttributes(); 1074261991Sdim 1075327952Sdim if (Arch != ARM::ArchKind::INVALID) 1076276479Sdim emitArchDefaultAttributes(); 1077276479Sdim 1078261991Sdim if (Contents.empty()) 1079261991Sdim return; 1080261991Sdim 1081344779Sdim llvm::sort(Contents, AttributeItem::LessTag); 1082261991Sdim 1083261991Sdim ARMELFStreamer &Streamer = getStreamer(); 1084261991Sdim 1085261991Sdim // Switch to .ARM.attributes section 1086261991Sdim if (AttributeSection) { 1087261991Sdim Streamer.SwitchSection(AttributeSection); 1088261991Sdim } else { 1089288943Sdim AttributeSection = Streamer.getContext().getELFSection( 1090288943Sdim ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0); 1091261991Sdim Streamer.SwitchSection(AttributeSection); 1092261991Sdim 1093261991Sdim // Format version 1094261991Sdim Streamer.EmitIntValue(0x41, 1); 1095261991Sdim } 1096261991Sdim 1097261991Sdim // Vendor size + Vendor name + '\0' 1098261991Sdim const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1; 1099261991Sdim 1100261991Sdim // Tag + Tag Size 1101261991Sdim const size_t TagHeaderSize = 1 + 4; 1102261991Sdim 1103261991Sdim const size_t ContentsSize = calculateContentSize(); 1104261991Sdim 1105261991Sdim Streamer.EmitIntValue(VendorHeaderSize + TagHeaderSize + ContentsSize, 4); 1106261991Sdim Streamer.EmitBytes(CurrentVendor); 1107261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 1108261991Sdim 1109261991Sdim Streamer.EmitIntValue(ARMBuildAttrs::File, 1); 1110261991Sdim Streamer.EmitIntValue(TagHeaderSize + ContentsSize, 4); 1111261991Sdim 1112261991Sdim // Size should have been accounted for already, now 1113261991Sdim // emit each field as its type (ULEB or String) 1114261991Sdim for (size_t i = 0; i < Contents.size(); ++i) { 1115261991Sdim AttributeItem item = Contents[i]; 1116261991Sdim Streamer.EmitULEB128IntValue(item.Tag); 1117261991Sdim switch (item.Type) { 1118261991Sdim default: llvm_unreachable("Invalid attribute type"); 1119261991Sdim case AttributeItem::NumericAttribute: 1120261991Sdim Streamer.EmitULEB128IntValue(item.IntValue); 1121261991Sdim break; 1122261991Sdim case AttributeItem::TextAttribute: 1123280031Sdim Streamer.EmitBytes(item.StringValue); 1124261991Sdim Streamer.EmitIntValue(0, 1); // '\0' 1125261991Sdim break; 1126276479Sdim case AttributeItem::NumericAndTextAttributes: 1127276479Sdim Streamer.EmitULEB128IntValue(item.IntValue); 1128280031Sdim Streamer.EmitBytes(item.StringValue); 1129276479Sdim Streamer.EmitIntValue(0, 1); // '\0' 1130276479Sdim break; 1131261991Sdim } 1132261991Sdim } 1133261991Sdim 1134261991Sdim Contents.clear(); 1135288943Sdim FPU = ARM::FK_INVALID; 1136261991Sdim} 1137261991Sdim 1138276479Sdimvoid ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) { 1139276479Sdim ARMELFStreamer &Streamer = getStreamer(); 1140276479Sdim if (!Streamer.IsThumb) 1141276479Sdim return; 1142276479Sdim 1143288943Sdim Streamer.getAssembler().registerSymbol(*Symbol); 1144288943Sdim unsigned Type = cast<MCSymbolELF>(Symbol)->getType(); 1145288943Sdim if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) 1146276479Sdim Streamer.EmitThumbFunc(Symbol); 1147276479Sdim} 1148276479Sdim 1149276479Sdimvoid 1150276479SdimARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) { 1151276479Sdim getStreamer().EmitFixup(S, FK_Data_4); 1152276479Sdim} 1153276479Sdim 1154276479Sdimvoid ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) { 1155276479Sdim if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) { 1156276479Sdim const MCSymbol &Sym = SRE->getSymbol(); 1157276479Sdim if (!Sym.isDefined()) { 1158276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1159276479Sdim return; 1160276479Sdim } 1161276479Sdim } 1162276479Sdim 1163276479Sdim getStreamer().EmitThumbFunc(Symbol); 1164276479Sdim getStreamer().EmitAssignment(Symbol, Value); 1165276479Sdim} 1166276479Sdim 1167276479Sdimvoid ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) { 1168276479Sdim getStreamer().emitInst(Inst, Suffix); 1169276479Sdim} 1170276479Sdim 1171296417Sdimvoid ARMTargetELFStreamer::reset() { AttributeSection = nullptr; } 1172296417Sdim 1173261991Sdimvoid ARMELFStreamer::FinishImpl() { 1174276479Sdim MCTargetStreamer &TS = *getTargetStreamer(); 1175261991Sdim ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1176261991Sdim ATS.finishAttributeSection(); 1177261991Sdim 1178261991Sdim MCELFStreamer::FinishImpl(); 1179261991Sdim} 1180261991Sdim 1181296417Sdimvoid ARMELFStreamer::reset() { 1182296417Sdim MCTargetStreamer &TS = *getTargetStreamer(); 1183296417Sdim ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS); 1184296417Sdim ATS.reset(); 1185296417Sdim MappingSymbolCounter = 0; 1186296417Sdim MCELFStreamer::reset(); 1187327952Sdim LastMappingSymbols.clear(); 1188327952Sdim LastEMSInfo.reset(); 1189296417Sdim // MCELFStreamer clear's the assembler's e_flags. However, for 1190296417Sdim // arm we manually set the ABI version on streamer creation, so 1191296417Sdim // do the same here 1192296417Sdim getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1193296417Sdim} 1194296417Sdim 1195314564Sdiminline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix, 1196249259Sdim unsigned Type, 1197249259Sdim unsigned Flags, 1198249259Sdim SectionKind Kind, 1199249259Sdim const MCSymbol &Fn) { 1200249259Sdim const MCSectionELF &FnSection = 1201249259Sdim static_cast<const MCSectionELF &>(Fn.getSection()); 1202249259Sdim 1203249259Sdim // Create the name for new section 1204249259Sdim StringRef FnSecName(FnSection.getSectionName()); 1205249259Sdim SmallString<128> EHSecName(Prefix); 1206249259Sdim if (FnSecName != ".text") { 1207249259Sdim EHSecName += FnSecName; 1208249259Sdim } 1209249259Sdim 1210249259Sdim // Get .ARM.extab or .ARM.exidx section 1211288943Sdim const MCSymbolELF *Group = FnSection.getGroup(); 1212288943Sdim if (Group) 1213288943Sdim Flags |= ELF::SHF_GROUP; 1214321369Sdim MCSectionELF *EHSection = getContext().getELFSection( 1215321369Sdim EHSecName, Type, Flags, 0, Group, FnSection.getUniqueID(), 1216321369Sdim static_cast<const MCSymbolELF *>(&Fn)); 1217288943Sdim 1218251662Sdim assert(EHSection && "Failed to get the required EH section"); 1219249259Sdim 1220249259Sdim // Switch to .ARM.extab or .ARM.exidx section 1221249259Sdim SwitchSection(EHSection); 1222276479Sdim EmitCodeAlignment(4); 1223249259Sdim} 1224249259Sdim 1225249259Sdiminline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) { 1226296417Sdim SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC, 1227296417Sdim SectionKind::getData(), FnStart); 1228249259Sdim} 1229249259Sdim 1230249259Sdiminline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) { 1231296417Sdim SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX, 1232249259Sdim ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER, 1233296417Sdim SectionKind::getData(), FnStart); 1234249259Sdim} 1235321369Sdim 1236276479Sdimvoid ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) { 1237276479Sdim MCDataFragment *Frag = getOrCreateDataFragment(); 1238288943Sdim Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr, 1239276479Sdim Kind)); 1240276479Sdim} 1241249259Sdim 1242296417Sdimvoid ARMELFStreamer::EHReset() { 1243276479Sdim ExTab = nullptr; 1244276479Sdim FnStart = nullptr; 1245276479Sdim Personality = nullptr; 1246276479Sdim PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX; 1247261991Sdim FPReg = ARM::SP; 1248251662Sdim FPOffset = 0; 1249251662Sdim SPOffset = 0; 1250261991Sdim PendingOffset = 0; 1251251662Sdim UsedFP = false; 1252249259Sdim CantUnwind = false; 1253251662Sdim 1254261991Sdim Opcodes.clear(); 1255251662Sdim UnwindOpAsm.Reset(); 1256249259Sdim} 1257249259Sdim 1258261991Sdimvoid ARMELFStreamer::emitFnStart() { 1259276479Sdim assert(FnStart == nullptr); 1260288943Sdim FnStart = getContext().createTempSymbol(); 1261249259Sdim EmitLabel(FnStart); 1262249259Sdim} 1263249259Sdim 1264261991Sdimvoid ARMELFStreamer::emitFnEnd() { 1265276479Sdim assert(FnStart && ".fnstart must precedes .fnend"); 1266249259Sdim 1267249259Sdim // Emit unwind opcodes if there is no .handlerdata directive 1268261991Sdim if (!ExTab && !CantUnwind) 1269261991Sdim FlushUnwindOpcodes(true); 1270249259Sdim 1271249259Sdim // Emit the exception index table entry 1272249259Sdim SwitchToExIdxSection(*FnStart); 1273249259Sdim 1274360784Sdim // The EHABI requires a dependency preserving R_ARM_NONE relocation to the 1275360784Sdim // personality routine to protect it from an arbitrary platform's static 1276360784Sdim // linker garbage collection. We disable this for Android where the unwinder 1277360784Sdim // is either dynamically linked or directly references the personality 1278360784Sdim // routine. 1279360784Sdim if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid) 1280251662Sdim EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex)); 1281249259Sdim 1282249259Sdim const MCSymbolRefExpr *FnStartRef = 1283288943Sdim MCSymbolRefExpr::create(FnStart, 1284249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1285249259Sdim getContext()); 1286249259Sdim 1287261991Sdim EmitValue(FnStartRef, 4); 1288249259Sdim 1289249259Sdim if (CantUnwind) { 1290276479Sdim EmitIntValue(ARM::EHABI::EXIDX_CANTUNWIND, 4); 1291251662Sdim } else if (ExTab) { 1292251662Sdim // Emit a reference to the unwind opcodes in the ".ARM.extab" section. 1293249259Sdim const MCSymbolRefExpr *ExTabEntryRef = 1294288943Sdim MCSymbolRefExpr::create(ExTab, 1295249259Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1296249259Sdim getContext()); 1297261991Sdim EmitValue(ExTabEntryRef, 4); 1298251662Sdim } else { 1299251662Sdim // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in 1300251662Sdim // the second word of exception index table entry. The size of the unwind 1301251662Sdim // opcodes should always be 4 bytes. 1302276479Sdim assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 && 1303276479Sdim "Compact model must use __aeabi_unwind_cpp_pr0 as personality"); 1304261991Sdim assert(Opcodes.size() == 4u && 1305276479Sdim "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4"); 1306276479Sdim uint64_t Intval = Opcodes[0] | 1307276479Sdim Opcodes[1] << 8 | 1308276479Sdim Opcodes[2] << 16 | 1309276479Sdim Opcodes[3] << 24; 1310276479Sdim EmitIntValue(Intval, Opcodes.size()); 1311249259Sdim } 1312249259Sdim 1313261991Sdim // Switch to the section containing FnStart 1314261991Sdim SwitchSection(&FnStart->getSection()); 1315261991Sdim 1316249259Sdim // Clean exception handling frame information 1317296417Sdim EHReset(); 1318249259Sdim} 1319249259Sdim 1320261991Sdimvoid ARMELFStreamer::emitCantUnwind() { CantUnwind = true; } 1321261991Sdim 1322261991Sdim// Add the R_ARM_NONE fixup at the same position 1323261991Sdimvoid ARMELFStreamer::EmitPersonalityFixup(StringRef Name) { 1324288943Sdim const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name); 1325261991Sdim 1326288943Sdim const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create( 1327261991Sdim PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext()); 1328261991Sdim 1329276479Sdim visitUsedExpr(*PersonalityRef); 1330261991Sdim MCDataFragment *DF = getOrCreateDataFragment(); 1331288943Sdim DF->getFixups().push_back(MCFixup::create(DF->getContents().size(), 1332261991Sdim PersonalityRef, 1333261991Sdim MCFixup::getKindForSize(4, false))); 1334249259Sdim} 1335249259Sdim 1336261991Sdimvoid ARMELFStreamer::FlushPendingOffset() { 1337261991Sdim if (PendingOffset != 0) { 1338261991Sdim UnwindOpAsm.EmitSPOffset(-PendingOffset); 1339261991Sdim PendingOffset = 0; 1340261991Sdim } 1341261991Sdim} 1342261991Sdim 1343261991Sdimvoid ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) { 1344261991Sdim // Emit the unwind opcode to restore $sp. 1345261991Sdim if (UsedFP) { 1346261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1347261991Sdim int64_t LastRegSaveSPOffset = SPOffset - PendingOffset; 1348261991Sdim UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset); 1349261991Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1350261991Sdim } else { 1351261991Sdim FlushPendingOffset(); 1352261991Sdim } 1353261991Sdim 1354261991Sdim // Finalize the unwind opcode sequence 1355261991Sdim UnwindOpAsm.Finalize(PersonalityIndex, Opcodes); 1356261991Sdim 1357261991Sdim // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx 1358261991Sdim // section. Thus, we don't have to create an entry in the .ARM.extab 1359261991Sdim // section. 1360276479Sdim if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0) 1361261991Sdim return; 1362261991Sdim 1363261991Sdim // Switch to .ARM.extab section. 1364249259Sdim SwitchToExTabSection(*FnStart); 1365249259Sdim 1366249259Sdim // Create .ARM.extab label for offset in .ARM.exidx 1367249259Sdim assert(!ExTab); 1368288943Sdim ExTab = getContext().createTempSymbol(); 1369249259Sdim EmitLabel(ExTab); 1370249259Sdim 1371261991Sdim // Emit personality 1372261991Sdim if (Personality) { 1373261991Sdim const MCSymbolRefExpr *PersonalityRef = 1374288943Sdim MCSymbolRefExpr::create(Personality, 1375261991Sdim MCSymbolRefExpr::VK_ARM_PREL31, 1376261991Sdim getContext()); 1377249259Sdim 1378261991Sdim EmitValue(PersonalityRef, 4); 1379261991Sdim } 1380249259Sdim 1381261991Sdim // Emit unwind opcodes 1382276479Sdim assert((Opcodes.size() % 4) == 0 && 1383276479Sdim "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4"); 1384276479Sdim for (unsigned I = 0; I != Opcodes.size(); I += 4) { 1385276479Sdim uint64_t Intval = Opcodes[I] | 1386276479Sdim Opcodes[I + 1] << 8 | 1387276479Sdim Opcodes[I + 2] << 16 | 1388276479Sdim Opcodes[I + 3] << 24; 1389276479Sdim EmitIntValue(Intval, 4); 1390276479Sdim } 1391249259Sdim 1392261991Sdim // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or 1393261991Sdim // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted 1394261991Sdim // after the unwind opcodes. The handler data consists of several 32-bit 1395261991Sdim // words, and should be terminated by zero. 1396261991Sdim // 1397261991Sdim // In case that the .handlerdata directive is not specified by the 1398261991Sdim // programmer, we should emit zero to terminate the handler data. 1399261991Sdim if (NoHandlerData && !Personality) 1400261991Sdim EmitIntValue(0, 4); 1401249259Sdim} 1402249259Sdim 1403261991Sdimvoid ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); } 1404261991Sdim 1405261991Sdimvoid ARMELFStreamer::emitPersonality(const MCSymbol *Per) { 1406249259Sdim Personality = Per; 1407251662Sdim UnwindOpAsm.setPersonality(Per); 1408249259Sdim} 1409249259Sdim 1410276479Sdimvoid ARMELFStreamer::emitPersonalityIndex(unsigned Index) { 1411276479Sdim assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index"); 1412276479Sdim PersonalityIndex = Index; 1413276479Sdim} 1414276479Sdim 1415261991Sdimvoid ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg, 1416249259Sdim int64_t Offset) { 1417261991Sdim assert((NewSPReg == ARM::SP || NewSPReg == FPReg) && 1418251662Sdim "the operand of .setfp directive should be either $sp or $fp"); 1419251662Sdim 1420251662Sdim UsedFP = true; 1421261991Sdim FPReg = NewFPReg; 1422261991Sdim 1423261991Sdim if (NewSPReg == ARM::SP) 1424261991Sdim FPOffset = SPOffset + Offset; 1425261991Sdim else 1426261991Sdim FPOffset += Offset; 1427249259Sdim} 1428249259Sdim 1429276479Sdimvoid ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) { 1430276479Sdim assert((Reg != ARM::SP && Reg != ARM::PC) && 1431276479Sdim "the operand of .movsp cannot be either sp or pc"); 1432276479Sdim assert(FPReg == ARM::SP && "current FP must be SP"); 1433276479Sdim 1434276479Sdim FlushPendingOffset(); 1435276479Sdim 1436276479Sdim FPReg = Reg; 1437276479Sdim FPOffset = SPOffset + Offset; 1438276479Sdim 1439276479Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1440276479Sdim UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg)); 1441276479Sdim} 1442276479Sdim 1443261991Sdimvoid ARMELFStreamer::emitPad(int64_t Offset) { 1444261991Sdim // Track the change of the $sp offset 1445261991Sdim SPOffset -= Offset; 1446261991Sdim 1447261991Sdim // To squash multiple .pad directives, we should delay the unwind opcode 1448261991Sdim // until the .save, .vsave, .handlerdata, or .fnend directives. 1449261991Sdim PendingOffset -= Offset; 1450249259Sdim} 1451249259Sdim 1452261991Sdimvoid ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList, 1453249259Sdim bool IsVector) { 1454261991Sdim // Collect the registers in the register list 1455261991Sdim unsigned Count = 0; 1456261991Sdim uint32_t Mask = 0; 1457261991Sdim const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 1458261991Sdim for (size_t i = 0; i < RegList.size(); ++i) { 1459261991Sdim unsigned Reg = MRI->getEncodingValue(RegList[i]); 1460261991Sdim assert(Reg < (IsVector ? 32U : 16U) && "Register out of range"); 1461261991Sdim unsigned Bit = (1u << Reg); 1462261991Sdim if ((Mask & Bit) == 0) { 1463261991Sdim Mask |= Bit; 1464261991Sdim ++Count; 1465261991Sdim } 1466261991Sdim } 1467251662Sdim 1468261991Sdim // Track the change the $sp offset: For the .save directive, the 1469261991Sdim // corresponding push instruction will decrease the $sp by (4 * Count). 1470261991Sdim // For the .vsave directive, the corresponding vpush instruction will 1471261991Sdim // decrease $sp by (8 * Count). 1472261991Sdim SPOffset -= Count * (IsVector ? 8 : 4); 1473251662Sdim 1474261991Sdim // Emit the opcode 1475261991Sdim FlushPendingOffset(); 1476261991Sdim if (IsVector) 1477261991Sdim UnwindOpAsm.EmitVFPRegSave(Mask); 1478261991Sdim else 1479261991Sdim UnwindOpAsm.EmitRegSave(Mask); 1480249259Sdim} 1481249259Sdim 1482276479Sdimvoid ARMELFStreamer::emitUnwindRaw(int64_t Offset, 1483276479Sdim const SmallVectorImpl<uint8_t> &Opcodes) { 1484276479Sdim FlushPendingOffset(); 1485276479Sdim SPOffset = SPOffset - Offset; 1486276479Sdim UnwindOpAsm.EmitRaw(Opcodes); 1487276479Sdim} 1488276479Sdim 1489249259Sdimnamespace llvm { 1490261991Sdim 1491288943SdimMCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S, 1492288943Sdim formatted_raw_ostream &OS, 1493288943Sdim MCInstPrinter *InstPrint, 1494288943Sdim bool isVerboseAsm) { 1495288943Sdim return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm); 1496276479Sdim} 1497261991Sdim 1498288943SdimMCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) { 1499288943Sdim return new ARMTargetStreamer(S); 1500261991Sdim} 1501261991Sdim 1502288943SdimMCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S, 1503288943Sdim const MCSubtargetInfo &STI) { 1504288943Sdim const Triple &TT = STI.getTargetTriple(); 1505288943Sdim if (TT.isOSBinFormatELF()) 1506288943Sdim return new ARMTargetELFStreamer(S); 1507288943Sdim return new ARMTargetStreamer(S); 1508288943Sdim} 1509288943Sdim 1510327952SdimMCELFStreamer *createARMELFStreamer(MCContext &Context, 1511327952Sdim std::unique_ptr<MCAsmBackend> TAB, 1512341825Sdim std::unique_ptr<MCObjectWriter> OW, 1513327952Sdim std::unique_ptr<MCCodeEmitter> Emitter, 1514360784Sdim bool RelaxAll, bool IsThumb, 1515360784Sdim bool IsAndroid) { 1516360784Sdim ARMELFStreamer *S = 1517360784Sdim new ARMELFStreamer(Context, std::move(TAB), std::move(OW), 1518360784Sdim std::move(Emitter), IsThumb, IsAndroid); 1519327952Sdim // FIXME: This should eventually end up somewhere else where more 1520327952Sdim // intelligent flag decisions can be made. For now we are just maintaining 1521327952Sdim // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default. 1522327952Sdim S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5); 1523261991Sdim 1524327952Sdim if (RelaxAll) 1525327952Sdim S->getAssembler().setRelaxAll(true); 1526327952Sdim return S; 1527249259Sdim} 1528249259Sdim 1529321369Sdim} // end namespace llvm 1530