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