LLVM 24.0.0git
ARMELFStreamer.cpp
Go to the documentation of this file.
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.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ARMMCTargetDesc.h"
16#include "ARMUnwindOpAsm.h"
18#include "Utils/ARMBaseInfo.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/DenseSet.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/Twine.h"
28#include "llvm/MC/MCAsmInfo.h"
29#include "llvm/MC/MCAssembler.h"
31#include "llvm/MC/MCContext.h"
34#include "llvm/MC/MCExpr.h"
35#include "llvm/MC/MCFixup.h"
36#include "llvm/MC/MCInst.h"
41#include "llvm/MC/MCSection.h"
43#include "llvm/MC/MCStreamer.h"
45#include "llvm/MC/MCSymbol.h"
46#include "llvm/MC/MCSymbolELF.h"
47#include "llvm/MC/SectionKind.h"
54#include <cassert>
55#include <climits>
56#include <cstdint>
57#include <string>
58
59using namespace llvm;
60
61static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
63 "Invalid personality index");
64 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
65}
66
67namespace {
68
69class ARMELFStreamer;
70
71class ARMTargetAsmStreamer : public ARMTargetStreamer {
72 formatted_raw_ostream &OS;
73 MCInstPrinter &InstPrinter;
74 bool IsVerboseAsm;
75
76 void emitFnStart() override;
77 void emitFnEnd() override;
78 void emitCantUnwind() override;
79 void emitPersonality(const MCSymbol *Personality) override;
80 void emitPersonalityIndex(unsigned Index) override;
81 void emitHandlerData() override;
82 void emitSetFP(MCRegister FpReg, MCRegister SpReg,
83 int64_t Offset = 0) override;
84 void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
85 void emitPad(int64_t Offset) override;
86 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
87 bool isVector) override;
88 void emitUnwindRaw(int64_t Offset,
89 const SmallVectorImpl<uint8_t> &Opcodes) override;
90
91 void switchVendor(StringRef Vendor) override;
92 void emitAttribute(unsigned Attribute, unsigned Value) override;
93 void emitTextAttribute(unsigned Attribute, StringRef String) override;
94 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
95 StringRef StringValue) override;
96 void emitArch(ARM::ArchKind Arch) override;
97 void emitArchExtension(uint64_t ArchExt) override;
98 void emitObjectArch(ARM::ArchKind Arch) override;
99 void emitFPU(ARM::FPUKind FPU) override;
100 void emitInst(uint32_t Inst, char Suffix = '\0') override;
101 void finishAttributeSection() override;
102
103 void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
104 void emitSyntaxUnified() override;
105 void emitCode16() override;
106 void emitCode32() override;
107 void emitThumbFunc(MCSymbol *Symbol) override;
108 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
109
110 void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override;
111 void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) override;
112 void emitARMWinCFISaveSP(unsigned Reg) override;
113 void emitARMWinCFISaveFRegs(unsigned First, unsigned Last) override;
114 void emitARMWinCFISaveLR(unsigned Offset) override;
115 void emitARMWinCFIPrologEnd(bool Fragment) override;
116 void emitARMWinCFINop(bool Wide) override;
117 void emitARMWinCFIEpilogStart(unsigned Condition) override;
118 void emitARMWinCFIEpilogEnd() override;
119 void emitARMWinCFICustom(unsigned Opcode) override;
120
121public:
122 ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
123 MCInstPrinter &InstPrinter);
124};
125
126ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
128 MCInstPrinter &InstPrinter)
129 : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
130 IsVerboseAsm(S.isVerboseAsm()) {}
131
132void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
133void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
134void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
135
136void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
137 OS << "\t.personality " << Personality->getName() << '\n';
138}
139
140void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
141 OS << "\t.personalityindex " << Index << '\n';
142}
143
144void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
145
146void ARMTargetAsmStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
147 int64_t Offset) {
148 OS << "\t.setfp\t";
149 InstPrinter.printRegName(OS, FpReg);
150 OS << ", ";
151 InstPrinter.printRegName(OS, SpReg);
152 if (Offset)
153 OS << ", #" << Offset;
154 OS << '\n';
155}
156
157void ARMTargetAsmStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
158 assert((Reg != ARM::SP && Reg != ARM::PC) &&
159 "the operand of .movsp cannot be either sp or pc");
160
161 OS << "\t.movsp\t";
162 InstPrinter.printRegName(OS, Reg);
163 if (Offset)
164 OS << ", #" << Offset;
165 OS << '\n';
166}
167
168void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
169 OS << "\t.pad\t#" << Offset << '\n';
170}
171
172void ARMTargetAsmStreamer::emitRegSave(
173 const SmallVectorImpl<MCRegister> &RegList, bool isVector) {
174 assert(RegList.size() && "RegList should not be empty");
175 if (isVector)
176 OS << "\t.vsave\t{";
177 else
178 OS << "\t.save\t{";
179
180 InstPrinter.printRegName(OS, RegList[0]);
181
182 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
183 OS << ", ";
184 InstPrinter.printRegName(OS, RegList[i]);
185 }
186
187 OS << "}\n";
188}
189
190void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
191
192void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
193 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
194 if (IsVerboseAsm) {
197 if (!Name.empty())
198 OS << "\t@ " << Name;
199 }
200 OS << "\n";
201}
202
203void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
204 StringRef String) {
205 switch (Attribute) {
207 OS << "\t.cpu\t" << String.lower();
208 break;
209 default:
210 OS << "\t.eabi_attribute\t" << Attribute << ", \"";
213 else
214 OS << String;
215 OS << "\"";
216 if (IsVerboseAsm) {
219 if (!Name.empty())
220 OS << "\t@ " << Name;
221 }
222 break;
223 }
224 OS << "\n";
225}
226
227void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
228 unsigned IntValue,
229 StringRef StringValue) {
230 switch (Attribute) {
231 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
233 OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
234 if (!StringValue.empty())
235 OS << ", \"" << StringValue << "\"";
236 if (IsVerboseAsm)
237 OS << "\t@ "
240 break;
241 }
242 OS << "\n";
243}
244
245void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
246 OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
247}
248
249void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
250 OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
251}
252
253void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
254 OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
255}
256
257void ARMTargetAsmStreamer::emitFPU(ARM::FPUKind FPU) {
258 OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
259}
260
261void ARMTargetAsmStreamer::finishAttributeSection() {}
262
263void ARMTargetAsmStreamer::annotateTLSDescriptorSequence(
264 const MCSymbolRefExpr *S) {
265 OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
266}
267
268void ARMTargetAsmStreamer::emitSyntaxUnified() { OS << "\t.syntax\tunified\n"; }
269
270void ARMTargetAsmStreamer::emitCode16() { OS << "\t.code\t16\n"; }
271
272void ARMTargetAsmStreamer::emitCode32() { OS << "\t.code\t32\n"; }
273
274void ARMTargetAsmStreamer::emitThumbFunc(MCSymbol *Symbol) {
275 const MCAsmInfo &MAI = Streamer.getContext().getAsmInfo();
276 OS << "\t.thumb_func";
277 // Only Mach-O hasSubsectionsViaSymbols()
278 if (MAI.hasSubsectionsViaSymbols()) {
279 OS << '\t';
280 Symbol->print(OS, MAI);
281 }
282 OS << '\n';
283}
284
285void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
286 const MCAsmInfo &MAI = Streamer.getContext().getAsmInfo();
287
288 OS << "\t.thumb_set\t";
289 Symbol->print(OS, MAI);
290 OS << ", ";
291 MAI.printExpr(OS, *Value);
292 OS << '\n';
293}
294
295void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
296 OS << "\t.inst";
297 if (Suffix)
298 OS << "." << Suffix;
299 OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
300}
301
302void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
303 const SmallVectorImpl<uint8_t> &Opcodes) {
304 OS << "\t.unwind_raw " << Offset;
305 for (uint8_t Opcode : Opcodes)
306 OS << ", 0x" << Twine::utohexstr(Opcode);
307 OS << '\n';
308}
309
310void ARMTargetAsmStreamer::emitARMWinCFIAllocStack(unsigned Size, bool Wide) {
311 if (Wide)
312 OS << "\t.seh_stackalloc_w\t" << Size << "\n";
313 else
314 OS << "\t.seh_stackalloc\t" << Size << "\n";
315}
316
317static void printRegs(formatted_raw_ostream &OS, ListSeparator &LS, int First,
318 int Last) {
319 if (First != Last)
320 OS << LS << "r" << First << "-r" << Last;
321 else
322 OS << LS << "r" << First;
323}
324
325void ARMTargetAsmStreamer::emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) {
326 if (Wide)
327 OS << "\t.seh_save_regs_w\t";
328 else
329 OS << "\t.seh_save_regs\t";
330 ListSeparator LS;
331 int First = -1;
332 OS << "{";
333 for (int I = 0; I <= 12; I++) {
334 if (Mask & (1 << I)) {
335 if (First < 0)
336 First = I;
337 } else {
338 if (First >= 0) {
339 printRegs(OS, LS, First, I - 1);
340 First = -1;
341 }
342 }
343 }
344 if (First >= 0)
345 printRegs(OS, LS, First, 12);
346 if (Mask & (1 << 14))
347 OS << LS << "lr";
348 OS << "}\n";
349}
350
351void ARMTargetAsmStreamer::emitARMWinCFISaveSP(unsigned Reg) {
352 OS << "\t.seh_save_sp\tr" << Reg << "\n";
353}
354
355void ARMTargetAsmStreamer::emitARMWinCFISaveFRegs(unsigned First,
356 unsigned Last) {
357 if (First != Last)
358 OS << "\t.seh_save_fregs\t{d" << First << "-d" << Last << "}\n";
359 else
360 OS << "\t.seh_save_fregs\t{d" << First << "}\n";
361}
362
363void ARMTargetAsmStreamer::emitARMWinCFISaveLR(unsigned Offset) {
364 OS << "\t.seh_save_lr\t" << Offset << "\n";
365}
366
367void ARMTargetAsmStreamer::emitARMWinCFIPrologEnd(bool Fragment) {
368 if (Fragment)
369 OS << "\t.seh_endprologue_fragment\n";
370 else
371 OS << "\t.seh_endprologue\n";
372}
373
374void ARMTargetAsmStreamer::emitARMWinCFINop(bool Wide) {
375 if (Wide)
376 OS << "\t.seh_nop_w\n";
377 else
378 OS << "\t.seh_nop\n";
379}
380
381void ARMTargetAsmStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {
382 if (Condition == ARMCC::AL)
383 OS << "\t.seh_startepilogue\n";
384 else
385 OS << "\t.seh_startepilogue_cond\t"
386 << ARMCondCodeToString(static_cast<ARMCC::CondCodes>(Condition)) << "\n";
387}
388
389void ARMTargetAsmStreamer::emitARMWinCFIEpilogEnd() {
390 OS << "\t.seh_endepilogue\n";
391}
392
393void ARMTargetAsmStreamer::emitARMWinCFICustom(unsigned Opcode) {
394 int I;
395 for (I = 3; I > 0; I--)
396 if (Opcode & (0xffu << (8 * I)))
397 break;
398 ListSeparator LS;
399 OS << "\t.seh_custom\t";
400 for (; I >= 0; I--)
401 OS << LS << ((Opcode >> (8 * I)) & 0xff);
402 OS << "\n";
403}
404
405class ARMTargetELFStreamer : public ARMTargetStreamer {
406private:
407 StringRef CurrentVendor;
408 ARM::FPUKind FPU = ARM::FK_INVALID;
409 ARM::ArchKind Arch = ARM::ArchKind::INVALID;
410 ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
411
412 MCSection *AttributeSection = nullptr;
413
414 void emitArchDefaultAttributes();
415 void emitFPUDefaultAttributes();
416
417 ARMELFStreamer &getStreamer();
418
419 void emitFnStart() override;
420 void emitFnEnd() override;
421 void emitCantUnwind() override;
422 void emitPersonality(const MCSymbol *Personality) override;
423 void emitPersonalityIndex(unsigned Index) override;
424 void emitHandlerData() override;
425 void emitSetFP(MCRegister FpReg, MCRegister SpReg,
426 int64_t Offset = 0) override;
427 void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
428 void emitPad(int64_t Offset) override;
429 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
430 bool isVector) override;
431 void emitUnwindRaw(int64_t Offset,
432 const SmallVectorImpl<uint8_t> &Opcodes) override;
433
434 void switchVendor(StringRef Vendor) override;
435 void emitAttribute(unsigned Attribute, unsigned Value) override;
436 void emitTextAttribute(unsigned Attribute, StringRef String) override;
437 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
438 StringRef StringValue) override;
439 void emitArch(ARM::ArchKind Arch) override;
440 void emitObjectArch(ARM::ArchKind Arch) override;
441 void emitFPU(ARM::FPUKind FPU) override;
442 void emitInst(uint32_t Inst, char Suffix = '\0') override;
443 void finishAttributeSection() override;
444 void emitLabel(MCSymbol *Symbol) override;
445
446 void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
447 void emitCode16() override;
448 void emitCode32() override;
449 void emitThumbFunc(MCSymbol *Symbol) override;
450 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
451
452 // Reset state between object emissions
453 void reset() override;
454
455 void finish() override;
456
457public:
458 ARMTargetELFStreamer(MCStreamer &S)
459 : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
460};
461
462/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
463/// the appropriate points in the object files. These symbols are defined in the
464/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
465///
466/// In brief: $a, $t or $d should be emitted at the start of each contiguous
467/// region of ARM code, Thumb code or data in a section. In practice, this
468/// emission does not rely on explicit assembler directives but on inherent
469/// properties of the directives doing the emission (e.g. ".byte" is data, "add
470/// r0, r0, r0" an instruction).
471///
472/// As a result this system is orthogonal to the DataRegion infrastructure used
473/// by MachO. Beware!
474class ARMELFStreamer : public MCELFStreamer {
475public:
476 friend class ARMTargetELFStreamer;
477
478 ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
479 std::unique_ptr<MCObjectWriter> OW,
480 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
481 bool IsAndroid)
482 : MCELFStreamer(Context, std::move(TAB), std::move(OW),
483 std::move(Emitter)),
484 IsThumb(IsThumb), IsAndroid(IsAndroid) {
485 EHReset();
486 }
487
488 ~ARMELFStreamer() override = default;
489
490 // ARM exception handling directives
491 void emitFnStart();
492 void emitFnEnd();
493 void emitCantUnwind();
494 void emitPersonality(const MCSymbol *Per);
495 void emitPersonalityIndex(unsigned index);
496 void emitHandlerData();
497 void emitSetFP(MCRegister NewFpReg, MCRegister NewSpReg, int64_t Offset = 0);
498 void emitMovSP(MCRegister Reg, int64_t Offset = 0);
499 void emitPad(int64_t Offset);
500 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList, bool isVector);
501 void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
502 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
503 SMLoc Loc) override {
504 emitDataMappingSymbol();
505 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
506 }
507
508 void changeSection(MCSection *Section, uint32_t Subsection) override {
509 LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
510 MCELFStreamer::changeSection(Section, Subsection);
511 auto LastMappingSymbol = LastMappingSymbols.find(Section);
512 if (LastMappingSymbol != LastMappingSymbols.end()) {
513 LastEMSInfo = std::move(LastMappingSymbol->second);
514 return;
515 }
516 LastEMSInfo.reset(new ElfMappingSymbolInfo);
517 }
518
519 /// This function is the one used to emit instruction data into the ELF
520 /// streamer. We override it to add the appropriate mapping symbol if
521 /// necessary.
522 void emitInstruction(const MCInst &Inst,
523 const MCSubtargetInfo &STI) override {
524 if (IsThumb)
525 EmitThumbMappingSymbol();
526 else
527 EmitARMMappingSymbol();
528
529 MCELFStreamer::emitInstruction(Inst, STI);
530 }
531
532 void emitInst(uint32_t Inst, char Suffix) {
533 unsigned Size;
534 char Buffer[4];
535 const bool LittleEndian = getContext().getAsmInfo().isLittleEndian();
536
537 switch (Suffix) {
538 case '\0':
539 Size = 4;
540
541 assert(!IsThumb);
542 EmitARMMappingSymbol();
543 for (unsigned II = 0, IE = Size; II != IE; II++) {
544 const unsigned I = LittleEndian ? (Size - II - 1) : II;
545 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
546 }
547
548 break;
549 case 'n':
550 case 'w':
551 Size = (Suffix == 'n' ? 2 : 4);
552
553 assert(IsThumb);
554 EmitThumbMappingSymbol();
555 // Thumb wide instructions are emitted as a pair of 16-bit words of the
556 // appropriate endianness.
557 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
558 const unsigned I0 = LittleEndian ? II + 0 : II + 1;
559 const unsigned I1 = LittleEndian ? II + 1 : II + 0;
560 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
561 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
562 }
563
564 break;
565 default:
566 llvm_unreachable("Invalid Suffix");
567 }
568
569 MCELFStreamer::emitBytes(StringRef(Buffer, Size));
570 }
571
572 /// This is one of the functions used to emit data into an ELF section, so the
573 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
574 /// necessary.
575 void emitBytes(StringRef Data) override {
576 emitDataMappingSymbol();
577 MCELFStreamer::emitBytes(Data);
578 }
579
580 void FlushPendingMappingSymbol() {
581 if (!LastEMSInfo->hasInfo())
582 return;
583 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
584 emitMappingSymbol("$d", *EMS->F, EMS->Offset);
585 EMS->resetInfo();
586 }
587
588 /// This is one of the functions used to emit data into an ELF section, so the
589 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
590 /// necessary.
591 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
592 if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
593 if (SRE->getSpecifier() == ARM::S_SBREL && !(Size == 4)) {
594 getContext().reportError(Loc, "relocated expression must be 32-bit");
595 return;
596 }
597 getCurrentFragment();
598 }
599
600 emitDataMappingSymbol();
601 MCELFStreamer::emitValueImpl(Value, Size, Loc);
602 }
603
604 /// Called to set any attribute on a symbol.
605 ///
606 /// If this function is called for the .type directive that marks an already
607 /// defined symbol as a function, use the state in which its label was defined
608 /// to determine whether it is a Thumb function. The active state may have
609 /// changed since the label was emitted.
610 ///
611 /// We do not mark the symbol as Thumb due to any attributes other than
612 /// setting its type to 'function', because there _are_ cases in practice
613 /// where an attribute directive such as .hidden can be widely separated from
614 /// the symbol definition. (For example, bug #180358: rustc targeting mostly
615 /// Thumb generates a top-level Arm function entirely in inline assembly, and
616 /// then uses an LLVM IR `declare` statement to mark it as hidden symbol
617 /// visibility, which causes LLVM to emit a `.hidden` directive after having
618 /// switched back to Thumb mode.)
619 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
621
624 Symbol->isDefined() && ThumbLabels.contains(Symbol))
625 getAssembler().setIsThumbFunc(Symbol);
626
627 return Val;
628 };
629
630 void setIsThumb(bool Val) { IsThumb = Val; }
631
632private:
633 enum ElfMappingSymbol {
634 EMS_None,
635 EMS_ARM,
636 EMS_Thumb,
637 EMS_Data
638 };
639
640 struct ElfMappingSymbolInfo {
641 void resetInfo() {
642 F = nullptr;
643 Offset = 0;
644 }
645 bool hasInfo() { return F != nullptr; }
646 MCFragment *F = nullptr;
647 uint64_t Offset = 0;
648 ElfMappingSymbol State = EMS_None;
649 };
650
651 void emitDataMappingSymbol() {
652 if (LastEMSInfo->State == EMS_Data)
653 return;
654 else if (LastEMSInfo->State == EMS_None) {
655 // This is a tentative symbol, it won't really be emitted until it's
656 // actually needed.
657 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
658 auto *DF = getCurrentFragment();
659 if (DF->getKind() != MCFragment::FT_Data)
660 return;
661 EMS->F = DF;
662 EMS->Offset = DF->getFixedSize();
663 LastEMSInfo->State = EMS_Data;
664 return;
665 }
666 EmitMappingSymbol("$d");
667 LastEMSInfo->State = EMS_Data;
668 }
669
670 void EmitThumbMappingSymbol() {
671 if (LastEMSInfo->State == EMS_Thumb)
672 return;
673 FlushPendingMappingSymbol();
674 EmitMappingSymbol("$t");
675 LastEMSInfo->State = EMS_Thumb;
676 }
677
678 void EmitARMMappingSymbol() {
679 if (LastEMSInfo->State == EMS_ARM)
680 return;
681 FlushPendingMappingSymbol();
682 EmitMappingSymbol("$a");
683 LastEMSInfo->State = EMS_ARM;
684 }
685
686 void EmitMappingSymbol(StringRef Name) {
687 auto *Symbol =
688 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
689 emitLabel(Symbol);
690
691 Symbol->setType(ELF::STT_NOTYPE);
692 Symbol->setBinding(ELF::STB_LOCAL);
693 }
694
695 void emitMappingSymbol(StringRef Name, MCFragment &F, uint64_t Offset) {
696 auto *Symbol =
697 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
698 emitLabelAtPos(Symbol, SMLoc(), F, Offset);
699 Symbol->setType(ELF::STT_NOTYPE);
700 Symbol->setBinding(ELF::STB_LOCAL);
701 }
702
703 // Helper functions for ARM exception handling directives
704 void EHReset();
705
706 // Reset state between object emissions
707 void reset() override;
708
709 void EmitPersonalityFixup(StringRef Name);
710 void FlushPendingOffset();
711 void FlushUnwindOpcodes(bool NoHandlerData);
712
713 void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
714 SectionKind Kind, const MCSymbol &Fn);
715 void SwitchToExTabSection(const MCSymbol &FnStart);
716 void SwitchToExIdxSection(const MCSymbol &FnStart);
717
718 bool IsThumb;
719 bool IsAndroid;
720 DenseSet<const MCSymbol *> ThumbLabels;
721
722 DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
723 LastMappingSymbols;
724
725 std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
726
727 // ARM Exception Handling Frame Information
728 MCSymbol *ExTab;
729 MCSymbol *FnStart;
730 const MCSymbol *Personality;
731 unsigned PersonalityIndex;
732 MCRegister FPReg; // Frame pointer register
733 int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
734 int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
735 int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
736 bool UsedFP;
737 bool CantUnwind;
739 UnwindOpcodeAssembler UnwindOpAsm;
740};
741
742} // end anonymous namespace
743
744ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
745 return static_cast<ARMELFStreamer &>(Streamer);
746}
747
748void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
749void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
750void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
751
752void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
753 getStreamer().emitPersonality(Personality);
754}
755
756void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
757 getStreamer().emitPersonalityIndex(Index);
758}
759
760void ARMTargetELFStreamer::emitHandlerData() {
761 getStreamer().emitHandlerData();
762}
763
764void ARMTargetELFStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
765 int64_t Offset) {
766 getStreamer().emitSetFP(FpReg, SpReg, Offset);
767}
768
769void ARMTargetELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
770 getStreamer().emitMovSP(Reg, Offset);
771}
772
773void ARMTargetELFStreamer::emitPad(int64_t Offset) {
774 getStreamer().emitPad(Offset);
775}
776
777void ARMTargetELFStreamer::emitRegSave(
778 const SmallVectorImpl<MCRegister> &RegList, bool isVector) {
779 getStreamer().emitRegSave(RegList, isVector);
780}
781
782void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
783 const SmallVectorImpl<uint8_t> &Opcodes) {
784 getStreamer().emitUnwindRaw(Offset, Opcodes);
785}
786
787void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
788 assert(!Vendor.empty() && "Vendor cannot be empty.");
789
790 if (CurrentVendor == Vendor)
791 return;
792
793 if (!CurrentVendor.empty())
794 finishAttributeSection();
795
796 assert(getStreamer().Contents.empty() &&
797 ".ARM.attributes should be flushed before changing vendor");
798 CurrentVendor = Vendor;
799
800}
801
802void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
803 getStreamer().setAttributeItem(Attribute, Value,
804 /* OverwriteExisting= */ true);
805}
806
807void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
808 StringRef Value) {
809 getStreamer().setAttributeItem(Attribute, Value,
810 /* OverwriteExisting= */ true);
811}
812
813void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
814 unsigned IntValue,
815 StringRef StringValue) {
816 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
817 /* OverwriteExisting= */ true);
818}
819
820void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
821 Arch = Value;
822}
823
824void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
825 EmittedArch = Value;
826}
827
828void ARMTargetELFStreamer::emitArchDefaultAttributes() {
829 using namespace ARMBuildAttrs;
830 ARMELFStreamer &S = getStreamer();
831
832 S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false);
833
834 if (EmittedArch == ARM::ArchKind::INVALID)
835 S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false);
836 else
837 S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false);
838
839 switch (Arch) {
840 case ARM::ArchKind::ARMV4:
841 S.setAttributeItem(ARM_ISA_use, Allowed, false);
842 break;
843
844 case ARM::ArchKind::ARMV4T:
845 case ARM::ArchKind::ARMV5T:
846 case ARM::ArchKind::XSCALE:
847 case ARM::ArchKind::ARMV5TE:
848 case ARM::ArchKind::ARMV6:
849 S.setAttributeItem(ARM_ISA_use, Allowed, false);
850 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
851 break;
852
853 case ARM::ArchKind::ARMV6T2:
854 S.setAttributeItem(ARM_ISA_use, Allowed, false);
855 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
856 break;
857
858 case ARM::ArchKind::ARMV6K:
859 case ARM::ArchKind::ARMV6KZ:
860 S.setAttributeItem(ARM_ISA_use, Allowed, false);
861 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
862 S.setAttributeItem(Virtualization_use, AllowTZ, false);
863 break;
864
865 case ARM::ArchKind::ARMV6M:
866 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
867 break;
868
869 case ARM::ArchKind::ARMV7A:
870 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
871 S.setAttributeItem(ARM_ISA_use, Allowed, false);
872 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
873 break;
874
875 case ARM::ArchKind::ARMV7R:
876 S.setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
877 S.setAttributeItem(ARM_ISA_use, Allowed, false);
878 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
879 break;
880
881 case ARM::ArchKind::ARMV7EM:
882 case ARM::ArchKind::ARMV7M:
883 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
884 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
885 break;
886
887 case ARM::ArchKind::ARMV8A:
888 case ARM::ArchKind::ARMV8_1A:
889 case ARM::ArchKind::ARMV8_2A:
890 case ARM::ArchKind::ARMV8_3A:
891 case ARM::ArchKind::ARMV8_4A:
892 case ARM::ArchKind::ARMV8_5A:
893 case ARM::ArchKind::ARMV8_6A:
894 case ARM::ArchKind::ARMV8_7A:
895 case ARM::ArchKind::ARMV8_8A:
896 case ARM::ArchKind::ARMV8_9A:
897 case ARM::ArchKind::ARMV9A:
898 case ARM::ArchKind::ARMV9_1A:
899 case ARM::ArchKind::ARMV9_2A:
900 case ARM::ArchKind::ARMV9_3A:
901 case ARM::ArchKind::ARMV9_4A:
902 case ARM::ArchKind::ARMV9_5A:
903 case ARM::ArchKind::ARMV9_6A:
904 case ARM::ArchKind::ARMV9_7A:
905 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
906 S.setAttributeItem(ARM_ISA_use, Allowed, false);
907 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
908 S.setAttributeItem(MPextension_use, Allowed, false);
909 S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
910 break;
911
912 case ARM::ArchKind::ARMV8MBaseline:
913 case ARM::ArchKind::ARMV8MMainline:
914 case ARM::ArchKind::ARMV8_1MMainline:
915 S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
916 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
917 break;
918
919 case ARM::ArchKind::IWMMXT:
920 S.setAttributeItem(ARM_ISA_use, Allowed, false);
921 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
922 S.setAttributeItem(WMMX_arch, AllowWMMXv1, false);
923 break;
924
925 case ARM::ArchKind::IWMMXT2:
926 S.setAttributeItem(ARM_ISA_use, Allowed, false);
927 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
928 S.setAttributeItem(WMMX_arch, AllowWMMXv2, false);
929 break;
930
931 default:
932 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
933 break;
934 }
935}
936
937void ARMTargetELFStreamer::emitFPU(ARM::FPUKind Value) { FPU = Value; }
938
939void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
940 ARMELFStreamer &S = getStreamer();
941
942 switch (FPU) {
943 case ARM::FK_VFP:
944 case ARM::FK_VFPV2:
946 /* OverwriteExisting= */ false);
947 break;
948
949 case ARM::FK_VFPV3:
951 /* OverwriteExisting= */ false);
952 break;
953
954 case ARM::FK_VFPV3_FP16:
956 /* OverwriteExisting= */ false);
958 /* OverwriteExisting= */ false);
959 break;
960
961 case ARM::FK_VFPV3_D16:
963 /* OverwriteExisting= */ false);
964 break;
965
966 case ARM::FK_VFPV3_D16_FP16:
968 /* OverwriteExisting= */ false);
970 /* OverwriteExisting= */ false);
971 break;
972
973 case ARM::FK_VFPV3XD:
975 /* OverwriteExisting= */ false);
976 break;
977 case ARM::FK_VFPV3XD_FP16:
979 /* OverwriteExisting= */ false);
981 /* OverwriteExisting= */ false);
982 break;
983
984 case ARM::FK_VFPV4:
986 /* OverwriteExisting= */ false);
987 break;
988
989 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
990 // as _D16 here.
991 case ARM::FK_FPV4_SP_D16:
992 case ARM::FK_VFPV4_D16:
994 /* OverwriteExisting= */ false);
995 break;
996
997 case ARM::FK_FP_ARMV8:
999 /* OverwriteExisting= */ false);
1000 break;
1001
1002 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
1003 // uses the FP_ARMV8_D16 build attribute.
1004 case ARM::FK_FPV5_SP_D16:
1005 case ARM::FK_FPV5_D16:
1006 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
1007 // FPU, but there are two different names for it depending on the CPU.
1008 case ARM::FK_FP_ARMV8_FULLFP16_SP_D16:
1009 case ARM::FK_FP_ARMV8_FULLFP16_D16:
1011 /* OverwriteExisting= */ false);
1012 break;
1013
1014 case ARM::FK_NEON:
1016 /* OverwriteExisting= */ false);
1017 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1019 /* OverwriteExisting= */ false);
1020 break;
1021
1022 case ARM::FK_NEON_FP16:
1024 /* OverwriteExisting= */ false);
1025 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1027 /* OverwriteExisting= */ false);
1029 /* OverwriteExisting= */ false);
1030 break;
1031
1032 case ARM::FK_NEON_VFPV4:
1034 /* OverwriteExisting= */ false);
1035 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1037 /* OverwriteExisting= */ false);
1038 break;
1039
1040 case ARM::FK_NEON_FP_ARMV8:
1041 case ARM::FK_CRYPTO_NEON_FP_ARMV8:
1043 /* OverwriteExisting= */ false);
1044 // 'Advanced_SIMD_arch' must be emitted not here, but within
1045 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
1046 break;
1047
1048 case ARM::FK_SOFTVFP:
1049 case ARM::FK_NONE:
1050 break;
1051
1052 default:
1053 report_fatal_error("Unknown FPU: " + Twine(FPU));
1054 break;
1055 }
1056}
1057
1058void ARMTargetELFStreamer::finishAttributeSection() {
1059 ARMELFStreamer &S = getStreamer();
1060
1061 if (FPU != ARM::FK_INVALID)
1062 emitFPUDefaultAttributes();
1063
1064 if (Arch != ARM::ArchKind::INVALID)
1065 emitArchDefaultAttributes();
1066
1067 if (S.Contents.empty())
1068 return;
1069
1070 auto LessTag = [](const MCELFStreamer::AttributeItem &LHS,
1071 const MCELFStreamer::AttributeItem &RHS) -> bool {
1072 // The conformance tag must be emitted first when serialised into an
1073 // object file. Specifically, the addenda to the ARM ABI states that
1074 // (2.3.7.4):
1075 //
1076 // "To simplify recognition by consumers in the common case of claiming
1077 // conformity for the whole file, this tag should be emitted first in a
1078 // file-scope sub-subsection of the first public subsection of the
1079 // attributes section."
1080 //
1081 // So it is special-cased in this comparison predicate when the
1082 // attributes are sorted in finishAttributeSection().
1083 return (RHS.Tag != ARMBuildAttrs::conformance) &&
1084 ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
1085 };
1086 llvm::sort(S.Contents, LessTag);
1087
1088 S.emitAttributesSection(CurrentVendor, ".ARM.attributes",
1089 ELF::SHT_ARM_ATTRIBUTES, AttributeSection);
1090
1091 FPU = ARM::FK_INVALID;
1092}
1093
1094void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
1095 ARMELFStreamer &Streamer = getStreamer();
1096 if (!Streamer.IsThumb)
1097 return;
1098
1099 Streamer.ThumbLabels.insert(Symbol);
1100 Streamer.getAssembler().registerSymbol(*Symbol);
1101 unsigned Type = static_cast<MCSymbolELF *>(Symbol)->getType();
1103 emitThumbFunc(Symbol);
1104}
1105
1106void ARMTargetELFStreamer::annotateTLSDescriptorSequence(
1107 const MCSymbolRefExpr *Expr) {
1108 getStreamer().addFixup(Expr, FK_Data_4);
1109}
1110
1111void ARMTargetELFStreamer::emitCode16() { getStreamer().setIsThumb(true); }
1112
1113void ARMTargetELFStreamer::emitCode32() { getStreamer().setIsThumb(false); }
1114
1115void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) {
1116 getStreamer().getAssembler().setIsThumbFunc(Symbol);
1117 getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction);
1118}
1119
1120void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
1121 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
1122 const MCSymbol &Sym = SRE->getSymbol();
1123 if (!Sym.isDefined()) {
1124 getStreamer().emitAssignment(Symbol, Value);
1125 return;
1126 }
1127 }
1128
1129 emitThumbFunc(Symbol);
1130 getStreamer().emitAssignment(Symbol, Value);
1131}
1132
1133void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1134 getStreamer().emitInst(Inst, Suffix);
1135}
1136
1137void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1138
1139void ARMTargetELFStreamer::finish() {
1140 ARMTargetStreamer::finish();
1141 finishAttributeSection();
1142
1143 // The mix of execute-only and non-execute-only at link time is
1144 // non-execute-only. To avoid the empty implicitly created .text
1145 // section from making the whole .text section non-execute-only, we
1146 // mark it execute-only if it is empty and there is at least one
1147 // execute-only section in the object.
1148 MCContext &Ctx = getContext();
1149 auto &Asm = getStreamer().getAssembler();
1150 if (any_of(Asm, [](const MCSection &Sec) {
1151 return static_cast<const MCSectionELF &>(Sec).getFlags() &
1153 })) {
1154 auto *Text =
1155 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
1156 for (auto &F : *Text)
1157 if (F.getSize())
1158 return;
1159 Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);
1160 }
1161}
1162
1163void ARMELFStreamer::reset() {
1164 MCTargetStreamer &TS = *getTargetStreamer();
1165 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1166 ATS.reset();
1168 ThumbLabels.clear();
1169 LastMappingSymbols.clear();
1170 LastEMSInfo.reset();
1171 // MCELFStreamer clear's the assembler's e_flags. However, for
1172 // arm we manually set the ABI version on streamer creation, so
1173 // do the same here
1174 getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1175}
1176
1177inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
1178 unsigned Type,
1179 unsigned Flags,
1180 SectionKind Kind,
1181 const MCSymbol &Fn) {
1182 const MCSectionELF &FnSection =
1183 static_cast<const MCSectionELF &>(Fn.getSection());
1184
1185 // Create the name for new section
1186 StringRef FnSecName(FnSection.getName());
1187 SmallString<128> EHSecName(Prefix);
1188 if (FnSecName != ".text") {
1189 EHSecName += FnSecName;
1190 }
1191
1192 // Get .ARM.extab or .ARM.exidx section
1193 const MCSymbolELF *Group = FnSection.getGroup();
1194 if (Group)
1196 MCSectionELF *EHSection = getContext().getELFSection(
1197 EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1198 FnSection.getUniqueID(),
1199 static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
1200
1201 assert(EHSection && "Failed to get the required EH section");
1202
1203 // Switch to .ARM.extab or .ARM.exidx section
1204 switchSection(EHSection);
1205 emitValueToAlignment(Align(4), 0, 1, 0);
1206}
1207
1208inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1209 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1210 SectionKind::getData(), FnStart);
1211}
1212
1213inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1214 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
1216 SectionKind::getData(), FnStart);
1217}
1218
1219void ARMELFStreamer::EHReset() {
1220 ExTab = nullptr;
1221 FnStart = nullptr;
1222 Personality = nullptr;
1223 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1224 FPReg = ARM::SP;
1225 FPOffset = 0;
1226 SPOffset = 0;
1227 PendingOffset = 0;
1228 UsedFP = false;
1229 CantUnwind = false;
1230
1231 Opcodes.clear();
1232 UnwindOpAsm.Reset();
1233}
1234
1235void ARMELFStreamer::emitFnStart() {
1236 assert(FnStart == nullptr);
1237 FnStart = getContext().createTempSymbol();
1238 emitLabel(FnStart);
1239}
1240
1241void ARMELFStreamer::emitFnEnd() {
1242 assert(FnStart && ".fnstart must precedes .fnend");
1243
1244 // Emit unwind opcodes if there is no .handlerdata directive
1245 if (!ExTab && !CantUnwind)
1246 FlushUnwindOpcodes(true);
1247
1248 // Emit the exception index table entry
1249 SwitchToExIdxSection(*FnStart);
1250
1251 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1252 // personality routine to protect it from an arbitrary platform's static
1253 // linker garbage collection. We disable this for Android where the unwinder
1254 // is either dynamically linked or directly references the personality
1255 // routine.
1256 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
1257 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1258
1259 const MCSymbolRefExpr *FnStartRef =
1261
1262 emitValue(FnStartRef, 4);
1263
1264 if (CantUnwind) {
1266 } else if (ExTab) {
1267 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1268 const MCSymbolRefExpr *ExTabEntryRef =
1270 emitValue(ExTabEntryRef, 4);
1271 } else {
1272 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1273 // the second word of exception index table entry. The size of the unwind
1274 // opcodes should always be 4 bytes.
1275 assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1276 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1277 assert(Opcodes.size() == 4u &&
1278 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1279 uint64_t Intval = Opcodes[0] |
1280 Opcodes[1] << 8 |
1281 Opcodes[2] << 16 |
1282 Opcodes[3] << 24;
1283 emitIntValue(Intval, Opcodes.size());
1284 }
1285
1286 // Switch to the section containing FnStart
1287 switchSection(&FnStart->getSection());
1288
1289 // Clean exception handling frame information
1290 EHReset();
1291}
1292
1293void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1294
1295// Add the R_ARM_NONE fixup at the same position
1296void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1297 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1298 visitUsedSymbol(*PersonalitySym);
1299
1300 const MCSymbolRefExpr *PersonalityRef =
1302 addFixup(PersonalityRef, FK_Data_4);
1303}
1304
1305void ARMELFStreamer::FlushPendingOffset() {
1306 if (PendingOffset != 0) {
1307 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1308 PendingOffset = 0;
1309 }
1310}
1311
1312void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1313 // Emit the unwind opcode to restore $sp.
1314 if (UsedFP) {
1315 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1316 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1317 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1318 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1319 } else {
1320 FlushPendingOffset();
1321 }
1322
1323 // Finalize the unwind opcode sequence
1324 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1325
1326 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1327 // section. Thus, we don't have to create an entry in the .ARM.extab
1328 // section.
1329 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1330 return;
1331
1332 // Switch to .ARM.extab section.
1333 SwitchToExTabSection(*FnStart);
1334
1335 // Create .ARM.extab label for offset in .ARM.exidx
1336 assert(!ExTab);
1337 ExTab = getContext().createTempSymbol();
1338 emitLabel(ExTab);
1339
1340 // Emit personality
1341 if (Personality) {
1342 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1343 Personality, uint16_t(ARM::S_PREL31), getContext());
1344
1345 emitValue(PersonalityRef, 4);
1346 }
1347
1348 // Emit unwind opcodes
1349 assert((Opcodes.size() % 4) == 0 &&
1350 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1351 for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1352 uint64_t Intval = Opcodes[I] |
1353 Opcodes[I + 1] << 8 |
1354 Opcodes[I + 2] << 16 |
1355 Opcodes[I + 3] << 24;
1356 emitInt32(Intval);
1357 }
1358
1359 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1360 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1361 // after the unwind opcodes. The handler data consists of several 32-bit
1362 // words, and should be terminated by zero.
1363 //
1364 // In case that the .handlerdata directive is not specified by the
1365 // programmer, we should emit zero to terminate the handler data.
1366 if (NoHandlerData && !Personality)
1367 emitInt32(0);
1368}
1369
1370void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1371
1372void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1373 Personality = Per;
1374 UnwindOpAsm.setPersonality(Per);
1375}
1376
1377void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1378 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1379 PersonalityIndex = Index;
1380}
1381
1382void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,
1383 int64_t Offset) {
1384 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1385 "the operand of .setfp directive should be either $sp or $fp");
1386
1387 UsedFP = true;
1388 FPReg = NewFPReg;
1389
1390 if (NewSPReg == ARM::SP)
1391 FPOffset = SPOffset + Offset;
1392 else
1393 FPOffset += Offset;
1394}
1395
1396void ARMELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
1397 assert((Reg != ARM::SP && Reg != ARM::PC) &&
1398 "the operand of .movsp cannot be either sp or pc");
1399 assert(FPReg == ARM::SP && "current FP must be SP");
1400
1401 FlushPendingOffset();
1402
1403 FPReg = Reg;
1404 FPOffset = SPOffset + Offset;
1405
1406 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1407 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1408}
1409
1410void ARMELFStreamer::emitPad(int64_t Offset) {
1411 // Track the change of the $sp offset
1412 SPOffset -= Offset;
1413
1414 // To squash multiple .pad directives, we should delay the unwind opcode
1415 // until the .save, .vsave, .handlerdata, or .fnend directives.
1416 PendingOffset -= Offset;
1417}
1418
1419static std::pair<unsigned, unsigned>
1420collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx,
1421 const SmallVectorImpl<MCRegister> &RegList, bool IsVector,
1422 uint32_t &Mask_) {
1423 uint32_t Mask = 0;
1424 unsigned Count = 0;
1425 while (Idx > 0) {
1426 MCRegister Reg = RegList[Idx - 1];
1427 if (Reg == ARM::RA_AUTH_CODE)
1428 break;
1429 unsigned RegEnc = MRI.getEncodingValue(Reg);
1430 assert(RegEnc < (IsVector ? 32U : 16U) && "Register out of range");
1431 unsigned Bit = (1u << RegEnc);
1432 if ((Mask & Bit) == 0) {
1433 Mask |= Bit;
1434 ++Count;
1435 }
1436 --Idx;
1437 }
1438
1439 Mask_ = Mask;
1440 return {Idx, Count};
1441}
1442
1443void ARMELFStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
1444 bool IsVector) {
1445 uint32_t Mask;
1446 unsigned Idx, Count;
1447 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
1448
1449 // Collect the registers in the register list. Issue unwinding instructions in
1450 // three parts: ordinary hardware registers, return address authentication
1451 // code pseudo register, the rest of the registers. The RA PAC is kept in an
1452 // architectural register (usually r12), but we treat it as a special case in
1453 // order to distinguish between that register containing RA PAC or a general
1454 // value.
1455 Idx = RegList.size();
1456 while (Idx > 0) {
1457 std::tie(Idx, Count) = collectHWRegs(MRI, Idx, RegList, IsVector, Mask);
1458 if (Count) {
1459 // Track the change the $sp offset: For the .save directive, the
1460 // corresponding push instruction will decrease the $sp by (4 * Count).
1461 // For the .vsave directive, the corresponding vpush instruction will
1462 // decrease $sp by (8 * Count).
1463 SPOffset -= Count * (IsVector ? 8 : 4);
1464
1465 // Emit the opcode
1466 FlushPendingOffset();
1467 if (IsVector)
1468 UnwindOpAsm.EmitVFPRegSave(Mask);
1469 else
1470 UnwindOpAsm.EmitRegSave(Mask);
1471 } else if (Idx > 0 && RegList[Idx - 1] == ARM::RA_AUTH_CODE) {
1472 --Idx;
1473 SPOffset -= 4;
1474 FlushPendingOffset();
1475 UnwindOpAsm.EmitRegSave(0);
1476 }
1477 }
1478}
1479
1480void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1481 const SmallVectorImpl<uint8_t> &Opcodes) {
1482 FlushPendingOffset();
1483 SPOffset = SPOffset - Offset;
1484 UnwindOpAsm.EmitRaw(Opcodes);
1485}
1486
1487namespace llvm {
1488
1491 MCInstPrinter *InstPrint) {
1492 return new ARMTargetAsmStreamer(S, OS, *InstPrint);
1493}
1494
1498
1500 return new ARMTargetELFStreamer(S);
1501}
1502
1504 std::unique_ptr<MCAsmBackend> TAB,
1505 std::unique_ptr<MCObjectWriter> OW,
1506 std::unique_ptr<MCCodeEmitter> Emitter,
1507 bool IsThumb, bool IsAndroid) {
1508 ARMELFStreamer *S =
1509 new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1510 std::move(Emitter), IsThumb, IsAndroid);
1511 // FIXME: This should eventually end up somewhere else where more
1512 // intelligent flag decisions can be made. For now we are just maintaining
1513 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1514 S->getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1515
1516 return S;
1517}
1518
1519} // end namespace llvm
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::pair< unsigned, unsigned > collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx, const SmallVectorImpl< MCRegister > &RegList, bool IsVector, uint32_t &Mask_)
static std::string GetAEABIUnwindPersonalityName(unsigned Index)
dxil DXContainer Global Emitter
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
uint64_t IntrinsicInst * II
static constexpr MCPhysReg FPReg
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallString class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
static uint32_t getFlags(const Symbol *Sym)
Definition TapiFile.cpp:26
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
Value * RHS
Value * LHS
virtual void reset()
Reset any state between object emissions, i.e.
void printExpr(raw_ostream &, const MCExpr &) const
bool hasSubsectionsViaSymbols() const
Definition MCAsmInfo.h:468
Context object for machine code objects.
Definition MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition MCContext.h:413
void changeSection(MCSection *Section, uint32_t Subsection=0) override
This is called by popSection and switchSection, if the current section changes.
void reset() override
state management
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
virtual void printRegName(raw_ostream &OS, MCRegister Reg)
Print the assembler register name.
void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc=SMLoc()) override
Emit Size bytes worth of the value specified by FillValue.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
unsigned getUniqueID() const
const MCSymbolELF * getGroup() const
StringRef getName() const
Definition MCSection.h:650
MCSymbol * getBeginSymbol()
Definition MCSection.h:653
Streaming machine code generation interface.
Definition MCStreamer.h:222
const MCSymbol & getSymbol() const
Definition MCExpr.h:226
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
Definition MCSymbol.h:233
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition MCSymbol.h:251
Target specific streamer interface.
Definition MCStreamer.h:95
static SectionKind getData()
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
void EmitSetSP(uint16_t Reg)
Emit unwind opcodes to copy address from source register to $sp.
void EmitVFPRegSave(uint32_t VFPRegSave)
Emit unwind opcodes for .vsave directives.
void EmitRegSave(uint32_t RegSave)
Emit unwind opcodes for .save directives.
void setPersonality(const MCSymbol *Per)
Set the personality.
void EmitSPOffset(int64_t Offset)
Emit unwind opcodes to add $sp with an offset.
void Reset()
Reset the unwind opcode assembler.
void EmitRaw(const SmallVectorImpl< uint8_t > &Opcodes)
Emit unwind raw opcodes.
void Finalize(unsigned &PersonalityIndex, SmallVectorImpl< uint8_t > &Result)
Finalize the unwind opcode sequence for emitBytes()
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
raw_ostream & write_escaped(StringRef Str, bool UseHexEscapes=false)
Output Str, turning '\', '\t', ' ', '"', and anything that doesn't satisfy llvm::isPrint into an esca...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
LLVM_ABI const TagNameMap & getARMAttributeTags()
@ EXIDX_CANTUNWIND
Special entry for the function never unwind.
Definition ARMEHABI.h:35
LLVM_ABI StringRef getArchExtName(uint64_t ArchExtKind)
LLVM_ABI StringRef getCPUAttr(ArchKind AK)
LLVM_ABI StringRef getArchName(ArchKind AK)
LLVM_ABI unsigned getArchAttr(ArchKind AK)
LLVM_ABI StringRef getFPUName(FPUKind FPUKind)
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_ABI StringRef attrTypeAsString(unsigned attr, TagNameMap tagNameMap, bool hasTagPrefix=true)
@ SHF_ALLOC
Definition ELF.h:1258
@ SHF_LINK_ORDER
Definition ELF.h:1273
@ SHF_GROUP
Definition ELF.h:1280
@ SHF_ARM_PURECODE
Definition ELF.h:1353
@ SHT_PROGBITS
Definition ELF.h:1156
@ SHT_ARM_ATTRIBUTES
Definition ELF.h:1218
@ SHT_ARM_EXIDX
Definition ELF.h:1214
@ STB_LOCAL
Definition ELF.h:1414
@ STT_FUNC
Definition ELF.h:1428
@ STT_NOTYPE
Definition ELF.h:1426
@ STT_GNU_IFUNC
Definition ELF.h:1433
@ EF_ARM_EABI_VER5
Definition ELF.h:459
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
LLVM_ABI MCELFStreamer * createARMELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter, bool IsThumb, bool IsAndroid)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
MCTargetStreamer * createARMObjectTargetELFStreamer(MCStreamer &S)
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ FK_Data_4
A four-byte fixup.
Definition MCFixup.h:36
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
MCTargetStreamer * createARMNullTargetStreamer(MCStreamer &S)
MCTargetStreamer * createARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint)
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function