LLVM 21.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"
17#include "Utils/ARMBaseInfo.h"
18#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ADT/Twine.h"
26#include "llvm/MC/MCAsmInfo.h"
27#include "llvm/MC/MCAssembler.h"
29#include "llvm/MC/MCContext.h"
32#include "llvm/MC/MCExpr.h"
33#include "llvm/MC/MCFixup.h"
34#include "llvm/MC/MCFragment.h"
35#include "llvm/MC/MCInst.h"
40#include "llvm/MC/MCSection.h"
42#include "llvm/MC/MCStreamer.h"
44#include "llvm/MC/MCSymbol.h"
45#include "llvm/MC/MCSymbolELF.h"
46#include "llvm/MC/SectionKind.h"
53#include <cassert>
54#include <climits>
55#include <cstdint>
56#include <string>
57
58using namespace llvm;
59
60static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
62 "Invalid personality index");
63 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
64}
65
66namespace {
67
68class ARMELFStreamer;
69
70class ARMTargetAsmStreamer : public ARMTargetStreamer {
72 MCInstPrinter &InstPrinter;
73 bool IsVerboseAsm;
74
75 void emitFnStart() override;
76 void emitFnEnd() override;
77 void emitCantUnwind() override;
78 void emitPersonality(const MCSymbol *Personality) override;
79 void emitPersonalityIndex(unsigned Index) override;
80 void emitHandlerData() override;
81 void emitSetFP(MCRegister FpReg, MCRegister SpReg,
82 int64_t Offset = 0) override;
83 void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
84 void emitPad(int64_t Offset) override;
85 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
86 bool isVector) override;
87 void emitUnwindRaw(int64_t Offset,
88 const SmallVectorImpl<uint8_t> &Opcodes) override;
89
90 void switchVendor(StringRef Vendor) override;
91 void emitAttribute(unsigned Attribute, unsigned Value) override;
92 void emitTextAttribute(unsigned Attribute, StringRef String) override;
93 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
94 StringRef StringValue) override;
95 void emitArch(ARM::ArchKind Arch) override;
96 void emitArchExtension(uint64_t ArchExt) override;
97 void emitObjectArch(ARM::ArchKind Arch) override;
98 void emitFPU(ARM::FPUKind FPU) override;
99 void emitInst(uint32_t Inst, char Suffix = '\0') override;
100 void finishAttributeSection() override;
101
102 void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
103 void emitThumbFunc(MCSymbol *Symbol) override;
104 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
105
106 void emitARMWinCFIAllocStack(unsigned Size, bool Wide) override;
107 void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) override;
108 void emitARMWinCFISaveSP(unsigned Reg) override;
109 void emitARMWinCFISaveFRegs(unsigned First, unsigned Last) override;
110 void emitARMWinCFISaveLR(unsigned Offset) override;
111 void emitARMWinCFIPrologEnd(bool Fragment) override;
112 void emitARMWinCFINop(bool Wide) override;
113 void emitARMWinCFIEpilogStart(unsigned Condition) override;
114 void emitARMWinCFIEpilogEnd() override;
115 void emitARMWinCFICustom(unsigned Opcode) override;
116
117public:
118 ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
119 MCInstPrinter &InstPrinter);
120};
121
122ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
124 MCInstPrinter &InstPrinter)
125 : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
126 IsVerboseAsm(S.isVerboseAsm()) {}
127
128void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
129void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
130void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
131
132void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
133 OS << "\t.personality " << Personality->getName() << '\n';
134}
135
136void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
137 OS << "\t.personalityindex " << Index << '\n';
138}
139
140void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
141
142void ARMTargetAsmStreamer::emitSetFP(MCRegister FpReg, MCRegister SpReg,
143 int64_t Offset) {
144 OS << "\t.setfp\t";
145 InstPrinter.printRegName(OS, FpReg);
146 OS << ", ";
147 InstPrinter.printRegName(OS, SpReg);
148 if (Offset)
149 OS << ", #" << Offset;
150 OS << '\n';
151}
152
153void ARMTargetAsmStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
154 assert((Reg != ARM::SP && Reg != ARM::PC) &&
155 "the operand of .movsp cannot be either sp or pc");
156
157 OS << "\t.movsp\t";
158 InstPrinter.printRegName(OS, Reg);
159 if (Offset)
160 OS << ", #" << Offset;
161 OS << '\n';
162}
163
164void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
165 OS << "\t.pad\t#" << Offset << '\n';
166}
167
168void ARMTargetAsmStreamer::emitRegSave(
169 const SmallVectorImpl<MCRegister> &RegList, bool isVector) {
170 assert(RegList.size() && "RegList should not be empty");
171 if (isVector)
172 OS << "\t.vsave\t{";
173 else
174 OS << "\t.save\t{";
175
176 InstPrinter.printRegName(OS, RegList[0]);
177
178 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
179 OS << ", ";
180 InstPrinter.printRegName(OS, RegList[i]);
181 }
182
183 OS << "}\n";
184}
185
186void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
187
188void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
189 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
190 if (IsVerboseAsm) {
193 if (!Name.empty())
194 OS << "\t@ " << Name;
195 }
196 OS << "\n";
197}
198
199void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
201 switch (Attribute) {
203 OS << "\t.cpu\t" << String.lower();
204 break;
205 default:
206 OS << "\t.eabi_attribute\t" << Attribute << ", \"";
209 else
210 OS << String;
211 OS << "\"";
212 if (IsVerboseAsm) {
215 if (!Name.empty())
216 OS << "\t@ " << Name;
217 }
218 break;
219 }
220 OS << "\n";
221}
222
223void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
224 unsigned IntValue,
225 StringRef StringValue) {
226 switch (Attribute) {
227 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
229 OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
230 if (!StringValue.empty())
231 OS << ", \"" << StringValue << "\"";
232 if (IsVerboseAsm)
233 OS << "\t@ "
236 break;
237 }
238 OS << "\n";
239}
240
241void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
242 OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
243}
244
245void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
246 OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
247}
248
249void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
250 OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
251}
252
253void ARMTargetAsmStreamer::emitFPU(ARM::FPUKind FPU) {
254 OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
255}
256
257void ARMTargetAsmStreamer::finishAttributeSection() {}
258
259void ARMTargetAsmStreamer::annotateTLSDescriptorSequence(
260 const MCSymbolRefExpr *S) {
261 OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
262}
263
264void ARMTargetAsmStreamer::emitThumbFunc(MCSymbol *Symbol) {
265 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
266 OS << "\t.thumb_func";
267 // Only Mach-O hasSubsectionsViaSymbols()
268 if (MAI->hasSubsectionsViaSymbols()) {
269 OS << '\t';
270 Symbol->print(OS, MAI);
271 }
272 OS << '\n';
273}
274
275void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
276 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
277
278 OS << "\t.thumb_set\t";
279 Symbol->print(OS, MAI);
280 OS << ", ";
281 Value->print(OS, MAI);
282 OS << '\n';
283}
284
285void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
286 OS << "\t.inst";
287 if (Suffix)
288 OS << "." << Suffix;
289 OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
290}
291
292void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
293 const SmallVectorImpl<uint8_t> &Opcodes) {
294 OS << "\t.unwind_raw " << Offset;
295 for (uint8_t Opcode : Opcodes)
296 OS << ", 0x" << Twine::utohexstr(Opcode);
297 OS << '\n';
298}
299
300void ARMTargetAsmStreamer::emitARMWinCFIAllocStack(unsigned Size, bool Wide) {
301 if (Wide)
302 OS << "\t.seh_stackalloc_w\t" << Size << "\n";
303 else
304 OS << "\t.seh_stackalloc\t" << Size << "\n";
305}
306
307static void printRegs(formatted_raw_ostream &OS, ListSeparator &LS, int First,
308 int Last) {
309 if (First != Last)
310 OS << LS << "r" << First << "-r" << Last;
311 else
312 OS << LS << "r" << First;
313}
314
315void ARMTargetAsmStreamer::emitARMWinCFISaveRegMask(unsigned Mask, bool Wide) {
316 if (Wide)
317 OS << "\t.seh_save_regs_w\t";
318 else
319 OS << "\t.seh_save_regs\t";
320 ListSeparator LS;
321 int First = -1;
322 OS << "{";
323 for (int I = 0; I <= 12; I++) {
324 if (Mask & (1 << I)) {
325 if (First < 0)
326 First = I;
327 } else {
328 if (First >= 0) {
329 printRegs(OS, LS, First, I - 1);
330 First = -1;
331 }
332 }
333 }
334 if (First >= 0)
335 printRegs(OS, LS, First, 12);
336 if (Mask & (1 << 14))
337 OS << LS << "lr";
338 OS << "}\n";
339}
340
341void ARMTargetAsmStreamer::emitARMWinCFISaveSP(unsigned Reg) {
342 OS << "\t.seh_save_sp\tr" << Reg << "\n";
343}
344
345void ARMTargetAsmStreamer::emitARMWinCFISaveFRegs(unsigned First,
346 unsigned Last) {
347 if (First != Last)
348 OS << "\t.seh_save_fregs\t{d" << First << "-d" << Last << "}\n";
349 else
350 OS << "\t.seh_save_fregs\t{d" << First << "}\n";
351}
352
353void ARMTargetAsmStreamer::emitARMWinCFISaveLR(unsigned Offset) {
354 OS << "\t.seh_save_lr\t" << Offset << "\n";
355}
356
357void ARMTargetAsmStreamer::emitARMWinCFIPrologEnd(bool Fragment) {
358 if (Fragment)
359 OS << "\t.seh_endprologue_fragment\n";
360 else
361 OS << "\t.seh_endprologue\n";
362}
363
364void ARMTargetAsmStreamer::emitARMWinCFINop(bool Wide) {
365 if (Wide)
366 OS << "\t.seh_nop_w\n";
367 else
368 OS << "\t.seh_nop\n";
369}
370
371void ARMTargetAsmStreamer::emitARMWinCFIEpilogStart(unsigned Condition) {
372 if (Condition == ARMCC::AL)
373 OS << "\t.seh_startepilogue\n";
374 else
375 OS << "\t.seh_startepilogue_cond\t"
376 << ARMCondCodeToString(static_cast<ARMCC::CondCodes>(Condition)) << "\n";
377}
378
379void ARMTargetAsmStreamer::emitARMWinCFIEpilogEnd() {
380 OS << "\t.seh_endepilogue\n";
381}
382
383void ARMTargetAsmStreamer::emitARMWinCFICustom(unsigned Opcode) {
384 int I;
385 for (I = 3; I > 0; I--)
386 if (Opcode & (0xffu << (8 * I)))
387 break;
388 ListSeparator LS;
389 OS << "\t.seh_custom\t";
390 for (; I >= 0; I--)
391 OS << LS << ((Opcode >> (8 * I)) & 0xff);
392 OS << "\n";
393}
394
395class ARMTargetELFStreamer : public ARMTargetStreamer {
396private:
397 StringRef CurrentVendor;
398 ARM::FPUKind FPU = ARM::FK_INVALID;
399 ARM::ArchKind Arch = ARM::ArchKind::INVALID;
400 ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
401
402 MCSection *AttributeSection = nullptr;
403
404 void emitArchDefaultAttributes();
405 void emitFPUDefaultAttributes();
406
407 ARMELFStreamer &getStreamer();
408
409 void emitFnStart() override;
410 void emitFnEnd() override;
411 void emitCantUnwind() override;
412 void emitPersonality(const MCSymbol *Personality) override;
413 void emitPersonalityIndex(unsigned Index) override;
414 void emitHandlerData() override;
415 void emitSetFP(MCRegister FpReg, MCRegister SpReg,
416 int64_t Offset = 0) override;
417 void emitMovSP(MCRegister Reg, int64_t Offset = 0) override;
418 void emitPad(int64_t Offset) override;
419 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
420 bool isVector) override;
421 void emitUnwindRaw(int64_t Offset,
422 const SmallVectorImpl<uint8_t> &Opcodes) override;
423
424 void switchVendor(StringRef Vendor) override;
425 void emitAttribute(unsigned Attribute, unsigned Value) override;
426 void emitTextAttribute(unsigned Attribute, StringRef String) override;
427 void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
428 StringRef StringValue) override;
429 void emitArch(ARM::ArchKind Arch) override;
430 void emitObjectArch(ARM::ArchKind Arch) override;
431 void emitFPU(ARM::FPUKind FPU) override;
432 void emitInst(uint32_t Inst, char Suffix = '\0') override;
433 void finishAttributeSection() override;
434 void emitLabel(MCSymbol *Symbol) override;
435
436 void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
437 void emitThumbFunc(MCSymbol *Symbol) override;
438 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
439
440 // Reset state between object emissions
441 void reset() override;
442
443 void finish() override;
444
445public:
446 ARMTargetELFStreamer(MCStreamer &S)
447 : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
448};
449
450/// Extend the generic ELFStreamer class so that it can emit mapping symbols at
451/// the appropriate points in the object files. These symbols are defined in the
452/// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
453///
454/// In brief: $a, $t or $d should be emitted at the start of each contiguous
455/// region of ARM code, Thumb code or data in a section. In practice, this
456/// emission does not rely on explicit assembler directives but on inherent
457/// properties of the directives doing the emission (e.g. ".byte" is data, "add
458/// r0, r0, r0" an instruction).
459///
460/// As a result this system is orthogonal to the DataRegion infrastructure used
461/// by MachO. Beware!
462class ARMELFStreamer : public MCELFStreamer {
463public:
464 friend class ARMTargetELFStreamer;
465
466 ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
467 std::unique_ptr<MCObjectWriter> OW,
468 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
469 bool IsAndroid)
470 : MCELFStreamer(Context, std::move(TAB), std::move(OW),
471 std::move(Emitter)),
472 IsThumb(IsThumb), IsAndroid(IsAndroid) {
473 EHReset();
474 }
475
476 ~ARMELFStreamer() override = default;
477
478 // ARM exception handling directives
479 void emitFnStart();
480 void emitFnEnd();
481 void emitCantUnwind();
482 void emitPersonality(const MCSymbol *Per);
483 void emitPersonalityIndex(unsigned index);
484 void emitHandlerData();
485 void emitSetFP(MCRegister NewFpReg, MCRegister NewSpReg, int64_t Offset = 0);
486 void emitMovSP(MCRegister Reg, int64_t Offset = 0);
487 void emitPad(int64_t Offset);
488 void emitRegSave(const SmallVectorImpl<MCRegister> &RegList, bool isVector);
489 void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
490 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
491 SMLoc Loc) override {
492 emitDataMappingSymbol();
493 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
494 }
495
496 void changeSection(MCSection *Section, uint32_t Subsection) override {
497 LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
498 MCELFStreamer::changeSection(Section, Subsection);
499 auto LastMappingSymbol = LastMappingSymbols.find(Section);
500 if (LastMappingSymbol != LastMappingSymbols.end()) {
501 LastEMSInfo = std::move(LastMappingSymbol->second);
502 return;
503 }
504 LastEMSInfo.reset(new ElfMappingSymbolInfo);
505 }
506
507 /// This function is the one used to emit instruction data into the ELF
508 /// streamer. We override it to add the appropriate mapping symbol if
509 /// necessary.
510 void emitInstruction(const MCInst &Inst,
511 const MCSubtargetInfo &STI) override {
512 if (IsThumb)
513 EmitThumbMappingSymbol();
514 else
515 EmitARMMappingSymbol();
516
518 }
519
520 void emitInst(uint32_t Inst, char Suffix) {
521 unsigned Size;
522 char Buffer[4];
523 const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
524
525 switch (Suffix) {
526 case '\0':
527 Size = 4;
528
529 assert(!IsThumb);
530 EmitARMMappingSymbol();
531 for (unsigned II = 0, IE = Size; II != IE; II++) {
532 const unsigned I = LittleEndian ? (Size - II - 1) : II;
533 Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
534 }
535
536 break;
537 case 'n':
538 case 'w':
539 Size = (Suffix == 'n' ? 2 : 4);
540
541 assert(IsThumb);
542 EmitThumbMappingSymbol();
543 // Thumb wide instructions are emitted as a pair of 16-bit words of the
544 // appropriate endianness.
545 for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
546 const unsigned I0 = LittleEndian ? II + 0 : II + 1;
547 const unsigned I1 = LittleEndian ? II + 1 : II + 0;
548 Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
549 Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
550 }
551
552 break;
553 default:
554 llvm_unreachable("Invalid Suffix");
555 }
556
558 }
559
560 /// This is one of the functions used to emit data into an ELF section, so the
561 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
562 /// necessary.
563 void emitBytes(StringRef Data) override {
564 emitDataMappingSymbol();
566 }
567
568 void FlushPendingMappingSymbol() {
569 if (!LastEMSInfo->hasInfo())
570 return;
571 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
572 emitMappingSymbol("$d", *EMS->F, EMS->Offset);
573 EMS->resetInfo();
574 }
575
576 /// This is one of the functions used to emit data into an ELF section, so the
577 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
578 /// necessary.
579 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
580 if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
581 if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
582 getContext().reportError(Loc, "relocated expression must be 32-bit");
583 return;
584 }
586 }
587
588 emitDataMappingSymbol();
590 }
591
592 void emitAssemblerFlag(MCAssemblerFlag Flag) override {
594
595 switch (Flag) {
597 return; // no-op here.
598 case MCAF_Code16:
599 IsThumb = true;
600 return; // Change to Thumb mode
601 case MCAF_Code32:
602 IsThumb = false;
603 return; // Change to ARM mode
604 case MCAF_Code64:
605 return;
607 return;
608 }
609 }
610
611 /// If a label is defined before the .type directive sets the label's type
612 /// then the label can't be recorded as thumb function when the label is
613 /// defined. We override emitSymbolAttribute() which is called as part of the
614 /// parsing of .type so that if the symbol has already been defined we can
615 /// record the label as Thumb. FIXME: there is a corner case where the state
616 /// is changed in between the label definition and the .type directive, this
617 /// is not expected to occur in practice and handling it would require the
618 /// backend to track IsThumb for every label.
619 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
621
622 if (!IsThumb)
623 return Val;
624
625 unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
626 if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
627 Symbol->isDefined())
629
630 return Val;
631 };
632
633private:
634 enum ElfMappingSymbol {
635 EMS_None,
636 EMS_ARM,
637 EMS_Thumb,
638 EMS_Data
639 };
640
641 struct ElfMappingSymbolInfo {
642 void resetInfo() {
643 F = nullptr;
644 Offset = 0;
645 }
646 bool hasInfo() { return F != nullptr; }
647 MCDataFragment *F = nullptr;
648 uint64_t Offset = 0;
649 ElfMappingSymbol State = EMS_None;
650 };
651
652 void emitDataMappingSymbol() {
653 if (LastEMSInfo->State == EMS_Data)
654 return;
655 else if (LastEMSInfo->State == EMS_None) {
656 // This is a tentative symbol, it won't really be emitted until it's
657 // actually needed.
658 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
659 auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
660 if (!DF)
661 return;
662 EMS->F = DF;
663 EMS->Offset = DF->getContents().size();
664 LastEMSInfo->State = EMS_Data;
665 return;
666 }
667 EmitMappingSymbol("$d");
668 LastEMSInfo->State = EMS_Data;
669 }
670
671 void EmitThumbMappingSymbol() {
672 if (LastEMSInfo->State == EMS_Thumb)
673 return;
674 FlushPendingMappingSymbol();
675 EmitMappingSymbol("$t");
676 LastEMSInfo->State = EMS_Thumb;
677 }
678
679 void EmitARMMappingSymbol() {
680 if (LastEMSInfo->State == EMS_ARM)
681 return;
682 FlushPendingMappingSymbol();
683 EmitMappingSymbol("$a");
684 LastEMSInfo->State = EMS_ARM;
685 }
686
687 void EmitMappingSymbol(StringRef Name) {
688 auto *Symbol = 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, MCDataFragment &F, uint64_t Offset) {
696 auto *Symbol = cast<MCSymbolELF>(getContext().createLocalSymbol(Name));
697 emitLabelAtPos(Symbol, SMLoc(), F, Offset);
698 Symbol->setType(ELF::STT_NOTYPE);
699 Symbol->setBinding(ELF::STB_LOCAL);
700 }
701
702 // Helper functions for ARM exception handling directives
703 void EHReset();
704
705 // Reset state between object emissions
706 void reset() override;
707
708 void EmitPersonalityFixup(StringRef Name);
709 void FlushPendingOffset();
710 void FlushUnwindOpcodes(bool NoHandlerData);
711
712 void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
713 SectionKind Kind, const MCSymbol &Fn);
714 void SwitchToExTabSection(const MCSymbol &FnStart);
715 void SwitchToExIdxSection(const MCSymbol &FnStart);
716
717 void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
718
719 bool IsThumb;
720 bool IsAndroid;
721
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,
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 S.setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
905 S.setAttributeItem(ARM_ISA_use, Allowed, false);
906 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
907 S.setAttributeItem(MPextension_use, Allowed, false);
908 S.setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
909 break;
910
911 case ARM::ArchKind::ARMV8MBaseline:
912 case ARM::ArchKind::ARMV8MMainline:
913 S.setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
914 S.setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
915 break;
916
917 case ARM::ArchKind::IWMMXT:
918 S.setAttributeItem(ARM_ISA_use, Allowed, false);
919 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
920 S.setAttributeItem(WMMX_arch, AllowWMMXv1, false);
921 break;
922
923 case ARM::ArchKind::IWMMXT2:
924 S.setAttributeItem(ARM_ISA_use, Allowed, false);
925 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
926 S.setAttributeItem(WMMX_arch, AllowWMMXv2, false);
927 break;
928
929 default:
930 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
931 break;
932 }
933}
934
935void ARMTargetELFStreamer::emitFPU(ARM::FPUKind Value) { FPU = Value; }
936
937void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
938 ARMELFStreamer &S = getStreamer();
939
940 switch (FPU) {
941 case ARM::FK_VFP:
942 case ARM::FK_VFPV2:
944 /* OverwriteExisting= */ false);
945 break;
946
947 case ARM::FK_VFPV3:
949 /* OverwriteExisting= */ false);
950 break;
951
952 case ARM::FK_VFPV3_FP16:
954 /* OverwriteExisting= */ false);
956 /* OverwriteExisting= */ false);
957 break;
958
959 case ARM::FK_VFPV3_D16:
961 /* OverwriteExisting= */ false);
962 break;
963
964 case ARM::FK_VFPV3_D16_FP16:
966 /* OverwriteExisting= */ false);
968 /* OverwriteExisting= */ false);
969 break;
970
971 case ARM::FK_VFPV3XD:
973 /* OverwriteExisting= */ false);
974 break;
975 case ARM::FK_VFPV3XD_FP16:
977 /* OverwriteExisting= */ false);
979 /* OverwriteExisting= */ false);
980 break;
981
982 case ARM::FK_VFPV4:
984 /* OverwriteExisting= */ false);
985 break;
986
987 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
988 // as _D16 here.
989 case ARM::FK_FPV4_SP_D16:
990 case ARM::FK_VFPV4_D16:
992 /* OverwriteExisting= */ false);
993 break;
994
995 case ARM::FK_FP_ARMV8:
997 /* OverwriteExisting= */ false);
998 break;
999
1000 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
1001 // uses the FP_ARMV8_D16 build attribute.
1002 case ARM::FK_FPV5_SP_D16:
1003 case ARM::FK_FPV5_D16:
1004 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
1005 // FPU, but there are two different names for it depending on the CPU.
1006 case ARM::FK_FP_ARMV8_FULLFP16_SP_D16:
1007 case ARM::FK_FP_ARMV8_FULLFP16_D16:
1009 /* OverwriteExisting= */ false);
1010 break;
1011
1012 case ARM::FK_NEON:
1014 /* OverwriteExisting= */ false);
1015 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1017 /* OverwriteExisting= */ false);
1018 break;
1019
1020 case ARM::FK_NEON_FP16:
1022 /* OverwriteExisting= */ false);
1023 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1025 /* OverwriteExisting= */ false);
1027 /* OverwriteExisting= */ false);
1028 break;
1029
1030 case ARM::FK_NEON_VFPV4:
1032 /* OverwriteExisting= */ false);
1033 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
1035 /* OverwriteExisting= */ false);
1036 break;
1037
1038 case ARM::FK_NEON_FP_ARMV8:
1039 case ARM::FK_CRYPTO_NEON_FP_ARMV8:
1041 /* OverwriteExisting= */ false);
1042 // 'Advanced_SIMD_arch' must be emitted not here, but within
1043 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
1044 break;
1045
1046 case ARM::FK_SOFTVFP:
1047 case ARM::FK_NONE:
1048 break;
1049
1050 default:
1051 report_fatal_error("Unknown FPU: " + Twine(FPU));
1052 break;
1053 }
1054}
1055
1056void ARMTargetELFStreamer::finishAttributeSection() {
1057 ARMELFStreamer &S = getStreamer();
1058
1059 if (FPU != ARM::FK_INVALID)
1060 emitFPUDefaultAttributes();
1061
1062 if (Arch != ARM::ArchKind::INVALID)
1063 emitArchDefaultAttributes();
1064
1065 if (S.Contents.empty())
1066 return;
1067
1068 auto LessTag = [](const MCELFStreamer::AttributeItem &LHS,
1069 const MCELFStreamer::AttributeItem &RHS) -> bool {
1070 // The conformance tag must be emitted first when serialised into an
1071 // object file. Specifically, the addenda to the ARM ABI states that
1072 // (2.3.7.4):
1073 //
1074 // "To simplify recognition by consumers in the common case of claiming
1075 // conformity for the whole file, this tag should be emitted first in a
1076 // file-scope sub-subsection of the first public subsection of the
1077 // attributes section."
1078 //
1079 // So it is special-cased in this comparison predicate when the
1080 // attributes are sorted in finishAttributeSection().
1081 return (RHS.Tag != ARMBuildAttrs::conformance) &&
1082 ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
1083 };
1084 llvm::sort(S.Contents, LessTag);
1085
1086 S.emitAttributesSection(CurrentVendor, ".ARM.attributes",
1087 ELF::SHT_ARM_ATTRIBUTES, AttributeSection);
1088
1089 FPU = ARM::FK_INVALID;
1090}
1091
1092void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
1093 ARMELFStreamer &Streamer = getStreamer();
1094 if (!Streamer.IsThumb)
1095 return;
1096
1097 Streamer.getAssembler().registerSymbol(*Symbol);
1098 unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
1100 emitThumbFunc(Symbol);
1101}
1102
1103void ARMTargetELFStreamer::annotateTLSDescriptorSequence(
1104 const MCSymbolRefExpr *S) {
1105 getStreamer().EmitFixup(S, FK_Data_4);
1106}
1107
1108void ARMTargetELFStreamer::emitThumbFunc(MCSymbol *Symbol) {
1109 getStreamer().getAssembler().setIsThumbFunc(Symbol);
1110 getStreamer().emitSymbolAttribute(Symbol, MCSA_ELF_TypeFunction);
1111}
1112
1113void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
1114 if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
1115 const MCSymbol &Sym = SRE->getSymbol();
1116 if (!Sym.isDefined()) {
1117 getStreamer().emitAssignment(Symbol, Value);
1118 return;
1119 }
1120 }
1121
1122 emitThumbFunc(Symbol);
1123 getStreamer().emitAssignment(Symbol, Value);
1124}
1125
1126void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1127 getStreamer().emitInst(Inst, Suffix);
1128}
1129
1130void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1131
1132void ARMTargetELFStreamer::finish() {
1133 ARMTargetStreamer::finish();
1134 finishAttributeSection();
1135
1136 // The mix of execute-only and non-execute-only at link time is
1137 // non-execute-only. To avoid the empty implicitly created .text
1138 // section from making the whole .text section non-execute-only, we
1139 // mark it execute-only if it is empty and there is at least one
1140 // execute-only section in the object.
1141 MCContext &Ctx = getStreamer().getContext();
1142 auto &Asm = getStreamer().getAssembler();
1143 if (any_of(Asm, [](const MCSection &Sec) {
1144 return cast<MCSectionELF>(Sec).getFlags() & ELF::SHF_ARM_PURECODE;
1145 })) {
1146 auto *Text =
1147 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
1148 for (auto &F : *Text)
1149 if (auto *DF = dyn_cast<MCDataFragment>(&F))
1150 if (!DF->getContents().empty())
1151 return;
1152 Text->setFlags(Text->getFlags() | ELF::SHF_ARM_PURECODE);
1153 }
1154}
1155
1156void ARMELFStreamer::reset() {
1157 MCTargetStreamer &TS = *getTargetStreamer();
1158 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1159 ATS.reset();
1161 LastMappingSymbols.clear();
1162 LastEMSInfo.reset();
1163 // MCELFStreamer clear's the assembler's e_flags. However, for
1164 // arm we manually set the ABI version on streamer creation, so
1165 // do the same here
1166 getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1167}
1168
1169inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
1170 unsigned Type,
1171 unsigned Flags,
1172 SectionKind Kind,
1173 const MCSymbol &Fn) {
1174 const MCSectionELF &FnSection =
1175 static_cast<const MCSectionELF &>(Fn.getSection());
1176
1177 // Create the name for new section
1178 StringRef FnSecName(FnSection.getName());
1179 SmallString<128> EHSecName(Prefix);
1180 if (FnSecName != ".text") {
1181 EHSecName += FnSecName;
1182 }
1183
1184 // Get .ARM.extab or .ARM.exidx section
1185 const MCSymbolELF *Group = FnSection.getGroup();
1186 if (Group)
1188 MCSectionELF *EHSection = getContext().getELFSection(
1189 EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1190 FnSection.getUniqueID(),
1191 static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
1192
1193 assert(EHSection && "Failed to get the required EH section");
1194
1195 // Switch to .ARM.extab or .ARM.exidx section
1196 switchSection(EHSection);
1197 emitValueToAlignment(Align(4), 0, 1, 0);
1198}
1199
1200inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1201 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1202 SectionKind::getData(), FnStart);
1203}
1204
1205inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
1206 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
1208 SectionKind::getData(), FnStart);
1209}
1210
1211void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
1212 MCDataFragment *Frag = getOrCreateDataFragment();
1213 Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
1214 Kind));
1215}
1216
1217void ARMELFStreamer::EHReset() {
1218 ExTab = nullptr;
1219 FnStart = nullptr;
1220 Personality = nullptr;
1221 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1222 FPReg = ARM::SP;
1223 FPOffset = 0;
1224 SPOffset = 0;
1225 PendingOffset = 0;
1226 UsedFP = false;
1227 CantUnwind = false;
1228
1229 Opcodes.clear();
1230 UnwindOpAsm.Reset();
1231}
1232
1233void ARMELFStreamer::emitFnStart() {
1234 assert(FnStart == nullptr);
1235 FnStart = getContext().createTempSymbol();
1236 emitLabel(FnStart);
1237}
1238
1239void ARMELFStreamer::emitFnEnd() {
1240 assert(FnStart && ".fnstart must precedes .fnend");
1241
1242 // Emit unwind opcodes if there is no .handlerdata directive
1243 if (!ExTab && !CantUnwind)
1244 FlushUnwindOpcodes(true);
1245
1246 // Emit the exception index table entry
1247 SwitchToExIdxSection(*FnStart);
1248
1249 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1250 // personality routine to protect it from an arbitrary platform's static
1251 // linker garbage collection. We disable this for Android where the unwinder
1252 // is either dynamically linked or directly references the personality
1253 // routine.
1254 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
1255 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1256
1257 const MCSymbolRefExpr *FnStartRef =
1260 getContext());
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 =
1271 getContext());
1272 emitValue(ExTabEntryRef, 4);
1273 } else {
1274 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1275 // the second word of exception index table entry. The size of the unwind
1276 // opcodes should always be 4 bytes.
1277 assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
1278 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1279 assert(Opcodes.size() == 4u &&
1280 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1281 uint64_t Intval = Opcodes[0] |
1282 Opcodes[1] << 8 |
1283 Opcodes[2] << 16 |
1284 Opcodes[3] << 24;
1285 emitIntValue(Intval, Opcodes.size());
1286 }
1287
1288 // Switch to the section containing FnStart
1289 switchSection(&FnStart->getSection());
1290
1291 // Clean exception handling frame information
1292 EHReset();
1293}
1294
1295void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1296
1297// Add the R_ARM_NONE fixup at the same position
1298void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1299 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1300
1301 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1302 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1303
1304 visitUsedExpr(*PersonalityRef);
1305 MCDataFragment *DF = getOrCreateDataFragment();
1306 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
1307 PersonalityRef,
1308 MCFixup::getKindForSize(4, false)));
1309}
1310
1311void ARMELFStreamer::FlushPendingOffset() {
1312 if (PendingOffset != 0) {
1313 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1314 PendingOffset = 0;
1315 }
1316}
1317
1318void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1319 // Emit the unwind opcode to restore $sp.
1320 if (UsedFP) {
1321 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1322 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1323 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1324 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1325 } else {
1326 FlushPendingOffset();
1327 }
1328
1329 // Finalize the unwind opcode sequence
1330 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1331
1332 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1333 // section. Thus, we don't have to create an entry in the .ARM.extab
1334 // section.
1335 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1336 return;
1337
1338 // Switch to .ARM.extab section.
1339 SwitchToExTabSection(*FnStart);
1340
1341 // Create .ARM.extab label for offset in .ARM.exidx
1342 assert(!ExTab);
1343 ExTab = getContext().createTempSymbol();
1344 emitLabel(ExTab);
1345
1346 // Emit personality
1347 if (Personality) {
1348 const MCSymbolRefExpr *PersonalityRef =
1349 MCSymbolRefExpr::create(Personality,
1351 getContext());
1352
1353 emitValue(PersonalityRef, 4);
1354 }
1355
1356 // Emit unwind opcodes
1357 assert((Opcodes.size() % 4) == 0 &&
1358 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1359 for (unsigned I = 0; I != Opcodes.size(); I += 4) {
1360 uint64_t Intval = Opcodes[I] |
1361 Opcodes[I + 1] << 8 |
1362 Opcodes[I + 2] << 16 |
1363 Opcodes[I + 3] << 24;
1364 emitInt32(Intval);
1365 }
1366
1367 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1368 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1369 // after the unwind opcodes. The handler data consists of several 32-bit
1370 // words, and should be terminated by zero.
1371 //
1372 // In case that the .handlerdata directive is not specified by the
1373 // programmer, we should emit zero to terminate the handler data.
1374 if (NoHandlerData && !Personality)
1375 emitInt32(0);
1376}
1377
1378void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1379
1380void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1381 Personality = Per;
1382 UnwindOpAsm.setPersonality(Per);
1383}
1384
1385void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1386 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1387 PersonalityIndex = Index;
1388}
1389
1390void ARMELFStreamer::emitSetFP(MCRegister NewFPReg, MCRegister NewSPReg,
1391 int64_t Offset) {
1392 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1393 "the operand of .setfp directive should be either $sp or $fp");
1394
1395 UsedFP = true;
1396 FPReg = NewFPReg;
1397
1398 if (NewSPReg == ARM::SP)
1399 FPOffset = SPOffset + Offset;
1400 else
1401 FPOffset += Offset;
1402}
1403
1404void ARMELFStreamer::emitMovSP(MCRegister Reg, int64_t Offset) {
1405 assert((Reg != ARM::SP && Reg != ARM::PC) &&
1406 "the operand of .movsp cannot be either sp or pc");
1407 assert(FPReg == ARM::SP && "current FP must be SP");
1408
1409 FlushPendingOffset();
1410
1411 FPReg = Reg;
1412 FPOffset = SPOffset + Offset;
1413
1414 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1415 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1416}
1417
1418void ARMELFStreamer::emitPad(int64_t Offset) {
1419 // Track the change of the $sp offset
1420 SPOffset -= Offset;
1421
1422 // To squash multiple .pad directives, we should delay the unwind opcode
1423 // until the .save, .vsave, .handlerdata, or .fnend directives.
1424 PendingOffset -= Offset;
1425}
1426
1427static std::pair<unsigned, unsigned>
1429 const SmallVectorImpl<MCRegister> &RegList, bool IsVector,
1430 uint32_t &Mask_) {
1431 uint32_t Mask = 0;
1432 unsigned Count = 0;
1433 while (Idx > 0) {
1434 MCRegister Reg = RegList[Idx - 1];
1435 if (Reg == ARM::RA_AUTH_CODE)
1436 break;
1437 unsigned RegEnc = MRI.getEncodingValue(Reg);
1438 assert(RegEnc < (IsVector ? 32U : 16U) && "Register out of range");
1439 unsigned Bit = (1u << RegEnc);
1440 if ((Mask & Bit) == 0) {
1441 Mask |= Bit;
1442 ++Count;
1443 }
1444 --Idx;
1445 }
1446
1447 Mask_ = Mask;
1448 return {Idx, Count};
1449}
1450
1451void ARMELFStreamer::emitRegSave(const SmallVectorImpl<MCRegister> &RegList,
1452 bool IsVector) {
1453 uint32_t Mask;
1454 unsigned Idx, Count;
1455 const MCRegisterInfo &MRI = *getContext().getRegisterInfo();
1456
1457 // Collect the registers in the register list. Issue unwinding instructions in
1458 // three parts: ordinary hardware registers, return address authentication
1459 // code pseudo register, the rest of the registers. The RA PAC is kept in an
1460 // architectural register (usually r12), but we treat it as a special case in
1461 // order to distinguish between that register containing RA PAC or a general
1462 // value.
1463 Idx = RegList.size();
1464 while (Idx > 0) {
1465 std::tie(Idx, Count) = collectHWRegs(MRI, Idx, RegList, IsVector, Mask);
1466 if (Count) {
1467 // Track the change the $sp offset: For the .save directive, the
1468 // corresponding push instruction will decrease the $sp by (4 * Count).
1469 // For the .vsave directive, the corresponding vpush instruction will
1470 // decrease $sp by (8 * Count).
1471 SPOffset -= Count * (IsVector ? 8 : 4);
1472
1473 // Emit the opcode
1474 FlushPendingOffset();
1475 if (IsVector)
1476 UnwindOpAsm.EmitVFPRegSave(Mask);
1477 else
1478 UnwindOpAsm.EmitRegSave(Mask);
1479 } else if (Idx > 0 && RegList[Idx - 1] == ARM::RA_AUTH_CODE) {
1480 --Idx;
1481 SPOffset -= 4;
1482 FlushPendingOffset();
1483 UnwindOpAsm.EmitRegSave(0);
1484 }
1485 }
1486}
1487
1488void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1489 const SmallVectorImpl<uint8_t> &Opcodes) {
1490 FlushPendingOffset();
1491 SPOffset = SPOffset - Offset;
1492 UnwindOpAsm.EmitRaw(Opcodes);
1493}
1494
1495namespace llvm {
1496
1499 MCInstPrinter *InstPrint) {
1500 return new ARMTargetAsmStreamer(S, OS, *InstPrint);
1501}
1502
1504 return new ARMTargetStreamer(S);
1505}
1506
1508 return new ARMTargetELFStreamer(S);
1509}
1510
1512 std::unique_ptr<MCAsmBackend> TAB,
1513 std::unique_ptr<MCObjectWriter> OW,
1514 std::unique_ptr<MCCodeEmitter> Emitter,
1515 bool IsThumb, bool IsAndroid) {
1516 ARMELFStreamer *S =
1517 new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1518 std::move(Emitter), IsThumb, IsAndroid);
1519 // FIXME: This should eventually end up somewhere else where more
1520 // intelligent flag decisions can be made. For now we are just maintaining
1521 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1522 S->getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1523
1524 return S;
1525}
1526
1527} // end namespace llvm
unsigned const MachineRegisterInfo * MRI
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
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file defines the DenseMap class.
std::string Name
uint64_t Size
Symbol * Sym
Definition: ELF_riscv.cpp:479
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned Reg
uint64_t IntrinsicInst * II
static constexpr MCPhysReg FPReg
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallString class.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
Value * RHS
Value * LHS
virtual void emitUnwindRaw(int64_t StackOffset, const SmallVectorImpl< uint8_t > &Opcodes)
virtual void reset()
Reset any state between object emissions, i.e.
virtual void emitSetFP(MCRegister FpReg, MCRegister SpReg, int64_t Offset=0)
virtual void annotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE)
virtual void finishAttributeSection()
virtual void emitMovSP(MCRegister Reg, int64_t Offset=0)
virtual void emitARMWinCFISaveSP(unsigned Reg)
virtual void emitPersonalityIndex(unsigned Index)
virtual void emitInst(uint32_t Inst, char Suffix='\0')
virtual void emitARMWinCFISaveLR(unsigned Offset)
virtual void emitArchExtension(uint64_t ArchExt)
virtual void emitTextAttribute(unsigned Attribute, StringRef String)
virtual void emitARMWinCFIAllocStack(unsigned Size, bool Wide)
virtual void emitARMWinCFICustom(unsigned Opcode)
virtual void emitARMWinCFISaveRegMask(unsigned Mask, bool Wide)
virtual void emitRegSave(const SmallVectorImpl< MCRegister > &RegList, bool isVector)
virtual void emitARMWinCFIEpilogEnd()
virtual void emitARMWinCFIPrologEnd(bool Fragment)
virtual void switchVendor(StringRef Vendor)
virtual void emitPersonality(const MCSymbol *Personality)
virtual void emitObjectArch(ARM::ArchKind Arch)
virtual void emitIntTextAttribute(unsigned Attribute, unsigned IntValue, StringRef StringValue="")
virtual void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value)
virtual void emitThumbFunc(MCSymbol *Symbol)
virtual void emitFPU(ARM::FPUKind FPU)
virtual void emitARMWinCFISaveFRegs(unsigned First, unsigned Last)
virtual void emitARMWinCFIEpilogStart(unsigned Condition)
virtual void emitPad(int64_t Offset)
virtual void emitAttribute(unsigned Attribute, unsigned Value)
virtual void emitARMWinCFINop(bool Wide)
virtual void emitArch(ARM::ArchKind Arch)
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
bool isLittleEndian() const
True if the target is little endian.
Definition: MCAsmInfo.h:458
bool hasSubsectionsViaSymbols() const
Definition: MCAsmInfo.h:463
void setIsThumbFunc(const MCSymbol *Func)
Flag a function symbol as the target of a .thumb_func directive.
Definition: MCAssembler.h:176
Context object for machine code objects.
Definition: MCContext.h:83
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:416
const MCAsmInfo * getAsmInfo() const
Definition: MCContext.h:412
void reportError(SMLoc L, const Twine &Msg)
Definition: MCContext.cpp:1073
Fragment for data and encoded instructions.
Definition: MCFragment.h:213
void changeSection(MCSection *Section, uint32_t Subsection=0) override
This is called by popSection and switchSection, if the current section changes.
void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc()) override
Emit the expression Value into the output as a native integer of the given Size bytes.
void emitAssemblerFlag(MCAssemblerFlag Flag) override
Note in the output the specified Flag.
void reset() override
state management
Definition: MCELFStreamer.h:41
void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc()) override
Emit a label for Symbol into the current section.
bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override
Add the given Attribute to Symbol.
void emitLabelAtPos(MCSymbol *Symbol, SMLoc Loc, MCDataFragment &F, uint64_t Offset) override
SmallVectorImpl< MCFixup > & getFixups()
Definition: MCFragment.h:200
SmallVectorImpl< char > & getContents()
Definition: MCFragment.h:193
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:34
static MCFixupKind getKindForSize(unsigned Size, bool IsPCRel)
Return the generic fixup kind for a value with the given size.
Definition: MCFixup.h:109
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
Definition: MCInstPrinter.h:46
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
MCSection * getTextSection() const
void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc=SMLoc()) override
Emit Size bytes worth of the value specified by FillValue.
MCDataFragment * getOrCreateDataFragment(const MCSubtargetInfo *STI=nullptr)
Get a data fragment to write into, creating a new one if the current fragment is not a data fragment.
MCAssembler & getAssembler()
void emitBytes(StringRef Data) override
Emit the bytes in Data into the output.
void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override
Emit the given Instruction into the current section.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:27
unsigned getUniqueID() const
Definition: MCSectionELF.h:94
const MCSymbolELF * getGroup() const
Definition: MCSectionELF.h:84
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:36
StringRef getName() const
Definition: MCSection.h:130
MCSymbol * getBeginSymbol()
Definition: MCSection.h:135
Streaming machine code generation interface.
Definition: MCStreamer.h:215
MCFragment * getCurrentFragment() const
Definition: MCStreamer.h:423
MCContext & getContext() const
Definition: MCStreamer.h:308
MCSectionSubPair getCurrentSection() const
Return the current section that the streamer is emitting code to.
Definition: MCStreamer.h:407
Generic base class for all target subtargets.
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
const MCSymbol & getSymbol() const
Definition: MCExpr.h:411
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:398
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
StringRef getName() const
getName - Get the symbol name.
Definition: MCSymbol.h:205
MCSection & getSection() const
Get the section associated with a defined, non-absolute symbol.
Definition: MCSymbol.h:269
Target specific streamer interface.
Definition: MCStreamer.h:94
virtual void finish()
Definition: MCStreamer.cpp:55
MCStreamer & getStreamer()
Definition: MCStreamer.h:102
virtual void emitLabel(MCSymbol *Symbol)
Definition: MCStreamer.cpp:53
Represents a location in source code.
Definition: SMLoc.h:23
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
static SectionKind getData()
Definition: SectionKind.h:213
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Twine utohexstr(const uint64_t &Val)
Definition: Twine.h:416
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:5066
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.
const TagNameMap & getARMAttributeTags()
@ EXIDX_CANTUNWIND
Special entry for the function never unwind.
Definition: ARMEHABI.h:35
StringRef getArchExtName(uint64_t ArchExtKind)
StringRef getCPUAttr(ArchKind AK)
StringRef getArchName(ArchKind AK)
unsigned getArchAttr(ArchKind AK)
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.
Definition: BitmaskEnum.h:125
StringRef attrTypeAsString(unsigned attr, TagNameMap tagNameMap, bool hasTagPrefix=true)
@ EF_ARM_EABI_VER5
Definition: ELF.h:450
@ SHT_PROGBITS
Definition: ELF.h:1108
@ SHT_ARM_ATTRIBUTES
Definition: ELF.h:1168
@ SHT_ARM_EXIDX
Definition: ELF.h:1164
@ SHF_ALLOC
Definition: ELF.h:1208
@ SHF_LINK_ORDER
Definition: ELF.h:1223
@ SHF_GROUP
Definition: ELF.h:1230
@ SHF_ARM_PURECODE
Definition: ELF.h:1303
@ STB_LOCAL
Definition: ELF.h:1361
@ STT_FUNC
Definition: ELF.h:1375
@ STT_NOTYPE
Definition: ELF.h:1373
@ STT_GNU_IFUNC
Definition: ELF.h:1380
Reg
All possible values of the reg field in the ModR/M byte.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
MCELFStreamer * createARMELFStreamer(MCContext &Context, std::unique_ptr< MCAsmBackend > TAB, std::unique_ptr< MCObjectWriter > OW, std::unique_ptr< MCCodeEmitter > Emitter, bool IsThumb, bool IsAndroid)
MCTargetStreamer * createARMObjectTargetELFStreamer(MCStreamer &S)
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:1664
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
@ FK_Data_4
A four-byte fixup.
Definition: MCFixup.h:25
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
MCAssemblerFlag
Definition: MCDirectives.h:53
@ MCAF_SyntaxUnified
.syntax (ARM/ELF)
Definition: MCDirectives.h:54
@ MCAF_Code64
.code64 (X86)
Definition: MCDirectives.h:58
@ MCAF_Code16
.code16 (X86) / .code 16 (ARM)
Definition: MCDirectives.h:56
@ MCAF_Code32
.code32 (X86) / .code 32 (ARM)
Definition: MCDirectives.h:57
@ MCAF_SubsectionsViaSymbols
.subsections_via_symbols (MachO)
Definition: MCDirectives.h:55
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:1873
static const char * ARMCondCodeToString(ARMCC::CondCodes CC)
Definition: ARMBaseInfo.h:146
MCTargetStreamer * createARMNullTargetStreamer(MCStreamer &S)
MCTargetStreamer * createARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint)
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
ELF object attributes section emission support.
Definition: MCELFStreamer.h:94