1 //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file assembles .s files and emits ARM ELF .o object files. Different
10 // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
11 // delimit regions of data and code.
13 //===----------------------------------------------------------------------===//
15 #include "ARMMCTargetDesc.h"
16 #include "ARMUnwindOpAsm.h"
17 #include "Utils/ARMBaseInfo.h"
18 #include "llvm/ADT/DenseMap.h"
19 #include "llvm/ADT/SmallString.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/ADT/StringRef.h"
23 #include "llvm/ADT/Twine.h"
24 #include "llvm/BinaryFormat/ELF.h"
25 #include "llvm/MC/MCAsmBackend.h"
26 #include "llvm/MC/MCAsmInfo.h"
27 #include "llvm/MC/MCAssembler.h"
28 #include "llvm/MC/MCCodeEmitter.h"
29 #include "llvm/MC/MCContext.h"
30 #include "llvm/MC/MCELFObjectWriter.h"
31 #include "llvm/MC/MCELFStreamer.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"
36 #include "llvm/MC/MCInstPrinter.h"
37 #include "llvm/MC/MCObjectFileInfo.h"
38 #include "llvm/MC/MCObjectWriter.h"
39 #include "llvm/MC/MCRegisterInfo.h"
40 #include "llvm/MC/MCSection.h"
41 #include "llvm/MC/MCSectionELF.h"
42 #include "llvm/MC/MCStreamer.h"
43 #include "llvm/MC/MCSubtargetInfo.h"
44 #include "llvm/MC/MCSymbol.h"
45 #include "llvm/MC/MCSymbolELF.h"
46 #include "llvm/MC/SectionKind.h"
47 #include "llvm/Support/ARMBuildAttributes.h"
48 #include "llvm/Support/ARMEHABI.h"
49 #include "llvm/Support/Casting.h"
50 #include "llvm/Support/ErrorHandling.h"
51 #include "llvm/Support/FormattedStream.h"
52 #include "llvm/Support/raw_ostream.h"
60 static std::string
GetAEABIUnwindPersonalityName(unsigned Index
) {
61 assert(Index
< ARM::EHABI::NUM_PERSONALITY_INDEX
&&
62 "Invalid personality index");
63 return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index
)).str();
70 class ARMTargetAsmStreamer
: public ARMTargetStreamer
{
71 formatted_raw_ostream
&OS
;
72 MCInstPrinter
&InstPrinter
;
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
;
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
;
102 void annotateTLSDescriptorSequence(const MCSymbolRefExpr
*SRE
) override
;
103 void emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
105 void emitARMWinCFIAllocStack(unsigned Size
, bool Wide
) override
;
106 void emitARMWinCFISaveRegMask(unsigned Mask
, bool Wide
) override
;
107 void emitARMWinCFISaveSP(unsigned Reg
) override
;
108 void emitARMWinCFISaveFRegs(unsigned First
, unsigned Last
) override
;
109 void emitARMWinCFISaveLR(unsigned Offset
) override
;
110 void emitARMWinCFIPrologEnd(bool Fragment
) override
;
111 void emitARMWinCFINop(bool Wide
) override
;
112 void emitARMWinCFIEpilogStart(unsigned Condition
) override
;
113 void emitARMWinCFIEpilogEnd() override
;
114 void emitARMWinCFICustom(unsigned Opcode
) override
;
117 ARMTargetAsmStreamer(MCStreamer
&S
, formatted_raw_ostream
&OS
,
118 MCInstPrinter
&InstPrinter
);
121 ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer
&S
,
122 formatted_raw_ostream
&OS
,
123 MCInstPrinter
&InstPrinter
)
124 : ARMTargetStreamer(S
), OS(OS
), InstPrinter(InstPrinter
),
125 IsVerboseAsm(S
.isVerboseAsm()) {}
127 void ARMTargetAsmStreamer::emitFnStart() { OS
<< "\t.fnstart\n"; }
128 void ARMTargetAsmStreamer::emitFnEnd() { OS
<< "\t.fnend\n"; }
129 void ARMTargetAsmStreamer::emitCantUnwind() { OS
<< "\t.cantunwind\n"; }
131 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol
*Personality
) {
132 OS
<< "\t.personality " << Personality
->getName() << '\n';
135 void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index
) {
136 OS
<< "\t.personalityindex " << Index
<< '\n';
139 void ARMTargetAsmStreamer::emitHandlerData() { OS
<< "\t.handlerdata\n"; }
141 void ARMTargetAsmStreamer::emitSetFP(MCRegister FpReg
, MCRegister SpReg
,
144 InstPrinter
.printRegName(OS
, FpReg
);
146 InstPrinter
.printRegName(OS
, SpReg
);
148 OS
<< ", #" << Offset
;
152 void ARMTargetAsmStreamer::emitMovSP(MCRegister Reg
, int64_t Offset
) {
153 assert((Reg
!= ARM::SP
&& Reg
!= ARM::PC
) &&
154 "the operand of .movsp cannot be either sp or pc");
157 InstPrinter
.printRegName(OS
, Reg
);
159 OS
<< ", #" << Offset
;
163 void ARMTargetAsmStreamer::emitPad(int64_t Offset
) {
164 OS
<< "\t.pad\t#" << Offset
<< '\n';
167 void ARMTargetAsmStreamer::emitRegSave(
168 const SmallVectorImpl
<MCRegister
> &RegList
, bool isVector
) {
169 assert(RegList
.size() && "RegList should not be empty");
175 InstPrinter
.printRegName(OS
, RegList
[0]);
177 for (unsigned i
= 1, e
= RegList
.size(); i
!= e
; ++i
) {
179 InstPrinter
.printRegName(OS
, RegList
[i
]);
185 void ARMTargetAsmStreamer::switchVendor(StringRef Vendor
) {}
187 void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
188 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", " << Twine(Value
);
190 StringRef Name
= ELFAttrs::attrTypeAsString(
191 Attribute
, ARMBuildAttrs::getARMAttributeTags());
193 OS
<< "\t@ " << Name
;
198 void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute
,
201 case ARMBuildAttrs::CPU_name
:
202 OS
<< "\t.cpu\t" << String
.lower();
205 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", \"";
206 if (Attribute
== ARMBuildAttrs::also_compatible_with
)
207 OS
.write_escaped(String
);
212 StringRef Name
= ELFAttrs::attrTypeAsString(
213 Attribute
, ARMBuildAttrs::getARMAttributeTags());
215 OS
<< "\t@ " << Name
;
222 void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute
,
224 StringRef StringValue
) {
226 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
227 case ARMBuildAttrs::compatibility
:
228 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", " << IntValue
;
229 if (!StringValue
.empty())
230 OS
<< ", \"" << StringValue
<< "\"";
233 << ELFAttrs::attrTypeAsString(Attribute
,
234 ARMBuildAttrs::getARMAttributeTags());
240 void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch
) {
241 OS
<< "\t.arch\t" << ARM::getArchName(Arch
) << "\n";
244 void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt
) {
245 OS
<< "\t.arch_extension\t" << ARM::getArchExtName(ArchExt
) << "\n";
248 void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch
) {
249 OS
<< "\t.object_arch\t" << ARM::getArchName(Arch
) << '\n';
252 void ARMTargetAsmStreamer::emitFPU(ARM::FPUKind FPU
) {
253 OS
<< "\t.fpu\t" << ARM::getFPUName(FPU
) << "\n";
256 void ARMTargetAsmStreamer::finishAttributeSection() {}
258 void ARMTargetAsmStreamer::annotateTLSDescriptorSequence(
259 const MCSymbolRefExpr
*S
) {
260 OS
<< "\t.tlsdescseq\t" << S
->getSymbol().getName() << "\n";
263 void ARMTargetAsmStreamer::emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) {
264 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
266 OS
<< "\t.thumb_set\t";
267 Symbol
->print(OS
, MAI
);
269 Value
->print(OS
, MAI
);
273 void ARMTargetAsmStreamer::emitInst(uint32_t Inst
, char Suffix
) {
277 OS
<< "\t0x" << Twine::utohexstr(Inst
) << "\n";
280 void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset
,
281 const SmallVectorImpl
<uint8_t> &Opcodes
) {
282 OS
<< "\t.unwind_raw " << Offset
;
283 for (uint8_t Opcode
: Opcodes
)
284 OS
<< ", 0x" << Twine::utohexstr(Opcode
);
288 void ARMTargetAsmStreamer::emitARMWinCFIAllocStack(unsigned Size
, bool Wide
) {
290 OS
<< "\t.seh_stackalloc_w\t" << Size
<< "\n";
292 OS
<< "\t.seh_stackalloc\t" << Size
<< "\n";
295 static void printRegs(formatted_raw_ostream
&OS
, ListSeparator
&LS
, int First
,
298 OS
<< LS
<< "r" << First
<< "-r" << Last
;
300 OS
<< LS
<< "r" << First
;
303 void ARMTargetAsmStreamer::emitARMWinCFISaveRegMask(unsigned Mask
, bool Wide
) {
305 OS
<< "\t.seh_save_regs_w\t";
307 OS
<< "\t.seh_save_regs\t";
311 for (int I
= 0; I
<= 12; I
++) {
312 if (Mask
& (1 << I
)) {
317 printRegs(OS
, LS
, First
, I
- 1);
323 printRegs(OS
, LS
, First
, 12);
324 if (Mask
& (1 << 14))
329 void ARMTargetAsmStreamer::emitARMWinCFISaveSP(unsigned Reg
) {
330 OS
<< "\t.seh_save_sp\tr" << Reg
<< "\n";
333 void ARMTargetAsmStreamer::emitARMWinCFISaveFRegs(unsigned First
,
336 OS
<< "\t.seh_save_fregs\t{d" << First
<< "-d" << Last
<< "}\n";
338 OS
<< "\t.seh_save_fregs\t{d" << First
<< "}\n";
341 void ARMTargetAsmStreamer::emitARMWinCFISaveLR(unsigned Offset
) {
342 OS
<< "\t.seh_save_lr\t" << Offset
<< "\n";
345 void ARMTargetAsmStreamer::emitARMWinCFIPrologEnd(bool Fragment
) {
347 OS
<< "\t.seh_endprologue_fragment\n";
349 OS
<< "\t.seh_endprologue\n";
352 void ARMTargetAsmStreamer::emitARMWinCFINop(bool Wide
) {
354 OS
<< "\t.seh_nop_w\n";
356 OS
<< "\t.seh_nop\n";
359 void ARMTargetAsmStreamer::emitARMWinCFIEpilogStart(unsigned Condition
) {
360 if (Condition
== ARMCC::AL
)
361 OS
<< "\t.seh_startepilogue\n";
363 OS
<< "\t.seh_startepilogue_cond\t"
364 << ARMCondCodeToString(static_cast<ARMCC::CondCodes
>(Condition
)) << "\n";
367 void ARMTargetAsmStreamer::emitARMWinCFIEpilogEnd() {
368 OS
<< "\t.seh_endepilogue\n";
371 void ARMTargetAsmStreamer::emitARMWinCFICustom(unsigned Opcode
) {
373 for (I
= 3; I
> 0; I
--)
374 if (Opcode
& (0xffu
<< (8 * I
)))
377 OS
<< "\t.seh_custom\t";
379 OS
<< LS
<< ((Opcode
>> (8 * I
)) & 0xff);
383 class ARMTargetELFStreamer
: public ARMTargetStreamer
{
385 StringRef CurrentVendor
;
386 ARM::FPUKind FPU
= ARM::FK_INVALID
;
387 ARM::ArchKind Arch
= ARM::ArchKind::INVALID
;
388 ARM::ArchKind EmittedArch
= ARM::ArchKind::INVALID
;
390 MCSection
*AttributeSection
= nullptr;
392 void emitArchDefaultAttributes();
393 void emitFPUDefaultAttributes();
395 ARMELFStreamer
&getStreamer();
397 void emitFnStart() override
;
398 void emitFnEnd() override
;
399 void emitCantUnwind() override
;
400 void emitPersonality(const MCSymbol
*Personality
) override
;
401 void emitPersonalityIndex(unsigned Index
) override
;
402 void emitHandlerData() override
;
403 void emitSetFP(MCRegister FpReg
, MCRegister SpReg
,
404 int64_t Offset
= 0) override
;
405 void emitMovSP(MCRegister Reg
, int64_t Offset
= 0) override
;
406 void emitPad(int64_t Offset
) override
;
407 void emitRegSave(const SmallVectorImpl
<MCRegister
> &RegList
,
408 bool isVector
) override
;
409 void emitUnwindRaw(int64_t Offset
,
410 const SmallVectorImpl
<uint8_t> &Opcodes
) override
;
412 void switchVendor(StringRef Vendor
) override
;
413 void emitAttribute(unsigned Attribute
, unsigned Value
) override
;
414 void emitTextAttribute(unsigned Attribute
, StringRef String
) override
;
415 void emitIntTextAttribute(unsigned Attribute
, unsigned IntValue
,
416 StringRef StringValue
) override
;
417 void emitArch(ARM::ArchKind Arch
) override
;
418 void emitObjectArch(ARM::ArchKind Arch
) override
;
419 void emitFPU(ARM::FPUKind FPU
) override
;
420 void emitInst(uint32_t Inst
, char Suffix
= '\0') override
;
421 void finishAttributeSection() override
;
422 void emitLabel(MCSymbol
*Symbol
) override
;
424 void annotateTLSDescriptorSequence(const MCSymbolRefExpr
*SRE
) override
;
425 void emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
427 // Reset state between object emissions
428 void reset() override
;
430 void finish() override
;
433 ARMTargetELFStreamer(MCStreamer
&S
)
434 : ARMTargetStreamer(S
), CurrentVendor("aeabi") {}
437 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
438 /// the appropriate points in the object files. These symbols are defined in the
439 /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
441 /// In brief: $a, $t or $d should be emitted at the start of each contiguous
442 /// region of ARM code, Thumb code or data in a section. In practice, this
443 /// emission does not rely on explicit assembler directives but on inherent
444 /// properties of the directives doing the emission (e.g. ".byte" is data, "add
445 /// r0, r0, r0" an instruction).
447 /// As a result this system is orthogonal to the DataRegion infrastructure used
448 /// by MachO. Beware!
449 class ARMELFStreamer
: public MCELFStreamer
{
451 friend class ARMTargetELFStreamer
;
453 ARMELFStreamer(MCContext
&Context
, std::unique_ptr
<MCAsmBackend
> TAB
,
454 std::unique_ptr
<MCObjectWriter
> OW
,
455 std::unique_ptr
<MCCodeEmitter
> Emitter
, bool IsThumb
,
457 : MCELFStreamer(Context
, std::move(TAB
), std::move(OW
),
459 IsThumb(IsThumb
), IsAndroid(IsAndroid
) {
463 ~ARMELFStreamer() override
= default;
465 // ARM exception handling directives
468 void emitCantUnwind();
469 void emitPersonality(const MCSymbol
*Per
);
470 void emitPersonalityIndex(unsigned index
);
471 void emitHandlerData();
472 void emitSetFP(MCRegister NewFpReg
, MCRegister NewSpReg
, int64_t Offset
= 0);
473 void emitMovSP(MCRegister Reg
, int64_t Offset
= 0);
474 void emitPad(int64_t Offset
);
475 void emitRegSave(const SmallVectorImpl
<MCRegister
> &RegList
, bool isVector
);
476 void emitUnwindRaw(int64_t Offset
, const SmallVectorImpl
<uint8_t> &Opcodes
);
477 void emitFill(const MCExpr
&NumBytes
, uint64_t FillValue
,
478 SMLoc Loc
) override
{
479 emitDataMappingSymbol();
480 MCObjectStreamer::emitFill(NumBytes
, FillValue
, Loc
);
483 void changeSection(MCSection
*Section
, uint32_t Subsection
) override
{
484 LastMappingSymbols
[getCurrentSection().first
] = std::move(LastEMSInfo
);
485 MCELFStreamer::changeSection(Section
, Subsection
);
486 auto LastMappingSymbol
= LastMappingSymbols
.find(Section
);
487 if (LastMappingSymbol
!= LastMappingSymbols
.end()) {
488 LastEMSInfo
= std::move(LastMappingSymbol
->second
);
491 LastEMSInfo
.reset(new ElfMappingSymbolInfo
);
494 /// This function is the one used to emit instruction data into the ELF
495 /// streamer. We override it to add the appropriate mapping symbol if
497 void emitInstruction(const MCInst
&Inst
,
498 const MCSubtargetInfo
&STI
) override
{
500 EmitThumbMappingSymbol();
502 EmitARMMappingSymbol();
504 MCELFStreamer::emitInstruction(Inst
, STI
);
507 void emitInst(uint32_t Inst
, char Suffix
) {
510 const bool LittleEndian
= getContext().getAsmInfo()->isLittleEndian();
517 EmitARMMappingSymbol();
518 for (unsigned II
= 0, IE
= Size
; II
!= IE
; II
++) {
519 const unsigned I
= LittleEndian
? (Size
- II
- 1) : II
;
520 Buffer
[Size
- II
- 1] = uint8_t(Inst
>> I
* CHAR_BIT
);
526 Size
= (Suffix
== 'n' ? 2 : 4);
529 EmitThumbMappingSymbol();
530 // Thumb wide instructions are emitted as a pair of 16-bit words of the
531 // appropriate endianness.
532 for (unsigned II
= 0, IE
= Size
; II
!= IE
; II
= II
+ 2) {
533 const unsigned I0
= LittleEndian
? II
+ 0 : II
+ 1;
534 const unsigned I1
= LittleEndian
? II
+ 1 : II
+ 0;
535 Buffer
[Size
- II
- 2] = uint8_t(Inst
>> I0
* CHAR_BIT
);
536 Buffer
[Size
- II
- 1] = uint8_t(Inst
>> I1
* CHAR_BIT
);
541 llvm_unreachable("Invalid Suffix");
544 MCELFStreamer::emitBytes(StringRef(Buffer
, Size
));
547 /// This is one of the functions used to emit data into an ELF section, so the
548 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
550 void emitBytes(StringRef Data
) override
{
551 emitDataMappingSymbol();
552 MCELFStreamer::emitBytes(Data
);
555 void FlushPendingMappingSymbol() {
556 if (!LastEMSInfo
->hasInfo())
558 ElfMappingSymbolInfo
*EMS
= LastEMSInfo
.get();
559 emitMappingSymbol("$d", *EMS
->F
, EMS
->Offset
);
563 /// This is one of the functions used to emit data into an ELF section, so the
564 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
566 void emitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) override
{
567 if (const MCSymbolRefExpr
*SRE
= dyn_cast_or_null
<MCSymbolRefExpr
>(Value
)) {
568 if (SRE
->getKind() == MCSymbolRefExpr::VK_ARM_SBREL
&& !(Size
== 4)) {
569 getContext().reportError(Loc
, "relocated expression must be 32-bit");
572 getOrCreateDataFragment();
575 emitDataMappingSymbol();
576 MCELFStreamer::emitValueImpl(Value
, Size
, Loc
);
579 void emitAssemblerFlag(MCAssemblerFlag Flag
) override
{
580 MCELFStreamer::emitAssemblerFlag(Flag
);
583 case MCAF_SyntaxUnified
:
584 return; // no-op here.
587 return; // Change to Thumb mode
590 return; // Change to ARM mode
593 case MCAF_SubsectionsViaSymbols
:
598 /// If a label is defined before the .type directive sets the label's type
599 /// then the label can't be recorded as thumb function when the label is
600 /// defined. We override emitSymbolAttribute() which is called as part of the
601 /// parsing of .type so that if the symbol has already been defined we can
602 /// record the label as Thumb. FIXME: there is a corner case where the state
603 /// is changed in between the label definition and the .type directive, this
604 /// is not expected to occur in practice and handling it would require the
605 /// backend to track IsThumb for every label.
606 bool emitSymbolAttribute(MCSymbol
*Symbol
, MCSymbolAttr Attribute
) override
{
607 bool Val
= MCELFStreamer::emitSymbolAttribute(Symbol
, Attribute
);
612 unsigned Type
= cast
<MCSymbolELF
>(Symbol
)->getType();
613 if ((Type
== ELF::STT_FUNC
|| Type
== ELF::STT_GNU_IFUNC
) &&
615 getAssembler().setIsThumbFunc(Symbol
);
621 enum ElfMappingSymbol
{
628 struct ElfMappingSymbolInfo
{
633 bool hasInfo() { return F
!= nullptr; }
634 MCDataFragment
*F
= nullptr;
636 ElfMappingSymbol State
= EMS_None
;
639 void emitDataMappingSymbol() {
640 if (LastEMSInfo
->State
== EMS_Data
)
642 else if (LastEMSInfo
->State
== EMS_None
) {
643 // This is a tentative symbol, it won't really be emitted until it's
645 ElfMappingSymbolInfo
*EMS
= LastEMSInfo
.get();
646 auto *DF
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
650 EMS
->Offset
= DF
->getContents().size();
651 LastEMSInfo
->State
= EMS_Data
;
654 EmitMappingSymbol("$d");
655 LastEMSInfo
->State
= EMS_Data
;
658 void EmitThumbMappingSymbol() {
659 if (LastEMSInfo
->State
== EMS_Thumb
)
661 FlushPendingMappingSymbol();
662 EmitMappingSymbol("$t");
663 LastEMSInfo
->State
= EMS_Thumb
;
666 void EmitARMMappingSymbol() {
667 if (LastEMSInfo
->State
== EMS_ARM
)
669 FlushPendingMappingSymbol();
670 EmitMappingSymbol("$a");
671 LastEMSInfo
->State
= EMS_ARM
;
674 void EmitMappingSymbol(StringRef Name
) {
675 auto *Symbol
= cast
<MCSymbolELF
>(getContext().createLocalSymbol(Name
));
678 Symbol
->setType(ELF::STT_NOTYPE
);
679 Symbol
->setBinding(ELF::STB_LOCAL
);
682 void emitMappingSymbol(StringRef Name
, MCDataFragment
&F
, uint64_t Offset
) {
683 auto *Symbol
= cast
<MCSymbolELF
>(getContext().createLocalSymbol(Name
));
684 emitLabelAtPos(Symbol
, SMLoc(), F
, Offset
);
685 Symbol
->setType(ELF::STT_NOTYPE
);
686 Symbol
->setBinding(ELF::STB_LOCAL
);
689 void emitThumbFunc(MCSymbol
*Func
) override
{
690 getAssembler().setIsThumbFunc(Func
);
691 emitSymbolAttribute(Func
, MCSA_ELF_TypeFunction
);
694 // Helper functions for ARM exception handling directives
697 // Reset state between object emissions
698 void reset() override
;
700 void EmitPersonalityFixup(StringRef Name
);
701 void FlushPendingOffset();
702 void FlushUnwindOpcodes(bool NoHandlerData
);
704 void SwitchToEHSection(StringRef Prefix
, unsigned Type
, unsigned Flags
,
705 SectionKind Kind
, const MCSymbol
&Fn
);
706 void SwitchToExTabSection(const MCSymbol
&FnStart
);
707 void SwitchToExIdxSection(const MCSymbol
&FnStart
);
709 void EmitFixup(const MCExpr
*Expr
, MCFixupKind Kind
);
714 DenseMap
<const MCSection
*, std::unique_ptr
<ElfMappingSymbolInfo
>>
717 std::unique_ptr
<ElfMappingSymbolInfo
> LastEMSInfo
;
719 // ARM Exception Handling Frame Information
722 const MCSymbol
*Personality
;
723 unsigned PersonalityIndex
;
724 MCRegister FPReg
; // Frame pointer register
725 int64_t FPOffset
; // Offset: (final frame pointer) - (initial $sp)
726 int64_t SPOffset
; // Offset: (final $sp) - (initial $sp)
727 int64_t PendingOffset
; // Offset: (final $sp) - (emitted $sp)
730 SmallVector
<uint8_t, 64> Opcodes
;
731 UnwindOpcodeAssembler UnwindOpAsm
;
734 } // end anonymous namespace
736 ARMELFStreamer
&ARMTargetELFStreamer::getStreamer() {
737 return static_cast<ARMELFStreamer
&>(Streamer
);
740 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
741 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
742 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
744 void ARMTargetELFStreamer::emitPersonality(const MCSymbol
*Personality
) {
745 getStreamer().emitPersonality(Personality
);
748 void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index
) {
749 getStreamer().emitPersonalityIndex(Index
);
752 void ARMTargetELFStreamer::emitHandlerData() {
753 getStreamer().emitHandlerData();
756 void ARMTargetELFStreamer::emitSetFP(MCRegister FpReg
, MCRegister SpReg
,
758 getStreamer().emitSetFP(FpReg
, SpReg
, Offset
);
761 void ARMTargetELFStreamer::emitMovSP(MCRegister Reg
, int64_t Offset
) {
762 getStreamer().emitMovSP(Reg
, Offset
);
765 void ARMTargetELFStreamer::emitPad(int64_t Offset
) {
766 getStreamer().emitPad(Offset
);
769 void ARMTargetELFStreamer::emitRegSave(
770 const SmallVectorImpl
<MCRegister
> &RegList
, bool isVector
) {
771 getStreamer().emitRegSave(RegList
, isVector
);
774 void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset
,
775 const SmallVectorImpl
<uint8_t> &Opcodes
) {
776 getStreamer().emitUnwindRaw(Offset
, Opcodes
);
779 void ARMTargetELFStreamer::switchVendor(StringRef Vendor
) {
780 assert(!Vendor
.empty() && "Vendor cannot be empty.");
782 if (CurrentVendor
== Vendor
)
785 if (!CurrentVendor
.empty())
786 finishAttributeSection();
788 assert(getStreamer().Contents
.empty() &&
789 ".ARM.attributes should be flushed before changing vendor");
790 CurrentVendor
= Vendor
;
794 void ARMTargetELFStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
795 getStreamer().setAttributeItem(Attribute
, Value
,
796 /* OverwriteExisting= */ true);
799 void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute
,
801 getStreamer().setAttributeItem(Attribute
, Value
,
802 /* OverwriteExisting= */ true);
805 void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute
,
807 StringRef StringValue
) {
808 getStreamer().setAttributeItems(Attribute
, IntValue
, StringValue
,
809 /* OverwriteExisting= */ true);
812 void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value
) {
816 void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value
) {
820 void ARMTargetELFStreamer::emitArchDefaultAttributes() {
821 using namespace ARMBuildAttrs
;
822 ARMELFStreamer
&S
= getStreamer();
824 S
.setAttributeItem(CPU_name
, ARM::getCPUAttr(Arch
), false);
826 if (EmittedArch
== ARM::ArchKind::INVALID
)
827 S
.setAttributeItem(CPU_arch
, ARM::getArchAttr(Arch
), false);
829 S
.setAttributeItem(CPU_arch
, ARM::getArchAttr(EmittedArch
), false);
832 case ARM::ArchKind::ARMV4
:
833 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
836 case ARM::ArchKind::ARMV4T
:
837 case ARM::ArchKind::ARMV5T
:
838 case ARM::ArchKind::XSCALE
:
839 case ARM::ArchKind::ARMV5TE
:
840 case ARM::ArchKind::ARMV6
:
841 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
842 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
845 case ARM::ArchKind::ARMV6T2
:
846 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
847 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
850 case ARM::ArchKind::ARMV6K
:
851 case ARM::ArchKind::ARMV6KZ
:
852 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
853 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
854 S
.setAttributeItem(Virtualization_use
, AllowTZ
, false);
857 case ARM::ArchKind::ARMV6M
:
858 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
861 case ARM::ArchKind::ARMV7A
:
862 S
.setAttributeItem(CPU_arch_profile
, ApplicationProfile
, false);
863 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
864 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
867 case ARM::ArchKind::ARMV7R
:
868 S
.setAttributeItem(CPU_arch_profile
, RealTimeProfile
, false);
869 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
870 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
873 case ARM::ArchKind::ARMV7EM
:
874 case ARM::ArchKind::ARMV7M
:
875 S
.setAttributeItem(CPU_arch_profile
, MicroControllerProfile
, false);
876 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
879 case ARM::ArchKind::ARMV8A
:
880 case ARM::ArchKind::ARMV8_1A
:
881 case ARM::ArchKind::ARMV8_2A
:
882 case ARM::ArchKind::ARMV8_3A
:
883 case ARM::ArchKind::ARMV8_4A
:
884 case ARM::ArchKind::ARMV8_5A
:
885 case ARM::ArchKind::ARMV8_6A
:
886 case ARM::ArchKind::ARMV8_7A
:
887 case ARM::ArchKind::ARMV8_8A
:
888 case ARM::ArchKind::ARMV8_9A
:
889 case ARM::ArchKind::ARMV9A
:
890 case ARM::ArchKind::ARMV9_1A
:
891 case ARM::ArchKind::ARMV9_2A
:
892 case ARM::ArchKind::ARMV9_3A
:
893 case ARM::ArchKind::ARMV9_4A
:
894 case ARM::ArchKind::ARMV9_5A
:
895 case ARM::ArchKind::ARMV9_6A
:
896 S
.setAttributeItem(CPU_arch_profile
, ApplicationProfile
, false);
897 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
898 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
899 S
.setAttributeItem(MPextension_use
, Allowed
, false);
900 S
.setAttributeItem(Virtualization_use
, AllowTZVirtualization
, false);
903 case ARM::ArchKind::ARMV8MBaseline
:
904 case ARM::ArchKind::ARMV8MMainline
:
905 S
.setAttributeItem(THUMB_ISA_use
, AllowThumbDerived
, false);
906 S
.setAttributeItem(CPU_arch_profile
, MicroControllerProfile
, false);
909 case ARM::ArchKind::IWMMXT
:
910 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
911 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
912 S
.setAttributeItem(WMMX_arch
, AllowWMMXv1
, false);
915 case ARM::ArchKind::IWMMXT2
:
916 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
917 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
918 S
.setAttributeItem(WMMX_arch
, AllowWMMXv2
, false);
922 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch
)));
927 void ARMTargetELFStreamer::emitFPU(ARM::FPUKind Value
) { FPU
= Value
; }
929 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
930 ARMELFStreamer
&S
= getStreamer();
935 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv2
,
936 /* OverwriteExisting= */ false);
940 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
941 /* OverwriteExisting= */ false);
944 case ARM::FK_VFPV3_FP16
:
945 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
946 /* OverwriteExisting= */ false);
947 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
948 /* OverwriteExisting= */ false);
951 case ARM::FK_VFPV3_D16
:
952 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
953 /* OverwriteExisting= */ false);
956 case ARM::FK_VFPV3_D16_FP16
:
957 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
958 /* OverwriteExisting= */ false);
959 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
960 /* OverwriteExisting= */ false);
963 case ARM::FK_VFPV3XD
:
964 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
965 /* OverwriteExisting= */ false);
967 case ARM::FK_VFPV3XD_FP16
:
968 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
969 /* OverwriteExisting= */ false);
970 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
971 /* OverwriteExisting= */ false);
975 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4A
,
976 /* OverwriteExisting= */ false);
979 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
981 case ARM::FK_FPV4_SP_D16
:
982 case ARM::FK_VFPV4_D16
:
983 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4B
,
984 /* OverwriteExisting= */ false);
987 case ARM::FK_FP_ARMV8
:
988 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8A
,
989 /* OverwriteExisting= */ false);
992 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
993 // uses the FP_ARMV8_D16 build attribute.
994 case ARM::FK_FPV5_SP_D16
:
995 case ARM::FK_FPV5_D16
:
996 // FPv5 and FP-ARMv8 have the same instructions, so are modeled as one
997 // FPU, but there are two different names for it depending on the CPU.
998 case ARM::FK_FP_ARMV8_FULLFP16_SP_D16
:
999 case ARM::FK_FP_ARMV8_FULLFP16_D16
:
1000 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8B
,
1001 /* OverwriteExisting= */ false);
1005 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
1006 /* OverwriteExisting= */ false);
1007 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
1008 ARMBuildAttrs::AllowNeon
,
1009 /* OverwriteExisting= */ false);
1012 case ARM::FK_NEON_FP16
:
1013 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
1014 /* OverwriteExisting= */ false);
1015 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
1016 ARMBuildAttrs::AllowNeon
,
1017 /* OverwriteExisting= */ false);
1018 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
1019 /* OverwriteExisting= */ false);
1022 case ARM::FK_NEON_VFPV4
:
1023 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4A
,
1024 /* OverwriteExisting= */ false);
1025 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
1026 ARMBuildAttrs::AllowNeon2
,
1027 /* OverwriteExisting= */ false);
1030 case ARM::FK_NEON_FP_ARMV8
:
1031 case ARM::FK_CRYPTO_NEON_FP_ARMV8
:
1032 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8A
,
1033 /* OverwriteExisting= */ false);
1034 // 'Advanced_SIMD_arch' must be emitted not here, but within
1035 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
1038 case ARM::FK_SOFTVFP
:
1043 report_fatal_error("Unknown FPU: " + Twine(FPU
));
1048 void ARMTargetELFStreamer::finishAttributeSection() {
1049 ARMELFStreamer
&S
= getStreamer();
1051 if (FPU
!= ARM::FK_INVALID
)
1052 emitFPUDefaultAttributes();
1054 if (Arch
!= ARM::ArchKind::INVALID
)
1055 emitArchDefaultAttributes();
1057 if (S
.Contents
.empty())
1060 auto LessTag
= [](const MCELFStreamer::AttributeItem
&LHS
,
1061 const MCELFStreamer::AttributeItem
&RHS
) -> bool {
1062 // The conformance tag must be emitted first when serialised into an
1063 // object file. Specifically, the addenda to the ARM ABI states that
1066 // "To simplify recognition by consumers in the common case of claiming
1067 // conformity for the whole file, this tag should be emitted first in a
1068 // file-scope sub-subsection of the first public subsection of the
1069 // attributes section."
1071 // So it is special-cased in this comparison predicate when the
1072 // attributes are sorted in finishAttributeSection().
1073 return (RHS
.Tag
!= ARMBuildAttrs::conformance
) &&
1074 ((LHS
.Tag
== ARMBuildAttrs::conformance
) || (LHS
.Tag
< RHS
.Tag
));
1076 llvm::sort(S
.Contents
, LessTag
);
1078 S
.emitAttributesSection(CurrentVendor
, ".ARM.attributes",
1079 ELF::SHT_ARM_ATTRIBUTES
, AttributeSection
);
1081 FPU
= ARM::FK_INVALID
;
1084 void ARMTargetELFStreamer::emitLabel(MCSymbol
*Symbol
) {
1085 ARMELFStreamer
&Streamer
= getStreamer();
1086 if (!Streamer
.IsThumb
)
1089 Streamer
.getAssembler().registerSymbol(*Symbol
);
1090 unsigned Type
= cast
<MCSymbolELF
>(Symbol
)->getType();
1091 if (Type
== ELF::STT_FUNC
|| Type
== ELF::STT_GNU_IFUNC
)
1092 Streamer
.emitThumbFunc(Symbol
);
1095 void ARMTargetELFStreamer::annotateTLSDescriptorSequence(
1096 const MCSymbolRefExpr
*S
) {
1097 getStreamer().EmitFixup(S
, FK_Data_4
);
1100 void ARMTargetELFStreamer::emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) {
1101 if (const MCSymbolRefExpr
*SRE
= dyn_cast
<MCSymbolRefExpr
>(Value
)) {
1102 const MCSymbol
&Sym
= SRE
->getSymbol();
1103 if (!Sym
.isDefined()) {
1104 getStreamer().emitAssignment(Symbol
, Value
);
1109 getStreamer().emitThumbFunc(Symbol
);
1110 getStreamer().emitAssignment(Symbol
, Value
);
1113 void ARMTargetELFStreamer::emitInst(uint32_t Inst
, char Suffix
) {
1114 getStreamer().emitInst(Inst
, Suffix
);
1117 void ARMTargetELFStreamer::reset() { AttributeSection
= nullptr; }
1119 void ARMTargetELFStreamer::finish() {
1120 ARMTargetStreamer::finish();
1121 finishAttributeSection();
1123 // The mix of execute-only and non-execute-only at link time is
1124 // non-execute-only. To avoid the empty implicitly created .text
1125 // section from making the whole .text section non-execute-only, we
1126 // mark it execute-only if it is empty and there is at least one
1127 // execute-only section in the object.
1128 MCContext
&Ctx
= getStreamer().getContext();
1129 auto &Asm
= getStreamer().getAssembler();
1130 if (any_of(Asm
, [](const MCSection
&Sec
) {
1131 return cast
<MCSectionELF
>(Sec
).getFlags() & ELF::SHF_ARM_PURECODE
;
1134 static_cast<MCSectionELF
*>(Ctx
.getObjectFileInfo()->getTextSection());
1135 for (auto &F
: *Text
)
1136 if (auto *DF
= dyn_cast
<MCDataFragment
>(&F
))
1137 if (!DF
->getContents().empty())
1139 Text
->setFlags(Text
->getFlags() | ELF::SHF_ARM_PURECODE
);
1143 void ARMELFStreamer::reset() {
1144 MCTargetStreamer
&TS
= *getTargetStreamer();
1145 ARMTargetStreamer
&ATS
= static_cast<ARMTargetStreamer
&>(TS
);
1147 MCELFStreamer::reset();
1148 LastMappingSymbols
.clear();
1149 LastEMSInfo
.reset();
1150 // MCELFStreamer clear's the assembler's e_flags. However, for
1151 // arm we manually set the ABI version on streamer creation, so
1153 getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5
);
1156 inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix
,
1160 const MCSymbol
&Fn
) {
1161 const MCSectionELF
&FnSection
=
1162 static_cast<const MCSectionELF
&>(Fn
.getSection());
1164 // Create the name for new section
1165 StringRef
FnSecName(FnSection
.getName());
1166 SmallString
<128> EHSecName(Prefix
);
1167 if (FnSecName
!= ".text") {
1168 EHSecName
+= FnSecName
;
1171 // Get .ARM.extab or .ARM.exidx section
1172 const MCSymbolELF
*Group
= FnSection
.getGroup();
1174 Flags
|= ELF::SHF_GROUP
;
1175 MCSectionELF
*EHSection
= getContext().getELFSection(
1176 EHSecName
, Type
, Flags
, 0, Group
, /*IsComdat=*/true,
1177 FnSection
.getUniqueID(),
1178 static_cast<const MCSymbolELF
*>(FnSection
.getBeginSymbol()));
1180 assert(EHSection
&& "Failed to get the required EH section");
1182 // Switch to .ARM.extab or .ARM.exidx section
1183 switchSection(EHSection
);
1184 emitValueToAlignment(Align(4), 0, 1, 0);
1187 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol
&FnStart
) {
1188 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
,
1189 SectionKind::getData(), FnStart
);
1192 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol
&FnStart
) {
1193 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX
,
1194 ELF::SHF_ALLOC
| ELF::SHF_LINK_ORDER
,
1195 SectionKind::getData(), FnStart
);
1198 void ARMELFStreamer::EmitFixup(const MCExpr
*Expr
, MCFixupKind Kind
) {
1199 MCDataFragment
*Frag
= getOrCreateDataFragment();
1200 Frag
->getFixups().push_back(MCFixup::create(Frag
->getContents().size(), Expr
,
1204 void ARMELFStreamer::EHReset() {
1207 Personality
= nullptr;
1208 PersonalityIndex
= ARM::EHABI::NUM_PERSONALITY_INDEX
;
1217 UnwindOpAsm
.Reset();
1220 void ARMELFStreamer::emitFnStart() {
1221 assert(FnStart
== nullptr);
1222 FnStart
= getContext().createTempSymbol();
1226 void ARMELFStreamer::emitFnEnd() {
1227 assert(FnStart
&& ".fnstart must precedes .fnend");
1229 // Emit unwind opcodes if there is no .handlerdata directive
1230 if (!ExTab
&& !CantUnwind
)
1231 FlushUnwindOpcodes(true);
1233 // Emit the exception index table entry
1234 SwitchToExIdxSection(*FnStart
);
1236 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1237 // personality routine to protect it from an arbitrary platform's static
1238 // linker garbage collection. We disable this for Android where the unwinder
1239 // is either dynamically linked or directly references the personality
1241 if (PersonalityIndex
< ARM::EHABI::NUM_PERSONALITY_INDEX
&& !IsAndroid
)
1242 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex
));
1244 const MCSymbolRefExpr
*FnStartRef
=
1245 MCSymbolRefExpr::create(FnStart
,
1246 MCSymbolRefExpr::VK_ARM_PREL31
,
1249 emitValue(FnStartRef
, 4);
1252 emitInt32(ARM::EHABI::EXIDX_CANTUNWIND
);
1254 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1255 const MCSymbolRefExpr
*ExTabEntryRef
=
1256 MCSymbolRefExpr::create(ExTab
,
1257 MCSymbolRefExpr::VK_ARM_PREL31
,
1259 emitValue(ExTabEntryRef
, 4);
1261 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1262 // the second word of exception index table entry. The size of the unwind
1263 // opcodes should always be 4 bytes.
1264 assert(PersonalityIndex
== ARM::EHABI::AEABI_UNWIND_CPP_PR0
&&
1265 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1266 assert(Opcodes
.size() == 4u &&
1267 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1268 uint64_t Intval
= Opcodes
[0] |
1272 emitIntValue(Intval
, Opcodes
.size());
1275 // Switch to the section containing FnStart
1276 switchSection(&FnStart
->getSection());
1278 // Clean exception handling frame information
1282 void ARMELFStreamer::emitCantUnwind() { CantUnwind
= true; }
1284 // Add the R_ARM_NONE fixup at the same position
1285 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name
) {
1286 const MCSymbol
*PersonalitySym
= getContext().getOrCreateSymbol(Name
);
1288 const MCSymbolRefExpr
*PersonalityRef
= MCSymbolRefExpr::create(
1289 PersonalitySym
, MCSymbolRefExpr::VK_ARM_NONE
, getContext());
1291 visitUsedExpr(*PersonalityRef
);
1292 MCDataFragment
*DF
= getOrCreateDataFragment();
1293 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
1295 MCFixup::getKindForSize(4, false)));
1298 void ARMELFStreamer::FlushPendingOffset() {
1299 if (PendingOffset
!= 0) {
1300 UnwindOpAsm
.EmitSPOffset(-PendingOffset
);
1305 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData
) {
1306 // Emit the unwind opcode to restore $sp.
1308 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
1309 int64_t LastRegSaveSPOffset
= SPOffset
- PendingOffset
;
1310 UnwindOpAsm
.EmitSPOffset(LastRegSaveSPOffset
- FPOffset
);
1311 UnwindOpAsm
.EmitSetSP(MRI
->getEncodingValue(FPReg
));
1313 FlushPendingOffset();
1316 // Finalize the unwind opcode sequence
1317 UnwindOpAsm
.Finalize(PersonalityIndex
, Opcodes
);
1319 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1320 // section. Thus, we don't have to create an entry in the .ARM.extab
1322 if (NoHandlerData
&& PersonalityIndex
== ARM::EHABI::AEABI_UNWIND_CPP_PR0
)
1325 // Switch to .ARM.extab section.
1326 SwitchToExTabSection(*FnStart
);
1328 // Create .ARM.extab label for offset in .ARM.exidx
1330 ExTab
= getContext().createTempSymbol();
1335 const MCSymbolRefExpr
*PersonalityRef
=
1336 MCSymbolRefExpr::create(Personality
,
1337 MCSymbolRefExpr::VK_ARM_PREL31
,
1340 emitValue(PersonalityRef
, 4);
1343 // Emit unwind opcodes
1344 assert((Opcodes
.size() % 4) == 0 &&
1345 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1346 for (unsigned I
= 0; I
!= Opcodes
.size(); I
+= 4) {
1347 uint64_t Intval
= Opcodes
[I
] |
1348 Opcodes
[I
+ 1] << 8 |
1349 Opcodes
[I
+ 2] << 16 |
1350 Opcodes
[I
+ 3] << 24;
1354 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1355 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1356 // after the unwind opcodes. The handler data consists of several 32-bit
1357 // words, and should be terminated by zero.
1359 // In case that the .handlerdata directive is not specified by the
1360 // programmer, we should emit zero to terminate the handler data.
1361 if (NoHandlerData
&& !Personality
)
1365 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1367 void ARMELFStreamer::emitPersonality(const MCSymbol
*Per
) {
1369 UnwindOpAsm
.setPersonality(Per
);
1372 void ARMELFStreamer::emitPersonalityIndex(unsigned Index
) {
1373 assert(Index
< ARM::EHABI::NUM_PERSONALITY_INDEX
&& "invalid index");
1374 PersonalityIndex
= Index
;
1377 void ARMELFStreamer::emitSetFP(MCRegister NewFPReg
, MCRegister NewSPReg
,
1379 assert((NewSPReg
== ARM::SP
|| NewSPReg
== FPReg
) &&
1380 "the operand of .setfp directive should be either $sp or $fp");
1385 if (NewSPReg
== ARM::SP
)
1386 FPOffset
= SPOffset
+ Offset
;
1391 void ARMELFStreamer::emitMovSP(MCRegister Reg
, int64_t Offset
) {
1392 assert((Reg
!= ARM::SP
&& Reg
!= ARM::PC
) &&
1393 "the operand of .movsp cannot be either sp or pc");
1394 assert(FPReg
== ARM::SP
&& "current FP must be SP");
1396 FlushPendingOffset();
1399 FPOffset
= SPOffset
+ Offset
;
1401 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
1402 UnwindOpAsm
.EmitSetSP(MRI
->getEncodingValue(FPReg
));
1405 void ARMELFStreamer::emitPad(int64_t Offset
) {
1406 // Track the change of the $sp offset
1409 // To squash multiple .pad directives, we should delay the unwind opcode
1410 // until the .save, .vsave, .handlerdata, or .fnend directives.
1411 PendingOffset
-= Offset
;
1414 static std::pair
<unsigned, unsigned>
1415 collectHWRegs(const MCRegisterInfo
&MRI
, unsigned Idx
,
1416 const SmallVectorImpl
<MCRegister
> &RegList
, bool IsVector
,
1421 MCRegister Reg
= RegList
[Idx
- 1];
1422 if (Reg
== ARM::RA_AUTH_CODE
)
1424 unsigned RegEnc
= MRI
.getEncodingValue(Reg
);
1425 assert(RegEnc
< (IsVector
? 32U : 16U) && "Register out of range");
1426 unsigned Bit
= (1u << RegEnc
);
1427 if ((Mask
& Bit
) == 0) {
1435 return {Idx
, Count
};
1438 void ARMELFStreamer::emitRegSave(const SmallVectorImpl
<MCRegister
> &RegList
,
1441 unsigned Idx
, Count
;
1442 const MCRegisterInfo
&MRI
= *getContext().getRegisterInfo();
1444 // Collect the registers in the register list. Issue unwinding instructions in
1445 // three parts: ordinary hardware registers, return address authentication
1446 // code pseudo register, the rest of the registers. The RA PAC is kept in an
1447 // architectural register (usually r12), but we treat it as a special case in
1448 // order to distinguish between that register containing RA PAC or a general
1450 Idx
= RegList
.size();
1452 std::tie(Idx
, Count
) = collectHWRegs(MRI
, Idx
, RegList
, IsVector
, Mask
);
1454 // Track the change the $sp offset: For the .save directive, the
1455 // corresponding push instruction will decrease the $sp by (4 * Count).
1456 // For the .vsave directive, the corresponding vpush instruction will
1457 // decrease $sp by (8 * Count).
1458 SPOffset
-= Count
* (IsVector
? 8 : 4);
1461 FlushPendingOffset();
1463 UnwindOpAsm
.EmitVFPRegSave(Mask
);
1465 UnwindOpAsm
.EmitRegSave(Mask
);
1466 } else if (Idx
> 0 && RegList
[Idx
- 1] == ARM::RA_AUTH_CODE
) {
1469 FlushPendingOffset();
1470 UnwindOpAsm
.EmitRegSave(0);
1475 void ARMELFStreamer::emitUnwindRaw(int64_t Offset
,
1476 const SmallVectorImpl
<uint8_t> &Opcodes
) {
1477 FlushPendingOffset();
1478 SPOffset
= SPOffset
- Offset
;
1479 UnwindOpAsm
.EmitRaw(Opcodes
);
1484 MCTargetStreamer
*createARMTargetAsmStreamer(MCStreamer
&S
,
1485 formatted_raw_ostream
&OS
,
1486 MCInstPrinter
*InstPrint
) {
1487 return new ARMTargetAsmStreamer(S
, OS
, *InstPrint
);
1490 MCTargetStreamer
*createARMNullTargetStreamer(MCStreamer
&S
) {
1491 return new ARMTargetStreamer(S
);
1494 MCTargetStreamer
*createARMObjectTargetELFStreamer(MCStreamer
&S
) {
1495 return new ARMTargetELFStreamer(S
);
1498 MCELFStreamer
*createARMELFStreamer(MCContext
&Context
,
1499 std::unique_ptr
<MCAsmBackend
> TAB
,
1500 std::unique_ptr
<MCObjectWriter
> OW
,
1501 std::unique_ptr
<MCCodeEmitter
> Emitter
,
1502 bool IsThumb
, bool IsAndroid
) {
1504 new ARMELFStreamer(Context
, std::move(TAB
), std::move(OW
),
1505 std::move(Emitter
), IsThumb
, IsAndroid
);
1506 // FIXME: This should eventually end up somewhere else where more
1507 // intelligent flag decisions can be made. For now we are just maintaining
1508 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1509 S
->getWriter().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5
);
1514 } // end namespace llvm