[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / Target / ARM / MCTargetDesc / ARMELFStreamer.cpp
blob12076b8c49c143cab1ab46505bd645d2298eddc9
1 //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
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 ARM ELF .o object files. Different
10 // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
11 // delimit regions of data and code.
13 //===----------------------------------------------------------------------===//
15 #include "ARMRegisterInfo.h"
16 #include "ARMUnwindOpAsm.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCAsmBackend.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCAssembler.h"
27 #include "llvm/MC/MCCodeEmitter.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCELFStreamer.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCFixup.h"
32 #include "llvm/MC/MCFragment.h"
33 #include "llvm/MC/MCInst.h"
34 #include "llvm/MC/MCInstPrinter.h"
35 #include "llvm/MC/MCObjectWriter.h"
36 #include "llvm/MC/MCRegisterInfo.h"
37 #include "llvm/MC/MCSection.h"
38 #include "llvm/MC/MCSectionELF.h"
39 #include "llvm/MC/MCStreamer.h"
40 #include "llvm/MC/MCSubtargetInfo.h"
41 #include "llvm/MC/MCSymbol.h"
42 #include "llvm/MC/MCSymbolELF.h"
43 #include "llvm/MC/SectionKind.h"
44 #include "llvm/Support/ARMBuildAttributes.h"
45 #include "llvm/Support/ARMEHABI.h"
46 #include "llvm/Support/Casting.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/FormattedStream.h"
49 #include "llvm/Support/TargetParser.h"
50 #include "llvm/Support/raw_ostream.h"
51 #include <algorithm>
52 #include <cassert>
53 #include <climits>
54 #include <cstddef>
55 #include <cstdint>
56 #include <string>
58 using namespace llvm;
60 static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
61 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
62 "Invalid personality index");
63 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
66 namespace {
68 class ARMELFStreamer;
70 class ARMTargetAsmStreamer : public ARMTargetStreamer {
71 formatted_raw_ostream &OS;
72 MCInstPrinter &InstPrinter;
73 bool IsVerboseAsm;
75 void emitFnStart() override;
76 void emitFnEnd() override;
77 void emitCantUnwind() override;
78 void emitPersonality(const MCSymbol *Personality) override;
79 void emitPersonalityIndex(unsigned Index) override;
80 void emitHandlerData() override;
81 void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
82 void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
83 void emitPad(int64_t Offset) override;
84 void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
85 bool isVector) override;
86 void emitUnwindRaw(int64_t Offset,
87 const SmallVectorImpl<uint8_t> &Opcodes) override;
89 void switchVendor(StringRef Vendor) override;
90 void emitAttribute(unsigned Attribute, unsigned Value) override;
91 void emitTextAttribute(unsigned Attribute, StringRef String) override;
92 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
93 StringRef StringValue) override;
94 void emitArch(ARM::ArchKind Arch) override;
95 void emitArchExtension(uint64_t ArchExt) override;
96 void emitObjectArch(ARM::ArchKind Arch) override;
97 void emitFPU(unsigned FPU) override;
98 void emitInst(uint32_t Inst, char Suffix = '\0') override;
99 void finishAttributeSection() override;
101 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
102 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
104 public:
105 ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
106 MCInstPrinter &InstPrinter, bool VerboseAsm);
109 ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
110 formatted_raw_ostream &OS,
111 MCInstPrinter &InstPrinter,
112 bool VerboseAsm)
113 : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
114 IsVerboseAsm(VerboseAsm) {}
116 void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
117 void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
118 void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
120 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
121 OS << "\t.personality " << Personality->getName() << '\n';
124 void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
125 OS << "\t.personalityindex " << Index << '\n';
128 void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
130 void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
131 int64_t Offset) {
132 OS << "\t.setfp\t";
133 InstPrinter.printRegName(OS, FpReg);
134 OS << ", ";
135 InstPrinter.printRegName(OS, SpReg);
136 if (Offset)
137 OS << ", #" << Offset;
138 OS << '\n';
141 void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
142 assert((Reg != ARM::SP && Reg != ARM::PC) &&
143 "the operand of .movsp cannot be either sp or pc");
145 OS << "\t.movsp\t";
146 InstPrinter.printRegName(OS, Reg);
147 if (Offset)
148 OS << ", #" << Offset;
149 OS << '\n';
152 void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
153 OS << "\t.pad\t#" << Offset << '\n';
156 void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
157 bool isVector) {
158 assert(RegList.size() && "RegList should not be empty");
159 if (isVector)
160 OS << "\t.vsave\t{";
161 else
162 OS << "\t.save\t{";
164 InstPrinter.printRegName(OS, RegList[0]);
166 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
167 OS << ", ";
168 InstPrinter.printRegName(OS, RegList[i]);
171 OS << "}\n";
174 void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
176 void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
177 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
178 if (IsVerboseAsm) {
179 StringRef Name = ELFAttrs::attrTypeAsString(
180 Attribute, ARMBuildAttrs::getARMAttributeTags());
181 if (!Name.empty())
182 OS << "\t@ " << Name;
184 OS << "\n";
187 void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
188 StringRef String) {
189 switch (Attribute) {
190 case ARMBuildAttrs::CPU_name:
191 OS << "\t.cpu\t" << String.lower();
192 break;
193 default:
194 OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
195 if (IsVerboseAsm) {
196 StringRef Name = ELFAttrs::attrTypeAsString(
197 Attribute, ARMBuildAttrs::getARMAttributeTags());
198 if (!Name.empty())
199 OS << "\t@ " << Name;
201 break;
203 OS << "\n";
206 void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
207 unsigned IntValue,
208 StringRef StringValue) {
209 switch (Attribute) {
210 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
211 case ARMBuildAttrs::compatibility:
212 OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
213 if (!StringValue.empty())
214 OS << ", \"" << StringValue << "\"";
215 if (IsVerboseAsm)
216 OS << "\t@ "
217 << ELFAttrs::attrTypeAsString(Attribute,
218 ARMBuildAttrs::getARMAttributeTags());
219 break;
221 OS << "\n";
224 void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
225 OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
228 void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
229 OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
232 void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
233 OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
236 void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
237 OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
240 void ARMTargetAsmStreamer::finishAttributeSection() {}
242 void
243 ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
244 OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
247 void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
248 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
250 OS << "\t.thumb_set\t";
251 Symbol->print(OS, MAI);
252 OS << ", ";
253 Value->print(OS, MAI);
254 OS << '\n';
257 void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
258 OS << "\t.inst";
259 if (Suffix)
260 OS << "." << Suffix;
261 OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
264 void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
265 const SmallVectorImpl<uint8_t> &Opcodes) {
266 OS << "\t.unwind_raw " << Offset;
267 for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
268 OCE = Opcodes.end();
269 OCI != OCE; ++OCI)
270 OS << ", 0x" << Twine::utohexstr(*OCI);
271 OS << '\n';
274 class ARMTargetELFStreamer : public ARMTargetStreamer {
275 private:
276 StringRef CurrentVendor;
277 unsigned FPU = ARM::FK_INVALID;
278 ARM::ArchKind Arch = ARM::ArchKind::INVALID;
279 ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
281 MCSection *AttributeSection = nullptr;
283 void emitArchDefaultAttributes();
284 void emitFPUDefaultAttributes();
286 ARMELFStreamer &getStreamer();
288 void emitFnStart() override;
289 void emitFnEnd() override;
290 void emitCantUnwind() override;
291 void emitPersonality(const MCSymbol *Personality) override;
292 void emitPersonalityIndex(unsigned Index) override;
293 void emitHandlerData() override;
294 void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
295 void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
296 void emitPad(int64_t Offset) override;
297 void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
298 bool isVector) override;
299 void emitUnwindRaw(int64_t Offset,
300 const SmallVectorImpl<uint8_t> &Opcodes) override;
302 void switchVendor(StringRef Vendor) override;
303 void emitAttribute(unsigned Attribute, unsigned Value) override;
304 void emitTextAttribute(unsigned Attribute, StringRef String) override;
305 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
306 StringRef StringValue) override;
307 void emitArch(ARM::ArchKind Arch) override;
308 void emitObjectArch(ARM::ArchKind Arch) override;
309 void emitFPU(unsigned FPU) override;
310 void emitInst(uint32_t Inst, char Suffix = '\0') override;
311 void finishAttributeSection() override;
312 void emitLabel(MCSymbol *Symbol) override;
314 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
315 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
317 // Reset state between object emissions
318 void reset() override;
320 public:
321 ARMTargetELFStreamer(MCStreamer &S)
322 : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
325 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
326 /// the appropriate points in the object files. These symbols are defined in the
327 /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
329 /// In brief: $a, $t or $d should be emitted at the start of each contiguous
330 /// region of ARM code, Thumb code or data in a section. In practice, this
331 /// emission does not rely on explicit assembler directives but on inherent
332 /// properties of the directives doing the emission (e.g. ".byte" is data, "add
333 /// r0, r0, r0" an instruction).
335 /// As a result this system is orthogonal to the DataRegion infrastructure used
336 /// by MachO. Beware!
337 class ARMELFStreamer : public MCELFStreamer {
338 public:
339 friend class ARMTargetELFStreamer;
341 ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
342 std::unique_ptr<MCObjectWriter> OW,
343 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
344 bool IsAndroid)
345 : MCELFStreamer(Context, std::move(TAB), std::move(OW),
346 std::move(Emitter)),
347 IsThumb(IsThumb), IsAndroid(IsAndroid) {
348 EHReset();
351 ~ARMELFStreamer() override = default;
353 void finishImpl() override;
355 // ARM exception handling directives
356 void emitFnStart();
357 void emitFnEnd();
358 void emitCantUnwind();
359 void emitPersonality(const MCSymbol *Per);
360 void emitPersonalityIndex(unsigned index);
361 void emitHandlerData();
362 void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
363 void emitMovSP(unsigned Reg, int64_t Offset = 0);
364 void emitPad(int64_t Offset);
365 void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
366 void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
367 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
368 SMLoc Loc) override {
369 emitDataMappingSymbol();
370 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
373 void changeSection(MCSection *Section, const MCExpr *Subsection) override {
374 LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
375 MCELFStreamer::changeSection(Section, Subsection);
376 auto LastMappingSymbol = LastMappingSymbols.find(Section);
377 if (LastMappingSymbol != LastMappingSymbols.end()) {
378 LastEMSInfo = std::move(LastMappingSymbol->second);
379 return;
381 LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
384 /// This function is the one used to emit instruction data into the ELF
385 /// streamer. We override it to add the appropriate mapping symbol if
386 /// necessary.
387 void emitInstruction(const MCInst &Inst,
388 const MCSubtargetInfo &STI) override {
389 if (IsThumb)
390 EmitThumbMappingSymbol();
391 else
392 EmitARMMappingSymbol();
394 MCELFStreamer::emitInstruction(Inst, STI);
397 void emitInst(uint32_t Inst, char Suffix) {
398 unsigned Size;
399 char Buffer[4];
400 const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
402 switch (Suffix) {
403 case '\0':
404 Size = 4;
406 assert(!IsThumb);
407 EmitARMMappingSymbol();
408 for (unsigned II = 0, IE = Size; II != IE; II++) {
409 const unsigned I = LittleEndian ? (Size - II - 1) : II;
410 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
413 break;
414 case 'n':
415 case 'w':
416 Size = (Suffix == 'n' ? 2 : 4);
418 assert(IsThumb);
419 EmitThumbMappingSymbol();
420 // Thumb wide instructions are emitted as a pair of 16-bit words of the
421 // appropriate endianness.
422 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
423 const unsigned I0 = LittleEndian ? II + 0 : II + 1;
424 const unsigned I1 = LittleEndian ? II + 1 : II + 0;
425 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
426 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
429 break;
430 default:
431 llvm_unreachable("Invalid Suffix");
434 MCELFStreamer::emitBytes(StringRef(Buffer, Size));
437 /// This is one of the functions used to emit data into an ELF section, so the
438 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
439 /// necessary.
440 void emitBytes(StringRef Data) override {
441 emitDataMappingSymbol();
442 MCELFStreamer::emitBytes(Data);
445 void FlushPendingMappingSymbol() {
446 if (!LastEMSInfo->hasInfo())
447 return;
448 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
449 EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
450 EMS->resetInfo();
453 /// This is one of the functions used to emit data into an ELF section, so the
454 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
455 /// necessary.
456 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
457 if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
458 if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
459 getContext().reportError(Loc, "relocated expression must be 32-bit");
460 return;
462 getOrCreateDataFragment();
465 emitDataMappingSymbol();
466 MCELFStreamer::emitValueImpl(Value, Size, Loc);
469 void emitAssemblerFlag(MCAssemblerFlag Flag) override {
470 MCELFStreamer::emitAssemblerFlag(Flag);
472 switch (Flag) {
473 case MCAF_SyntaxUnified:
474 return; // no-op here.
475 case MCAF_Code16:
476 IsThumb = true;
477 return; // Change to Thumb mode
478 case MCAF_Code32:
479 IsThumb = false;
480 return; // Change to ARM mode
481 case MCAF_Code64:
482 return;
483 case MCAF_SubsectionsViaSymbols:
484 return;
488 /// If a label is defined before the .type directive sets the label's type
489 /// then the label can't be recorded as thumb function when the label is
490 /// defined. We override emitSymbolAttribute() which is called as part of the
491 /// parsing of .type so that if the symbol has already been defined we can
492 /// record the label as Thumb. FIXME: there is a corner case where the state
493 /// is changed in between the label definition and the .type directive, this
494 /// is not expected to occur in practice and handling it would require the
495 /// backend to track IsThumb for every label.
496 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
497 bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);
499 if (!IsThumb)
500 return Val;
502 unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
503 if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
504 Symbol->isDefined())
505 getAssembler().setIsThumbFunc(Symbol);
507 return Val;
510 private:
511 enum ElfMappingSymbol {
512 EMS_None,
513 EMS_ARM,
514 EMS_Thumb,
515 EMS_Data
518 struct ElfMappingSymbolInfo {
519 explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
520 : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
521 void resetInfo() {
522 F = nullptr;
523 Offset = 0;
525 bool hasInfo() { return F != nullptr; }
526 SMLoc Loc;
527 MCFragment *F;
528 uint64_t Offset;
529 ElfMappingSymbol State;
532 void emitDataMappingSymbol() {
533 if (LastEMSInfo->State == EMS_Data)
534 return;
535 else if (LastEMSInfo->State == EMS_None) {
536 // This is a tentative symbol, it won't really be emitted until it's
537 // actually needed.
538 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
539 auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
540 if (!DF)
541 return;
542 EMS->Loc = SMLoc();
543 EMS->F = getCurrentFragment();
544 EMS->Offset = DF->getContents().size();
545 LastEMSInfo->State = EMS_Data;
546 return;
548 EmitMappingSymbol("$d");
549 LastEMSInfo->State = EMS_Data;
552 void EmitThumbMappingSymbol() {
553 if (LastEMSInfo->State == EMS_Thumb)
554 return;
555 FlushPendingMappingSymbol();
556 EmitMappingSymbol("$t");
557 LastEMSInfo->State = EMS_Thumb;
560 void EmitARMMappingSymbol() {
561 if (LastEMSInfo->State == EMS_ARM)
562 return;
563 FlushPendingMappingSymbol();
564 EmitMappingSymbol("$a");
565 LastEMSInfo->State = EMS_ARM;
568 void EmitMappingSymbol(StringRef Name) {
569 auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
570 Name + "." + Twine(MappingSymbolCounter++)));
571 emitLabel(Symbol);
573 Symbol->setType(ELF::STT_NOTYPE);
574 Symbol->setBinding(ELF::STB_LOCAL);
577 void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
578 uint64_t Offset) {
579 auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
580 Name + "." + Twine(MappingSymbolCounter++)));
581 emitLabelAtPos(Symbol, Loc, F, Offset);
582 Symbol->setType(ELF::STT_NOTYPE);
583 Symbol->setBinding(ELF::STB_LOCAL);
586 void emitThumbFunc(MCSymbol *Func) override {
587 getAssembler().setIsThumbFunc(Func);
588 emitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
591 // Helper functions for ARM exception handling directives
592 void EHReset();
594 // Reset state between object emissions
595 void reset() override;
597 void EmitPersonalityFixup(StringRef Name);
598 void FlushPendingOffset();
599 void FlushUnwindOpcodes(bool NoHandlerData);
601 void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
602 SectionKind Kind, const MCSymbol &Fn);
603 void SwitchToExTabSection(const MCSymbol &FnStart);
604 void SwitchToExIdxSection(const MCSymbol &FnStart);
606 void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
608 bool IsThumb;
609 bool IsAndroid;
610 int64_t MappingSymbolCounter = 0;
612 DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
613 LastMappingSymbols;
615 std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
617 // ARM Exception Handling Frame Information
618 MCSymbol *ExTab;
619 MCSymbol *FnStart;
620 const MCSymbol *Personality;
621 unsigned PersonalityIndex;
622 unsigned FPReg; // Frame pointer register
623 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
624 int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
625 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
626 bool UsedFP;
627 bool CantUnwind;
628 SmallVector<uint8_t, 64> Opcodes;
629 UnwindOpcodeAssembler UnwindOpAsm;
632 } // end anonymous namespace
634 ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
635 return static_cast<ARMELFStreamer &>(Streamer);
638 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
639 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
640 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
642 void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
643 getStreamer().emitPersonality(Personality);
646 void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
647 getStreamer().emitPersonalityIndex(Index);
650 void ARMTargetELFStreamer::emitHandlerData() {
651 getStreamer().emitHandlerData();
654 void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
655 int64_t Offset) {
656 getStreamer().emitSetFP(FpReg, SpReg, Offset);
659 void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
660 getStreamer().emitMovSP(Reg, Offset);
663 void ARMTargetELFStreamer::emitPad(int64_t Offset) {
664 getStreamer().emitPad(Offset);
667 void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
668 bool isVector) {
669 getStreamer().emitRegSave(RegList, isVector);
672 void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
673 const SmallVectorImpl<uint8_t> &Opcodes) {
674 getStreamer().emitUnwindRaw(Offset, Opcodes);
677 void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
678 assert(!Vendor.empty() && "Vendor cannot be empty.");
680 if (CurrentVendor == Vendor)
681 return;
683 if (!CurrentVendor.empty())
684 finishAttributeSection();
686 assert(getStreamer().Contents.empty() &&
687 ".ARM.attributes should be flushed before changing vendor");
688 CurrentVendor = Vendor;
692 void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
693 getStreamer().setAttributeItem(Attribute, Value,
694 /* OverwriteExisting= */ true);
697 void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
698 StringRef Value) {
699 getStreamer().setAttributeItem(Attribute, Value,
700 /* OverwriteExisting= */ true);
703 void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
704 unsigned IntValue,
705 StringRef StringValue) {
706 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
707 /* OverwriteExisting= */ true);
710 void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
711 Arch = Value;
714 void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
715 EmittedArch = Value;
718 void ARMTargetELFStreamer::emitArchDefaultAttributes() {
719 using namespace ARMBuildAttrs;
720 ARMELFStreamer &S = getStreamer();
722 S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false);
724 if (EmittedArch == ARM::ArchKind::INVALID)
725 S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false);
726 else
727 S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false);
729 switch (Arch) {
730 case ARM::ArchKind::ARMV2:
731 case ARM::ArchKind::ARMV2A:
732 case ARM::ArchKind::ARMV3:
733 case ARM::ArchKind::ARMV3M:
734 case ARM::ArchKind::ARMV4:
735 S.setAttributeItem(ARM_ISA_use, Allowed, false);
736 break;
738 case ARM::ArchKind::ARMV4T:
739 case ARM::ArchKind::ARMV5T:
740 case ARM::ArchKind::XSCALE:
741 case ARM::ArchKind::ARMV5TE:
742 case ARM::ArchKind::ARMV6:
743 S.setAttributeItem(ARM_ISA_use, Allowed, false);
744 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
745 break;
747 case ARM::ArchKind::ARMV6T2:
748 S.setAttributeItem(ARM_ISA_use, Allowed, false);
749 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
750 break;
752 case ARM::ArchKind::ARMV6K:
753 case ARM::ArchKind::ARMV6KZ:
754 S.setAttributeItem(ARM_ISA_use, Allowed, false);
755 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
756 S.setAttributeItem(Virtualization_use, AllowTZ, false);
757 break;
759 case ARM::ArchKind::ARMV6M:
760 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
761 break;
763 case ARM::ArchKind::ARMV7A:
764 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
765 S.setAttributeItem(ARM_ISA_use, Allowed, false);
766 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
767 break;
769 case ARM::ArchKind::ARMV7R:
770 S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
771 S.setAttributeItem(ARM_ISA_use, Allowed, false);
772 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
773 break;
775 case ARM::ArchKind::ARMV7EM:
776 case ARM::ArchKind::ARMV7M:
777 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
778 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
779 break;
781 case ARM::ArchKind::ARMV8A:
782 case ARM::ArchKind::ARMV8_1A:
783 case ARM::ArchKind::ARMV8_2A:
784 case ARM::ArchKind::ARMV8_3A:
785 case ARM::ArchKind::ARMV8_4A:
786 case ARM::ArchKind::ARMV8_5A:
787 case ARM::ArchKind::ARMV8_6A:
788 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
789 S.setAttributeItem(ARM_ISA_use, Allowed, false);
790 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
791 S.setAttributeItem(MPextension_use, Allowed, false);
792 S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
793 break;
795 case ARM::ArchKind::ARMV8MBaseline:
796 case ARM::ArchKind::ARMV8MMainline:
797 S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
798 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
799 break;
801 case ARM::ArchKind::IWMMXT:
802 S.setAttributeItem(ARM_ISA_use, Allowed, false);
803 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
804 S.setAttributeItem(WMMX_arch, AllowWMMXv1, false);
805 break;
807 case ARM::ArchKind::IWMMXT2:
808 S.setAttributeItem(ARM_ISA_use, Allowed, false);
809 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
810 S.setAttributeItem(WMMX_arch, AllowWMMXv2, false);
811 break;
813 default:
814 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
815 break;
819 void ARMTargetELFStreamer::emitFPU(unsigned Value) {
820 FPU = Value;
823 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
824 ARMELFStreamer &S = getStreamer();
826 switch (FPU) {
827 case ARM::FK_VFP:
828 case ARM::FK_VFPV2:
829 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv2,
830 /* OverwriteExisting= */ false);
831 break;
833 case ARM::FK_VFPV3:
834 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
835 /* OverwriteExisting= */ false);
836 break;
838 case ARM::FK_VFPV3_FP16:
839 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
840 /* OverwriteExisting= */ false);
841 S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,
842 /* OverwriteExisting= */ false);
843 break;
845 case ARM::FK_VFPV3_D16:
846 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
847 /* OverwriteExisting= */ false);
848 break;
850 case ARM::FK_VFPV3_D16_FP16:
851 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
852 /* OverwriteExisting= */ false);
853 S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,
854 /* OverwriteExisting= */ false);
855 break;
857 case ARM::FK_VFPV3XD:
858 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
859 /* OverwriteExisting= */ false);
860 break;
861 case ARM::FK_VFPV3XD_FP16:
862 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
863 /* OverwriteExisting= */ false);
864 S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,
865 /* OverwriteExisting= */ false);
866 break;
868 case ARM::FK_VFPV4:
869 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A,
870 /* OverwriteExisting= */ false);
871 break;
873 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
874 // as _D16 here.
875 case ARM::FK_FPV4_SP_D16:
876 case ARM::FK_VFPV4_D16:
877 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4B,
878 /* OverwriteExisting= */ false);
879 break;
881 case ARM::FK_FP_ARMV8:
882 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A,
883 /* OverwriteExisting= */ false);
884 break;
886 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
887 // uses the FP_ARMV8_D16 build attribute.
888 case ARM::FK_FPV5_SP_D16:
889 case ARM::FK_FPV5_D16:
890 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8B,
891 /* OverwriteExisting= */ false);
892 break;
894 case ARM::FK_NEON:
895 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
896 /* OverwriteExisting= */ false);
897 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
898 ARMBuildAttrs::AllowNeon,
899 /* OverwriteExisting= */ false);
900 break;
902 case ARM::FK_NEON_FP16:
903 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
904 /* OverwriteExisting= */ false);
905 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
906 ARMBuildAttrs::AllowNeon,
907 /* OverwriteExisting= */ false);
908 S.setAttributeItem(ARMBuildAttrs::FP_HP_extension, ARMBuildAttrs::AllowHPFP,
909 /* OverwriteExisting= */ false);
910 break;
912 case ARM::FK_NEON_VFPV4:
913 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A,
914 /* OverwriteExisting= */ false);
915 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
916 ARMBuildAttrs::AllowNeon2,
917 /* OverwriteExisting= */ false);
918 break;
920 case ARM::FK_NEON_FP_ARMV8:
921 case ARM::FK_CRYPTO_NEON_FP_ARMV8:
922 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A,
923 /* OverwriteExisting= */ false);
924 // 'Advanced_SIMD_arch' must be emitted not here, but within
925 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
926 break;
928 case ARM::FK_SOFTVFP:
929 case ARM::FK_NONE:
930 break;
932 default:
933 report_fatal_error("Unknown FPU: " + Twine(FPU));
934 break;
938 void ARMTargetELFStreamer::finishAttributeSection() {
939 ARMELFStreamer &S = getStreamer();
941 if (FPU != ARM::FK_INVALID)
942 emitFPUDefaultAttributes();
944 if (Arch != ARM::ArchKind::INVALID)
945 emitArchDefaultAttributes();
947 if (S.Contents.empty())
948 return;
950 auto LessTag = [](const MCELFStreamer::AttributeItem &LHS,
951 const MCELFStreamer::AttributeItem &RHS) -> bool {
952 // The conformance tag must be emitted first when serialised into an
953 // object file. Specifically, the addenda to the ARM ABI states that
954 // (2.3.7.4):
956 // "To simplify recognition by consumers in the common case of claiming
957 // conformity for the whole file, this tag should be emitted first in a
958 // file-scope sub-subsection of the first public subsection of the
959 // attributes section."
961 // So it is special-cased in this comparison predicate when the
962 // attributes are sorted in finishAttributeSection().
963 return (RHS.Tag != ARMBuildAttrs::conformance) &&
964 ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
966 llvm::sort(S.Contents, LessTag);
968 S.emitAttributesSection(CurrentVendor, ".ARM.attributes",
969 ELF::SHT_ARM_ATTRIBUTES, AttributeSection);
971 FPU = ARM::FK_INVALID;
974 void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
975 ARMELFStreamer &Streamer = getStreamer();
976 if (!Streamer.IsThumb)
977 return;
979 Streamer.getAssembler().registerSymbol(*Symbol);
980 unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
981 if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
982 Streamer.emitThumbFunc(Symbol);
985 void
986 ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
987 getStreamer().EmitFixup(S, FK_Data_4);
990 void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
991 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
992 const MCSymbol &Sym = SRE->getSymbol();
993 if (!Sym.isDefined()) {
994 getStreamer().emitAssignment(Symbol, Value);
995 return;
999 getStreamer().emitThumbFunc(Symbol);
1000 getStreamer().emitAssignment(Symbol, Value);
1003 void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1004 getStreamer().emitInst(Inst, Suffix);
1007 void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1009 void ARMELFStreamer::finishImpl() {
1010 MCTargetStreamer &TS = *getTargetStreamer();
1011 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1012 ATS.finishAttributeSection();
1014 MCELFStreamer::finishImpl();
1017 void ARMELFStreamer::reset() {
1018 MCTargetStreamer &TS = *getTargetStreamer();
1019 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1020 ATS.reset();
1021 MappingSymbolCounter = 0;
1022 MCELFStreamer::reset();
1023 LastMappingSymbols.clear();
1024 LastEMSInfo.reset();
1025 // MCELFStreamer clear's the assembler's e_flags. However, for
1026 // arm we manually set the ABI version on streamer creation, so
1027 // do the same here
1028 getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1031 inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
1032 unsigned Type,
1033 unsigned Flags,
1034 SectionKind Kind,
1035 const MCSymbol &Fn) {
1036 const MCSectionELF &FnSection =
1037 static_cast<const MCSectionELF &>(Fn.getSection());
1039 // Create the name for new section
1040 StringRef FnSecName(FnSection.getName());
1041 SmallString<128> EHSecName(Prefix);
1042 if (FnSecName != ".text") {
1043 EHSecName += FnSecName;
1046 // Get .ARM.extab or .ARM.exidx section
1047 const MCSymbolELF *Group = FnSection.getGroup();
1048 if (Group)
1049 Flags |= ELF::SHF_GROUP;
1050 MCSectionELF *EHSection = getContext().getELFSection(
1051 EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1052 FnSection.getUniqueID(),
1053 static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
1055 assert(EHSection && "Failed to get the required EH section");
1057 // Switch to .ARM.extab or .ARM.exidx section
1058 SwitchSection(EHSection);
1059 emitCodeAlignment(4);
1062 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1063 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1064 SectionKind::getData(), FnStart);
1067 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1068 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
1069 ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
1070 SectionKind::getData(), FnStart);
1073 void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
1074 MCDataFragment *Frag = getOrCreateDataFragment();
1075 Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
1076 Kind));
1079 void ARMELFStreamer::EHReset() {
1080 ExTab = nullptr;
1081 FnStart = nullptr;
1082 Personality = nullptr;
1083 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1084 FPReg = ARM::SP;
1085 FPOffset = 0;
1086 SPOffset = 0;
1087 PendingOffset = 0;
1088 UsedFP = false;
1089 CantUnwind = false;
1091 Opcodes.clear();
1092 UnwindOpAsm.Reset();
1095 void ARMELFStreamer::emitFnStart() {
1096 assert(FnStart == nullptr);
1097 FnStart = getContext().createTempSymbol();
1098 emitLabel(FnStart);
1101 void ARMELFStreamer::emitFnEnd() {
1102 assert(FnStart && ".fnstart must precedes .fnend");
1104 // Emit unwind opcodes if there is no .handlerdata directive
1105 if (!ExTab && !CantUnwind)
1106 FlushUnwindOpcodes(true);
1108 // Emit the exception index table entry
1109 SwitchToExIdxSection(*FnStart);
1111 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1112 // personality routine to protect it from an arbitrary platform's static
1113 // linker garbage collection. We disable this for Android where the unwinder
1114 // is either dynamically linked or directly references the personality
1115 // routine.
1116 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
1117 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1119 const MCSymbolRefExpr *FnStartRef =
1120 MCSymbolRefExpr::create(FnStart,
1121 MCSymbolRefExpr::VK_ARM_PREL31,
1122 getContext());
1124 emitValue(FnStartRef, 4);
1126 if (CantUnwind) {
1127 emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
1128 } else if (ExTab) {
1129 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1130 const MCSymbolRefExpr *ExTabEntryRef =
1131 MCSymbolRefExpr::create(ExTab,
1132 MCSymbolRefExpr::VK_ARM_PREL31,
1133 getContext());
1134 emitValue(ExTabEntryRef, 4);
1135 } else {
1136 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1137 // the second word of exception index table entry. The size of the unwind
1138 // opcodes should always be 4 bytes.
1139 assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1140 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1141 assert(Opcodes.size() == 4u &&
1142 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1143 uint64_t Intval = Opcodes[0] |
1144 Opcodes[1] << 8 |
1145 Opcodes[2] << 16 |
1146 Opcodes[3] << 24;
1147 emitIntValue(Intval, Opcodes.size());
1150 // Switch to the section containing FnStart
1151 SwitchSection(&FnStart->getSection());
1153 // Clean exception handling frame information
1154 EHReset();
1157 void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1159 // Add the R_ARM_NONE fixup at the same position
1160 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1161 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1163 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1164 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1166 visitUsedExpr(*PersonalityRef);
1167 MCDataFragment *DF = getOrCreateDataFragment();
1168 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
1169 PersonalityRef,
1170 MCFixup::getKindForSize(4, false)));
1173 void ARMELFStreamer::FlushPendingOffset() {
1174 if (PendingOffset != 0) {
1175 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1176 PendingOffset = 0;
1180 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1181 // Emit the unwind opcode to restore $sp.
1182 if (UsedFP) {
1183 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1184 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1185 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1186 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1187 } else {
1188 FlushPendingOffset();
1191 // Finalize the unwind opcode sequence
1192 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1194 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1195 // section. Thus, we don't have to create an entry in the .ARM.extab
1196 // section.
1197 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1198 return;
1200 // Switch to .ARM.extab section.
1201 SwitchToExTabSection(*FnStart);
1203 // Create .ARM.extab label for offset in .ARM.exidx
1204 assert(!ExTab);
1205 ExTab = getContext().createTempSymbol();
1206 emitLabel(ExTab);
1208 // Emit personality
1209 if (Personality) {
1210 const MCSymbolRefExpr *PersonalityRef =
1211 MCSymbolRefExpr::create(Personality,
1212 MCSymbolRefExpr::VK_ARM_PREL31,
1213 getContext());
1215 emitValue(PersonalityRef, 4);
1218 // Emit unwind opcodes
1219 assert((Opcodes.size() % 4) == 0 &&
1220 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1221 for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1222 uint64_t Intval = Opcodes[I] |
1223 Opcodes[I + 1] << 8 |
1224 Opcodes[I + 2] << 16 |
1225 Opcodes[I + 3] << 24;
1226 emitInt32(Intval);
1229 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1230 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1231 // after the unwind opcodes. The handler data consists of several 32-bit
1232 // words, and should be terminated by zero.
1234 // In case that the .handlerdata directive is not specified by the
1235 // programmer, we should emit zero to terminate the handler data.
1236 if (NoHandlerData && !Personality)
1237 emitInt32(0);
1240 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1242 void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1243 Personality = Per;
1244 UnwindOpAsm.setPersonality(Per);
1247 void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1248 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1249 PersonalityIndex = Index;
1252 void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
1253 int64_t Offset) {
1254 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1255 "the operand of .setfp directive should be either $sp or $fp");
1257 UsedFP = true;
1258 FPReg = NewFPReg;
1260 if (NewSPReg == ARM::SP)
1261 FPOffset = SPOffset + Offset;
1262 else
1263 FPOffset += Offset;
1266 void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
1267 assert((Reg != ARM::SP && Reg != ARM::PC) &&
1268 "the operand of .movsp cannot be either sp or pc");
1269 assert(FPReg == ARM::SP && "current FP must be SP");
1271 FlushPendingOffset();
1273 FPReg = Reg;
1274 FPOffset = SPOffset + Offset;
1276 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1277 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1280 void ARMELFStreamer::emitPad(int64_t Offset) {
1281 // Track the change of the $sp offset
1282 SPOffset -= Offset;
1284 // To squash multiple .pad directives, we should delay the unwind opcode
1285 // until the .save, .vsave, .handlerdata, or .fnend directives.
1286 PendingOffset -= Offset;
1289 void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
1290 bool IsVector) {
1291 // Collect the registers in the register list
1292 unsigned Count = 0;
1293 uint32_t Mask = 0;
1294 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1295 for (size_t i = 0; i < RegList.size(); ++i) {
1296 unsigned Reg = MRI->getEncodingValue(RegList[i]);
1297 assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
1298 unsigned Bit = (1u << Reg);
1299 if ((Mask & Bit) == 0) {
1300 Mask |= Bit;
1301 ++Count;
1305 // Track the change the $sp offset: For the .save directive, the
1306 // corresponding push instruction will decrease the $sp by (4 * Count).
1307 // For the .vsave directive, the corresponding vpush instruction will
1308 // decrease $sp by (8 * Count).
1309 SPOffset -= Count * (IsVector ? 8 : 4);
1311 // Emit the opcode
1312 FlushPendingOffset();
1313 if (IsVector)
1314 UnwindOpAsm.EmitVFPRegSave(Mask);
1315 else
1316 UnwindOpAsm.EmitRegSave(Mask);
1319 void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1320 const SmallVectorImpl<uint8_t> &Opcodes) {
1321 FlushPendingOffset();
1322 SPOffset = SPOffset - Offset;
1323 UnwindOpAsm.EmitRaw(Opcodes);
1326 namespace llvm {
1328 MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
1329 formatted_raw_ostream &OS,
1330 MCInstPrinter *InstPrint,
1331 bool isVerboseAsm) {
1332 return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
1335 MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
1336 return new ARMTargetStreamer(S);
1339 MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
1340 const MCSubtargetInfo &STI) {
1341 const Triple &TT = STI.getTargetTriple();
1342 if (TT.isOSBinFormatELF())
1343 return new ARMTargetELFStreamer(S);
1344 return new ARMTargetStreamer(S);
1347 MCELFStreamer *createARMELFStreamer(MCContext &Context,
1348 std::unique_ptr<MCAsmBackend> TAB,
1349 std::unique_ptr<MCObjectWriter> OW,
1350 std::unique_ptr<MCCodeEmitter> Emitter,
1351 bool RelaxAll, bool IsThumb,
1352 bool IsAndroid) {
1353 ARMELFStreamer *S =
1354 new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1355 std::move(Emitter), IsThumb, IsAndroid);
1356 // FIXME: This should eventually end up somewhere else where more
1357 // intelligent flag decisions can be made. For now we are just maintaining
1358 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1359 S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1361 if (RelaxAll)
1362 S->getAssembler().setRelaxAll(true);
1363 return S;
1366 } // end namespace llvm