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 "ARMRegisterInfo.h"
16 #include "ARMUnwindOpAsm.h"
17 #include "llvm/ADT/DenseMap.h"
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/ADT/Triple.h"
22 #include "llvm/ADT/Twine.h"
23 #include "llvm/BinaryFormat/ELF.h"
24 #include "llvm/MC/MCAsmBackend.h"
25 #include "llvm/MC/MCAsmInfo.h"
26 #include "llvm/MC/MCAssembler.h"
27 #include "llvm/MC/MCCodeEmitter.h"
28 #include "llvm/MC/MCContext.h"
29 #include "llvm/MC/MCELFStreamer.h"
30 #include "llvm/MC/MCExpr.h"
31 #include "llvm/MC/MCFixup.h"
32 #include "llvm/MC/MCFragment.h"
33 #include "llvm/MC/MCInst.h"
34 #include "llvm/MC/MCInstPrinter.h"
35 #include "llvm/MC/MCObjectWriter.h"
36 #include "llvm/MC/MCRegisterInfo.h"
37 #include "llvm/MC/MCSection.h"
38 #include "llvm/MC/MCSectionELF.h"
39 #include "llvm/MC/MCStreamer.h"
40 #include "llvm/MC/MCSubtargetInfo.h"
41 #include "llvm/MC/MCSymbol.h"
42 #include "llvm/MC/MCSymbolELF.h"
43 #include "llvm/MC/SectionKind.h"
44 #include "llvm/Support/ARMBuildAttributes.h"
45 #include "llvm/Support/ARMEHABI.h"
46 #include "llvm/Support/Casting.h"
47 #include "llvm/Support/ErrorHandling.h"
48 #include "llvm/Support/FormattedStream.h"
49 #include "llvm/Support/TargetParser.h"
50 #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(unsigned FpReg
, unsigned SpReg
, int64_t Offset
= 0) override
;
82 void emitMovSP(unsigned Reg
, int64_t Offset
= 0) override
;
83 void emitPad(int64_t Offset
) override
;
84 void emitRegSave(const SmallVectorImpl
<unsigned> &RegList
,
85 bool isVector
) override
;
86 void emitUnwindRaw(int64_t Offset
,
87 const SmallVectorImpl
<uint8_t> &Opcodes
) override
;
89 void switchVendor(StringRef Vendor
) override
;
90 void emitAttribute(unsigned Attribute
, unsigned Value
) override
;
91 void emitTextAttribute(unsigned Attribute
, StringRef String
) override
;
92 void emitIntTextAttribute(unsigned Attribute
, unsigned IntValue
,
93 StringRef StringValue
) override
;
94 void emitArch(ARM::ArchKind Arch
) override
;
95 void emitArchExtension(uint64_t ArchExt
) override
;
96 void emitObjectArch(ARM::ArchKind Arch
) override
;
97 void emitFPU(unsigned FPU
) override
;
98 void emitInst(uint32_t Inst
, char Suffix
= '\0') override
;
99 void finishAttributeSection() override
;
101 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr
*SRE
) override
;
102 void emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
105 ARMTargetAsmStreamer(MCStreamer
&S
, formatted_raw_ostream
&OS
,
106 MCInstPrinter
&InstPrinter
, bool VerboseAsm
);
109 ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer
&S
,
110 formatted_raw_ostream
&OS
,
111 MCInstPrinter
&InstPrinter
,
113 : ARMTargetStreamer(S
), OS(OS
), InstPrinter(InstPrinter
),
114 IsVerboseAsm(VerboseAsm
) {}
116 void ARMTargetAsmStreamer::emitFnStart() { OS
<< "\t.fnstart\n"; }
117 void ARMTargetAsmStreamer::emitFnEnd() { OS
<< "\t.fnend\n"; }
118 void ARMTargetAsmStreamer::emitCantUnwind() { OS
<< "\t.cantunwind\n"; }
120 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol
*Personality
) {
121 OS
<< "\t.personality " << Personality
->getName() << '\n';
124 void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index
) {
125 OS
<< "\t.personalityindex " << Index
<< '\n';
128 void ARMTargetAsmStreamer::emitHandlerData() { OS
<< "\t.handlerdata\n"; }
130 void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg
, unsigned SpReg
,
133 InstPrinter
.printRegName(OS
, FpReg
);
135 InstPrinter
.printRegName(OS
, SpReg
);
137 OS
<< ", #" << Offset
;
141 void ARMTargetAsmStreamer::emitMovSP(unsigned Reg
, int64_t Offset
) {
142 assert((Reg
!= ARM::SP
&& Reg
!= ARM::PC
) &&
143 "the operand of .movsp cannot be either sp or pc");
146 InstPrinter
.printRegName(OS
, Reg
);
148 OS
<< ", #" << Offset
;
152 void ARMTargetAsmStreamer::emitPad(int64_t Offset
) {
153 OS
<< "\t.pad\t#" << Offset
<< '\n';
156 void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl
<unsigned> &RegList
,
158 assert(RegList
.size() && "RegList should not be empty");
164 InstPrinter
.printRegName(OS
, RegList
[0]);
166 for (unsigned i
= 1, e
= RegList
.size(); i
!= e
; ++i
) {
168 InstPrinter
.printRegName(OS
, RegList
[i
]);
174 void ARMTargetAsmStreamer::switchVendor(StringRef Vendor
) {}
176 void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
177 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", " << Twine(Value
);
179 StringRef Name
= ELFAttrs::attrTypeAsString(
180 Attribute
, ARMBuildAttrs::getARMAttributeTags());
182 OS
<< "\t@ " << Name
;
187 void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute
,
190 case ARMBuildAttrs::CPU_name
:
191 OS
<< "\t.cpu\t" << String
.lower();
194 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", \"" << String
<< "\"";
196 StringRef Name
= ELFAttrs::attrTypeAsString(
197 Attribute
, ARMBuildAttrs::getARMAttributeTags());
199 OS
<< "\t@ " << Name
;
206 void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute
,
208 StringRef StringValue
) {
210 default: llvm_unreachable("unsupported multi-value attribute in asm mode");
211 case ARMBuildAttrs::compatibility
:
212 OS
<< "\t.eabi_attribute\t" << Attribute
<< ", " << IntValue
;
213 if (!StringValue
.empty())
214 OS
<< ", \"" << StringValue
<< "\"";
217 << ELFAttrs::attrTypeAsString(Attribute
,
218 ARMBuildAttrs::getARMAttributeTags());
224 void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch
) {
225 OS
<< "\t.arch\t" << ARM::getArchName(Arch
) << "\n";
228 void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt
) {
229 OS
<< "\t.arch_extension\t" << ARM::getArchExtName(ArchExt
) << "\n";
232 void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch
) {
233 OS
<< "\t.object_arch\t" << ARM::getArchName(Arch
) << '\n';
236 void ARMTargetAsmStreamer::emitFPU(unsigned FPU
) {
237 OS
<< "\t.fpu\t" << ARM::getFPUName(FPU
) << "\n";
240 void ARMTargetAsmStreamer::finishAttributeSection() {}
243 ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr
*S
) {
244 OS
<< "\t.tlsdescseq\t" << S
->getSymbol().getName() << "\n";
247 void ARMTargetAsmStreamer::emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) {
248 const MCAsmInfo
*MAI
= Streamer
.getContext().getAsmInfo();
250 OS
<< "\t.thumb_set\t";
251 Symbol
->print(OS
, MAI
);
253 Value
->print(OS
, MAI
);
257 void ARMTargetAsmStreamer::emitInst(uint32_t Inst
, char Suffix
) {
261 OS
<< "\t0x" << Twine::utohexstr(Inst
) << "\n";
264 void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset
,
265 const SmallVectorImpl
<uint8_t> &Opcodes
) {
266 OS
<< "\t.unwind_raw " << Offset
;
267 for (SmallVectorImpl
<uint8_t>::const_iterator OCI
= Opcodes
.begin(),
270 OS
<< ", 0x" << Twine::utohexstr(*OCI
);
274 class ARMTargetELFStreamer
: public ARMTargetStreamer
{
276 StringRef CurrentVendor
;
277 unsigned FPU
= ARM::FK_INVALID
;
278 ARM::ArchKind Arch
= ARM::ArchKind::INVALID
;
279 ARM::ArchKind EmittedArch
= ARM::ArchKind::INVALID
;
281 MCSection
*AttributeSection
= nullptr;
283 void emitArchDefaultAttributes();
284 void emitFPUDefaultAttributes();
286 ARMELFStreamer
&getStreamer();
288 void emitFnStart() override
;
289 void emitFnEnd() override
;
290 void emitCantUnwind() override
;
291 void emitPersonality(const MCSymbol
*Personality
) override
;
292 void emitPersonalityIndex(unsigned Index
) override
;
293 void emitHandlerData() override
;
294 void emitSetFP(unsigned FpReg
, unsigned SpReg
, int64_t Offset
= 0) override
;
295 void emitMovSP(unsigned Reg
, int64_t Offset
= 0) override
;
296 void emitPad(int64_t Offset
) override
;
297 void emitRegSave(const SmallVectorImpl
<unsigned> &RegList
,
298 bool isVector
) override
;
299 void emitUnwindRaw(int64_t Offset
,
300 const SmallVectorImpl
<uint8_t> &Opcodes
) override
;
302 void switchVendor(StringRef Vendor
) override
;
303 void emitAttribute(unsigned Attribute
, unsigned Value
) override
;
304 void emitTextAttribute(unsigned Attribute
, StringRef String
) override
;
305 void emitIntTextAttribute(unsigned Attribute
, unsigned IntValue
,
306 StringRef StringValue
) override
;
307 void emitArch(ARM::ArchKind Arch
) override
;
308 void emitObjectArch(ARM::ArchKind Arch
) override
;
309 void emitFPU(unsigned FPU
) override
;
310 void emitInst(uint32_t Inst
, char Suffix
= '\0') override
;
311 void finishAttributeSection() override
;
312 void emitLabel(MCSymbol
*Symbol
) override
;
314 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr
*SRE
) override
;
315 void emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) override
;
317 // Reset state between object emissions
318 void reset() override
;
321 ARMTargetELFStreamer(MCStreamer
&S
)
322 : ARMTargetStreamer(S
), CurrentVendor("aeabi") {}
325 /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
326 /// the appropriate points in the object files. These symbols are defined in the
327 /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
329 /// In brief: $a, $t or $d should be emitted at the start of each contiguous
330 /// region of ARM code, Thumb code or data in a section. In practice, this
331 /// emission does not rely on explicit assembler directives but on inherent
332 /// properties of the directives doing the emission (e.g. ".byte" is data, "add
333 /// r0, r0, r0" an instruction).
335 /// As a result this system is orthogonal to the DataRegion infrastructure used
336 /// by MachO. Beware!
337 class ARMELFStreamer
: public MCELFStreamer
{
339 friend class ARMTargetELFStreamer
;
341 ARMELFStreamer(MCContext
&Context
, std::unique_ptr
<MCAsmBackend
> TAB
,
342 std::unique_ptr
<MCObjectWriter
> OW
,
343 std::unique_ptr
<MCCodeEmitter
> Emitter
, bool IsThumb
,
345 : MCELFStreamer(Context
, std::move(TAB
), std::move(OW
),
347 IsThumb(IsThumb
), IsAndroid(IsAndroid
) {
351 ~ARMELFStreamer() override
= default;
353 void finishImpl() override
;
355 // ARM exception handling directives
358 void emitCantUnwind();
359 void emitPersonality(const MCSymbol
*Per
);
360 void emitPersonalityIndex(unsigned index
);
361 void emitHandlerData();
362 void emitSetFP(unsigned NewFpReg
, unsigned NewSpReg
, int64_t Offset
= 0);
363 void emitMovSP(unsigned Reg
, int64_t Offset
= 0);
364 void emitPad(int64_t Offset
);
365 void emitRegSave(const SmallVectorImpl
<unsigned> &RegList
, bool isVector
);
366 void emitUnwindRaw(int64_t Offset
, const SmallVectorImpl
<uint8_t> &Opcodes
);
367 void emitFill(const MCExpr
&NumBytes
, uint64_t FillValue
,
368 SMLoc Loc
) override
{
369 emitDataMappingSymbol();
370 MCObjectStreamer::emitFill(NumBytes
, FillValue
, Loc
);
373 void changeSection(MCSection
*Section
, const MCExpr
*Subsection
) override
{
374 LastMappingSymbols
[getCurrentSection().first
] = std::move(LastEMSInfo
);
375 MCELFStreamer::changeSection(Section
, Subsection
);
376 auto LastMappingSymbol
= LastMappingSymbols
.find(Section
);
377 if (LastMappingSymbol
!= LastMappingSymbols
.end()) {
378 LastEMSInfo
= std::move(LastMappingSymbol
->second
);
381 LastEMSInfo
.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
384 /// This function is the one used to emit instruction data into the ELF
385 /// streamer. We override it to add the appropriate mapping symbol if
387 void emitInstruction(const MCInst
&Inst
,
388 const MCSubtargetInfo
&STI
) override
{
390 EmitThumbMappingSymbol();
392 EmitARMMappingSymbol();
394 MCELFStreamer::emitInstruction(Inst
, STI
);
397 void emitInst(uint32_t Inst
, char Suffix
) {
400 const bool LittleEndian
= getContext().getAsmInfo()->isLittleEndian();
407 EmitARMMappingSymbol();
408 for (unsigned II
= 0, IE
= Size
; II
!= IE
; II
++) {
409 const unsigned I
= LittleEndian
? (Size
- II
- 1) : II
;
410 Buffer
[Size
- II
- 1] = uint8_t(Inst
>> I
* CHAR_BIT
);
416 Size
= (Suffix
== 'n' ? 2 : 4);
419 EmitThumbMappingSymbol();
420 // Thumb wide instructions are emitted as a pair of 16-bit words of the
421 // appropriate endianness.
422 for (unsigned II
= 0, IE
= Size
; II
!= IE
; II
= II
+ 2) {
423 const unsigned I0
= LittleEndian
? II
+ 0 : II
+ 1;
424 const unsigned I1
= LittleEndian
? II
+ 1 : II
+ 0;
425 Buffer
[Size
- II
- 2] = uint8_t(Inst
>> I0
* CHAR_BIT
);
426 Buffer
[Size
- II
- 1] = uint8_t(Inst
>> I1
* CHAR_BIT
);
431 llvm_unreachable("Invalid Suffix");
434 MCELFStreamer::emitBytes(StringRef(Buffer
, Size
));
437 /// This is one of the functions used to emit data into an ELF section, so the
438 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
440 void emitBytes(StringRef Data
) override
{
441 emitDataMappingSymbol();
442 MCELFStreamer::emitBytes(Data
);
445 void FlushPendingMappingSymbol() {
446 if (!LastEMSInfo
->hasInfo())
448 ElfMappingSymbolInfo
*EMS
= LastEMSInfo
.get();
449 EmitMappingSymbol("$d", EMS
->Loc
, EMS
->F
, EMS
->Offset
);
453 /// This is one of the functions used to emit data into an ELF section, so the
454 /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
456 void emitValueImpl(const MCExpr
*Value
, unsigned Size
, SMLoc Loc
) override
{
457 if (const MCSymbolRefExpr
*SRE
= dyn_cast_or_null
<MCSymbolRefExpr
>(Value
)) {
458 if (SRE
->getKind() == MCSymbolRefExpr::VK_ARM_SBREL
&& !(Size
== 4)) {
459 getContext().reportError(Loc
, "relocated expression must be 32-bit");
462 getOrCreateDataFragment();
465 emitDataMappingSymbol();
466 MCELFStreamer::emitValueImpl(Value
, Size
, Loc
);
469 void emitAssemblerFlag(MCAssemblerFlag Flag
) override
{
470 MCELFStreamer::emitAssemblerFlag(Flag
);
473 case MCAF_SyntaxUnified
:
474 return; // no-op here.
477 return; // Change to Thumb mode
480 return; // Change to ARM mode
483 case MCAF_SubsectionsViaSymbols
:
488 /// If a label is defined before the .type directive sets the label's type
489 /// then the label can't be recorded as thumb function when the label is
490 /// defined. We override emitSymbolAttribute() which is called as part of the
491 /// parsing of .type so that if the symbol has already been defined we can
492 /// record the label as Thumb. FIXME: there is a corner case where the state
493 /// is changed in between the label definition and the .type directive, this
494 /// is not expected to occur in practice and handling it would require the
495 /// backend to track IsThumb for every label.
496 bool emitSymbolAttribute(MCSymbol
*Symbol
, MCSymbolAttr Attribute
) override
{
497 bool Val
= MCELFStreamer::emitSymbolAttribute(Symbol
, Attribute
);
502 unsigned Type
= cast
<MCSymbolELF
>(Symbol
)->getType();
503 if ((Type
== ELF::STT_FUNC
|| Type
== ELF::STT_GNU_IFUNC
) &&
505 getAssembler().setIsThumbFunc(Symbol
);
511 enum ElfMappingSymbol
{
518 struct ElfMappingSymbolInfo
{
519 explicit ElfMappingSymbolInfo(SMLoc Loc
, MCFragment
*F
, uint64_t O
)
520 : Loc(Loc
), F(F
), Offset(O
), State(EMS_None
) {}
525 bool hasInfo() { return F
!= nullptr; }
529 ElfMappingSymbol State
;
532 void emitDataMappingSymbol() {
533 if (LastEMSInfo
->State
== EMS_Data
)
535 else if (LastEMSInfo
->State
== EMS_None
) {
536 // This is a tentative symbol, it won't really be emitted until it's
538 ElfMappingSymbolInfo
*EMS
= LastEMSInfo
.get();
539 auto *DF
= dyn_cast_or_null
<MCDataFragment
>(getCurrentFragment());
543 EMS
->F
= getCurrentFragment();
544 EMS
->Offset
= DF
->getContents().size();
545 LastEMSInfo
->State
= EMS_Data
;
548 EmitMappingSymbol("$d");
549 LastEMSInfo
->State
= EMS_Data
;
552 void EmitThumbMappingSymbol() {
553 if (LastEMSInfo
->State
== EMS_Thumb
)
555 FlushPendingMappingSymbol();
556 EmitMappingSymbol("$t");
557 LastEMSInfo
->State
= EMS_Thumb
;
560 void EmitARMMappingSymbol() {
561 if (LastEMSInfo
->State
== EMS_ARM
)
563 FlushPendingMappingSymbol();
564 EmitMappingSymbol("$a");
565 LastEMSInfo
->State
= EMS_ARM
;
568 void EmitMappingSymbol(StringRef Name
) {
569 auto *Symbol
= cast
<MCSymbolELF
>(getContext().getOrCreateSymbol(
570 Name
+ "." + Twine(MappingSymbolCounter
++)));
573 Symbol
->setType(ELF::STT_NOTYPE
);
574 Symbol
->setBinding(ELF::STB_LOCAL
);
577 void EmitMappingSymbol(StringRef Name
, SMLoc Loc
, MCFragment
*F
,
579 auto *Symbol
= cast
<MCSymbolELF
>(getContext().getOrCreateSymbol(
580 Name
+ "." + Twine(MappingSymbolCounter
++)));
581 emitLabelAtPos(Symbol
, Loc
, F
, Offset
);
582 Symbol
->setType(ELF::STT_NOTYPE
);
583 Symbol
->setBinding(ELF::STB_LOCAL
);
586 void emitThumbFunc(MCSymbol
*Func
) override
{
587 getAssembler().setIsThumbFunc(Func
);
588 emitSymbolAttribute(Func
, MCSA_ELF_TypeFunction
);
591 // Helper functions for ARM exception handling directives
594 // Reset state between object emissions
595 void reset() override
;
597 void EmitPersonalityFixup(StringRef Name
);
598 void FlushPendingOffset();
599 void FlushUnwindOpcodes(bool NoHandlerData
);
601 void SwitchToEHSection(StringRef Prefix
, unsigned Type
, unsigned Flags
,
602 SectionKind Kind
, const MCSymbol
&Fn
);
603 void SwitchToExTabSection(const MCSymbol
&FnStart
);
604 void SwitchToExIdxSection(const MCSymbol
&FnStart
);
606 void EmitFixup(const MCExpr
*Expr
, MCFixupKind Kind
);
610 int64_t MappingSymbolCounter
= 0;
612 DenseMap
<const MCSection
*, std::unique_ptr
<ElfMappingSymbolInfo
>>
615 std::unique_ptr
<ElfMappingSymbolInfo
> LastEMSInfo
;
617 // ARM Exception Handling Frame Information
620 const MCSymbol
*Personality
;
621 unsigned PersonalityIndex
;
622 unsigned FPReg
; // Frame pointer register
623 int64_t FPOffset
; // Offset: (final frame pointer) - (initial $sp)
624 int64_t SPOffset
; // Offset: (final $sp) - (initial $sp)
625 int64_t PendingOffset
; // Offset: (final $sp) - (emitted $sp)
628 SmallVector
<uint8_t, 64> Opcodes
;
629 UnwindOpcodeAssembler UnwindOpAsm
;
632 } // end anonymous namespace
634 ARMELFStreamer
&ARMTargetELFStreamer::getStreamer() {
635 return static_cast<ARMELFStreamer
&>(Streamer
);
638 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
639 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
640 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
642 void ARMTargetELFStreamer::emitPersonality(const MCSymbol
*Personality
) {
643 getStreamer().emitPersonality(Personality
);
646 void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index
) {
647 getStreamer().emitPersonalityIndex(Index
);
650 void ARMTargetELFStreamer::emitHandlerData() {
651 getStreamer().emitHandlerData();
654 void ARMTargetELFStreamer::emitSetFP(unsigned FpReg
, unsigned SpReg
,
656 getStreamer().emitSetFP(FpReg
, SpReg
, Offset
);
659 void ARMTargetELFStreamer::emitMovSP(unsigned Reg
, int64_t Offset
) {
660 getStreamer().emitMovSP(Reg
, Offset
);
663 void ARMTargetELFStreamer::emitPad(int64_t Offset
) {
664 getStreamer().emitPad(Offset
);
667 void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl
<unsigned> &RegList
,
669 getStreamer().emitRegSave(RegList
, isVector
);
672 void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset
,
673 const SmallVectorImpl
<uint8_t> &Opcodes
) {
674 getStreamer().emitUnwindRaw(Offset
, Opcodes
);
677 void ARMTargetELFStreamer::switchVendor(StringRef Vendor
) {
678 assert(!Vendor
.empty() && "Vendor cannot be empty.");
680 if (CurrentVendor
== Vendor
)
683 if (!CurrentVendor
.empty())
684 finishAttributeSection();
686 assert(getStreamer().Contents
.empty() &&
687 ".ARM.attributes should be flushed before changing vendor");
688 CurrentVendor
= Vendor
;
692 void ARMTargetELFStreamer::emitAttribute(unsigned Attribute
, unsigned Value
) {
693 getStreamer().setAttributeItem(Attribute
, Value
,
694 /* OverwriteExisting= */ true);
697 void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute
,
699 getStreamer().setAttributeItem(Attribute
, Value
,
700 /* OverwriteExisting= */ true);
703 void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute
,
705 StringRef StringValue
) {
706 getStreamer().setAttributeItems(Attribute
, IntValue
, StringValue
,
707 /* OverwriteExisting= */ true);
710 void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value
) {
714 void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value
) {
718 void ARMTargetELFStreamer::emitArchDefaultAttributes() {
719 using namespace ARMBuildAttrs
;
720 ARMELFStreamer
&S
= getStreamer();
722 S
.setAttributeItem(CPU_name
, ARM::getCPUAttr(Arch
), false);
724 if (EmittedArch
== ARM::ArchKind::INVALID
)
725 S
.setAttributeItem(CPU_arch
, ARM::getArchAttr(Arch
), false);
727 S
.setAttributeItem(CPU_arch
, ARM::getArchAttr(EmittedArch
), false);
730 case ARM::ArchKind::ARMV2
:
731 case ARM::ArchKind::ARMV2A
:
732 case ARM::ArchKind::ARMV3
:
733 case ARM::ArchKind::ARMV3M
:
734 case ARM::ArchKind::ARMV4
:
735 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
738 case ARM::ArchKind::ARMV4T
:
739 case ARM::ArchKind::ARMV5T
:
740 case ARM::ArchKind::XSCALE
:
741 case ARM::ArchKind::ARMV5TE
:
742 case ARM::ArchKind::ARMV6
:
743 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
744 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
747 case ARM::ArchKind::ARMV6T2
:
748 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
749 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
752 case ARM::ArchKind::ARMV6K
:
753 case ARM::ArchKind::ARMV6KZ
:
754 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
755 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
756 S
.setAttributeItem(Virtualization_use
, AllowTZ
, false);
759 case ARM::ArchKind::ARMV6M
:
760 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
763 case ARM::ArchKind::ARMV7A
:
764 S
.setAttributeItem(CPU_arch_profile
, ApplicationProfile
, false);
765 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
766 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
769 case ARM::ArchKind::ARMV7R
:
770 S
.setAttributeItem(CPU_arch_profile
, RealTimeProfile
, false);
771 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
772 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
775 case ARM::ArchKind::ARMV7EM
:
776 case ARM::ArchKind::ARMV7M
:
777 S
.setAttributeItem(CPU_arch_profile
, MicroControllerProfile
, false);
778 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
781 case ARM::ArchKind::ARMV8A
:
782 case ARM::ArchKind::ARMV8_1A
:
783 case ARM::ArchKind::ARMV8_2A
:
784 case ARM::ArchKind::ARMV8_3A
:
785 case ARM::ArchKind::ARMV8_4A
:
786 case ARM::ArchKind::ARMV8_5A
:
787 case ARM::ArchKind::ARMV8_6A
:
788 S
.setAttributeItem(CPU_arch_profile
, ApplicationProfile
, false);
789 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
790 S
.setAttributeItem(THUMB_ISA_use
, AllowThumb32
, false);
791 S
.setAttributeItem(MPextension_use
, Allowed
, false);
792 S
.setAttributeItem(Virtualization_use
, AllowTZVirtualization
, false);
795 case ARM::ArchKind::ARMV8MBaseline
:
796 case ARM::ArchKind::ARMV8MMainline
:
797 S
.setAttributeItem(THUMB_ISA_use
, AllowThumbDerived
, false);
798 S
.setAttributeItem(CPU_arch_profile
, MicroControllerProfile
, false);
801 case ARM::ArchKind::IWMMXT
:
802 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
803 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
804 S
.setAttributeItem(WMMX_arch
, AllowWMMXv1
, false);
807 case ARM::ArchKind::IWMMXT2
:
808 S
.setAttributeItem(ARM_ISA_use
, Allowed
, false);
809 S
.setAttributeItem(THUMB_ISA_use
, Allowed
, false);
810 S
.setAttributeItem(WMMX_arch
, AllowWMMXv2
, false);
814 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch
)));
819 void ARMTargetELFStreamer::emitFPU(unsigned Value
) {
823 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
824 ARMELFStreamer
&S
= getStreamer();
829 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv2
,
830 /* OverwriteExisting= */ false);
834 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
835 /* OverwriteExisting= */ false);
838 case ARM::FK_VFPV3_FP16
:
839 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
840 /* OverwriteExisting= */ false);
841 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
842 /* OverwriteExisting= */ false);
845 case ARM::FK_VFPV3_D16
:
846 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
847 /* OverwriteExisting= */ false);
850 case ARM::FK_VFPV3_D16_FP16
:
851 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
852 /* OverwriteExisting= */ false);
853 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
854 /* OverwriteExisting= */ false);
857 case ARM::FK_VFPV3XD
:
858 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
859 /* OverwriteExisting= */ false);
861 case ARM::FK_VFPV3XD_FP16
:
862 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3B
,
863 /* OverwriteExisting= */ false);
864 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
865 /* OverwriteExisting= */ false);
869 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4A
,
870 /* OverwriteExisting= */ false);
873 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
875 case ARM::FK_FPV4_SP_D16
:
876 case ARM::FK_VFPV4_D16
:
877 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4B
,
878 /* OverwriteExisting= */ false);
881 case ARM::FK_FP_ARMV8
:
882 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8A
,
883 /* OverwriteExisting= */ false);
886 // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
887 // uses the FP_ARMV8_D16 build attribute.
888 case ARM::FK_FPV5_SP_D16
:
889 case ARM::FK_FPV5_D16
:
890 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8B
,
891 /* OverwriteExisting= */ false);
895 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
896 /* OverwriteExisting= */ false);
897 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
898 ARMBuildAttrs::AllowNeon
,
899 /* OverwriteExisting= */ false);
902 case ARM::FK_NEON_FP16
:
903 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv3A
,
904 /* OverwriteExisting= */ false);
905 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
906 ARMBuildAttrs::AllowNeon
,
907 /* OverwriteExisting= */ false);
908 S
.setAttributeItem(ARMBuildAttrs::FP_HP_extension
, ARMBuildAttrs::AllowHPFP
,
909 /* OverwriteExisting= */ false);
912 case ARM::FK_NEON_VFPV4
:
913 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPv4A
,
914 /* OverwriteExisting= */ false);
915 S
.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch
,
916 ARMBuildAttrs::AllowNeon2
,
917 /* OverwriteExisting= */ false);
920 case ARM::FK_NEON_FP_ARMV8
:
921 case ARM::FK_CRYPTO_NEON_FP_ARMV8
:
922 S
.setAttributeItem(ARMBuildAttrs::FP_arch
, ARMBuildAttrs::AllowFPARMv8A
,
923 /* OverwriteExisting= */ false);
924 // 'Advanced_SIMD_arch' must be emitted not here, but within
925 // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
928 case ARM::FK_SOFTVFP
:
933 report_fatal_error("Unknown FPU: " + Twine(FPU
));
938 void ARMTargetELFStreamer::finishAttributeSection() {
939 ARMELFStreamer
&S
= getStreamer();
941 if (FPU
!= ARM::FK_INVALID
)
942 emitFPUDefaultAttributes();
944 if (Arch
!= ARM::ArchKind::INVALID
)
945 emitArchDefaultAttributes();
947 if (S
.Contents
.empty())
950 auto LessTag
= [](const MCELFStreamer::AttributeItem
&LHS
,
951 const MCELFStreamer::AttributeItem
&RHS
) -> bool {
952 // The conformance tag must be emitted first when serialised into an
953 // object file. Specifically, the addenda to the ARM ABI states that
956 // "To simplify recognition by consumers in the common case of claiming
957 // conformity for the whole file, this tag should be emitted first in a
958 // file-scope sub-subsection of the first public subsection of the
959 // attributes section."
961 // So it is special-cased in this comparison predicate when the
962 // attributes are sorted in finishAttributeSection().
963 return (RHS
.Tag
!= ARMBuildAttrs::conformance
) &&
964 ((LHS
.Tag
== ARMBuildAttrs::conformance
) || (LHS
.Tag
< RHS
.Tag
));
966 llvm::sort(S
.Contents
, LessTag
);
968 S
.emitAttributesSection(CurrentVendor
, ".ARM.attributes",
969 ELF::SHT_ARM_ATTRIBUTES
, AttributeSection
);
971 FPU
= ARM::FK_INVALID
;
974 void ARMTargetELFStreamer::emitLabel(MCSymbol
*Symbol
) {
975 ARMELFStreamer
&Streamer
= getStreamer();
976 if (!Streamer
.IsThumb
)
979 Streamer
.getAssembler().registerSymbol(*Symbol
);
980 unsigned Type
= cast
<MCSymbolELF
>(Symbol
)->getType();
981 if (Type
== ELF::STT_FUNC
|| Type
== ELF::STT_GNU_IFUNC
)
982 Streamer
.emitThumbFunc(Symbol
);
986 ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr
*S
) {
987 getStreamer().EmitFixup(S
, FK_Data_4
);
990 void ARMTargetELFStreamer::emitThumbSet(MCSymbol
*Symbol
, const MCExpr
*Value
) {
991 if (const MCSymbolRefExpr
*SRE
= dyn_cast
<MCSymbolRefExpr
>(Value
)) {
992 const MCSymbol
&Sym
= SRE
->getSymbol();
993 if (!Sym
.isDefined()) {
994 getStreamer().emitAssignment(Symbol
, Value
);
999 getStreamer().emitThumbFunc(Symbol
);
1000 getStreamer().emitAssignment(Symbol
, Value
);
1003 void ARMTargetELFStreamer::emitInst(uint32_t Inst
, char Suffix
) {
1004 getStreamer().emitInst(Inst
, Suffix
);
1007 void ARMTargetELFStreamer::reset() { AttributeSection
= nullptr; }
1009 void ARMELFStreamer::finishImpl() {
1010 MCTargetStreamer
&TS
= *getTargetStreamer();
1011 ARMTargetStreamer
&ATS
= static_cast<ARMTargetStreamer
&>(TS
);
1012 ATS
.finishAttributeSection();
1014 MCELFStreamer::finishImpl();
1017 void ARMELFStreamer::reset() {
1018 MCTargetStreamer
&TS
= *getTargetStreamer();
1019 ARMTargetStreamer
&ATS
= static_cast<ARMTargetStreamer
&>(TS
);
1021 MappingSymbolCounter
= 0;
1022 MCELFStreamer::reset();
1023 LastMappingSymbols
.clear();
1024 LastEMSInfo
.reset();
1025 // MCELFStreamer clear's the assembler's e_flags. However, for
1026 // arm we manually set the ABI version on streamer creation, so
1028 getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5
);
1031 inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix
,
1035 const MCSymbol
&Fn
) {
1036 const MCSectionELF
&FnSection
=
1037 static_cast<const MCSectionELF
&>(Fn
.getSection());
1039 // Create the name for new section
1040 StringRef
FnSecName(FnSection
.getName());
1041 SmallString
<128> EHSecName(Prefix
);
1042 if (FnSecName
!= ".text") {
1043 EHSecName
+= FnSecName
;
1046 // Get .ARM.extab or .ARM.exidx section
1047 const MCSymbolELF
*Group
= FnSection
.getGroup();
1049 Flags
|= ELF::SHF_GROUP
;
1050 MCSectionELF
*EHSection
= getContext().getELFSection(
1051 EHSecName
, Type
, Flags
, 0, Group
, /*IsComdat=*/true,
1052 FnSection
.getUniqueID(),
1053 static_cast<const MCSymbolELF
*>(FnSection
.getBeginSymbol()));
1055 assert(EHSection
&& "Failed to get the required EH section");
1057 // Switch to .ARM.extab or .ARM.exidx section
1058 SwitchSection(EHSection
);
1059 emitCodeAlignment(4);
1062 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol
&FnStart
) {
1063 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS
, ELF::SHF_ALLOC
,
1064 SectionKind::getData(), FnStart
);
1067 inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol
&FnStart
) {
1068 SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX
,
1069 ELF::SHF_ALLOC
| ELF::SHF_LINK_ORDER
,
1070 SectionKind::getData(), FnStart
);
1073 void ARMELFStreamer::EmitFixup(const MCExpr
*Expr
, MCFixupKind Kind
) {
1074 MCDataFragment
*Frag
= getOrCreateDataFragment();
1075 Frag
->getFixups().push_back(MCFixup::create(Frag
->getContents().size(), Expr
,
1079 void ARMELFStreamer::EHReset() {
1082 Personality
= nullptr;
1083 PersonalityIndex
= ARM::EHABI::NUM_PERSONALITY_INDEX
;
1092 UnwindOpAsm
.Reset();
1095 void ARMELFStreamer::emitFnStart() {
1096 assert(FnStart
== nullptr);
1097 FnStart
= getContext().createTempSymbol();
1101 void ARMELFStreamer::emitFnEnd() {
1102 assert(FnStart
&& ".fnstart must precedes .fnend");
1104 // Emit unwind opcodes if there is no .handlerdata directive
1105 if (!ExTab
&& !CantUnwind
)
1106 FlushUnwindOpcodes(true);
1108 // Emit the exception index table entry
1109 SwitchToExIdxSection(*FnStart
);
1111 // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1112 // personality routine to protect it from an arbitrary platform's static
1113 // linker garbage collection. We disable this for Android where the unwinder
1114 // is either dynamically linked or directly references the personality
1116 if (PersonalityIndex
< ARM::EHABI::NUM_PERSONALITY_INDEX
&& !IsAndroid
)
1117 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex
));
1119 const MCSymbolRefExpr
*FnStartRef
=
1120 MCSymbolRefExpr::create(FnStart
,
1121 MCSymbolRefExpr::VK_ARM_PREL31
,
1124 emitValue(FnStartRef
, 4);
1127 emitInt32(ARM::EHABI::EXIDX_CANTUNWIND
);
1129 // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
1130 const MCSymbolRefExpr
*ExTabEntryRef
=
1131 MCSymbolRefExpr::create(ExTab
,
1132 MCSymbolRefExpr::VK_ARM_PREL31
,
1134 emitValue(ExTabEntryRef
, 4);
1136 // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
1137 // the second word of exception index table entry. The size of the unwind
1138 // opcodes should always be 4 bytes.
1139 assert(PersonalityIndex
== ARM::EHABI::AEABI_UNWIND_CPP_PR0
&&
1140 "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
1141 assert(Opcodes
.size() == 4u &&
1142 "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
1143 uint64_t Intval
= Opcodes
[0] |
1147 emitIntValue(Intval
, Opcodes
.size());
1150 // Switch to the section containing FnStart
1151 SwitchSection(&FnStart
->getSection());
1153 // Clean exception handling frame information
1157 void ARMELFStreamer::emitCantUnwind() { CantUnwind
= true; }
1159 // Add the R_ARM_NONE fixup at the same position
1160 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name
) {
1161 const MCSymbol
*PersonalitySym
= getContext().getOrCreateSymbol(Name
);
1163 const MCSymbolRefExpr
*PersonalityRef
= MCSymbolRefExpr::create(
1164 PersonalitySym
, MCSymbolRefExpr::VK_ARM_NONE
, getContext());
1166 visitUsedExpr(*PersonalityRef
);
1167 MCDataFragment
*DF
= getOrCreateDataFragment();
1168 DF
->getFixups().push_back(MCFixup::create(DF
->getContents().size(),
1170 MCFixup::getKindForSize(4, false)));
1173 void ARMELFStreamer::FlushPendingOffset() {
1174 if (PendingOffset
!= 0) {
1175 UnwindOpAsm
.EmitSPOffset(-PendingOffset
);
1180 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData
) {
1181 // Emit the unwind opcode to restore $sp.
1183 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
1184 int64_t LastRegSaveSPOffset
= SPOffset
- PendingOffset
;
1185 UnwindOpAsm
.EmitSPOffset(LastRegSaveSPOffset
- FPOffset
);
1186 UnwindOpAsm
.EmitSetSP(MRI
->getEncodingValue(FPReg
));
1188 FlushPendingOffset();
1191 // Finalize the unwind opcode sequence
1192 UnwindOpAsm
.Finalize(PersonalityIndex
, Opcodes
);
1194 // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
1195 // section. Thus, we don't have to create an entry in the .ARM.extab
1197 if (NoHandlerData
&& PersonalityIndex
== ARM::EHABI::AEABI_UNWIND_CPP_PR0
)
1200 // Switch to .ARM.extab section.
1201 SwitchToExTabSection(*FnStart
);
1203 // Create .ARM.extab label for offset in .ARM.exidx
1205 ExTab
= getContext().createTempSymbol();
1210 const MCSymbolRefExpr
*PersonalityRef
=
1211 MCSymbolRefExpr::create(Personality
,
1212 MCSymbolRefExpr::VK_ARM_PREL31
,
1215 emitValue(PersonalityRef
, 4);
1218 // Emit unwind opcodes
1219 assert((Opcodes
.size() % 4) == 0 &&
1220 "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
1221 for (unsigned I
= 0; I
!= Opcodes
.size(); I
+= 4) {
1222 uint64_t Intval
= Opcodes
[I
] |
1223 Opcodes
[I
+ 1] << 8 |
1224 Opcodes
[I
+ 2] << 16 |
1225 Opcodes
[I
+ 3] << 24;
1229 // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
1230 // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
1231 // after the unwind opcodes. The handler data consists of several 32-bit
1232 // words, and should be terminated by zero.
1234 // In case that the .handlerdata directive is not specified by the
1235 // programmer, we should emit zero to terminate the handler data.
1236 if (NoHandlerData
&& !Personality
)
1240 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1242 void ARMELFStreamer::emitPersonality(const MCSymbol
*Per
) {
1244 UnwindOpAsm
.setPersonality(Per
);
1247 void ARMELFStreamer::emitPersonalityIndex(unsigned Index
) {
1248 assert(Index
< ARM::EHABI::NUM_PERSONALITY_INDEX
&& "invalid index");
1249 PersonalityIndex
= Index
;
1252 void ARMELFStreamer::emitSetFP(unsigned NewFPReg
, unsigned NewSPReg
,
1254 assert((NewSPReg
== ARM::SP
|| NewSPReg
== FPReg
) &&
1255 "the operand of .setfp directive should be either $sp or $fp");
1260 if (NewSPReg
== ARM::SP
)
1261 FPOffset
= SPOffset
+ Offset
;
1266 void ARMELFStreamer::emitMovSP(unsigned Reg
, int64_t Offset
) {
1267 assert((Reg
!= ARM::SP
&& Reg
!= ARM::PC
) &&
1268 "the operand of .movsp cannot be either sp or pc");
1269 assert(FPReg
== ARM::SP
&& "current FP must be SP");
1271 FlushPendingOffset();
1274 FPOffset
= SPOffset
+ Offset
;
1276 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
1277 UnwindOpAsm
.EmitSetSP(MRI
->getEncodingValue(FPReg
));
1280 void ARMELFStreamer::emitPad(int64_t Offset
) {
1281 // Track the change of the $sp offset
1284 // To squash multiple .pad directives, we should delay the unwind opcode
1285 // until the .save, .vsave, .handlerdata, or .fnend directives.
1286 PendingOffset
-= Offset
;
1289 void ARMELFStreamer::emitRegSave(const SmallVectorImpl
<unsigned> &RegList
,
1291 // Collect the registers in the register list
1294 const MCRegisterInfo
*MRI
= getContext().getRegisterInfo();
1295 for (size_t i
= 0; i
< RegList
.size(); ++i
) {
1296 unsigned Reg
= MRI
->getEncodingValue(RegList
[i
]);
1297 assert(Reg
< (IsVector
? 32U : 16U) && "Register out of range");
1298 unsigned Bit
= (1u << Reg
);
1299 if ((Mask
& Bit
) == 0) {
1305 // Track the change the $sp offset: For the .save directive, the
1306 // corresponding push instruction will decrease the $sp by (4 * Count).
1307 // For the .vsave directive, the corresponding vpush instruction will
1308 // decrease $sp by (8 * Count).
1309 SPOffset
-= Count
* (IsVector
? 8 : 4);
1312 FlushPendingOffset();
1314 UnwindOpAsm
.EmitVFPRegSave(Mask
);
1316 UnwindOpAsm
.EmitRegSave(Mask
);
1319 void ARMELFStreamer::emitUnwindRaw(int64_t Offset
,
1320 const SmallVectorImpl
<uint8_t> &Opcodes
) {
1321 FlushPendingOffset();
1322 SPOffset
= SPOffset
- Offset
;
1323 UnwindOpAsm
.EmitRaw(Opcodes
);
1328 MCTargetStreamer
*createARMTargetAsmStreamer(MCStreamer
&S
,
1329 formatted_raw_ostream
&OS
,
1330 MCInstPrinter
*InstPrint
,
1331 bool isVerboseAsm
) {
1332 return new ARMTargetAsmStreamer(S
, OS
, *InstPrint
, isVerboseAsm
);
1335 MCTargetStreamer
*createARMNullTargetStreamer(MCStreamer
&S
) {
1336 return new ARMTargetStreamer(S
);
1339 MCTargetStreamer
*createARMObjectTargetStreamer(MCStreamer
&S
,
1340 const MCSubtargetInfo
&STI
) {
1341 const Triple
&TT
= STI
.getTargetTriple();
1342 if (TT
.isOSBinFormatELF())
1343 return new ARMTargetELFStreamer(S
);
1344 return new ARMTargetStreamer(S
);
1347 MCELFStreamer
*createARMELFStreamer(MCContext
&Context
,
1348 std::unique_ptr
<MCAsmBackend
> TAB
,
1349 std::unique_ptr
<MCObjectWriter
> OW
,
1350 std::unique_ptr
<MCCodeEmitter
> Emitter
,
1351 bool RelaxAll
, bool IsThumb
,
1354 new ARMELFStreamer(Context
, std::move(TAB
), std::move(OW
),
1355 std::move(Emitter
), IsThumb
, IsAndroid
);
1356 // FIXME: This should eventually end up somewhere else where more
1357 // intelligent flag decisions can be made. For now we are just maintaining
1358 // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
1359 S
->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5
);
1362 S
->getAssembler().setRelaxAll(true);
1366 } // end namespace llvm