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 case ARM::ArchKind::ARMV9_8A:
906 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
907 S.setAttributeItem(ARM_ISA_use, Allowed, false);
908 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
909 S.setAttributeItem(MPextension_use, Allowed, false);
910 S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
911 break;
912
913 case ARM::ArchKind::ARMV8MBaseline:
914 case ARM::ArchKind::ARMV8MMainline:
915 case ARM::ArchKind::ARMV8_1MMainline:
916 S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
917 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
918 break;
919
920 case ARM::ArchKind::IWMMXT:
921 S.setAttributeItem(ARM_ISA_use, Allowed, false);
922 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
923 S.setAttributeItem(WMMX_arch, AllowWMMXv1, false);
924 break;
925
926 case ARM::ArchKind::IWMMXT2:
927 S.setAttributeItem(ARM_ISA_use, Allowed, false);
928 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
929 S.setAttributeItem(WMMX_arch, AllowWMMXv2, false);
930 break;
931
932 default:
933 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
934 break;
935 }
936}
937
938void ARMTargetELFStreamer::emitFPU(ARM::FPUKind Value) { FPU = Value; }
939
940void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
941 ARMELFStreamer &S = getStreamer();
942
943 switch (FPU) {
944 case ARM::FK_VFP:
945 case ARM::FK_VFPV2:
947 /* OverwriteExisting= */ false);
948 break;
949
950 case ARM::FK_VFPV3:
952 /* OverwriteExisting= */ false);
953 break;
954
955 case ARM::FK_VFPV3_FP16:
957 /* OverwriteExisting= */ false);
959 /* OverwriteExisting= */ false);
960 break;
961
962 case ARM::FK_VFPV3_D16:
964 /* OverwriteExisting= */ false);
965 break;
966
967 case ARM::FK_VFPV3_D16_FP16:
969 /* OverwriteExisting= */ false);
971 /* OverwriteExisting= */ false);
972 break;
973
974 case ARM::FK_VFPV3XD:
976 /* OverwriteExisting= */ false);
977 break;
978 case ARM::FK_VFPV3XD_FP16:
980 /* OverwriteExisting= */ false);
982 /* OverwriteExisting= */ false);
983 break;
984
985 case ARM::FK_VFPV4:
987 /* OverwriteExisting= */ false);
988 break;
989
990 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
991 // as _D16 here.
992 case ARM::FK_FPV4_SP_D16:
993 case ARM::FK_VFPV4_D16:
995 /* OverwriteExisting= */ false);
996 break;
997
998 case ARM::FK_FP_ARMV8:
1000 /* OverwriteExisting= */ false);
1001 break;
1002
1003 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
1004 // uses the FP_ARMV8_D16 build attribute.
1005 case ARM::FK_FPV5_SP_D16:
1006 case ARM::FK_FPV5_D16:
1007 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
1008 // FPU, but there are two different names for it depending on the CPU.
1009 case ARM::FK_FP_ARMV8_FULLFP16_SP_D16:
1010 case ARM::FK_FP_ARMV8_FULLFP16_D16:
1012 /* OverwriteExisting= */ false);
1013 break;
1014
1015 case ARM::FK_NEON:
1017 /* OverwriteExisting= */ false);
1018 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1020 /* OverwriteExisting= */ false);
1021 break;
1022
1023 case ARM::FK_NEON_FP16:
1025 /* OverwriteExisting= */ false);
1026 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1028 /* OverwriteExisting= */ false);
1030 /* OverwriteExisting= */ false);
1031 break;
1032
1033 case ARM::FK_NEON_VFPV4:
1035 /* OverwriteExisting= */ false);
1036 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1038 /* OverwriteExisting= */ false);
1039 break;
1040
1041 case ARM::FK_NEON_FP_ARMV8:
1042 case ARM::FK_CRYPTO_NEON_FP_ARMV8:
1044 /* OverwriteExisting= */ false);
1045 // 'Advanced_SIMD_arch' must be emitted not here, but within
1046 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
1047 break;
1048
1049 case ARM::FK_SOFTVFP:
1050 case ARM::FK_NONE:
1051 break;
1052
1053 default:
1054 report_fatal_error("Unknown FPU: " + Twine(FPU));
1055 break;
1056 }
1057}
1058
1059void ARMTargetELFStreamer::finishAttributeSection() {
1060 ARMELFStreamer &S = getStreamer();
1061
1062 if (FPU != ARM::FK_INVALID)
1063 emitFPUDefaultAttributes();
1064
1065 if (Arch != ARM::ArchKind::INVALID)
1066 emitArchDefaultAttributes();
1067
1068 if (S.Contents.empty())
1069 return;
1070
1071 auto LessTag = [](const MCELFStreamer::AttributeItem &LHS,
1072 const MCELFStreamer::AttributeItem &RHS) -> bool {
1073 // The conformance tag must be emitted first when serialised into an
1074 // object file. Specifically, the addenda to the ARM ABI states that
1075 // (2.3.7.4):
1076 //
1077 // "To simplify recognition by consumers in the common case of claiming
1078 // conformity for the whole file, this tag should be emitted first in a
1079 // file-scope sub-subsection of the first public subsection of the
1080 // attributes section."
1081 //
1082 // So it is special-cased in this comparison predicate when the
1083 // attributes are sorted in finishAttributeSection().
1084 return (RHS.Tag != ARMBuildAttrs::conformance) &&
1085 ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
1086 };
1087 llvm::sort(S.Contents, LessTag);
1088
1089 S.emitAttributesSection(CurrentVendor, ".ARM.attributes",
1090 ELF::SHT_ARM_ATTRIBUTES, AttributeSection);
1091
1092 FPU = ARM::FK_INVALID;
1093}
1094
1095void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
1096 ARMELFStreamer &Streamer = getStreamer();
1097 if (!Streamer.IsThumb)
1098 return;
1099
1100 Streamer.ThumbLabels.insert(Symbol);
1101 Streamer.getAssembler().registerSymbol(*Symbol);
1102 unsigned Type = static_cast<MCSymbolELF *>(Symbol)->getType();
1104 emitThumbFunc(Symbol);
1105}
1106
1107void ARMTargetELFStreamer::annotateTLSDescriptorSequence(
1108 const MCSymbolRefExpr *Expr) {
1109 getStreamer().addFixup(Expr, FK_Data_4);
1110}
1111
1112void ARMTargetELFStreamer::emitCode16() { getStreamer().setIsThumb(true); }
1113
1114void ARMTargetELFStreamer::emitCode32() { getStreamer().setIsThumb(false); }
1115
1116void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) {
1117 getStreamer().getAssembler().setIsThumbFunc(Symbol);
1118 getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction);
1119}
1120
1121void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
1122 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
1123 const MCSymbol &Sym = SRE->getSymbol();
1124 if (!Sym.isDefined()) {
1125 getStreamer().emitAssignment(Symbol, Value);
1126 return;
1127 }
1128 }
1129
1130 emitThumbFunc(Symbol);
1131 getStreamer().emitAssignment(Symbol, Value);
1132}
1133
1134void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1135 getStreamer().emitInst(Inst, Suffix);
1136}
1137
1138void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1139
1140void ARMTargetELFStreamer::finish() {
1141 ARMTargetStreamer::finish();
1142 finishAttributeSection();
1143
1144 // The mix of execute-only and non-execute-only at link time is
1145 // non-execute-only. To avoid the empty implicitly created .text
1146 // section from making the whole .text section non-execute-only, we
1147 // mark it execute-only if it is empty and there is at least one
1148 // execute-only section in the object.
1149 MCContext &Ctx = getContext();
1150 auto &Asm = getStreamer().getAssembler();
1151 if (any_of(Asm, [](const MCSection &Sec) {
1152 return static_cast<const MCSectionELF &>(Sec).getFlags() &
1154 })) {
1155 auto *Text =
1156 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
1157 for (auto &F : *Text)
1158 if (F.getSize())
1159 return;
1160 Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);
1161 }
1162}
1163
1164void ARMELFStreamer::reset() {
1165 MCTargetStreamer &TS = *getTargetStreamer();
1166 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1167 ATS.reset();
1169 ThumbLabels.clear();
1170 LastMappingSymbols.clear();
1171 LastEMSInfo.reset();
1172 // MCELFStreamer clear's the assembler's e_flags. However, for
1173 // arm we manually set the ABI version on streamer creation, so
1174 // do the same here
1175 getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1176}
1177
1178inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
1179 unsigned Type,
1180 unsigned Flags,
1181 SectionKind Kind,
1182 const MCSymbol &Fn) {
1183 const MCSectionELF &FnSection =
1184 static_cast<const MCSectionELF &>(Fn.getSection());
1185
1186 // Create the name for new section
1187 StringRef FnSecName(FnSection.getName());
1188 SmallString<128> EHSecName(Prefix);
1189 if (FnSecName != ".text") {
1190 EHSecName += FnSecName;
1191 }
1192
1193 // Get .ARM.extab or .ARM.exidx section
1194 const MCSymbolELF *Group = FnSection.getGroup();
1195 if (Group)
1197 MCSectionELF *EHSection = getContext().getELFSection(
1198 EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1199 FnSection.getUniqueID(),
1200 static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
1201
1202 assert(EHSection && "Failed to get the required EH section");
1203
1204 // Switch to .ARM.extab or .ARM.exidx section
1205 switchSection(EHSection);
1206 emitValueToAlignment(Align(4), 0, 1, 0);
1207}
1208
1209inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1210 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1211 SectionKind::getData(), FnStart);
1212}
1213
1214inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1215 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
1217 SectionKind::getData(), FnStart);
1218}
1219
1220void ARMELFStreamer::EHReset() {
1221 ExTab = nullptr;
1222 FnStart = nullptr;
1223 Personality = nullptr;
1224 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1225 FPReg = ARM::SP;
1226 FPOffset = 0;
1227 SPOffset = 0;
1228 PendingOffset = 0;
1229 UsedFP = false;
1230 CantUnwind = false;
1231
1232 Opcodes.clear();
1233 UnwindOpAsm.Reset();
1234}
1235
1236void ARMELFStreamer::emitFnStart() {
1237 assert(FnStart == nullptr);
1238 FnStart = getContext().createTempSymbol();
1239 emitLabel(FnStart);
1240}
1241
1242void ARMELFStreamer::emitFnEnd() {
1243 assert(FnStart && ".fnstart must precedes .fnend");
1244
1245 // Emit unwind opcodes if there is no .handlerdata directive
1246 if (!ExTab && !CantUnwind)
1247 FlushUnwindOpcodes(true);
1248
1249 // Emit the exception index table entry
1250 SwitchToExIdxSection(*FnStart);
1251
1252 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1253 // personality routine to protect it from an arbitrary platform's static
1254 // linker garbage collection. We disable this for Android where the unwinder
1255 // is either dynamically linked or directly references the personality
1256 // routine.
1257 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
1258 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1259
1260 const MCSymbolRefExpr *FnStartRef =
1262
1263 emitValue(FnStartRef, 4);
1264
1265 if (CantUnwind) {
1267 } else if (ExTab) {
1268 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1269 const MCSymbolRefExpr *ExTabEntryRef =
1271 emitValue(ExTabEntryRef, 4);
1272 } else {
1273 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1274 // the second word of exception index table entry. The size of the unwind
1275 // opcodes should always be 4 bytes.
1276 assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1277 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1278 assert(Opcodes.size() == 4u &&
1279 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1280 uint64_t Intval = Opcodes[0] |
1281 Opcodes[1] << 8 |
1282 Opcodes[2] << 16 |
1283 Opcodes[3] << 24;
1284 emitIntValue(Intval, Opcodes.size());
1285 }
1286
1287 // Switch to the section containing FnStart
1288 switchSection(&FnStart->getSection());
1289
1290 // Clean exception handling frame information
1291 EHReset();
1292}
1293
1294void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1295
1296// Add the R_ARM_NONE fixup at the same position
1297void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1298 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1299 visitUsedSymbol(*PersonalitySym);
1300
1301 const MCSymbolRefExpr *PersonalityRef =
1303 addFixup(PersonalityRef, FK_Data_4);
1304}
1305
1306void ARMELFStreamer::FlushPendingOffset() {
1307 if (PendingOffset != 0) {
1308 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1309 PendingOffset = 0;
1310 }
1311}
1312
1313void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1314 // Emit the unwind opcode to restore $sp.
1315 if (UsedFP) {
1316 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1317 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1318 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1319 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1320 } else {
1321 FlushPendingOffset();
1322 }
1323
1324 // Finalize the unwind opcode sequence
1325 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1326
1327 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1328 // section. Thus, we don't have to create an entry in the .ARM.extab
1329 // section.
1330 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1331 return;
1332
1333 // Switch to .ARM.extab section.
1334 SwitchToExTabSection(*FnStart);
1335
1336 // Create .ARM.extab label for offset in .ARM.exidx
1337 assert(!ExTab);
1338 ExTab = getContext().createTempSymbol();
1339 emitLabel(ExTab);
1340
1341 // Emit personality
1342 if (Personality) {
1343 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1344 Personality, uint16_t(ARM::S_PREL31), getContext());
1345
1346 emitValue(PersonalityRef, 4);
1347 }
1348
1349 // Emit unwind opcodes
1350 assert((Opcodes.size() % 4) == 0 &&
1351 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1352 for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1353 uint64_t Intval = Opcodes[I] |
1354 Opcodes[I + 1] << 8 |
1355 Opcodes[I + 2] << 16 |
1356 Opcodes[I + 3] << 24;
1357 emitInt32(Intval);
1358 }
1359
1360 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1361 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1362 // after the unwind opcodes. The handler data consists of several 32-bit
1363 // words, and should be terminated by zero.
1364 //
1365 // In case that the .handlerdata directive is not specified by the
1366 // programmer, we should emit zero to terminate the handler data.
1367 if (NoHandlerData && !Personality)
1368 emitInt32(0);
1369}
1370
1371void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1372
1373void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1374 Personality = Per;
1375 UnwindOpAsm.setPersonality(Per);
1376}
1377
1378void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1379 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1380 PersonalityIndex = Index;
1381}
1382
1383void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,
1384 int64_t Offset) {
1385 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1386 "the operand of .setfp directive should be either $sp or $fp");
1387
1388 UsedFP = true;
1389 FPReg = NewFPReg;
1390
1391 if (NewSPReg == ARM::SP)
1392 FPOffset = SPOffset + Offset;
1393 else
1394 FPOffset += Offset;
1395}
1396
1397void ARMELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
1398 assert((Reg != ARM::SP && Reg != ARM::PC) &&
1399 "the operand of .movsp cannot be either sp or pc");
1400 assert(FPReg == ARM::SP && "current FP must be SP");
1401
1402 FlushPendingOffset();
1403
1404 FPReg = Reg;
1405 FPOffset = SPOffset + Offset;
1406
1407 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1408 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1409}
1410
1411void ARMELFStreamer::emitPad(int64_t Offset) {
1412 // Track the change of the $sp offset
1413 SPOffset -= Offset;
1414
1415 // To squash multiple .pad directives, we should delay the unwind opcode
1416 // until the .save, .vsave, .handlerdata, or .fnend directives.
1417 PendingOffset -= Offset;
1418}
1419
1420static std::pair<unsigned, unsigned>
1421collectHWRegs(const MCRegisterInfo &MRI, unsigned Idx,
1422 const SmallVectorImpl<MCRegister> &RegList, bool IsVector,
1423 uint32_t &Mask_) {
1424 uint32_t Mask = 0;
1425 unsigned Count = 0;
1426 while (Idx > 0) {
1427 MCRegister Reg = RegList[Idx - 1];
1428 if (Reg == ARM::RA_AUTH_CODE)
1429 break;
1430 unsigned RegEnc = MRI.getEncodingValue(Reg);
1431 assert(RegEnc < (IsVector ? 32U : 16U) && "Register out of range");
1432 unsigned Bit = (1u << RegEnc);
1433 if ((Mask & Bit) == 0) {
1434 Mask |= Bit;
1435 ++Count;
1436 }
1437 --Idx;
1438 }
1439
1440 Mask_ = Mask;
1441 return {Idx, Count};
1442}
1443
1444void ARMELFStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
1445 bool IsVector) {
1446 uint32_t Mask;
1447 unsigned Idx, Count;
1448 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
1449
1450 // Collect the registers in the register list. Issue unwinding instructions in
1451 // three parts: ordinary hardware registers, return address authentication
1452 // code pseudo register, the rest of the registers. The RA PAC is kept in an
1453 // architectural register (usually r12), but we treat it as a special case in
1454 // order to distinguish between that register containing RA PAC or a general
1455 // value.
1456 Idx = RegList.size();
1457 while (Idx > 0) {
1458 std::tie(Idx, Count) = collectHWRegs(MRI, Idx, RegList, IsVector, Mask);
1459 if (Count) {
1460 // Track the change the $sp offset: For the .save directive, the
1461 // corresponding push instruction will decrease the $sp by (4 * Count).
1462 // For the .vsave directive, the corresponding vpush instruction will
1463 // decrease $sp by (8 * Count).
1464 SPOffset -= Count * (IsVector ? 8 : 4);
1465
1466 // Emit the opcode
1467 FlushPendingOffset();
1468 if (IsVector)
1469 UnwindOpAsm.EmitVFPRegSave(Mask);
1470 else
1471 UnwindOpAsm.EmitRegSave(Mask);
1472 } else if (Idx > 0 && RegList[Idx - 1] == ARM::RA_AUTH_CODE) {
1473 --Idx;
1474 SPOffset -= 4;
1475 FlushPendingOffset();
1476 UnwindOpAsm.EmitRegSave(0);
1477 }
1478 }
1479}
1480
1481void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1482 const SmallVectorImpl<uint8_t> &Opcodes) {
1483 FlushPendingOffset();
1484 SPOffset = SPOffset - Offset;
1485 UnwindOpAsm.EmitRaw(Opcodes);
1486}
1487
1488namespace llvm {
1489
1492 MCInstPrinter *InstPrint) {
1493 return new ARMTargetAsmStreamer(S, OS, *InstPrint);
1494}
1495
1499
1501 return new ARMTargetELFStreamer(S);
1502}
1503
1505 std::unique_ptr<MCAsmBackend> TAB,
1506 std::unique_ptr<MCObjectWriter> OW,
1507 std::unique_ptr<MCCodeEmitter> Emitter,
1508 bool IsThumb, bool IsAndroid) {
1509 ARMELFStreamer *S =
1510 new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1511 std::move(Emitter), IsThumb, IsAndroid);
1512 // FIXME: This should eventually end up somewhere else where more
1513 // intelligent flag decisions can be made. For now we are just maintaining
1514 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1515 S->getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1516
1517 return S;
1518}
1519
1520} // 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!")
unsigned uint64_t
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.
std::unique_ptr< MCStreamer > && Streamer
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:1259
@ SHF_LINK_ORDER
Definition ELF.h:1274
@ SHF_GROUP
Definition ELF.h:1281
@ SHF_ARM_PURECODE
Definition ELF.h:1354
@ SHT_PROGBITS
Definition ELF.h:1157
@ SHT_ARM_ATTRIBUTES
Definition ELF.h:1219
@ SHT_ARM_EXIDX
Definition ELF.h:1215
@ STB_LOCAL
Definition ELF.h:1421
@ STT_FUNC
Definition ELF.h:1435
@ STT_NOTYPE
Definition ELF.h:1433
@ STT_GNU_IFUNC
Definition ELF.h:1440
@ 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:577
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:1762
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
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:40
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:1933
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