106f32e7eSjoerg //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file assembles .s files and emits ARM ELF .o object files. Different
1006f32e7eSjoerg // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
1106f32e7eSjoerg // delimit regions of data and code.
1206f32e7eSjoerg //
1306f32e7eSjoerg //===----------------------------------------------------------------------===//
1406f32e7eSjoerg
1506f32e7eSjoerg #include "ARMRegisterInfo.h"
1606f32e7eSjoerg #include "ARMUnwindOpAsm.h"
1706f32e7eSjoerg #include "llvm/ADT/DenseMap.h"
1806f32e7eSjoerg #include "llvm/ADT/SmallString.h"
1906f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
2006f32e7eSjoerg #include "llvm/ADT/StringRef.h"
2106f32e7eSjoerg #include "llvm/ADT/Triple.h"
2206f32e7eSjoerg #include "llvm/ADT/Twine.h"
2306f32e7eSjoerg #include "llvm/BinaryFormat/ELF.h"
2406f32e7eSjoerg #include "llvm/MC/MCAsmBackend.h"
2506f32e7eSjoerg #include "llvm/MC/MCAsmInfo.h"
2606f32e7eSjoerg #include "llvm/MC/MCAssembler.h"
2706f32e7eSjoerg #include "llvm/MC/MCCodeEmitter.h"
2806f32e7eSjoerg #include "llvm/MC/MCContext.h"
2906f32e7eSjoerg #include "llvm/MC/MCELFStreamer.h"
3006f32e7eSjoerg #include "llvm/MC/MCExpr.h"
3106f32e7eSjoerg #include "llvm/MC/MCFixup.h"
3206f32e7eSjoerg #include "llvm/MC/MCFragment.h"
3306f32e7eSjoerg #include "llvm/MC/MCInst.h"
3406f32e7eSjoerg #include "llvm/MC/MCInstPrinter.h"
3506f32e7eSjoerg #include "llvm/MC/MCObjectWriter.h"
3606f32e7eSjoerg #include "llvm/MC/MCRegisterInfo.h"
3706f32e7eSjoerg #include "llvm/MC/MCSection.h"
3806f32e7eSjoerg #include "llvm/MC/MCSectionELF.h"
3906f32e7eSjoerg #include "llvm/MC/MCStreamer.h"
4006f32e7eSjoerg #include "llvm/MC/MCSubtargetInfo.h"
4106f32e7eSjoerg #include "llvm/MC/MCSymbol.h"
4206f32e7eSjoerg #include "llvm/MC/MCSymbolELF.h"
4306f32e7eSjoerg #include "llvm/MC/SectionKind.h"
4406f32e7eSjoerg #include "llvm/Support/ARMBuildAttributes.h"
4506f32e7eSjoerg #include "llvm/Support/ARMEHABI.h"
4606f32e7eSjoerg #include "llvm/Support/Casting.h"
4706f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
4806f32e7eSjoerg #include "llvm/Support/FormattedStream.h"
4906f32e7eSjoerg #include "llvm/Support/LEB128.h"
5006f32e7eSjoerg #include "llvm/Support/TargetParser.h"
5106f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
5206f32e7eSjoerg #include <algorithm>
5306f32e7eSjoerg #include <cassert>
5406f32e7eSjoerg #include <climits>
5506f32e7eSjoerg #include <cstddef>
5606f32e7eSjoerg #include <cstdint>
5706f32e7eSjoerg #include <string>
5806f32e7eSjoerg
5906f32e7eSjoerg using namespace llvm;
6006f32e7eSjoerg
GetAEABIUnwindPersonalityName(unsigned Index)6106f32e7eSjoerg static std::string GetAEABIUnwindPersonalityName(unsigned Index) {
6206f32e7eSjoerg assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX &&
6306f32e7eSjoerg "Invalid personality index");
6406f32e7eSjoerg return (Twine("__aeabi_unwind_cpp_pr") + Twine(Index)).str();
6506f32e7eSjoerg }
6606f32e7eSjoerg
6706f32e7eSjoerg namespace {
6806f32e7eSjoerg
6906f32e7eSjoerg class ARMELFStreamer;
7006f32e7eSjoerg
7106f32e7eSjoerg class ARMTargetAsmStreamer : public ARMTargetStreamer {
7206f32e7eSjoerg formatted_raw_ostream &OS;
7306f32e7eSjoerg MCInstPrinter &InstPrinter;
7406f32e7eSjoerg bool IsVerboseAsm;
7506f32e7eSjoerg
7606f32e7eSjoerg void emitFnStart() override;
7706f32e7eSjoerg void emitFnEnd() override;
7806f32e7eSjoerg void emitCantUnwind() override;
7906f32e7eSjoerg void emitPersonality(const MCSymbol *Personality) override;
8006f32e7eSjoerg void emitPersonalityIndex(unsigned Index) override;
8106f32e7eSjoerg void emitHandlerData() override;
8206f32e7eSjoerg void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
8306f32e7eSjoerg void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
8406f32e7eSjoerg void emitPad(int64_t Offset) override;
8506f32e7eSjoerg void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
8606f32e7eSjoerg bool isVector) override;
8706f32e7eSjoerg void emitUnwindRaw(int64_t Offset,
8806f32e7eSjoerg const SmallVectorImpl<uint8_t> &Opcodes) override;
8906f32e7eSjoerg
9006f32e7eSjoerg void switchVendor(StringRef Vendor) override;
9106f32e7eSjoerg void emitAttribute(unsigned Attribute, unsigned Value) override;
9206f32e7eSjoerg void emitTextAttribute(unsigned Attribute, StringRef String) override;
9306f32e7eSjoerg void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
9406f32e7eSjoerg StringRef StringValue) override;
9506f32e7eSjoerg void emitArch(ARM::ArchKind Arch) override;
96*da58b97aSjoerg void emitArchExtension(uint64_t ArchExt) override;
9706f32e7eSjoerg void emitObjectArch(ARM::ArchKind Arch) override;
9806f32e7eSjoerg void emitFPU(unsigned FPU) override;
9906f32e7eSjoerg void emitInst(uint32_t Inst, char Suffix = '\0') override;
10006f32e7eSjoerg void finishAttributeSection() override;
10106f32e7eSjoerg
10206f32e7eSjoerg void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
10306f32e7eSjoerg void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
10406f32e7eSjoerg
10506f32e7eSjoerg public:
10606f32e7eSjoerg ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
10706f32e7eSjoerg MCInstPrinter &InstPrinter, bool VerboseAsm);
10806f32e7eSjoerg };
10906f32e7eSjoerg
ARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter & InstPrinter,bool VerboseAsm)11006f32e7eSjoerg ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
11106f32e7eSjoerg formatted_raw_ostream &OS,
11206f32e7eSjoerg MCInstPrinter &InstPrinter,
11306f32e7eSjoerg bool VerboseAsm)
11406f32e7eSjoerg : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
11506f32e7eSjoerg IsVerboseAsm(VerboseAsm) {}
11606f32e7eSjoerg
emitFnStart()11706f32e7eSjoerg void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
emitFnEnd()11806f32e7eSjoerg void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
emitCantUnwind()11906f32e7eSjoerg void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
12006f32e7eSjoerg
emitPersonality(const MCSymbol * Personality)12106f32e7eSjoerg void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
12206f32e7eSjoerg OS << "\t.personality " << Personality->getName() << '\n';
12306f32e7eSjoerg }
12406f32e7eSjoerg
emitPersonalityIndex(unsigned Index)12506f32e7eSjoerg void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
12606f32e7eSjoerg OS << "\t.personalityindex " << Index << '\n';
12706f32e7eSjoerg }
12806f32e7eSjoerg
emitHandlerData()12906f32e7eSjoerg void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
13006f32e7eSjoerg
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)13106f32e7eSjoerg void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
13206f32e7eSjoerg int64_t Offset) {
13306f32e7eSjoerg OS << "\t.setfp\t";
13406f32e7eSjoerg InstPrinter.printRegName(OS, FpReg);
13506f32e7eSjoerg OS << ", ";
13606f32e7eSjoerg InstPrinter.printRegName(OS, SpReg);
13706f32e7eSjoerg if (Offset)
13806f32e7eSjoerg OS << ", #" << Offset;
13906f32e7eSjoerg OS << '\n';
14006f32e7eSjoerg }
14106f32e7eSjoerg
emitMovSP(unsigned Reg,int64_t Offset)14206f32e7eSjoerg void ARMTargetAsmStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
14306f32e7eSjoerg assert((Reg != ARM::SP && Reg != ARM::PC) &&
14406f32e7eSjoerg "the operand of .movsp cannot be either sp or pc");
14506f32e7eSjoerg
14606f32e7eSjoerg OS << "\t.movsp\t";
14706f32e7eSjoerg InstPrinter.printRegName(OS, Reg);
14806f32e7eSjoerg if (Offset)
14906f32e7eSjoerg OS << ", #" << Offset;
15006f32e7eSjoerg OS << '\n';
15106f32e7eSjoerg }
15206f32e7eSjoerg
emitPad(int64_t Offset)15306f32e7eSjoerg void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
15406f32e7eSjoerg OS << "\t.pad\t#" << Offset << '\n';
15506f32e7eSjoerg }
15606f32e7eSjoerg
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)15706f32e7eSjoerg void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
15806f32e7eSjoerg bool isVector) {
15906f32e7eSjoerg assert(RegList.size() && "RegList should not be empty");
16006f32e7eSjoerg if (isVector)
16106f32e7eSjoerg OS << "\t.vsave\t{";
16206f32e7eSjoerg else
16306f32e7eSjoerg OS << "\t.save\t{";
16406f32e7eSjoerg
16506f32e7eSjoerg InstPrinter.printRegName(OS, RegList[0]);
16606f32e7eSjoerg
16706f32e7eSjoerg for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
16806f32e7eSjoerg OS << ", ";
16906f32e7eSjoerg InstPrinter.printRegName(OS, RegList[i]);
17006f32e7eSjoerg }
17106f32e7eSjoerg
17206f32e7eSjoerg OS << "}\n";
17306f32e7eSjoerg }
17406f32e7eSjoerg
switchVendor(StringRef Vendor)17506f32e7eSjoerg void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
17606f32e7eSjoerg
emitAttribute(unsigned Attribute,unsigned Value)17706f32e7eSjoerg void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
17806f32e7eSjoerg OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
17906f32e7eSjoerg if (IsVerboseAsm) {
180*da58b97aSjoerg StringRef Name =
181*da58b97aSjoerg ELFAttrs::attrTypeAsString(Attribute, ARMBuildAttrs::ARMAttributeTags);
18206f32e7eSjoerg if (!Name.empty())
18306f32e7eSjoerg OS << "\t@ " << Name;
18406f32e7eSjoerg }
18506f32e7eSjoerg OS << "\n";
18606f32e7eSjoerg }
18706f32e7eSjoerg
emitTextAttribute(unsigned Attribute,StringRef String)18806f32e7eSjoerg void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
18906f32e7eSjoerg StringRef String) {
19006f32e7eSjoerg switch (Attribute) {
19106f32e7eSjoerg case ARMBuildAttrs::CPU_name:
19206f32e7eSjoerg OS << "\t.cpu\t" << String.lower();
19306f32e7eSjoerg break;
19406f32e7eSjoerg default:
19506f32e7eSjoerg OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
19606f32e7eSjoerg if (IsVerboseAsm) {
197*da58b97aSjoerg StringRef Name = ELFAttrs::attrTypeAsString(
198*da58b97aSjoerg Attribute, ARMBuildAttrs::ARMAttributeTags);
19906f32e7eSjoerg if (!Name.empty())
20006f32e7eSjoerg OS << "\t@ " << Name;
20106f32e7eSjoerg }
20206f32e7eSjoerg break;
20306f32e7eSjoerg }
20406f32e7eSjoerg OS << "\n";
20506f32e7eSjoerg }
20606f32e7eSjoerg
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)20706f32e7eSjoerg void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
20806f32e7eSjoerg unsigned IntValue,
20906f32e7eSjoerg StringRef StringValue) {
21006f32e7eSjoerg switch (Attribute) {
21106f32e7eSjoerg default: llvm_unreachable("unsupported multi-value attribute in asm mode");
21206f32e7eSjoerg case ARMBuildAttrs::compatibility:
21306f32e7eSjoerg OS << "\t.eabi_attribute\t" << Attribute << ", " << IntValue;
21406f32e7eSjoerg if (!StringValue.empty())
21506f32e7eSjoerg OS << ", \"" << StringValue << "\"";
21606f32e7eSjoerg if (IsVerboseAsm)
217*da58b97aSjoerg OS << "\t@ "
218*da58b97aSjoerg << ELFAttrs::attrTypeAsString(Attribute,
219*da58b97aSjoerg ARMBuildAttrs::ARMAttributeTags);
22006f32e7eSjoerg break;
22106f32e7eSjoerg }
22206f32e7eSjoerg OS << "\n";
22306f32e7eSjoerg }
22406f32e7eSjoerg
emitArch(ARM::ArchKind Arch)22506f32e7eSjoerg void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
22606f32e7eSjoerg OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
22706f32e7eSjoerg }
22806f32e7eSjoerg
emitArchExtension(uint64_t ArchExt)229*da58b97aSjoerg void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
23006f32e7eSjoerg OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
23106f32e7eSjoerg }
23206f32e7eSjoerg
emitObjectArch(ARM::ArchKind Arch)23306f32e7eSjoerg void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
23406f32e7eSjoerg OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
23506f32e7eSjoerg }
23606f32e7eSjoerg
emitFPU(unsigned FPU)23706f32e7eSjoerg void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
23806f32e7eSjoerg OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
23906f32e7eSjoerg }
24006f32e7eSjoerg
finishAttributeSection()24106f32e7eSjoerg void ARMTargetAsmStreamer::finishAttributeSection() {}
24206f32e7eSjoerg
24306f32e7eSjoerg void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)24406f32e7eSjoerg ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
245*da58b97aSjoerg OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
24606f32e7eSjoerg }
24706f32e7eSjoerg
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)24806f32e7eSjoerg void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
24906f32e7eSjoerg const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
25006f32e7eSjoerg
25106f32e7eSjoerg OS << "\t.thumb_set\t";
25206f32e7eSjoerg Symbol->print(OS, MAI);
25306f32e7eSjoerg OS << ", ";
25406f32e7eSjoerg Value->print(OS, MAI);
25506f32e7eSjoerg OS << '\n';
25606f32e7eSjoerg }
25706f32e7eSjoerg
emitInst(uint32_t Inst,char Suffix)25806f32e7eSjoerg void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
25906f32e7eSjoerg OS << "\t.inst";
26006f32e7eSjoerg if (Suffix)
26106f32e7eSjoerg OS << "." << Suffix;
26206f32e7eSjoerg OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
26306f32e7eSjoerg }
26406f32e7eSjoerg
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)26506f32e7eSjoerg void ARMTargetAsmStreamer::emitUnwindRaw(int64_t Offset,
26606f32e7eSjoerg const SmallVectorImpl<uint8_t> &Opcodes) {
26706f32e7eSjoerg OS << "\t.unwind_raw " << Offset;
26806f32e7eSjoerg for (SmallVectorImpl<uint8_t>::const_iterator OCI = Opcodes.begin(),
26906f32e7eSjoerg OCE = Opcodes.end();
27006f32e7eSjoerg OCI != OCE; ++OCI)
27106f32e7eSjoerg OS << ", 0x" << Twine::utohexstr(*OCI);
27206f32e7eSjoerg OS << '\n';
27306f32e7eSjoerg }
27406f32e7eSjoerg
27506f32e7eSjoerg class ARMTargetELFStreamer : public ARMTargetStreamer {
27606f32e7eSjoerg private:
27706f32e7eSjoerg // This structure holds all attributes, accounting for
27806f32e7eSjoerg // their string/numeric value, so we can later emit them
27906f32e7eSjoerg // in declaration order, keeping all in the same vector
28006f32e7eSjoerg struct AttributeItem {
28106f32e7eSjoerg enum {
28206f32e7eSjoerg HiddenAttribute = 0,
28306f32e7eSjoerg NumericAttribute,
28406f32e7eSjoerg TextAttribute,
28506f32e7eSjoerg NumericAndTextAttributes
28606f32e7eSjoerg } Type;
28706f32e7eSjoerg unsigned Tag;
28806f32e7eSjoerg unsigned IntValue;
28906f32e7eSjoerg std::string StringValue;
29006f32e7eSjoerg
LessTag__anon5806bc350111::ARMTargetELFStreamer::AttributeItem29106f32e7eSjoerg static bool LessTag(const AttributeItem &LHS, const AttributeItem &RHS) {
29206f32e7eSjoerg // The conformance tag must be emitted first when serialised
29306f32e7eSjoerg // into an object file. Specifically, the addenda to the ARM ABI
29406f32e7eSjoerg // states that (2.3.7.4):
29506f32e7eSjoerg //
29606f32e7eSjoerg // "To simplify recognition by consumers in the common case of
29706f32e7eSjoerg // claiming conformity for the whole file, this tag should be
29806f32e7eSjoerg // emitted first in a file-scope sub-subsection of the first
29906f32e7eSjoerg // public subsection of the attributes section."
30006f32e7eSjoerg //
30106f32e7eSjoerg // So it is special-cased in this comparison predicate when the
30206f32e7eSjoerg // attributes are sorted in finishAttributeSection().
30306f32e7eSjoerg return (RHS.Tag != ARMBuildAttrs::conformance) &&
30406f32e7eSjoerg ((LHS.Tag == ARMBuildAttrs::conformance) || (LHS.Tag < RHS.Tag));
30506f32e7eSjoerg }
30606f32e7eSjoerg };
30706f32e7eSjoerg
30806f32e7eSjoerg StringRef CurrentVendor;
30906f32e7eSjoerg unsigned FPU = ARM::FK_INVALID;
31006f32e7eSjoerg ARM::ArchKind Arch = ARM::ArchKind::INVALID;
31106f32e7eSjoerg ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
31206f32e7eSjoerg SmallVector<AttributeItem, 64> Contents;
31306f32e7eSjoerg
31406f32e7eSjoerg MCSection *AttributeSection = nullptr;
31506f32e7eSjoerg
getAttributeItem(unsigned Attribute)31606f32e7eSjoerg AttributeItem *getAttributeItem(unsigned Attribute) {
31706f32e7eSjoerg for (size_t i = 0; i < Contents.size(); ++i)
31806f32e7eSjoerg if (Contents[i].Tag == Attribute)
31906f32e7eSjoerg return &Contents[i];
32006f32e7eSjoerg return nullptr;
32106f32e7eSjoerg }
32206f32e7eSjoerg
setAttributeItem(unsigned Attribute,unsigned Value,bool OverwriteExisting)32306f32e7eSjoerg void setAttributeItem(unsigned Attribute, unsigned Value,
32406f32e7eSjoerg bool OverwriteExisting) {
32506f32e7eSjoerg // Look for existing attribute item
32606f32e7eSjoerg if (AttributeItem *Item = getAttributeItem(Attribute)) {
32706f32e7eSjoerg if (!OverwriteExisting)
32806f32e7eSjoerg return;
32906f32e7eSjoerg Item->Type = AttributeItem::NumericAttribute;
33006f32e7eSjoerg Item->IntValue = Value;
33106f32e7eSjoerg return;
33206f32e7eSjoerg }
33306f32e7eSjoerg
33406f32e7eSjoerg // Create new attribute item
335*da58b97aSjoerg AttributeItem Item = {AttributeItem::NumericAttribute, Attribute, Value,
336*da58b97aSjoerg std::string(StringRef(""))};
33706f32e7eSjoerg Contents.push_back(Item);
33806f32e7eSjoerg }
33906f32e7eSjoerg
setAttributeItem(unsigned Attribute,StringRef Value,bool OverwriteExisting)34006f32e7eSjoerg void setAttributeItem(unsigned Attribute, StringRef Value,
34106f32e7eSjoerg bool OverwriteExisting) {
34206f32e7eSjoerg // Look for existing attribute item
34306f32e7eSjoerg if (AttributeItem *Item = getAttributeItem(Attribute)) {
34406f32e7eSjoerg if (!OverwriteExisting)
34506f32e7eSjoerg return;
34606f32e7eSjoerg Item->Type = AttributeItem::TextAttribute;
347*da58b97aSjoerg Item->StringValue = std::string(Value);
34806f32e7eSjoerg return;
34906f32e7eSjoerg }
35006f32e7eSjoerg
35106f32e7eSjoerg // Create new attribute item
352*da58b97aSjoerg AttributeItem Item = {AttributeItem::TextAttribute, Attribute, 0,
353*da58b97aSjoerg std::string(Value)};
35406f32e7eSjoerg Contents.push_back(Item);
35506f32e7eSjoerg }
35606f32e7eSjoerg
setAttributeItems(unsigned Attribute,unsigned IntValue,StringRef StringValue,bool OverwriteExisting)35706f32e7eSjoerg void setAttributeItems(unsigned Attribute, unsigned IntValue,
35806f32e7eSjoerg StringRef StringValue, bool OverwriteExisting) {
35906f32e7eSjoerg // Look for existing attribute item
36006f32e7eSjoerg if (AttributeItem *Item = getAttributeItem(Attribute)) {
36106f32e7eSjoerg if (!OverwriteExisting)
36206f32e7eSjoerg return;
36306f32e7eSjoerg Item->Type = AttributeItem::NumericAndTextAttributes;
36406f32e7eSjoerg Item->IntValue = IntValue;
365*da58b97aSjoerg Item->StringValue = std::string(StringValue);
36606f32e7eSjoerg return;
36706f32e7eSjoerg }
36806f32e7eSjoerg
36906f32e7eSjoerg // Create new attribute item
370*da58b97aSjoerg AttributeItem Item = {AttributeItem::NumericAndTextAttributes, Attribute,
371*da58b97aSjoerg IntValue, std::string(StringValue)};
37206f32e7eSjoerg Contents.push_back(Item);
37306f32e7eSjoerg }
37406f32e7eSjoerg
37506f32e7eSjoerg void emitArchDefaultAttributes();
37606f32e7eSjoerg void emitFPUDefaultAttributes();
37706f32e7eSjoerg
37806f32e7eSjoerg ARMELFStreamer &getStreamer();
37906f32e7eSjoerg
38006f32e7eSjoerg void emitFnStart() override;
38106f32e7eSjoerg void emitFnEnd() override;
38206f32e7eSjoerg void emitCantUnwind() override;
38306f32e7eSjoerg void emitPersonality(const MCSymbol *Personality) override;
38406f32e7eSjoerg void emitPersonalityIndex(unsigned Index) override;
38506f32e7eSjoerg void emitHandlerData() override;
38606f32e7eSjoerg void emitSetFP(unsigned FpReg, unsigned SpReg, int64_t Offset = 0) override;
38706f32e7eSjoerg void emitMovSP(unsigned Reg, int64_t Offset = 0) override;
38806f32e7eSjoerg void emitPad(int64_t Offset) override;
38906f32e7eSjoerg void emitRegSave(const SmallVectorImpl<unsigned> &RegList,
39006f32e7eSjoerg bool isVector) override;
39106f32e7eSjoerg void emitUnwindRaw(int64_t Offset,
39206f32e7eSjoerg const SmallVectorImpl<uint8_t> &Opcodes) override;
39306f32e7eSjoerg
39406f32e7eSjoerg void switchVendor(StringRef Vendor) override;
39506f32e7eSjoerg void emitAttribute(unsigned Attribute, unsigned Value) override;
39606f32e7eSjoerg void emitTextAttribute(unsigned Attribute, StringRef String) override;
39706f32e7eSjoerg void emitIntTextAttribute(unsigned Attribute, unsigned IntValue,
39806f32e7eSjoerg StringRef StringValue) override;
39906f32e7eSjoerg void emitArch(ARM::ArchKind Arch) override;
40006f32e7eSjoerg void emitObjectArch(ARM::ArchKind Arch) override;
40106f32e7eSjoerg void emitFPU(unsigned FPU) override;
40206f32e7eSjoerg void emitInst(uint32_t Inst, char Suffix = '\0') override;
40306f32e7eSjoerg void finishAttributeSection() override;
40406f32e7eSjoerg void emitLabel(MCSymbol *Symbol) override;
40506f32e7eSjoerg
40606f32e7eSjoerg void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
40706f32e7eSjoerg void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
40806f32e7eSjoerg
40906f32e7eSjoerg size_t calculateContentSize() const;
41006f32e7eSjoerg
41106f32e7eSjoerg // Reset state between object emissions
41206f32e7eSjoerg void reset() override;
41306f32e7eSjoerg
41406f32e7eSjoerg public:
ARMTargetELFStreamer(MCStreamer & S)41506f32e7eSjoerg ARMTargetELFStreamer(MCStreamer &S)
41606f32e7eSjoerg : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
41706f32e7eSjoerg };
41806f32e7eSjoerg
41906f32e7eSjoerg /// Extend the generic ELFStreamer class so that it can emit mapping symbols at
42006f32e7eSjoerg /// the appropriate points in the object files. These symbols are defined in the
42106f32e7eSjoerg /// ARM ELF ABI: infocenter.arm.com/help/topic/com.arm.../IHI0044D_aaelf.pdf.
42206f32e7eSjoerg ///
42306f32e7eSjoerg /// In brief: $a, $t or $d should be emitted at the start of each contiguous
42406f32e7eSjoerg /// region of ARM code, Thumb code or data in a section. In practice, this
42506f32e7eSjoerg /// emission does not rely on explicit assembler directives but on inherent
42606f32e7eSjoerg /// properties of the directives doing the emission (e.g. ".byte" is data, "add
42706f32e7eSjoerg /// r0, r0, r0" an instruction).
42806f32e7eSjoerg ///
42906f32e7eSjoerg /// As a result this system is orthogonal to the DataRegion infrastructure used
43006f32e7eSjoerg /// by MachO. Beware!
43106f32e7eSjoerg class ARMELFStreamer : public MCELFStreamer {
43206f32e7eSjoerg public:
43306f32e7eSjoerg friend class ARMTargetELFStreamer;
43406f32e7eSjoerg
ARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool IsThumb,bool IsAndroid)43506f32e7eSjoerg ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
436*da58b97aSjoerg std::unique_ptr<MCObjectWriter> OW,
437*da58b97aSjoerg std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
438*da58b97aSjoerg bool IsAndroid)
439*da58b97aSjoerg : MCELFStreamer(Context, std::move(TAB), std::move(OW),
440*da58b97aSjoerg std::move(Emitter)),
441*da58b97aSjoerg IsThumb(IsThumb), IsAndroid(IsAndroid) {
44206f32e7eSjoerg EHReset();
44306f32e7eSjoerg }
44406f32e7eSjoerg
44506f32e7eSjoerg ~ARMELFStreamer() override = default;
44606f32e7eSjoerg
447*da58b97aSjoerg void finishImpl() override;
44806f32e7eSjoerg
44906f32e7eSjoerg // ARM exception handling directives
45006f32e7eSjoerg void emitFnStart();
45106f32e7eSjoerg void emitFnEnd();
45206f32e7eSjoerg void emitCantUnwind();
45306f32e7eSjoerg void emitPersonality(const MCSymbol *Per);
45406f32e7eSjoerg void emitPersonalityIndex(unsigned index);
45506f32e7eSjoerg void emitHandlerData();
45606f32e7eSjoerg void emitSetFP(unsigned NewFpReg, unsigned NewSpReg, int64_t Offset = 0);
45706f32e7eSjoerg void emitMovSP(unsigned Reg, int64_t Offset = 0);
45806f32e7eSjoerg void emitPad(int64_t Offset);
45906f32e7eSjoerg void emitRegSave(const SmallVectorImpl<unsigned> &RegList, bool isVector);
46006f32e7eSjoerg void emitUnwindRaw(int64_t Offset, const SmallVectorImpl<uint8_t> &Opcodes);
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)46106f32e7eSjoerg void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
46206f32e7eSjoerg SMLoc Loc) override {
463*da58b97aSjoerg emitDataMappingSymbol();
46406f32e7eSjoerg MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
46506f32e7eSjoerg }
46606f32e7eSjoerg
changeSection(MCSection * Section,const MCExpr * Subsection)467*da58b97aSjoerg void changeSection(MCSection *Section, const MCExpr *Subsection) override {
46806f32e7eSjoerg LastMappingSymbols[getCurrentSection().first] = std::move(LastEMSInfo);
469*da58b97aSjoerg MCELFStreamer::changeSection(Section, Subsection);
47006f32e7eSjoerg auto LastMappingSymbol = LastMappingSymbols.find(Section);
47106f32e7eSjoerg if (LastMappingSymbol != LastMappingSymbols.end()) {
47206f32e7eSjoerg LastEMSInfo = std::move(LastMappingSymbol->second);
47306f32e7eSjoerg return;
47406f32e7eSjoerg }
47506f32e7eSjoerg LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
47606f32e7eSjoerg }
47706f32e7eSjoerg
47806f32e7eSjoerg /// This function is the one used to emit instruction data into the ELF
47906f32e7eSjoerg /// streamer. We override it to add the appropriate mapping symbol if
48006f32e7eSjoerg /// necessary.
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)481*da58b97aSjoerg void emitInstruction(const MCInst &Inst,
48206f32e7eSjoerg const MCSubtargetInfo &STI) override {
48306f32e7eSjoerg if (IsThumb)
48406f32e7eSjoerg EmitThumbMappingSymbol();
48506f32e7eSjoerg else
48606f32e7eSjoerg EmitARMMappingSymbol();
48706f32e7eSjoerg
488*da58b97aSjoerg MCELFStreamer::emitInstruction(Inst, STI);
48906f32e7eSjoerg }
49006f32e7eSjoerg
emitInst(uint32_t Inst,char Suffix)49106f32e7eSjoerg void emitInst(uint32_t Inst, char Suffix) {
49206f32e7eSjoerg unsigned Size;
49306f32e7eSjoerg char Buffer[4];
49406f32e7eSjoerg const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
49506f32e7eSjoerg
49606f32e7eSjoerg switch (Suffix) {
49706f32e7eSjoerg case '\0':
49806f32e7eSjoerg Size = 4;
49906f32e7eSjoerg
50006f32e7eSjoerg assert(!IsThumb);
50106f32e7eSjoerg EmitARMMappingSymbol();
50206f32e7eSjoerg for (unsigned II = 0, IE = Size; II != IE; II++) {
50306f32e7eSjoerg const unsigned I = LittleEndian ? (Size - II - 1) : II;
50406f32e7eSjoerg Buffer[Size - II - 1] = uint8_t(Inst >> I * CHAR_BIT);
50506f32e7eSjoerg }
50606f32e7eSjoerg
50706f32e7eSjoerg break;
50806f32e7eSjoerg case 'n':
50906f32e7eSjoerg case 'w':
51006f32e7eSjoerg Size = (Suffix == 'n' ? 2 : 4);
51106f32e7eSjoerg
51206f32e7eSjoerg assert(IsThumb);
51306f32e7eSjoerg EmitThumbMappingSymbol();
51406f32e7eSjoerg // Thumb wide instructions are emitted as a pair of 16-bit words of the
51506f32e7eSjoerg // appropriate endianness.
51606f32e7eSjoerg for (unsigned II = 0, IE = Size; II != IE; II = II + 2) {
51706f32e7eSjoerg const unsigned I0 = LittleEndian ? II + 0 : II + 1;
51806f32e7eSjoerg const unsigned I1 = LittleEndian ? II + 1 : II + 0;
51906f32e7eSjoerg Buffer[Size - II - 2] = uint8_t(Inst >> I0 * CHAR_BIT);
52006f32e7eSjoerg Buffer[Size - II - 1] = uint8_t(Inst >> I1 * CHAR_BIT);
52106f32e7eSjoerg }
52206f32e7eSjoerg
52306f32e7eSjoerg break;
52406f32e7eSjoerg default:
52506f32e7eSjoerg llvm_unreachable("Invalid Suffix");
52606f32e7eSjoerg }
52706f32e7eSjoerg
528*da58b97aSjoerg MCELFStreamer::emitBytes(StringRef(Buffer, Size));
52906f32e7eSjoerg }
53006f32e7eSjoerg
53106f32e7eSjoerg /// This is one of the functions used to emit data into an ELF section, so the
53206f32e7eSjoerg /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
53306f32e7eSjoerg /// necessary.
emitBytes(StringRef Data)534*da58b97aSjoerg void emitBytes(StringRef Data) override {
535*da58b97aSjoerg emitDataMappingSymbol();
536*da58b97aSjoerg MCELFStreamer::emitBytes(Data);
53706f32e7eSjoerg }
53806f32e7eSjoerg
FlushPendingMappingSymbol()53906f32e7eSjoerg void FlushPendingMappingSymbol() {
54006f32e7eSjoerg if (!LastEMSInfo->hasInfo())
54106f32e7eSjoerg return;
54206f32e7eSjoerg ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
54306f32e7eSjoerg EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
54406f32e7eSjoerg EMS->resetInfo();
54506f32e7eSjoerg }
54606f32e7eSjoerg
54706f32e7eSjoerg /// This is one of the functions used to emit data into an ELF section, so the
54806f32e7eSjoerg /// ARM streamer overrides it to add the appropriate mapping symbol ($d) if
54906f32e7eSjoerg /// necessary.
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)550*da58b97aSjoerg void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
55106f32e7eSjoerg if (const MCSymbolRefExpr *SRE = dyn_cast_or_null<MCSymbolRefExpr>(Value)) {
55206f32e7eSjoerg if (SRE->getKind() == MCSymbolRefExpr::VK_ARM_SBREL && !(Size == 4)) {
55306f32e7eSjoerg getContext().reportError(Loc, "relocated expression must be 32-bit");
55406f32e7eSjoerg return;
55506f32e7eSjoerg }
55606f32e7eSjoerg getOrCreateDataFragment();
55706f32e7eSjoerg }
55806f32e7eSjoerg
559*da58b97aSjoerg emitDataMappingSymbol();
560*da58b97aSjoerg MCELFStreamer::emitValueImpl(Value, Size, Loc);
56106f32e7eSjoerg }
56206f32e7eSjoerg
emitAssemblerFlag(MCAssemblerFlag Flag)563*da58b97aSjoerg void emitAssemblerFlag(MCAssemblerFlag Flag) override {
564*da58b97aSjoerg MCELFStreamer::emitAssemblerFlag(Flag);
56506f32e7eSjoerg
56606f32e7eSjoerg switch (Flag) {
56706f32e7eSjoerg case MCAF_SyntaxUnified:
56806f32e7eSjoerg return; // no-op here.
56906f32e7eSjoerg case MCAF_Code16:
57006f32e7eSjoerg IsThumb = true;
57106f32e7eSjoerg return; // Change to Thumb mode
57206f32e7eSjoerg case MCAF_Code32:
57306f32e7eSjoerg IsThumb = false;
57406f32e7eSjoerg return; // Change to ARM mode
57506f32e7eSjoerg case MCAF_Code64:
57606f32e7eSjoerg return;
57706f32e7eSjoerg case MCAF_SubsectionsViaSymbols:
57806f32e7eSjoerg return;
57906f32e7eSjoerg }
58006f32e7eSjoerg }
58106f32e7eSjoerg
582*da58b97aSjoerg /// If a label is defined before the .type directive sets the label's type
583*da58b97aSjoerg /// then the label can't be recorded as thumb function when the label is
584*da58b97aSjoerg /// defined. We override emitSymbolAttribute() which is called as part of the
585*da58b97aSjoerg /// parsing of .type so that if the symbol has already been defined we can
586*da58b97aSjoerg /// record the label as Thumb. FIXME: there is a corner case where the state
587*da58b97aSjoerg /// is changed in between the label definition and the .type directive, this
588*da58b97aSjoerg /// is not expected to occur in practice and handling it would require the
589*da58b97aSjoerg /// backend to track IsThumb for every label.
emitSymbolAttribute(MCSymbol * Symbol,MCSymbolAttr Attribute)590*da58b97aSjoerg bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
591*da58b97aSjoerg bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);
592*da58b97aSjoerg
593*da58b97aSjoerg if (!IsThumb)
594*da58b97aSjoerg return Val;
595*da58b97aSjoerg
596*da58b97aSjoerg unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
597*da58b97aSjoerg if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
598*da58b97aSjoerg Symbol->isDefined())
599*da58b97aSjoerg getAssembler().setIsThumbFunc(Symbol);
600*da58b97aSjoerg
601*da58b97aSjoerg return Val;
602*da58b97aSjoerg };
603*da58b97aSjoerg
60406f32e7eSjoerg private:
60506f32e7eSjoerg enum ElfMappingSymbol {
60606f32e7eSjoerg EMS_None,
60706f32e7eSjoerg EMS_ARM,
60806f32e7eSjoerg EMS_Thumb,
60906f32e7eSjoerg EMS_Data
61006f32e7eSjoerg };
61106f32e7eSjoerg
61206f32e7eSjoerg struct ElfMappingSymbolInfo {
ElfMappingSymbolInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61306f32e7eSjoerg explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
61406f32e7eSjoerg : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
resetInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61506f32e7eSjoerg void resetInfo() {
61606f32e7eSjoerg F = nullptr;
61706f32e7eSjoerg Offset = 0;
61806f32e7eSjoerg }
hasInfo__anon5806bc350111::ARMELFStreamer::ElfMappingSymbolInfo61906f32e7eSjoerg bool hasInfo() { return F != nullptr; }
62006f32e7eSjoerg SMLoc Loc;
62106f32e7eSjoerg MCFragment *F;
62206f32e7eSjoerg uint64_t Offset;
62306f32e7eSjoerg ElfMappingSymbol State;
62406f32e7eSjoerg };
62506f32e7eSjoerg
emitDataMappingSymbol()626*da58b97aSjoerg void emitDataMappingSymbol() {
62706f32e7eSjoerg if (LastEMSInfo->State == EMS_Data)
62806f32e7eSjoerg return;
62906f32e7eSjoerg else if (LastEMSInfo->State == EMS_None) {
63006f32e7eSjoerg // This is a tentative symbol, it won't really be emitted until it's
63106f32e7eSjoerg // actually needed.
63206f32e7eSjoerg ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
63306f32e7eSjoerg auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
63406f32e7eSjoerg if (!DF)
63506f32e7eSjoerg return;
63606f32e7eSjoerg EMS->Loc = SMLoc();
63706f32e7eSjoerg EMS->F = getCurrentFragment();
63806f32e7eSjoerg EMS->Offset = DF->getContents().size();
63906f32e7eSjoerg LastEMSInfo->State = EMS_Data;
64006f32e7eSjoerg return;
64106f32e7eSjoerg }
64206f32e7eSjoerg EmitMappingSymbol("$d");
64306f32e7eSjoerg LastEMSInfo->State = EMS_Data;
64406f32e7eSjoerg }
64506f32e7eSjoerg
EmitThumbMappingSymbol()64606f32e7eSjoerg void EmitThumbMappingSymbol() {
64706f32e7eSjoerg if (LastEMSInfo->State == EMS_Thumb)
64806f32e7eSjoerg return;
64906f32e7eSjoerg FlushPendingMappingSymbol();
65006f32e7eSjoerg EmitMappingSymbol("$t");
65106f32e7eSjoerg LastEMSInfo->State = EMS_Thumb;
65206f32e7eSjoerg }
65306f32e7eSjoerg
EmitARMMappingSymbol()65406f32e7eSjoerg void EmitARMMappingSymbol() {
65506f32e7eSjoerg if (LastEMSInfo->State == EMS_ARM)
65606f32e7eSjoerg return;
65706f32e7eSjoerg FlushPendingMappingSymbol();
65806f32e7eSjoerg EmitMappingSymbol("$a");
65906f32e7eSjoerg LastEMSInfo->State = EMS_ARM;
66006f32e7eSjoerg }
66106f32e7eSjoerg
EmitMappingSymbol(StringRef Name)66206f32e7eSjoerg void EmitMappingSymbol(StringRef Name) {
66306f32e7eSjoerg auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
66406f32e7eSjoerg Name + "." + Twine(MappingSymbolCounter++)));
665*da58b97aSjoerg emitLabel(Symbol);
66606f32e7eSjoerg
66706f32e7eSjoerg Symbol->setType(ELF::STT_NOTYPE);
66806f32e7eSjoerg Symbol->setBinding(ELF::STB_LOCAL);
66906f32e7eSjoerg }
67006f32e7eSjoerg
EmitMappingSymbol(StringRef Name,SMLoc Loc,MCFragment * F,uint64_t Offset)67106f32e7eSjoerg void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
67206f32e7eSjoerg uint64_t Offset) {
67306f32e7eSjoerg auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
67406f32e7eSjoerg Name + "." + Twine(MappingSymbolCounter++)));
675*da58b97aSjoerg emitLabelAtPos(Symbol, Loc, F, Offset);
67606f32e7eSjoerg Symbol->setType(ELF::STT_NOTYPE);
67706f32e7eSjoerg Symbol->setBinding(ELF::STB_LOCAL);
67806f32e7eSjoerg }
67906f32e7eSjoerg
emitThumbFunc(MCSymbol * Func)680*da58b97aSjoerg void emitThumbFunc(MCSymbol *Func) override {
68106f32e7eSjoerg getAssembler().setIsThumbFunc(Func);
682*da58b97aSjoerg emitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
68306f32e7eSjoerg }
68406f32e7eSjoerg
68506f32e7eSjoerg // Helper functions for ARM exception handling directives
68606f32e7eSjoerg void EHReset();
68706f32e7eSjoerg
68806f32e7eSjoerg // Reset state between object emissions
68906f32e7eSjoerg void reset() override;
69006f32e7eSjoerg
69106f32e7eSjoerg void EmitPersonalityFixup(StringRef Name);
69206f32e7eSjoerg void FlushPendingOffset();
69306f32e7eSjoerg void FlushUnwindOpcodes(bool NoHandlerData);
69406f32e7eSjoerg
69506f32e7eSjoerg void SwitchToEHSection(StringRef Prefix, unsigned Type, unsigned Flags,
69606f32e7eSjoerg SectionKind Kind, const MCSymbol &Fn);
69706f32e7eSjoerg void SwitchToExTabSection(const MCSymbol &FnStart);
69806f32e7eSjoerg void SwitchToExIdxSection(const MCSymbol &FnStart);
69906f32e7eSjoerg
70006f32e7eSjoerg void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
70106f32e7eSjoerg
70206f32e7eSjoerg bool IsThumb;
703*da58b97aSjoerg bool IsAndroid;
70406f32e7eSjoerg int64_t MappingSymbolCounter = 0;
70506f32e7eSjoerg
70606f32e7eSjoerg DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
70706f32e7eSjoerg LastMappingSymbols;
70806f32e7eSjoerg
70906f32e7eSjoerg std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
71006f32e7eSjoerg
71106f32e7eSjoerg // ARM Exception Handling Frame Information
71206f32e7eSjoerg MCSymbol *ExTab;
71306f32e7eSjoerg MCSymbol *FnStart;
71406f32e7eSjoerg const MCSymbol *Personality;
71506f32e7eSjoerg unsigned PersonalityIndex;
71606f32e7eSjoerg unsigned FPReg; // Frame pointer register
71706f32e7eSjoerg int64_t FPOffset; // Offset: (final frame pointer) - (initial $sp)
71806f32e7eSjoerg int64_t SPOffset; // Offset: (final $sp) - (initial $sp)
71906f32e7eSjoerg int64_t PendingOffset; // Offset: (final $sp) - (emitted $sp)
72006f32e7eSjoerg bool UsedFP;
72106f32e7eSjoerg bool CantUnwind;
72206f32e7eSjoerg SmallVector<uint8_t, 64> Opcodes;
72306f32e7eSjoerg UnwindOpcodeAssembler UnwindOpAsm;
72406f32e7eSjoerg };
72506f32e7eSjoerg
72606f32e7eSjoerg } // end anonymous namespace
72706f32e7eSjoerg
getStreamer()72806f32e7eSjoerg ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
72906f32e7eSjoerg return static_cast<ARMELFStreamer &>(Streamer);
73006f32e7eSjoerg }
73106f32e7eSjoerg
emitFnStart()73206f32e7eSjoerg void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
emitFnEnd()73306f32e7eSjoerg void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
emitCantUnwind()73406f32e7eSjoerg void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
73506f32e7eSjoerg
emitPersonality(const MCSymbol * Personality)73606f32e7eSjoerg void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
73706f32e7eSjoerg getStreamer().emitPersonality(Personality);
73806f32e7eSjoerg }
73906f32e7eSjoerg
emitPersonalityIndex(unsigned Index)74006f32e7eSjoerg void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
74106f32e7eSjoerg getStreamer().emitPersonalityIndex(Index);
74206f32e7eSjoerg }
74306f32e7eSjoerg
emitHandlerData()74406f32e7eSjoerg void ARMTargetELFStreamer::emitHandlerData() {
74506f32e7eSjoerg getStreamer().emitHandlerData();
74606f32e7eSjoerg }
74706f32e7eSjoerg
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)74806f32e7eSjoerg void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
74906f32e7eSjoerg int64_t Offset) {
75006f32e7eSjoerg getStreamer().emitSetFP(FpReg, SpReg, Offset);
75106f32e7eSjoerg }
75206f32e7eSjoerg
emitMovSP(unsigned Reg,int64_t Offset)75306f32e7eSjoerg void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
75406f32e7eSjoerg getStreamer().emitMovSP(Reg, Offset);
75506f32e7eSjoerg }
75606f32e7eSjoerg
emitPad(int64_t Offset)75706f32e7eSjoerg void ARMTargetELFStreamer::emitPad(int64_t Offset) {
75806f32e7eSjoerg getStreamer().emitPad(Offset);
75906f32e7eSjoerg }
76006f32e7eSjoerg
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)76106f32e7eSjoerg void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
76206f32e7eSjoerg bool isVector) {
76306f32e7eSjoerg getStreamer().emitRegSave(RegList, isVector);
76406f32e7eSjoerg }
76506f32e7eSjoerg
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)76606f32e7eSjoerg void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
76706f32e7eSjoerg const SmallVectorImpl<uint8_t> &Opcodes) {
76806f32e7eSjoerg getStreamer().emitUnwindRaw(Offset, Opcodes);
76906f32e7eSjoerg }
77006f32e7eSjoerg
switchVendor(StringRef Vendor)77106f32e7eSjoerg void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
77206f32e7eSjoerg assert(!Vendor.empty() && "Vendor cannot be empty.");
77306f32e7eSjoerg
77406f32e7eSjoerg if (CurrentVendor == Vendor)
77506f32e7eSjoerg return;
77606f32e7eSjoerg
77706f32e7eSjoerg if (!CurrentVendor.empty())
77806f32e7eSjoerg finishAttributeSection();
77906f32e7eSjoerg
78006f32e7eSjoerg assert(Contents.empty() &&
78106f32e7eSjoerg ".ARM.attributes should be flushed before changing vendor");
78206f32e7eSjoerg CurrentVendor = Vendor;
78306f32e7eSjoerg
78406f32e7eSjoerg }
78506f32e7eSjoerg
emitAttribute(unsigned Attribute,unsigned Value)78606f32e7eSjoerg void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
78706f32e7eSjoerg setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
78806f32e7eSjoerg }
78906f32e7eSjoerg
emitTextAttribute(unsigned Attribute,StringRef Value)79006f32e7eSjoerg void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
79106f32e7eSjoerg StringRef Value) {
79206f32e7eSjoerg setAttributeItem(Attribute, Value, /* OverwriteExisting= */ true);
79306f32e7eSjoerg }
79406f32e7eSjoerg
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)79506f32e7eSjoerg void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
79606f32e7eSjoerg unsigned IntValue,
79706f32e7eSjoerg StringRef StringValue) {
79806f32e7eSjoerg setAttributeItems(Attribute, IntValue, StringValue,
79906f32e7eSjoerg /* OverwriteExisting= */ true);
80006f32e7eSjoerg }
80106f32e7eSjoerg
emitArch(ARM::ArchKind Value)80206f32e7eSjoerg void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
80306f32e7eSjoerg Arch = Value;
80406f32e7eSjoerg }
80506f32e7eSjoerg
emitObjectArch(ARM::ArchKind Value)80606f32e7eSjoerg void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
80706f32e7eSjoerg EmittedArch = Value;
80806f32e7eSjoerg }
80906f32e7eSjoerg
emitArchDefaultAttributes()81006f32e7eSjoerg void ARMTargetELFStreamer::emitArchDefaultAttributes() {
81106f32e7eSjoerg using namespace ARMBuildAttrs;
81206f32e7eSjoerg
81306f32e7eSjoerg setAttributeItem(CPU_name,
81406f32e7eSjoerg ARM::getCPUAttr(Arch),
81506f32e7eSjoerg false);
81606f32e7eSjoerg
81706f32e7eSjoerg if (EmittedArch == ARM::ArchKind::INVALID)
81806f32e7eSjoerg setAttributeItem(CPU_arch,
81906f32e7eSjoerg ARM::getArchAttr(Arch),
82006f32e7eSjoerg false);
82106f32e7eSjoerg else
82206f32e7eSjoerg setAttributeItem(CPU_arch,
82306f32e7eSjoerg ARM::getArchAttr(EmittedArch),
82406f32e7eSjoerg false);
82506f32e7eSjoerg
82606f32e7eSjoerg switch (Arch) {
82706f32e7eSjoerg case ARM::ArchKind::ARMV2:
82806f32e7eSjoerg case ARM::ArchKind::ARMV2A:
82906f32e7eSjoerg case ARM::ArchKind::ARMV3:
83006f32e7eSjoerg case ARM::ArchKind::ARMV3M:
83106f32e7eSjoerg case ARM::ArchKind::ARMV4:
83206f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
83306f32e7eSjoerg break;
83406f32e7eSjoerg
83506f32e7eSjoerg case ARM::ArchKind::ARMV4T:
83606f32e7eSjoerg case ARM::ArchKind::ARMV5T:
83706f32e7eSjoerg case ARM::ArchKind::ARMV5TE:
83806f32e7eSjoerg case ARM::ArchKind::ARMV6:
83906f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
84006f32e7eSjoerg setAttributeItem(THUMB_ISA_use, Allowed, false);
84106f32e7eSjoerg break;
84206f32e7eSjoerg
84306f32e7eSjoerg case ARM::ArchKind::ARMV6T2:
84406f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
84506f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
84606f32e7eSjoerg break;
84706f32e7eSjoerg
84806f32e7eSjoerg case ARM::ArchKind::ARMV6K:
84906f32e7eSjoerg case ARM::ArchKind::ARMV6KZ:
85006f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
85106f32e7eSjoerg setAttributeItem(THUMB_ISA_use, Allowed, false);
85206f32e7eSjoerg setAttributeItem(Virtualization_use, AllowTZ, false);
85306f32e7eSjoerg break;
85406f32e7eSjoerg
85506f32e7eSjoerg case ARM::ArchKind::ARMV6M:
85606f32e7eSjoerg setAttributeItem(THUMB_ISA_use, Allowed, false);
85706f32e7eSjoerg break;
85806f32e7eSjoerg
85906f32e7eSjoerg case ARM::ArchKind::ARMV7A:
86006f32e7eSjoerg setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
86106f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
86206f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
86306f32e7eSjoerg break;
86406f32e7eSjoerg
86506f32e7eSjoerg case ARM::ArchKind::ARMV7R:
86606f32e7eSjoerg setAttributeItem(CPU_arch_profile, RealTimeProfile, false);
86706f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
86806f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
86906f32e7eSjoerg break;
87006f32e7eSjoerg
87106f32e7eSjoerg case ARM::ArchKind::ARMV7EM:
87206f32e7eSjoerg case ARM::ArchKind::ARMV7M:
87306f32e7eSjoerg setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
87406f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
87506f32e7eSjoerg break;
87606f32e7eSjoerg
87706f32e7eSjoerg case ARM::ArchKind::ARMV8A:
87806f32e7eSjoerg case ARM::ArchKind::ARMV8_1A:
87906f32e7eSjoerg case ARM::ArchKind::ARMV8_2A:
88006f32e7eSjoerg case ARM::ArchKind::ARMV8_3A:
88106f32e7eSjoerg case ARM::ArchKind::ARMV8_4A:
88206f32e7eSjoerg case ARM::ArchKind::ARMV8_5A:
883*da58b97aSjoerg case ARM::ArchKind::ARMV8_6A:
88406f32e7eSjoerg setAttributeItem(CPU_arch_profile, ApplicationProfile, false);
88506f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
88606f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
88706f32e7eSjoerg setAttributeItem(MPextension_use, Allowed, false);
88806f32e7eSjoerg setAttributeItem(Virtualization_use, AllowTZVirtualization, false);
88906f32e7eSjoerg break;
89006f32e7eSjoerg
89106f32e7eSjoerg case ARM::ArchKind::ARMV8MBaseline:
89206f32e7eSjoerg case ARM::ArchKind::ARMV8MMainline:
89306f32e7eSjoerg setAttributeItem(THUMB_ISA_use, AllowThumbDerived, false);
89406f32e7eSjoerg setAttributeItem(CPU_arch_profile, MicroControllerProfile, false);
89506f32e7eSjoerg break;
89606f32e7eSjoerg
89706f32e7eSjoerg case ARM::ArchKind::IWMMXT:
89806f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
89906f32e7eSjoerg setAttributeItem(THUMB_ISA_use, Allowed, false);
90006f32e7eSjoerg setAttributeItem(WMMX_arch, AllowWMMXv1, false);
90106f32e7eSjoerg break;
90206f32e7eSjoerg
90306f32e7eSjoerg case ARM::ArchKind::IWMMXT2:
90406f32e7eSjoerg setAttributeItem(ARM_ISA_use, Allowed, false);
90506f32e7eSjoerg setAttributeItem(THUMB_ISA_use, Allowed, false);
90606f32e7eSjoerg setAttributeItem(WMMX_arch, AllowWMMXv2, false);
90706f32e7eSjoerg break;
90806f32e7eSjoerg
90906f32e7eSjoerg default:
91006f32e7eSjoerg report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
91106f32e7eSjoerg break;
91206f32e7eSjoerg }
91306f32e7eSjoerg }
91406f32e7eSjoerg
emitFPU(unsigned Value)91506f32e7eSjoerg void ARMTargetELFStreamer::emitFPU(unsigned Value) {
91606f32e7eSjoerg FPU = Value;
91706f32e7eSjoerg }
91806f32e7eSjoerg
emitFPUDefaultAttributes()91906f32e7eSjoerg void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
92006f32e7eSjoerg switch (FPU) {
92106f32e7eSjoerg case ARM::FK_VFP:
92206f32e7eSjoerg case ARM::FK_VFPV2:
92306f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
92406f32e7eSjoerg ARMBuildAttrs::AllowFPv2,
92506f32e7eSjoerg /* OverwriteExisting= */ false);
92606f32e7eSjoerg break;
92706f32e7eSjoerg
92806f32e7eSjoerg case ARM::FK_VFPV3:
92906f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
93006f32e7eSjoerg ARMBuildAttrs::AllowFPv3A,
93106f32e7eSjoerg /* OverwriteExisting= */ false);
93206f32e7eSjoerg break;
93306f32e7eSjoerg
93406f32e7eSjoerg case ARM::FK_VFPV3_FP16:
93506f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
93606f32e7eSjoerg ARMBuildAttrs::AllowFPv3A,
93706f32e7eSjoerg /* OverwriteExisting= */ false);
93806f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_HP_extension,
93906f32e7eSjoerg ARMBuildAttrs::AllowHPFP,
94006f32e7eSjoerg /* OverwriteExisting= */ false);
94106f32e7eSjoerg break;
94206f32e7eSjoerg
94306f32e7eSjoerg case ARM::FK_VFPV3_D16:
94406f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
94506f32e7eSjoerg ARMBuildAttrs::AllowFPv3B,
94606f32e7eSjoerg /* OverwriteExisting= */ false);
94706f32e7eSjoerg break;
94806f32e7eSjoerg
94906f32e7eSjoerg case ARM::FK_VFPV3_D16_FP16:
95006f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
95106f32e7eSjoerg ARMBuildAttrs::AllowFPv3B,
95206f32e7eSjoerg /* OverwriteExisting= */ false);
95306f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_HP_extension,
95406f32e7eSjoerg ARMBuildAttrs::AllowHPFP,
95506f32e7eSjoerg /* OverwriteExisting= */ false);
95606f32e7eSjoerg break;
95706f32e7eSjoerg
95806f32e7eSjoerg case ARM::FK_VFPV3XD:
95906f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
96006f32e7eSjoerg ARMBuildAttrs::AllowFPv3B,
96106f32e7eSjoerg /* OverwriteExisting= */ false);
96206f32e7eSjoerg break;
96306f32e7eSjoerg case ARM::FK_VFPV3XD_FP16:
96406f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
96506f32e7eSjoerg ARMBuildAttrs::AllowFPv3B,
96606f32e7eSjoerg /* OverwriteExisting= */ false);
96706f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_HP_extension,
96806f32e7eSjoerg ARMBuildAttrs::AllowHPFP,
96906f32e7eSjoerg /* OverwriteExisting= */ false);
97006f32e7eSjoerg break;
97106f32e7eSjoerg
97206f32e7eSjoerg case ARM::FK_VFPV4:
97306f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
97406f32e7eSjoerg ARMBuildAttrs::AllowFPv4A,
97506f32e7eSjoerg /* OverwriteExisting= */ false);
97606f32e7eSjoerg break;
97706f32e7eSjoerg
97806f32e7eSjoerg // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
97906f32e7eSjoerg // as _D16 here.
98006f32e7eSjoerg case ARM::FK_FPV4_SP_D16:
98106f32e7eSjoerg case ARM::FK_VFPV4_D16:
98206f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
98306f32e7eSjoerg ARMBuildAttrs::AllowFPv4B,
98406f32e7eSjoerg /* OverwriteExisting= */ false);
98506f32e7eSjoerg break;
98606f32e7eSjoerg
98706f32e7eSjoerg case ARM::FK_FP_ARMV8:
98806f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
98906f32e7eSjoerg ARMBuildAttrs::AllowFPARMv8A,
99006f32e7eSjoerg /* OverwriteExisting= */ false);
99106f32e7eSjoerg break;
99206f32e7eSjoerg
99306f32e7eSjoerg // FPV5_D16 is identical to FP_ARMV8 except for the number of D registers, so
99406f32e7eSjoerg // uses the FP_ARMV8_D16 build attribute.
99506f32e7eSjoerg case ARM::FK_FPV5_SP_D16:
99606f32e7eSjoerg case ARM::FK_FPV5_D16:
99706f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
99806f32e7eSjoerg ARMBuildAttrs::AllowFPARMv8B,
99906f32e7eSjoerg /* OverwriteExisting= */ false);
100006f32e7eSjoerg break;
100106f32e7eSjoerg
100206f32e7eSjoerg case ARM::FK_NEON:
100306f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
100406f32e7eSjoerg ARMBuildAttrs::AllowFPv3A,
100506f32e7eSjoerg /* OverwriteExisting= */ false);
100606f32e7eSjoerg setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
100706f32e7eSjoerg ARMBuildAttrs::AllowNeon,
100806f32e7eSjoerg /* OverwriteExisting= */ false);
100906f32e7eSjoerg break;
101006f32e7eSjoerg
101106f32e7eSjoerg case ARM::FK_NEON_FP16:
101206f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
101306f32e7eSjoerg ARMBuildAttrs::AllowFPv3A,
101406f32e7eSjoerg /* OverwriteExisting= */ false);
101506f32e7eSjoerg setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
101606f32e7eSjoerg ARMBuildAttrs::AllowNeon,
101706f32e7eSjoerg /* OverwriteExisting= */ false);
101806f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_HP_extension,
101906f32e7eSjoerg ARMBuildAttrs::AllowHPFP,
102006f32e7eSjoerg /* OverwriteExisting= */ false);
102106f32e7eSjoerg break;
102206f32e7eSjoerg
102306f32e7eSjoerg case ARM::FK_NEON_VFPV4:
102406f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
102506f32e7eSjoerg ARMBuildAttrs::AllowFPv4A,
102606f32e7eSjoerg /* OverwriteExisting= */ false);
102706f32e7eSjoerg setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
102806f32e7eSjoerg ARMBuildAttrs::AllowNeon2,
102906f32e7eSjoerg /* OverwriteExisting= */ false);
103006f32e7eSjoerg break;
103106f32e7eSjoerg
103206f32e7eSjoerg case ARM::FK_NEON_FP_ARMV8:
103306f32e7eSjoerg case ARM::FK_CRYPTO_NEON_FP_ARMV8:
103406f32e7eSjoerg setAttributeItem(ARMBuildAttrs::FP_arch,
103506f32e7eSjoerg ARMBuildAttrs::AllowFPARMv8A,
103606f32e7eSjoerg /* OverwriteExisting= */ false);
103706f32e7eSjoerg // 'Advanced_SIMD_arch' must be emitted not here, but within
103806f32e7eSjoerg // ARMAsmPrinter::emitAttributes(), depending on hasV8Ops() and hasV8_1a()
103906f32e7eSjoerg break;
104006f32e7eSjoerg
104106f32e7eSjoerg case ARM::FK_SOFTVFP:
104206f32e7eSjoerg case ARM::FK_NONE:
104306f32e7eSjoerg break;
104406f32e7eSjoerg
104506f32e7eSjoerg default:
104606f32e7eSjoerg report_fatal_error("Unknown FPU: " + Twine(FPU));
104706f32e7eSjoerg break;
104806f32e7eSjoerg }
104906f32e7eSjoerg }
105006f32e7eSjoerg
calculateContentSize() const105106f32e7eSjoerg size_t ARMTargetELFStreamer::calculateContentSize() const {
105206f32e7eSjoerg size_t Result = 0;
105306f32e7eSjoerg for (size_t i = 0; i < Contents.size(); ++i) {
105406f32e7eSjoerg AttributeItem item = Contents[i];
105506f32e7eSjoerg switch (item.Type) {
105606f32e7eSjoerg case AttributeItem::HiddenAttribute:
105706f32e7eSjoerg break;
105806f32e7eSjoerg case AttributeItem::NumericAttribute:
105906f32e7eSjoerg Result += getULEB128Size(item.Tag);
106006f32e7eSjoerg Result += getULEB128Size(item.IntValue);
106106f32e7eSjoerg break;
106206f32e7eSjoerg case AttributeItem::TextAttribute:
106306f32e7eSjoerg Result += getULEB128Size(item.Tag);
106406f32e7eSjoerg Result += item.StringValue.size() + 1; // string + '\0'
106506f32e7eSjoerg break;
106606f32e7eSjoerg case AttributeItem::NumericAndTextAttributes:
106706f32e7eSjoerg Result += getULEB128Size(item.Tag);
106806f32e7eSjoerg Result += getULEB128Size(item.IntValue);
106906f32e7eSjoerg Result += item.StringValue.size() + 1; // string + '\0';
107006f32e7eSjoerg break;
107106f32e7eSjoerg }
107206f32e7eSjoerg }
107306f32e7eSjoerg return Result;
107406f32e7eSjoerg }
107506f32e7eSjoerg
finishAttributeSection()107606f32e7eSjoerg void ARMTargetELFStreamer::finishAttributeSection() {
107706f32e7eSjoerg // <format-version>
107806f32e7eSjoerg // [ <section-length> "vendor-name"
107906f32e7eSjoerg // [ <file-tag> <size> <attribute>*
108006f32e7eSjoerg // | <section-tag> <size> <section-number>* 0 <attribute>*
108106f32e7eSjoerg // | <symbol-tag> <size> <symbol-number>* 0 <attribute>*
108206f32e7eSjoerg // ]+
108306f32e7eSjoerg // ]*
108406f32e7eSjoerg
108506f32e7eSjoerg if (FPU != ARM::FK_INVALID)
108606f32e7eSjoerg emitFPUDefaultAttributes();
108706f32e7eSjoerg
108806f32e7eSjoerg if (Arch != ARM::ArchKind::INVALID)
108906f32e7eSjoerg emitArchDefaultAttributes();
109006f32e7eSjoerg
109106f32e7eSjoerg if (Contents.empty())
109206f32e7eSjoerg return;
109306f32e7eSjoerg
109406f32e7eSjoerg llvm::sort(Contents, AttributeItem::LessTag);
109506f32e7eSjoerg
109606f32e7eSjoerg ARMELFStreamer &Streamer = getStreamer();
109706f32e7eSjoerg
109806f32e7eSjoerg // Switch to .ARM.attributes section
109906f32e7eSjoerg if (AttributeSection) {
110006f32e7eSjoerg Streamer.SwitchSection(AttributeSection);
110106f32e7eSjoerg } else {
110206f32e7eSjoerg AttributeSection = Streamer.getContext().getELFSection(
110306f32e7eSjoerg ".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0);
110406f32e7eSjoerg Streamer.SwitchSection(AttributeSection);
110506f32e7eSjoerg
110606f32e7eSjoerg // Format version
1107*da58b97aSjoerg Streamer.emitInt8(0x41);
110806f32e7eSjoerg }
110906f32e7eSjoerg
111006f32e7eSjoerg // Vendor size + Vendor name + '\0'
111106f32e7eSjoerg const size_t VendorHeaderSize = 4 + CurrentVendor.size() + 1;
111206f32e7eSjoerg
111306f32e7eSjoerg // Tag + Tag Size
111406f32e7eSjoerg const size_t TagHeaderSize = 1 + 4;
111506f32e7eSjoerg
111606f32e7eSjoerg const size_t ContentsSize = calculateContentSize();
111706f32e7eSjoerg
1118*da58b97aSjoerg Streamer.emitInt32(VendorHeaderSize + TagHeaderSize + ContentsSize);
1119*da58b97aSjoerg Streamer.emitBytes(CurrentVendor);
1120*da58b97aSjoerg Streamer.emitInt8(0); // '\0'
112106f32e7eSjoerg
1122*da58b97aSjoerg Streamer.emitInt8(ARMBuildAttrs::File);
1123*da58b97aSjoerg Streamer.emitInt32(TagHeaderSize + ContentsSize);
112406f32e7eSjoerg
112506f32e7eSjoerg // Size should have been accounted for already, now
112606f32e7eSjoerg // emit each field as its type (ULEB or String)
112706f32e7eSjoerg for (size_t i = 0; i < Contents.size(); ++i) {
112806f32e7eSjoerg AttributeItem item = Contents[i];
1129*da58b97aSjoerg Streamer.emitULEB128IntValue(item.Tag);
113006f32e7eSjoerg switch (item.Type) {
113106f32e7eSjoerg default: llvm_unreachable("Invalid attribute type");
113206f32e7eSjoerg case AttributeItem::NumericAttribute:
1133*da58b97aSjoerg Streamer.emitULEB128IntValue(item.IntValue);
113406f32e7eSjoerg break;
113506f32e7eSjoerg case AttributeItem::TextAttribute:
1136*da58b97aSjoerg Streamer.emitBytes(item.StringValue);
1137*da58b97aSjoerg Streamer.emitInt8(0); // '\0'
113806f32e7eSjoerg break;
113906f32e7eSjoerg case AttributeItem::NumericAndTextAttributes:
1140*da58b97aSjoerg Streamer.emitULEB128IntValue(item.IntValue);
1141*da58b97aSjoerg Streamer.emitBytes(item.StringValue);
1142*da58b97aSjoerg Streamer.emitInt8(0); // '\0'
114306f32e7eSjoerg break;
114406f32e7eSjoerg }
114506f32e7eSjoerg }
114606f32e7eSjoerg
114706f32e7eSjoerg Contents.clear();
114806f32e7eSjoerg FPU = ARM::FK_INVALID;
114906f32e7eSjoerg }
115006f32e7eSjoerg
emitLabel(MCSymbol * Symbol)115106f32e7eSjoerg void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
115206f32e7eSjoerg ARMELFStreamer &Streamer = getStreamer();
115306f32e7eSjoerg if (!Streamer.IsThumb)
115406f32e7eSjoerg return;
115506f32e7eSjoerg
115606f32e7eSjoerg Streamer.getAssembler().registerSymbol(*Symbol);
115706f32e7eSjoerg unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
115806f32e7eSjoerg if (Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC)
1159*da58b97aSjoerg Streamer.emitThumbFunc(Symbol);
116006f32e7eSjoerg }
116106f32e7eSjoerg
116206f32e7eSjoerg void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)116306f32e7eSjoerg ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
116406f32e7eSjoerg getStreamer().EmitFixup(S, FK_Data_4);
116506f32e7eSjoerg }
116606f32e7eSjoerg
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)116706f32e7eSjoerg void ARMTargetELFStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
116806f32e7eSjoerg if (const MCSymbolRefExpr *SRE = dyn_cast<MCSymbolRefExpr>(Value)) {
116906f32e7eSjoerg const MCSymbol &Sym = SRE->getSymbol();
117006f32e7eSjoerg if (!Sym.isDefined()) {
1171*da58b97aSjoerg getStreamer().emitAssignment(Symbol, Value);
117206f32e7eSjoerg return;
117306f32e7eSjoerg }
117406f32e7eSjoerg }
117506f32e7eSjoerg
1176*da58b97aSjoerg getStreamer().emitThumbFunc(Symbol);
1177*da58b97aSjoerg getStreamer().emitAssignment(Symbol, Value);
117806f32e7eSjoerg }
117906f32e7eSjoerg
emitInst(uint32_t Inst,char Suffix)118006f32e7eSjoerg void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
118106f32e7eSjoerg getStreamer().emitInst(Inst, Suffix);
118206f32e7eSjoerg }
118306f32e7eSjoerg
reset()118406f32e7eSjoerg void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
118506f32e7eSjoerg
finishImpl()1186*da58b97aSjoerg void ARMELFStreamer::finishImpl() {
118706f32e7eSjoerg MCTargetStreamer &TS = *getTargetStreamer();
118806f32e7eSjoerg ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
118906f32e7eSjoerg ATS.finishAttributeSection();
119006f32e7eSjoerg
1191*da58b97aSjoerg MCELFStreamer::finishImpl();
119206f32e7eSjoerg }
119306f32e7eSjoerg
reset()119406f32e7eSjoerg void ARMELFStreamer::reset() {
119506f32e7eSjoerg MCTargetStreamer &TS = *getTargetStreamer();
119606f32e7eSjoerg ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
119706f32e7eSjoerg ATS.reset();
119806f32e7eSjoerg MappingSymbolCounter = 0;
119906f32e7eSjoerg MCELFStreamer::reset();
120006f32e7eSjoerg LastMappingSymbols.clear();
120106f32e7eSjoerg LastEMSInfo.reset();
120206f32e7eSjoerg // MCELFStreamer clear's the assembler's e_flags. However, for
120306f32e7eSjoerg // arm we manually set the ABI version on streamer creation, so
120406f32e7eSjoerg // do the same here
120506f32e7eSjoerg getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
120606f32e7eSjoerg }
120706f32e7eSjoerg
SwitchToEHSection(StringRef Prefix,unsigned Type,unsigned Flags,SectionKind Kind,const MCSymbol & Fn)120806f32e7eSjoerg inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
120906f32e7eSjoerg unsigned Type,
121006f32e7eSjoerg unsigned Flags,
121106f32e7eSjoerg SectionKind Kind,
121206f32e7eSjoerg const MCSymbol &Fn) {
121306f32e7eSjoerg const MCSectionELF &FnSection =
121406f32e7eSjoerg static_cast<const MCSectionELF &>(Fn.getSection());
121506f32e7eSjoerg
121606f32e7eSjoerg // Create the name for new section
1217*da58b97aSjoerg StringRef FnSecName(FnSection.getName());
121806f32e7eSjoerg SmallString<128> EHSecName(Prefix);
121906f32e7eSjoerg if (FnSecName != ".text") {
122006f32e7eSjoerg EHSecName += FnSecName;
122106f32e7eSjoerg }
122206f32e7eSjoerg
122306f32e7eSjoerg // Get .ARM.extab or .ARM.exidx section
122406f32e7eSjoerg const MCSymbolELF *Group = FnSection.getGroup();
122506f32e7eSjoerg if (Group)
122606f32e7eSjoerg Flags |= ELF::SHF_GROUP;
122706f32e7eSjoerg MCSectionELF *EHSection = getContext().getELFSection(
1228*da58b97aSjoerg EHSecName, Type, Flags, 0, Group, /*IsComdat=*/true,
1229*da58b97aSjoerg FnSection.getUniqueID(),
1230*da58b97aSjoerg static_cast<const MCSymbolELF *>(FnSection.getBeginSymbol()));
123106f32e7eSjoerg
123206f32e7eSjoerg assert(EHSection && "Failed to get the required EH section");
123306f32e7eSjoerg
123406f32e7eSjoerg // Switch to .ARM.extab or .ARM.exidx section
123506f32e7eSjoerg SwitchSection(EHSection);
1236*da58b97aSjoerg emitCodeAlignment(4);
123706f32e7eSjoerg }
123806f32e7eSjoerg
SwitchToExTabSection(const MCSymbol & FnStart)123906f32e7eSjoerg inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
124006f32e7eSjoerg SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
124106f32e7eSjoerg SectionKind::getData(), FnStart);
124206f32e7eSjoerg }
124306f32e7eSjoerg
SwitchToExIdxSection(const MCSymbol & FnStart)124406f32e7eSjoerg inline void ARMELFStreamer::SwitchToExIdxSection(const MCSymbol &FnStart) {
124506f32e7eSjoerg SwitchToEHSection(".ARM.exidx", ELF::SHT_ARM_EXIDX,
124606f32e7eSjoerg ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER,
124706f32e7eSjoerg SectionKind::getData(), FnStart);
124806f32e7eSjoerg }
124906f32e7eSjoerg
EmitFixup(const MCExpr * Expr,MCFixupKind Kind)125006f32e7eSjoerg void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
125106f32e7eSjoerg MCDataFragment *Frag = getOrCreateDataFragment();
125206f32e7eSjoerg Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
125306f32e7eSjoerg Kind));
125406f32e7eSjoerg }
125506f32e7eSjoerg
EHReset()125606f32e7eSjoerg void ARMELFStreamer::EHReset() {
125706f32e7eSjoerg ExTab = nullptr;
125806f32e7eSjoerg FnStart = nullptr;
125906f32e7eSjoerg Personality = nullptr;
126006f32e7eSjoerg PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
126106f32e7eSjoerg FPReg = ARM::SP;
126206f32e7eSjoerg FPOffset = 0;
126306f32e7eSjoerg SPOffset = 0;
126406f32e7eSjoerg PendingOffset = 0;
126506f32e7eSjoerg UsedFP = false;
126606f32e7eSjoerg CantUnwind = false;
126706f32e7eSjoerg
126806f32e7eSjoerg Opcodes.clear();
126906f32e7eSjoerg UnwindOpAsm.Reset();
127006f32e7eSjoerg }
127106f32e7eSjoerg
emitFnStart()127206f32e7eSjoerg void ARMELFStreamer::emitFnStart() {
127306f32e7eSjoerg assert(FnStart == nullptr);
127406f32e7eSjoerg FnStart = getContext().createTempSymbol();
1275*da58b97aSjoerg emitLabel(FnStart);
127606f32e7eSjoerg }
127706f32e7eSjoerg
emitFnEnd()127806f32e7eSjoerg void ARMELFStreamer::emitFnEnd() {
127906f32e7eSjoerg assert(FnStart && ".fnstart must precedes .fnend");
128006f32e7eSjoerg
128106f32e7eSjoerg // Emit unwind opcodes if there is no .handlerdata directive
128206f32e7eSjoerg if (!ExTab && !CantUnwind)
128306f32e7eSjoerg FlushUnwindOpcodes(true);
128406f32e7eSjoerg
128506f32e7eSjoerg // Emit the exception index table entry
128606f32e7eSjoerg SwitchToExIdxSection(*FnStart);
128706f32e7eSjoerg
1288*da58b97aSjoerg // The EHABI requires a dependency preserving R_ARM_NONE relocation to the
1289*da58b97aSjoerg // personality routine to protect it from an arbitrary platform's static
1290*da58b97aSjoerg // linker garbage collection. We disable this for Android where the unwinder
1291*da58b97aSjoerg // is either dynamically linked or directly references the personality
1292*da58b97aSjoerg // routine.
1293*da58b97aSjoerg if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
129406f32e7eSjoerg EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
129506f32e7eSjoerg
129606f32e7eSjoerg const MCSymbolRefExpr *FnStartRef =
129706f32e7eSjoerg MCSymbolRefExpr::create(FnStart,
129806f32e7eSjoerg MCSymbolRefExpr::VK_ARM_PREL31,
129906f32e7eSjoerg getContext());
130006f32e7eSjoerg
1301*da58b97aSjoerg emitValue(FnStartRef, 4);
130206f32e7eSjoerg
130306f32e7eSjoerg if (CantUnwind) {
1304*da58b97aSjoerg emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
130506f32e7eSjoerg } else if (ExTab) {
130606f32e7eSjoerg // Emit a reference to the unwind opcodes in the ".ARM.extab" section.
130706f32e7eSjoerg const MCSymbolRefExpr *ExTabEntryRef =
130806f32e7eSjoerg MCSymbolRefExpr::create(ExTab,
130906f32e7eSjoerg MCSymbolRefExpr::VK_ARM_PREL31,
131006f32e7eSjoerg getContext());
1311*da58b97aSjoerg emitValue(ExTabEntryRef, 4);
131206f32e7eSjoerg } else {
131306f32e7eSjoerg // For the __aeabi_unwind_cpp_pr0, we have to emit the unwind opcodes in
131406f32e7eSjoerg // the second word of exception index table entry. The size of the unwind
131506f32e7eSjoerg // opcodes should always be 4 bytes.
131606f32e7eSjoerg assert(PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0 &&
131706f32e7eSjoerg "Compact model must use __aeabi_unwind_cpp_pr0 as personality");
131806f32e7eSjoerg assert(Opcodes.size() == 4u &&
131906f32e7eSjoerg "Unwind opcode size for __aeabi_unwind_cpp_pr0 must be equal to 4");
132006f32e7eSjoerg uint64_t Intval = Opcodes[0] |
132106f32e7eSjoerg Opcodes[1] << 8 |
132206f32e7eSjoerg Opcodes[2] << 16 |
132306f32e7eSjoerg Opcodes[3] << 24;
1324*da58b97aSjoerg emitIntValue(Intval, Opcodes.size());
132506f32e7eSjoerg }
132606f32e7eSjoerg
132706f32e7eSjoerg // Switch to the section containing FnStart
132806f32e7eSjoerg SwitchSection(&FnStart->getSection());
132906f32e7eSjoerg
133006f32e7eSjoerg // Clean exception handling frame information
133106f32e7eSjoerg EHReset();
133206f32e7eSjoerg }
133306f32e7eSjoerg
emitCantUnwind()133406f32e7eSjoerg void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
133506f32e7eSjoerg
133606f32e7eSjoerg // Add the R_ARM_NONE fixup at the same position
EmitPersonalityFixup(StringRef Name)133706f32e7eSjoerg void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
133806f32e7eSjoerg const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
133906f32e7eSjoerg
134006f32e7eSjoerg const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
134106f32e7eSjoerg PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
134206f32e7eSjoerg
134306f32e7eSjoerg visitUsedExpr(*PersonalityRef);
134406f32e7eSjoerg MCDataFragment *DF = getOrCreateDataFragment();
134506f32e7eSjoerg DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
134606f32e7eSjoerg PersonalityRef,
134706f32e7eSjoerg MCFixup::getKindForSize(4, false)));
134806f32e7eSjoerg }
134906f32e7eSjoerg
FlushPendingOffset()135006f32e7eSjoerg void ARMELFStreamer::FlushPendingOffset() {
135106f32e7eSjoerg if (PendingOffset != 0) {
135206f32e7eSjoerg UnwindOpAsm.EmitSPOffset(-PendingOffset);
135306f32e7eSjoerg PendingOffset = 0;
135406f32e7eSjoerg }
135506f32e7eSjoerg }
135606f32e7eSjoerg
FlushUnwindOpcodes(bool NoHandlerData)135706f32e7eSjoerg void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
135806f32e7eSjoerg // Emit the unwind opcode to restore $sp.
135906f32e7eSjoerg if (UsedFP) {
136006f32e7eSjoerg const MCRegisterInfo *MRI = getContext().getRegisterInfo();
136106f32e7eSjoerg int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
136206f32e7eSjoerg UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
136306f32e7eSjoerg UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
136406f32e7eSjoerg } else {
136506f32e7eSjoerg FlushPendingOffset();
136606f32e7eSjoerg }
136706f32e7eSjoerg
136806f32e7eSjoerg // Finalize the unwind opcode sequence
136906f32e7eSjoerg UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
137006f32e7eSjoerg
137106f32e7eSjoerg // For compact model 0, we have to emit the unwind opcodes in the .ARM.exidx
137206f32e7eSjoerg // section. Thus, we don't have to create an entry in the .ARM.extab
137306f32e7eSjoerg // section.
137406f32e7eSjoerg if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
137506f32e7eSjoerg return;
137606f32e7eSjoerg
137706f32e7eSjoerg // Switch to .ARM.extab section.
137806f32e7eSjoerg SwitchToExTabSection(*FnStart);
137906f32e7eSjoerg
138006f32e7eSjoerg // Create .ARM.extab label for offset in .ARM.exidx
138106f32e7eSjoerg assert(!ExTab);
138206f32e7eSjoerg ExTab = getContext().createTempSymbol();
1383*da58b97aSjoerg emitLabel(ExTab);
138406f32e7eSjoerg
138506f32e7eSjoerg // Emit personality
138606f32e7eSjoerg if (Personality) {
138706f32e7eSjoerg const MCSymbolRefExpr *PersonalityRef =
138806f32e7eSjoerg MCSymbolRefExpr::create(Personality,
138906f32e7eSjoerg MCSymbolRefExpr::VK_ARM_PREL31,
139006f32e7eSjoerg getContext());
139106f32e7eSjoerg
1392*da58b97aSjoerg emitValue(PersonalityRef, 4);
139306f32e7eSjoerg }
139406f32e7eSjoerg
139506f32e7eSjoerg // Emit unwind opcodes
139606f32e7eSjoerg assert((Opcodes.size() % 4) == 0 &&
139706f32e7eSjoerg "Unwind opcode size for __aeabi_cpp_unwind_pr0 must be multiple of 4");
139806f32e7eSjoerg for (unsigned I = 0; I != Opcodes.size(); I += 4) {
139906f32e7eSjoerg uint64_t Intval = Opcodes[I] |
140006f32e7eSjoerg Opcodes[I + 1] << 8 |
140106f32e7eSjoerg Opcodes[I + 2] << 16 |
140206f32e7eSjoerg Opcodes[I + 3] << 24;
1403*da58b97aSjoerg emitInt32(Intval);
140406f32e7eSjoerg }
140506f32e7eSjoerg
140606f32e7eSjoerg // According to ARM EHABI section 9.2, if the __aeabi_unwind_cpp_pr1() or
140706f32e7eSjoerg // __aeabi_unwind_cpp_pr2() is used, then the handler data must be emitted
140806f32e7eSjoerg // after the unwind opcodes. The handler data consists of several 32-bit
140906f32e7eSjoerg // words, and should be terminated by zero.
141006f32e7eSjoerg //
141106f32e7eSjoerg // In case that the .handlerdata directive is not specified by the
141206f32e7eSjoerg // programmer, we should emit zero to terminate the handler data.
141306f32e7eSjoerg if (NoHandlerData && !Personality)
1414*da58b97aSjoerg emitInt32(0);
141506f32e7eSjoerg }
141606f32e7eSjoerg
emitHandlerData()141706f32e7eSjoerg void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
141806f32e7eSjoerg
emitPersonality(const MCSymbol * Per)141906f32e7eSjoerg void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
142006f32e7eSjoerg Personality = Per;
142106f32e7eSjoerg UnwindOpAsm.setPersonality(Per);
142206f32e7eSjoerg }
142306f32e7eSjoerg
emitPersonalityIndex(unsigned Index)142406f32e7eSjoerg void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
142506f32e7eSjoerg assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
142606f32e7eSjoerg PersonalityIndex = Index;
142706f32e7eSjoerg }
142806f32e7eSjoerg
emitSetFP(unsigned NewFPReg,unsigned NewSPReg,int64_t Offset)142906f32e7eSjoerg void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
143006f32e7eSjoerg int64_t Offset) {
143106f32e7eSjoerg assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
143206f32e7eSjoerg "the operand of .setfp directive should be either $sp or $fp");
143306f32e7eSjoerg
143406f32e7eSjoerg UsedFP = true;
143506f32e7eSjoerg FPReg = NewFPReg;
143606f32e7eSjoerg
143706f32e7eSjoerg if (NewSPReg == ARM::SP)
143806f32e7eSjoerg FPOffset = SPOffset + Offset;
143906f32e7eSjoerg else
144006f32e7eSjoerg FPOffset += Offset;
144106f32e7eSjoerg }
144206f32e7eSjoerg
emitMovSP(unsigned Reg,int64_t Offset)144306f32e7eSjoerg void ARMELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
144406f32e7eSjoerg assert((Reg != ARM::SP && Reg != ARM::PC) &&
144506f32e7eSjoerg "the operand of .movsp cannot be either sp or pc");
144606f32e7eSjoerg assert(FPReg == ARM::SP && "current FP must be SP");
144706f32e7eSjoerg
144806f32e7eSjoerg FlushPendingOffset();
144906f32e7eSjoerg
145006f32e7eSjoerg FPReg = Reg;
145106f32e7eSjoerg FPOffset = SPOffset + Offset;
145206f32e7eSjoerg
145306f32e7eSjoerg const MCRegisterInfo *MRI = getContext().getRegisterInfo();
145406f32e7eSjoerg UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
145506f32e7eSjoerg }
145606f32e7eSjoerg
emitPad(int64_t Offset)145706f32e7eSjoerg void ARMELFStreamer::emitPad(int64_t Offset) {
145806f32e7eSjoerg // Track the change of the $sp offset
145906f32e7eSjoerg SPOffset -= Offset;
146006f32e7eSjoerg
146106f32e7eSjoerg // To squash multiple .pad directives, we should delay the unwind opcode
146206f32e7eSjoerg // until the .save, .vsave, .handlerdata, or .fnend directives.
146306f32e7eSjoerg PendingOffset -= Offset;
146406f32e7eSjoerg }
146506f32e7eSjoerg
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool IsVector)146606f32e7eSjoerg void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
146706f32e7eSjoerg bool IsVector) {
146806f32e7eSjoerg // Collect the registers in the register list
146906f32e7eSjoerg unsigned Count = 0;
147006f32e7eSjoerg uint32_t Mask = 0;
147106f32e7eSjoerg const MCRegisterInfo *MRI = getContext().getRegisterInfo();
147206f32e7eSjoerg for (size_t i = 0; i < RegList.size(); ++i) {
147306f32e7eSjoerg unsigned Reg = MRI->getEncodingValue(RegList[i]);
147406f32e7eSjoerg assert(Reg < (IsVector ? 32U : 16U) && "Register out of range");
147506f32e7eSjoerg unsigned Bit = (1u << Reg);
147606f32e7eSjoerg if ((Mask & Bit) == 0) {
147706f32e7eSjoerg Mask |= Bit;
147806f32e7eSjoerg ++Count;
147906f32e7eSjoerg }
148006f32e7eSjoerg }
148106f32e7eSjoerg
148206f32e7eSjoerg // Track the change the $sp offset: For the .save directive, the
148306f32e7eSjoerg // corresponding push instruction will decrease the $sp by (4 * Count).
148406f32e7eSjoerg // For the .vsave directive, the corresponding vpush instruction will
148506f32e7eSjoerg // decrease $sp by (8 * Count).
148606f32e7eSjoerg SPOffset -= Count * (IsVector ? 8 : 4);
148706f32e7eSjoerg
148806f32e7eSjoerg // Emit the opcode
148906f32e7eSjoerg FlushPendingOffset();
149006f32e7eSjoerg if (IsVector)
149106f32e7eSjoerg UnwindOpAsm.EmitVFPRegSave(Mask);
149206f32e7eSjoerg else
149306f32e7eSjoerg UnwindOpAsm.EmitRegSave(Mask);
149406f32e7eSjoerg }
149506f32e7eSjoerg
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)149606f32e7eSjoerg void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
149706f32e7eSjoerg const SmallVectorImpl<uint8_t> &Opcodes) {
149806f32e7eSjoerg FlushPendingOffset();
149906f32e7eSjoerg SPOffset = SPOffset - Offset;
150006f32e7eSjoerg UnwindOpAsm.EmitRaw(Opcodes);
150106f32e7eSjoerg }
150206f32e7eSjoerg
150306f32e7eSjoerg namespace llvm {
150406f32e7eSjoerg
createARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)150506f32e7eSjoerg MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
150606f32e7eSjoerg formatted_raw_ostream &OS,
150706f32e7eSjoerg MCInstPrinter *InstPrint,
150806f32e7eSjoerg bool isVerboseAsm) {
150906f32e7eSjoerg return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
151006f32e7eSjoerg }
151106f32e7eSjoerg
createARMNullTargetStreamer(MCStreamer & S)151206f32e7eSjoerg MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
151306f32e7eSjoerg return new ARMTargetStreamer(S);
151406f32e7eSjoerg }
151506f32e7eSjoerg
createARMObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)151606f32e7eSjoerg MCTargetStreamer *createARMObjectTargetStreamer(MCStreamer &S,
151706f32e7eSjoerg const MCSubtargetInfo &STI) {
151806f32e7eSjoerg const Triple &TT = STI.getTargetTriple();
151906f32e7eSjoerg if (TT.isOSBinFormatELF())
152006f32e7eSjoerg return new ARMTargetELFStreamer(S);
152106f32e7eSjoerg return new ARMTargetStreamer(S);
152206f32e7eSjoerg }
152306f32e7eSjoerg
createARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool RelaxAll,bool IsThumb,bool IsAndroid)152406f32e7eSjoerg MCELFStreamer *createARMELFStreamer(MCContext &Context,
152506f32e7eSjoerg std::unique_ptr<MCAsmBackend> TAB,
152606f32e7eSjoerg std::unique_ptr<MCObjectWriter> OW,
152706f32e7eSjoerg std::unique_ptr<MCCodeEmitter> Emitter,
1528*da58b97aSjoerg bool RelaxAll, bool IsThumb,
1529*da58b97aSjoerg bool IsAndroid) {
1530*da58b97aSjoerg ARMELFStreamer *S =
1531*da58b97aSjoerg new ARMELFStreamer(Context, std::move(TAB), std::move(OW),
1532*da58b97aSjoerg std::move(Emitter), IsThumb, IsAndroid);
153306f32e7eSjoerg // FIXME: This should eventually end up somewhere else where more
153406f32e7eSjoerg // intelligent flag decisions can be made. For now we are just maintaining
153506f32e7eSjoerg // the status quo for ARM and setting EF_ARM_EABI_VER5 as the default.
153606f32e7eSjoerg S->getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
153706f32e7eSjoerg
153806f32e7eSjoerg if (RelaxAll)
153906f32e7eSjoerg S->getAssembler().setRelaxAll(true);
154006f32e7eSjoerg return S;
154106f32e7eSjoerg }
154206f32e7eSjoerg
154306f32e7eSjoerg } // end namespace llvm
1544