xref: /llvm-project/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (revision de4bbbfdccb6172c563b07889ecfb06bc4974a7e)
1 //===- lib/MC/AArch64ELFStreamer.cpp - ELF Object Output for AArch64 ------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file assembles .s files and emits AArch64 ELF .o object files. Different
10 // from generic ELF streamer in emitting mapping symbols ($x and $d) to delimit
11 // regions of data and code.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "AArch64ELFStreamer.h"
16 #include "AArch64MCTargetDesc.h"
17 #include "AArch64TargetStreamer.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Twine.h"
21 #include "llvm/BinaryFormat/ELF.h"
22 #include "llvm/MC/MCAsmBackend.h"
23 #include "llvm/MC/MCAssembler.h"
24 #include "llvm/MC/MCCodeEmitter.h"
25 #include "llvm/MC/MCContext.h"
26 #include "llvm/MC/MCELFObjectWriter.h"
27 #include "llvm/MC/MCELFStreamer.h"
28 #include "llvm/MC/MCExpr.h"
29 #include "llvm/MC/MCInst.h"
30 #include "llvm/MC/MCSectionELF.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSubtargetInfo.h"
33 #include "llvm/MC/MCSymbolELF.h"
34 #include "llvm/MC/MCTargetOptions.h"
35 #include "llvm/MC/MCWinCOFFStreamer.h"
36 #include "llvm/Support/AArch64BuildAttributes.h"
37 #include "llvm/Support/Casting.h"
38 #include "llvm/Support/FormattedStream.h"
39 #include "llvm/Support/raw_ostream.h"
40 
41 using namespace llvm;
42 
43 namespace {
44 
45 class AArch64ELFStreamer;
46 
47 class AArch64TargetAsmStreamer : public AArch64TargetStreamer {
48   formatted_raw_ostream &OS;
49   std::string VendorTag;
50 
51   void emitInst(uint32_t Inst) override;
52 
53   void emitDirectiveVariantPCS(MCSymbol *Symbol) override {
54     OS << "\t.variant_pcs\t" << Symbol->getName() << "\n";
55   }
56 
57   void emitARM64WinCFIAllocStack(unsigned Size) override {
58     OS << "\t.seh_stackalloc\t" << Size << "\n";
59   }
60   void emitARM64WinCFISaveR19R20X(int Offset) override {
61     OS << "\t.seh_save_r19r20_x\t" << Offset << "\n";
62   }
63   void emitARM64WinCFISaveFPLR(int Offset) override {
64     OS << "\t.seh_save_fplr\t" << Offset << "\n";
65   }
66   void emitARM64WinCFISaveFPLRX(int Offset) override {
67     OS << "\t.seh_save_fplr_x\t" << Offset << "\n";
68   }
69   void emitARM64WinCFISaveReg(unsigned Reg, int Offset) override {
70     OS << "\t.seh_save_reg\tx" << Reg << ", " << Offset << "\n";
71   }
72   void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) override {
73     OS << "\t.seh_save_reg_x\tx" << Reg << ", " << Offset << "\n";
74   }
75   void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) override {
76     OS << "\t.seh_save_regp\tx" << Reg << ", " << Offset << "\n";
77   }
78   void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override {
79     OS << "\t.seh_save_regp_x\tx" << Reg << ", " << Offset << "\n";
80   }
81   void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override {
82     OS << "\t.seh_save_lrpair\tx" << Reg << ", " << Offset << "\n";
83   }
84   void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) override {
85     OS << "\t.seh_save_freg\td" << Reg << ", " << Offset << "\n";
86   }
87   void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override {
88     OS << "\t.seh_save_freg_x\td" << Reg << ", " << Offset << "\n";
89   }
90   void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override {
91     OS << "\t.seh_save_fregp\td" << Reg << ", " << Offset << "\n";
92   }
93   void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override {
94     OS << "\t.seh_save_fregp_x\td" << Reg << ", " << Offset << "\n";
95   }
96   void emitARM64WinCFISetFP() override { OS << "\t.seh_set_fp\n"; }
97   void emitARM64WinCFIAddFP(unsigned Size) override {
98     OS << "\t.seh_add_fp\t" << Size << "\n";
99   }
100   void emitARM64WinCFINop() override { OS << "\t.seh_nop\n"; }
101   void emitARM64WinCFISaveNext() override { OS << "\t.seh_save_next\n"; }
102   void emitARM64WinCFIPrologEnd() override { OS << "\t.seh_endprologue\n"; }
103   void emitARM64WinCFIEpilogStart() override { OS << "\t.seh_startepilogue\n"; }
104   void emitARM64WinCFIEpilogEnd() override { OS << "\t.seh_endepilogue\n"; }
105   void emitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
106   void emitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
107   void emitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
108   void emitARM64WinCFIECContext() override { OS << "\t.seh_ec_context\n"; }
109   void emitARM64WinCFIClearUnwoundToCall() override {
110     OS << "\t.seh_clear_unwound_to_call\n";
111   }
112   void emitARM64WinCFIPACSignLR() override {
113     OS << "\t.seh_pac_sign_lr\n";
114   }
115 
116   void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override {
117     OS << "\t.seh_save_any_reg\tx" << Reg << ", " << Offset << "\n";
118   }
119   void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override {
120     OS << "\t.seh_save_any_reg_p\tx" << Reg << ", " << Offset << "\n";
121   }
122   void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override {
123     OS << "\t.seh_save_any_reg\td" << Reg << ", " << Offset << "\n";
124   }
125   void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override {
126     OS << "\t.seh_save_any_reg_p\td" << Reg << ", " << Offset << "\n";
127   }
128   void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override {
129     OS << "\t.seh_save_any_reg\tq" << Reg << ", " << Offset << "\n";
130   }
131   void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override {
132     OS << "\t.seh_save_any_reg_p\tq" << Reg << ", " << Offset << "\n";
133   }
134   void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override {
135     OS << "\t.seh_save_any_reg_x\tx" << Reg << ", " << Offset << "\n";
136   }
137   void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override {
138     OS << "\t.seh_save_any_reg_px\tx" << Reg << ", " << Offset << "\n";
139   }
140   void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override {
141     OS << "\t.seh_save_any_reg_x\td" << Reg << ", " << Offset << "\n";
142   }
143   void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override {
144     OS << "\t.seh_save_any_reg_px\td" << Reg << ", " << Offset << "\n";
145   }
146   void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override {
147     OS << "\t.seh_save_any_reg_x\tq" << Reg << ", " << Offset << "\n";
148   }
149   void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override {
150     OS << "\t.seh_save_any_reg_px\tq" << Reg << ", " << Offset << "\n";
151   }
152 
153   void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value,
154                      std::string String, bool Override) override {
155 
156     // AArch64 build attributes for assembly attribute form:
157     // .aeabi_attribute tag, value
158     if (unsigned(-1) == Value && "" == String) {
159       assert(0 && "Arguments error");
160       return;
161     }
162 
163     unsigned VendorID = AArch64BuildAttrs::getVendorID(VendorName);
164 
165     switch (VendorID) {
166     default:
167       assert(0 && "Subsection name error");
168       break;
169     case AArch64BuildAttrs::VENDOR_UNKNOWN:
170       if (unsigned(-1) != Value) {
171         OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
172         AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
173                                              Override);
174       }
175       if ("" != String) {
176         OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << String;
177         AArch64TargetStreamer::emitAttribute(VendorName, Tag, unsigned(-1),
178                                              String, Override);
179       }
180       break;
181     // Note: AEABI_FEATURE_AND_BITS takes only unsigned values
182     case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS:
183       switch (Tag) {
184       default: // allow emitting any attribute by number
185         OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
186         // Keep the data structure consistent with the case of ELF emission
187         // (important for llvm-mc asm parsing)
188         AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
189                                              Override);
190         break;
191       case AArch64BuildAttrs::TAG_FEATURE_BTI:
192       case AArch64BuildAttrs::TAG_FEATURE_GCS:
193       case AArch64BuildAttrs::TAG_FEATURE_PAC:
194         OS << "\t.aeabi_attribute" << "\t"
195            << AArch64BuildAttrs::getFeatureAndBitsTagsStr(Tag) << ", " << Value;
196         AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
197                                              Override);
198         break;
199       }
200       break;
201     // Note: AEABI_PAUTHABI takes only unsigned values
202     case AArch64BuildAttrs::AEABI_PAUTHABI:
203       switch (Tag) {
204       default: // allow emitting any attribute by number
205         OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
206         // Keep the data structure consistent with the case of ELF emission
207         // (important for llvm-mc asm parsing)
208         AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
209                                              Override);
210         break;
211       case AArch64BuildAttrs::TAG_PAUTH_PLATFORM:
212       case AArch64BuildAttrs::TAG_PAUTH_SCHEMA:
213         OS << "\t.aeabi_attribute" << "\t"
214            << AArch64BuildAttrs::getPauthABITagsStr(Tag) << ", " << Value;
215         AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "",
216                                              Override);
217         break;
218       }
219       break;
220     }
221     OS << "\n";
222   }
223 
224   void emitAtributesSubsection(
225       StringRef SubsectionName, AArch64BuildAttrs::SubsectionOptional Optional,
226       AArch64BuildAttrs::SubsectionType ParameterType) override {
227     // The AArch64 build attributes assembly subsection header format:
228     // ".aeabi_subsection name, optional, parameter type"
229     // optional: required (0) optional (1)
230     // parameter type: uleb128 or ULEB128 (0) ntbs or NTBS (1)
231     unsigned SubsectionID = AArch64BuildAttrs::getVendorID(SubsectionName);
232 
233     assert((0 == Optional || 1 == Optional) &&
234            AArch64BuildAttrs::getSubsectionOptionalUnknownError().data());
235     assert((0 == ParameterType || 1 == ParameterType) &&
236            AArch64BuildAttrs::getSubsectionTypeUnknownError().data());
237 
238     std::string SubsectionTag = ".aeabi_subsection";
239     StringRef OptionalStr = getOptionalStr(Optional);
240     StringRef ParameterStr = getTypeStr(ParameterType);
241 
242     switch (SubsectionID) {
243     default: {
244       // Treated as a private subsection
245       break;
246     }
247     case AArch64BuildAttrs::AEABI_PAUTHABI: {
248       assert(AArch64BuildAttrs::REQUIRED == Optional &&
249              "subsection .aeabi-pauthabi should be marked as "
250              "required and not as optional");
251       assert(AArch64BuildAttrs::ULEB128 == ParameterType &&
252              "subsection .aeabi-pauthabi should be "
253              "marked as uleb128 and not as ntbs");
254       break;
255     }
256     case AArch64BuildAttrs::AEABI_FEATURE_AND_BITS: {
257       assert(AArch64BuildAttrs::OPTIONAL == Optional &&
258              "subsection .aeabi_feature_and_bits should be "
259              "marked as optional and not as required");
260       assert(AArch64BuildAttrs::ULEB128 == ParameterType &&
261              "subsection .aeabi_feature_and_bits should "
262              "be marked as uleb128 and not as ntbs");
263       break;
264     }
265     }
266     OS << "\t" << SubsectionTag << "\t" << SubsectionName << ", " << OptionalStr
267        << ", " << ParameterStr;
268     // Keep the data structure consistent with the case of ELF emission
269     // (important for llvm-mc asm parsing)
270     AArch64TargetStreamer::emitAtributesSubsection(SubsectionName, Optional,
271                                                    ParameterType);
272     OS << "\n";
273   }
274 
275 public:
276   AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
277 };
278 
279 AArch64TargetAsmStreamer::AArch64TargetAsmStreamer(MCStreamer &S,
280                                                    formatted_raw_ostream &OS)
281     : AArch64TargetStreamer(S), OS(OS) {}
282 
283 void AArch64TargetAsmStreamer::emitInst(uint32_t Inst) {
284   OS << "\t.inst\t0x" << Twine::utohexstr(Inst) << "\n";
285 }
286 
287 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
288 /// the appropriate points in the object files. These symbols are defined in the
289 /// AArch64 ELF ABI:
290 ///    infocenter.arm.com/help/topic/com.arm.doc.ihi0056a/IHI0056A_aaelf64.pdf
291 ///
292 /// In brief: $x or $d should be emitted at the start of each contiguous region
293 /// of A64 code or data in a section. In practice, this emission does not rely
294 /// on explicit assembler directives but on inherent properties of the
295 /// directives doing the emission (e.g. ".byte" is data, "add x0, x0, x0" an
296 /// instruction).
297 ///
298 /// As a result this system is orthogonal to the DataRegion infrastructure used
299 /// by MachO. Beware!
300 class AArch64ELFStreamer : public MCELFStreamer {
301 public:
302   friend AArch64TargetELFStreamer;
303   AArch64ELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
304                      std::unique_ptr<MCObjectWriter> OW,
305                      std::unique_ptr<MCCodeEmitter> Emitter)
306       : MCELFStreamer(Context, std::move(TAB), std::move(OW),
307                       std::move(Emitter)),
308         LastEMS(EMS_None) {
309     auto *TO = getContext().getTargetOptions();
310     ImplicitMapSyms = TO && TO->ImplicitMapSyms;
311   }
312 
313   void changeSection(MCSection *Section, uint32_t Subsection = 0) override {
314     // Save the mapping symbol state for potential reuse when revisiting the
315     // section. When ImplicitMapSyms is true, the initial state is
316     // EMS_A64 for text sections and EMS_Data for the others.
317     LastMappingSymbols[getCurrentSection().first] = LastEMS;
318     auto It = LastMappingSymbols.find(Section);
319     if (It != LastMappingSymbols.end())
320       LastEMS = It->second;
321     else if (ImplicitMapSyms)
322       LastEMS = Section->isText() ? EMS_A64 : EMS_Data;
323     else
324       LastEMS = EMS_None;
325 
326     MCELFStreamer::changeSection(Section, Subsection);
327   }
328 
329   // Reset state between object emissions
330   void reset() override {
331     MCELFStreamer::reset();
332     LastMappingSymbols.clear();
333     LastEMS = EMS_None;
334   }
335 
336   /// This function is the one used to emit instruction data into the ELF
337   /// streamer. We override it to add the appropriate mapping symbol if
338   /// necessary.
339   void emitInstruction(const MCInst &Inst,
340                        const MCSubtargetInfo &STI) override {
341     emitA64MappingSymbol();
342     MCELFStreamer::emitInstruction(Inst, STI);
343   }
344 
345   /// Emit a 32-bit value as an instruction. This is only used for the .inst
346   /// directive, EmitInstruction should be used in other cases.
347   void emitInst(uint32_t Inst) {
348     char Buffer[4];
349 
350     // We can't just use EmitIntValue here, as that will emit a data mapping
351     // symbol, and swap the endianness on big-endian systems (instructions are
352     // always little-endian).
353     for (char &C : Buffer) {
354       C = uint8_t(Inst);
355       Inst >>= 8;
356     }
357 
358     emitA64MappingSymbol();
359     MCELFStreamer::emitBytes(StringRef(Buffer, 4));
360   }
361 
362   /// This is one of the functions used to emit data into an ELF section, so the
363   /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d)
364   /// if necessary.
365   void emitBytes(StringRef Data) override {
366     emitDataMappingSymbol();
367     MCELFStreamer::emitBytes(Data);
368   }
369 
370   /// This is one of the functions used to emit data into an ELF section, so the
371   /// AArch64 streamer overrides it to add the appropriate mapping symbol ($d)
372   /// if necessary.
373   void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
374     emitDataMappingSymbol();
375     MCELFStreamer::emitValueImpl(Value, Size, Loc);
376   }
377 
378   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
379                                   SMLoc Loc) override {
380     emitDataMappingSymbol();
381     MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
382   }
383 
384 private:
385   enum ElfMappingSymbol {
386     EMS_None,
387     EMS_A64,
388     EMS_Data
389   };
390 
391   void emitDataMappingSymbol() {
392     if (LastEMS == EMS_Data)
393       return;
394     emitMappingSymbol("$d");
395     LastEMS = EMS_Data;
396   }
397 
398   void emitA64MappingSymbol() {
399     if (LastEMS == EMS_A64)
400       return;
401     emitMappingSymbol("$x");
402     LastEMS = EMS_A64;
403   }
404 
405   MCSymbol *emitMappingSymbol(StringRef Name) {
406     auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
407     emitLabel(Symbol);
408     return Symbol;
409   }
410 
411   DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
412   ElfMappingSymbol LastEMS;
413   bool ImplicitMapSyms;
414 };
415 } // end anonymous namespace
416 
417 AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() {
418   return static_cast<AArch64ELFStreamer &>(Streamer);
419 }
420 
421 void AArch64TargetELFStreamer::emitAtributesSubsection(
422     StringRef VendorName, AArch64BuildAttrs::SubsectionOptional IsOptional,
423     AArch64BuildAttrs::SubsectionType ParameterType) {
424   AArch64TargetStreamer::emitAtributesSubsection(VendorName, IsOptional,
425                                                  ParameterType);
426 }
427 
428 void AArch64TargetELFStreamer::emitAttribute(StringRef VendorName, unsigned Tag,
429                                              unsigned Value, std::string String,
430                                              bool Override) {
431   if (unsigned(-1) != Value)
432     AArch64TargetStreamer::emitAttribute(VendorName, Tag, Value, "", Override);
433   if ("" != String)
434     AArch64TargetStreamer::emitAttribute(VendorName, Tag, unsigned(-1), String,
435                                          Override);
436 }
437 
438 void AArch64TargetELFStreamer::emitInst(uint32_t Inst) {
439   getStreamer().emitInst(Inst);
440 }
441 
442 void AArch64TargetELFStreamer::emitDirectiveVariantPCS(MCSymbol *Symbol) {
443   getStreamer().getAssembler().registerSymbol(*Symbol);
444   cast<MCSymbolELF>(Symbol)->setOther(ELF::STO_AARCH64_VARIANT_PCS);
445 }
446 
447 void AArch64TargetELFStreamer::finish() {
448   AArch64TargetStreamer::finish();
449   AArch64ELFStreamer &S = getStreamer();
450   MCContext &Ctx = S.getContext();
451   auto &Asm = S.getAssembler();
452 
453   S.emitAttributesSection(AttributeSection, ".ARM.attributes",
454                           ELF::SHT_AARCH64_ATTRIBUTES, AttributeSubSections);
455 
456   // If ImplicitMapSyms is specified, ensure that text sections end with
457   // the A64 state while non-text sections end with the data state. When
458   // sections are combined by the linker, the subsequent section will start with
459   // the right state. The ending mapping symbol is added right after the last
460   // symbol relative to the section. When a dumb linker combines (.text.0; .word
461   // 0) and (.text.1; .word 0), the ending $x of .text.0 precedes the $d of
462   // .text.1, even if they have the same address.
463   if (S.ImplicitMapSyms) {
464     auto &Syms = Asm.getSymbols();
465     const size_t NumSyms = Syms.size();
466     DenseMap<MCSection *, std::pair<size_t, MCSymbol *>> EndMapSym;
467     for (MCSection &Sec : Asm) {
468       S.switchSection(&Sec);
469       if (S.LastEMS == (Sec.isText() ? AArch64ELFStreamer::EMS_Data
470                                      : AArch64ELFStreamer::EMS_A64))
471         EndMapSym.insert(
472             {&Sec, {NumSyms, S.emitMappingSymbol(Sec.isText() ? "$x" : "$d")}});
473     }
474     if (Syms.size() != NumSyms) {
475       SmallVector<const MCSymbol *, 0> NewSyms;
476       DenseMap<MCSection *, size_t> Cnt;
477       Syms.truncate(NumSyms);
478       // Find the last symbol index for each candidate section.
479       for (auto [I, Sym] : llvm::enumerate(Syms)) {
480         if (!Sym->isInSection())
481           continue;
482         auto It = EndMapSym.find(&Sym->getSection());
483         if (It != EndMapSym.end())
484           It->second.first = I;
485       }
486       SmallVector<size_t, 0> Idx;
487       for (auto [I, Sym] : llvm::enumerate(Syms)) {
488         NewSyms.push_back(Sym);
489         if (!Sym->isInSection())
490           continue;
491         auto It = EndMapSym.find(&Sym->getSection());
492         // If `Sym` is the last symbol relative to the section, add the ending
493         // mapping symbol after `Sym`.
494         if (It != EndMapSym.end() && I == It->second.first) {
495           NewSyms.push_back(It->second.second);
496           Idx.push_back(I);
497         }
498       }
499       Syms = std::move(NewSyms);
500       // F.second holds the number of symbols added before the FILE symbol.
501       // Take into account the inserted mapping symbols.
502       for (auto &F : S.getWriter().getFileNames())
503         F.second += llvm::lower_bound(Idx, F.second) - Idx.begin();
504     }
505   }
506 
507   MCSectionELF *MemtagSec = nullptr;
508   for (const MCSymbol &Symbol : Asm.symbols()) {
509     const auto &Sym = cast<MCSymbolELF>(Symbol);
510     if (Sym.isMemtag()) {
511       MemtagSec = Ctx.getELFSection(".memtag.globals.static",
512                                     ELF::SHT_AARCH64_MEMTAG_GLOBALS_STATIC, 0);
513       break;
514     }
515   }
516   if (!MemtagSec)
517     return;
518 
519   // switchSection registers the section symbol and invalidates symbols(). We
520   // need a separate symbols() loop.
521   S.switchSection(MemtagSec);
522   const auto *Zero = MCConstantExpr::create(0, Ctx);
523   for (const MCSymbol &Symbol : Asm.symbols()) {
524     const auto &Sym = cast<MCSymbolELF>(Symbol);
525     if (!Sym.isMemtag())
526       continue;
527     auto *SRE = MCSymbolRefExpr::create(&Sym, MCSymbolRefExpr::VK_None, Ctx);
528     (void)S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE, SMLoc(),
529                                *Ctx.getSubtargetInfo());
530   }
531 }
532 
533 MCTargetStreamer *
534 llvm::createAArch64AsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS,
535                                      MCInstPrinter *InstPrint) {
536   return new AArch64TargetAsmStreamer(S, OS);
537 }
538 
539 MCELFStreamer *
540 llvm::createAArch64ELFStreamer(MCContext &Context,
541                                std::unique_ptr<MCAsmBackend> TAB,
542                                std::unique_ptr<MCObjectWriter> OW,
543                                std::unique_ptr<MCCodeEmitter> Emitter) {
544   AArch64ELFStreamer *S = new AArch64ELFStreamer(
545       Context, std::move(TAB), std::move(OW), std::move(Emitter));
546   return S;
547 }
548