1 //===- lib/MC/ARMELFStreamer.cpp - ELF Object Output for ARM --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file assembles .s files and emits ARM ELF .o object files. Different
10 // from generic ELF streamer in emitting mapping symbols ($a, $t and $d) to
11 // delimit regions of data and code.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "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"
51 #include <algorithm>
52 #include <cassert>
53 #include <climits>
54 #include <cstddef>
55 #include <cstdint>
56 #include <string>
57
58 using namespace llvm;
59
GetAEABIUnwindPersonalityName(unsigned Index)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();
64 }
65
66 namespace {
67
68 class ARMELFStreamer;
69
70 class ARMTargetAsmStreamer : public ARMTargetStreamer {
71 formatted_raw_ostream &OS;
72 MCInstPrinter &InstPrinter;
73 bool IsVerboseAsm;
74
75 void emitFnStart() override;
76 void emitFnEnd() override;
77 void emitCantUnwind() override;
78 void emitPersonality(const MCSymbol *Personality) override;
79 void emitPersonalityIndex(unsigned Index) override;
80 void emitHandlerData() override;
81 void emitSetFP(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;
88
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;
100
101 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
102 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
103
104 public:
105 ARMTargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS,
106 MCInstPrinter &InstPrinter, bool VerboseAsm);
107 };
108
ARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter & InstPrinter,bool VerboseAsm)109 ARMTargetAsmStreamer::ARMTargetAsmStreamer(MCStreamer &S,
110 formatted_raw_ostream &OS,
111 MCInstPrinter &InstPrinter,
112 bool VerboseAsm)
113 : ARMTargetStreamer(S), OS(OS), InstPrinter(InstPrinter),
114 IsVerboseAsm(VerboseAsm) {}
115
emitFnStart()116 void ARMTargetAsmStreamer::emitFnStart() { OS << "\t.fnstart\n"; }
emitFnEnd()117 void ARMTargetAsmStreamer::emitFnEnd() { OS << "\t.fnend\n"; }
emitCantUnwind()118 void ARMTargetAsmStreamer::emitCantUnwind() { OS << "\t.cantunwind\n"; }
119
emitPersonality(const MCSymbol * Personality)120 void ARMTargetAsmStreamer::emitPersonality(const MCSymbol *Personality) {
121 OS << "\t.personality " << Personality->getName() << '\n';
122 }
123
emitPersonalityIndex(unsigned Index)124 void ARMTargetAsmStreamer::emitPersonalityIndex(unsigned Index) {
125 OS << "\t.personalityindex " << Index << '\n';
126 }
127
emitHandlerData()128 void ARMTargetAsmStreamer::emitHandlerData() { OS << "\t.handlerdata\n"; }
129
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)130 void ARMTargetAsmStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
131 int64_t Offset) {
132 OS << "\t.setfp\t";
133 InstPrinter.printRegName(OS, FpReg);
134 OS << ", ";
135 InstPrinter.printRegName(OS, SpReg);
136 if (Offset)
137 OS << ", #" << Offset;
138 OS << '\n';
139 }
140
emitMovSP(unsigned Reg,int64_t 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");
144
145 OS << "\t.movsp\t";
146 InstPrinter.printRegName(OS, Reg);
147 if (Offset)
148 OS << ", #" << Offset;
149 OS << '\n';
150 }
151
emitPad(int64_t Offset)152 void ARMTargetAsmStreamer::emitPad(int64_t Offset) {
153 OS << "\t.pad\t#" << Offset << '\n';
154 }
155
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)156 void ARMTargetAsmStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
157 bool isVector) {
158 assert(RegList.size() && "RegList should not be empty");
159 if (isVector)
160 OS << "\t.vsave\t{";
161 else
162 OS << "\t.save\t{";
163
164 InstPrinter.printRegName(OS, RegList[0]);
165
166 for (unsigned i = 1, e = RegList.size(); i != e; ++i) {
167 OS << ", ";
168 InstPrinter.printRegName(OS, RegList[i]);
169 }
170
171 OS << "}\n";
172 }
173
switchVendor(StringRef Vendor)174 void ARMTargetAsmStreamer::switchVendor(StringRef Vendor) {}
175
emitAttribute(unsigned Attribute,unsigned Value)176 void ARMTargetAsmStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
177 OS << "\t.eabi_attribute\t" << Attribute << ", " << Twine(Value);
178 if (IsVerboseAsm) {
179 StringRef Name = ELFAttrs::attrTypeAsString(
180 Attribute, ARMBuildAttrs::getARMAttributeTags());
181 if (!Name.empty())
182 OS << "\t@ " << Name;
183 }
184 OS << "\n";
185 }
186
emitTextAttribute(unsigned Attribute,StringRef String)187 void ARMTargetAsmStreamer::emitTextAttribute(unsigned Attribute,
188 StringRef String) {
189 switch (Attribute) {
190 case ARMBuildAttrs::CPU_name:
191 OS << "\t.cpu\t" << String.lower();
192 break;
193 default:
194 OS << "\t.eabi_attribute\t" << Attribute << ", \"" << String << "\"";
195 if (IsVerboseAsm) {
196 StringRef Name = ELFAttrs::attrTypeAsString(
197 Attribute, ARMBuildAttrs::getARMAttributeTags());
198 if (!Name.empty())
199 OS << "\t@ " << Name;
200 }
201 break;
202 }
203 OS << "\n";
204 }
205
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)206 void ARMTargetAsmStreamer::emitIntTextAttribute(unsigned Attribute,
207 unsigned IntValue,
208 StringRef StringValue) {
209 switch (Attribute) {
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 << "\"";
215 if (IsVerboseAsm)
216 OS << "\t@ "
217 << ELFAttrs::attrTypeAsString(Attribute,
218 ARMBuildAttrs::getARMAttributeTags());
219 break;
220 }
221 OS << "\n";
222 }
223
emitArch(ARM::ArchKind Arch)224 void ARMTargetAsmStreamer::emitArch(ARM::ArchKind Arch) {
225 OS << "\t.arch\t" << ARM::getArchName(Arch) << "\n";
226 }
227
emitArchExtension(uint64_t ArchExt)228 void ARMTargetAsmStreamer::emitArchExtension(uint64_t ArchExt) {
229 OS << "\t.arch_extension\t" << ARM::getArchExtName(ArchExt) << "\n";
230 }
231
emitObjectArch(ARM::ArchKind Arch)232 void ARMTargetAsmStreamer::emitObjectArch(ARM::ArchKind Arch) {
233 OS << "\t.object_arch\t" << ARM::getArchName(Arch) << '\n';
234 }
235
emitFPU(unsigned FPU)236 void ARMTargetAsmStreamer::emitFPU(unsigned FPU) {
237 OS << "\t.fpu\t" << ARM::getFPUName(FPU) << "\n";
238 }
239
finishAttributeSection()240 void ARMTargetAsmStreamer::finishAttributeSection() {}
241
242 void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)243 ARMTargetAsmStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
244 OS << "\t.tlsdescseq\t" << S->getSymbol().getName() << "\n";
245 }
246
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)247 void ARMTargetAsmStreamer::emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) {
248 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
249
250 OS << "\t.thumb_set\t";
251 Symbol->print(OS, MAI);
252 OS << ", ";
253 Value->print(OS, MAI);
254 OS << '\n';
255 }
256
emitInst(uint32_t Inst,char Suffix)257 void ARMTargetAsmStreamer::emitInst(uint32_t Inst, char Suffix) {
258 OS << "\t.inst";
259 if (Suffix)
260 OS << "." << Suffix;
261 OS << "\t0x" << Twine::utohexstr(Inst) << "\n";
262 }
263
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)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(),
268 OCE = Opcodes.end();
269 OCI != OCE; ++OCI)
270 OS << ", 0x" << Twine::utohexstr(*OCI);
271 OS << '\n';
272 }
273
274 class ARMTargetELFStreamer : public ARMTargetStreamer {
275 private:
276 StringRef CurrentVendor;
277 unsigned FPU = ARM::FK_INVALID;
278 ARM::ArchKind Arch = ARM::ArchKind::INVALID;
279 ARM::ArchKind EmittedArch = ARM::ArchKind::INVALID;
280
281 MCSection *AttributeSection = nullptr;
282
283 void emitArchDefaultAttributes();
284 void emitFPUDefaultAttributes();
285
286 ARMELFStreamer &getStreamer();
287
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;
301
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;
313
314 void AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *SRE) override;
315 void emitThumbSet(MCSymbol *Symbol, const MCExpr *Value) override;
316
317 // Reset state between object emissions
318 void reset() override;
319
320 public:
ARMTargetELFStreamer(MCStreamer & S)321 ARMTargetELFStreamer(MCStreamer &S)
322 : ARMTargetStreamer(S), CurrentVendor("aeabi") {}
323 };
324
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.
328 ///
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).
334 ///
335 /// As a result this system is orthogonal to the DataRegion infrastructure used
336 /// by MachO. Beware!
337 class ARMELFStreamer : public MCELFStreamer {
338 public:
339 friend class ARMTargetELFStreamer;
340
ARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool IsThumb,bool IsAndroid)341 ARMELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
342 std::unique_ptr<MCObjectWriter> OW,
343 std::unique_ptr<MCCodeEmitter> Emitter, bool IsThumb,
344 bool IsAndroid)
345 : MCELFStreamer(Context, std::move(TAB), std::move(OW),
346 std::move(Emitter)),
347 IsThumb(IsThumb), IsAndroid(IsAndroid) {
348 EHReset();
349 }
350
351 ~ARMELFStreamer() override = default;
352
353 void finishImpl() override;
354
355 // ARM exception handling directives
356 void emitFnStart();
357 void emitFnEnd();
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);
emitFill(const MCExpr & NumBytes,uint64_t FillValue,SMLoc Loc)367 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
368 SMLoc Loc) override {
369 emitDataMappingSymbol();
370 MCObjectStreamer::emitFill(NumBytes, FillValue, Loc);
371 }
372
changeSection(MCSection * Section,const MCExpr * Subsection)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);
379 return;
380 }
381 LastEMSInfo.reset(new ElfMappingSymbolInfo(SMLoc(), nullptr, 0));
382 }
383
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
386 /// necessary.
emitInstruction(const MCInst & Inst,const MCSubtargetInfo & STI)387 void emitInstruction(const MCInst &Inst,
388 const MCSubtargetInfo &STI) override {
389 if (IsThumb)
390 EmitThumbMappingSymbol();
391 else
392 EmitARMMappingSymbol();
393
394 MCELFStreamer::emitInstruction(Inst, STI);
395 }
396
emitInst(uint32_t Inst,char Suffix)397 void emitInst(uint32_t Inst, char Suffix) {
398 unsigned Size;
399 char Buffer[4];
400 const bool LittleEndian = getContext().getAsmInfo()->isLittleEndian();
401
402 switch (Suffix) {
403 case '\0':
404 Size = 4;
405
406 assert(!IsThumb);
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);
411 }
412
413 break;
414 case 'n':
415 case 'w':
416 Size = (Suffix == 'n' ? 2 : 4);
417
418 assert(IsThumb);
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);
427 }
428
429 break;
430 default:
431 llvm_unreachable("Invalid Suffix");
432 }
433
434 MCELFStreamer::emitBytes(StringRef(Buffer, Size));
435 }
436
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
439 /// necessary.
emitBytes(StringRef Data)440 void emitBytes(StringRef Data) override {
441 emitDataMappingSymbol();
442 MCELFStreamer::emitBytes(Data);
443 }
444
FlushPendingMappingSymbol()445 void FlushPendingMappingSymbol() {
446 if (!LastEMSInfo->hasInfo())
447 return;
448 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
449 EmitMappingSymbol("$d", EMS->Loc, EMS->F, EMS->Offset);
450 EMS->resetInfo();
451 }
452
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
455 /// necessary.
emitValueImpl(const MCExpr * Value,unsigned Size,SMLoc Loc)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");
460 return;
461 }
462 getOrCreateDataFragment();
463 }
464
465 emitDataMappingSymbol();
466 MCELFStreamer::emitValueImpl(Value, Size, Loc);
467 }
468
emitAssemblerFlag(MCAssemblerFlag Flag)469 void emitAssemblerFlag(MCAssemblerFlag Flag) override {
470 MCELFStreamer::emitAssemblerFlag(Flag);
471
472 switch (Flag) {
473 case MCAF_SyntaxUnified:
474 return; // no-op here.
475 case MCAF_Code16:
476 IsThumb = true;
477 return; // Change to Thumb mode
478 case MCAF_Code32:
479 IsThumb = false;
480 return; // Change to ARM mode
481 case MCAF_Code64:
482 return;
483 case MCAF_SubsectionsViaSymbols:
484 return;
485 }
486 }
487
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.
emitSymbolAttribute(MCSymbol * Symbol,MCSymbolAttr Attribute)496 bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
497 bool Val = MCELFStreamer::emitSymbolAttribute(Symbol, Attribute);
498
499 if (!IsThumb)
500 return Val;
501
502 unsigned Type = cast<MCSymbolELF>(Symbol)->getType();
503 if ((Type == ELF::STT_FUNC || Type == ELF::STT_GNU_IFUNC) &&
504 Symbol->isDefined())
505 getAssembler().setIsThumbFunc(Symbol);
506
507 return Val;
508 };
509
510 private:
511 enum ElfMappingSymbol {
512 EMS_None,
513 EMS_ARM,
514 EMS_Thumb,
515 EMS_Data
516 };
517
518 struct ElfMappingSymbolInfo {
ElfMappingSymbolInfo__anon46d2e8300111::ARMELFStreamer::ElfMappingSymbolInfo519 explicit ElfMappingSymbolInfo(SMLoc Loc, MCFragment *F, uint64_t O)
520 : Loc(Loc), F(F), Offset(O), State(EMS_None) {}
resetInfo__anon46d2e8300111::ARMELFStreamer::ElfMappingSymbolInfo521 void resetInfo() {
522 F = nullptr;
523 Offset = 0;
524 }
hasInfo__anon46d2e8300111::ARMELFStreamer::ElfMappingSymbolInfo525 bool hasInfo() { return F != nullptr; }
526 SMLoc Loc;
527 MCFragment *F;
528 uint64_t Offset;
529 ElfMappingSymbol State;
530 };
531
emitDataMappingSymbol()532 void emitDataMappingSymbol() {
533 if (LastEMSInfo->State == EMS_Data)
534 return;
535 else if (LastEMSInfo->State == EMS_None) {
536 // This is a tentative symbol, it won't really be emitted until it's
537 // actually needed.
538 ElfMappingSymbolInfo *EMS = LastEMSInfo.get();
539 auto *DF = dyn_cast_or_null<MCDataFragment>(getCurrentFragment());
540 if (!DF)
541 return;
542 EMS->Loc = SMLoc();
543 EMS->F = getCurrentFragment();
544 EMS->Offset = DF->getContents().size();
545 LastEMSInfo->State = EMS_Data;
546 return;
547 }
548 EmitMappingSymbol("$d");
549 LastEMSInfo->State = EMS_Data;
550 }
551
EmitThumbMappingSymbol()552 void EmitThumbMappingSymbol() {
553 if (LastEMSInfo->State == EMS_Thumb)
554 return;
555 FlushPendingMappingSymbol();
556 EmitMappingSymbol("$t");
557 LastEMSInfo->State = EMS_Thumb;
558 }
559
EmitARMMappingSymbol()560 void EmitARMMappingSymbol() {
561 if (LastEMSInfo->State == EMS_ARM)
562 return;
563 FlushPendingMappingSymbol();
564 EmitMappingSymbol("$a");
565 LastEMSInfo->State = EMS_ARM;
566 }
567
EmitMappingSymbol(StringRef Name)568 void EmitMappingSymbol(StringRef Name) {
569 auto *Symbol = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
570 Name + "." + Twine(MappingSymbolCounter++)));
571 emitLabel(Symbol);
572
573 Symbol->setType(ELF::STT_NOTYPE);
574 Symbol->setBinding(ELF::STB_LOCAL);
575 }
576
EmitMappingSymbol(StringRef Name,SMLoc Loc,MCFragment * F,uint64_t Offset)577 void EmitMappingSymbol(StringRef Name, SMLoc Loc, MCFragment *F,
578 uint64_t Offset) {
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);
584 }
585
emitThumbFunc(MCSymbol * Func)586 void emitThumbFunc(MCSymbol *Func) override {
587 getAssembler().setIsThumbFunc(Func);
588 emitSymbolAttribute(Func, MCSA_ELF_TypeFunction);
589 }
590
591 // Helper functions for ARM exception handling directives
592 void EHReset();
593
594 // Reset state between object emissions
595 void reset() override;
596
597 void EmitPersonalityFixup(StringRef Name);
598 void FlushPendingOffset();
599 void FlushUnwindOpcodes(bool NoHandlerData);
600
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);
605
606 void EmitFixup(const MCExpr *Expr, MCFixupKind Kind);
607
608 bool IsThumb;
609 bool IsAndroid;
610 int64_t MappingSymbolCounter = 0;
611
612 DenseMap<const MCSection *, std::unique_ptr<ElfMappingSymbolInfo>>
613 LastMappingSymbols;
614
615 std::unique_ptr<ElfMappingSymbolInfo> LastEMSInfo;
616
617 // ARM Exception Handling Frame Information
618 MCSymbol *ExTab;
619 MCSymbol *FnStart;
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)
626 bool UsedFP;
627 bool CantUnwind;
628 SmallVector<uint8_t, 64> Opcodes;
629 UnwindOpcodeAssembler UnwindOpAsm;
630 };
631
632 } // end anonymous namespace
633
getStreamer()634 ARMELFStreamer &ARMTargetELFStreamer::getStreamer() {
635 return static_cast<ARMELFStreamer &>(Streamer);
636 }
637
emitFnStart()638 void ARMTargetELFStreamer::emitFnStart() { getStreamer().emitFnStart(); }
emitFnEnd()639 void ARMTargetELFStreamer::emitFnEnd() { getStreamer().emitFnEnd(); }
emitCantUnwind()640 void ARMTargetELFStreamer::emitCantUnwind() { getStreamer().emitCantUnwind(); }
641
emitPersonality(const MCSymbol * Personality)642 void ARMTargetELFStreamer::emitPersonality(const MCSymbol *Personality) {
643 getStreamer().emitPersonality(Personality);
644 }
645
emitPersonalityIndex(unsigned Index)646 void ARMTargetELFStreamer::emitPersonalityIndex(unsigned Index) {
647 getStreamer().emitPersonalityIndex(Index);
648 }
649
emitHandlerData()650 void ARMTargetELFStreamer::emitHandlerData() {
651 getStreamer().emitHandlerData();
652 }
653
emitSetFP(unsigned FpReg,unsigned SpReg,int64_t Offset)654 void ARMTargetELFStreamer::emitSetFP(unsigned FpReg, unsigned SpReg,
655 int64_t Offset) {
656 getStreamer().emitSetFP(FpReg, SpReg, Offset);
657 }
658
emitMovSP(unsigned Reg,int64_t Offset)659 void ARMTargetELFStreamer::emitMovSP(unsigned Reg, int64_t Offset) {
660 getStreamer().emitMovSP(Reg, Offset);
661 }
662
emitPad(int64_t Offset)663 void ARMTargetELFStreamer::emitPad(int64_t Offset) {
664 getStreamer().emitPad(Offset);
665 }
666
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool isVector)667 void ARMTargetELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
668 bool isVector) {
669 getStreamer().emitRegSave(RegList, isVector);
670 }
671
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)672 void ARMTargetELFStreamer::emitUnwindRaw(int64_t Offset,
673 const SmallVectorImpl<uint8_t> &Opcodes) {
674 getStreamer().emitUnwindRaw(Offset, Opcodes);
675 }
676
switchVendor(StringRef Vendor)677 void ARMTargetELFStreamer::switchVendor(StringRef Vendor) {
678 assert(!Vendor.empty() && "Vendor cannot be empty.");
679
680 if (CurrentVendor == Vendor)
681 return;
682
683 if (!CurrentVendor.empty())
684 finishAttributeSection();
685
686 assert(getStreamer().Contents.empty() &&
687 ".ARM.attributes should be flushed before changing vendor");
688 CurrentVendor = Vendor;
689
690 }
691
emitAttribute(unsigned Attribute,unsigned Value)692 void ARMTargetELFStreamer::emitAttribute(unsigned Attribute, unsigned Value) {
693 getStreamer().setAttributeItem(Attribute, Value,
694 /* OverwriteExisting= */ true);
695 }
696
emitTextAttribute(unsigned Attribute,StringRef Value)697 void ARMTargetELFStreamer::emitTextAttribute(unsigned Attribute,
698 StringRef Value) {
699 getStreamer().setAttributeItem(Attribute, Value,
700 /* OverwriteExisting= */ true);
701 }
702
emitIntTextAttribute(unsigned Attribute,unsigned IntValue,StringRef StringValue)703 void ARMTargetELFStreamer::emitIntTextAttribute(unsigned Attribute,
704 unsigned IntValue,
705 StringRef StringValue) {
706 getStreamer().setAttributeItems(Attribute, IntValue, StringValue,
707 /* OverwriteExisting= */ true);
708 }
709
emitArch(ARM::ArchKind Value)710 void ARMTargetELFStreamer::emitArch(ARM::ArchKind Value) {
711 Arch = Value;
712 }
713
emitObjectArch(ARM::ArchKind Value)714 void ARMTargetELFStreamer::emitObjectArch(ARM::ArchKind Value) {
715 EmittedArch = Value;
716 }
717
emitArchDefaultAttributes()718 void ARMTargetELFStreamer::emitArchDefaultAttributes() {
719 using namespace ARMBuildAttrs;
720 ARMELFStreamer &S = getStreamer();
721
722 S.setAttributeItem(CPU_name, ARM::getCPUAttr(Arch), false);
723
724 if (EmittedArch == ARM::ArchKind::INVALID)
725 S.setAttributeItem(CPU_arch, ARM::getArchAttr(Arch), false);
726 else
727 S.setAttributeItem(CPU_arch, ARM::getArchAttr(EmittedArch), false);
728
729 switch (Arch) {
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);
736 break;
737
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);
745 break;
746
747 case ARM::ArchKind::ARMV6T2:
748 S.setAttributeItem(ARM_ISA_use, Allowed, false);
749 S.setAttributeItem(THUMB_ISA_use, AllowThumb32, false);
750 break;
751
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);
757 break;
758
759 case ARM::ArchKind::ARMV6M:
760 S.setAttributeItem(THUMB_ISA_use, Allowed, false);
761 break;
762
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);
767 break;
768
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);
773 break;
774
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);
779 break;
780
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);
793 break;
794
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);
799 break;
800
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);
805 break;
806
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);
811 break;
812
813 default:
814 report_fatal_error("Unknown Arch: " + Twine(ARM::getArchName(Arch)));
815 break;
816 }
817 }
818
emitFPU(unsigned Value)819 void ARMTargetELFStreamer::emitFPU(unsigned Value) {
820 FPU = Value;
821 }
822
emitFPUDefaultAttributes()823 void ARMTargetELFStreamer::emitFPUDefaultAttributes() {
824 ARMELFStreamer &S = getStreamer();
825
826 switch (FPU) {
827 case ARM::FK_VFP:
828 case ARM::FK_VFPV2:
829 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv2,
830 /* OverwriteExisting= */ false);
831 break;
832
833 case ARM::FK_VFPV3:
834 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
835 /* OverwriteExisting= */ false);
836 break;
837
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);
843 break;
844
845 case ARM::FK_VFPV3_D16:
846 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
847 /* OverwriteExisting= */ false);
848 break;
849
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);
855 break;
856
857 case ARM::FK_VFPV3XD:
858 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3B,
859 /* OverwriteExisting= */ false);
860 break;
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);
866 break;
867
868 case ARM::FK_VFPV4:
869 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4A,
870 /* OverwriteExisting= */ false);
871 break;
872
873 // ABI_HardFP_use is handled in ARMAsmPrinter, so _SP_D16 is treated the same
874 // as _D16 here.
875 case ARM::FK_FPV4_SP_D16:
876 case ARM::FK_VFPV4_D16:
877 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv4B,
878 /* OverwriteExisting= */ false);
879 break;
880
881 case ARM::FK_FP_ARMV8:
882 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPARMv8A,
883 /* OverwriteExisting= */ false);
884 break;
885
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);
892 break;
893
894 case ARM::FK_NEON:
895 S.setAttributeItem(ARMBuildAttrs::FP_arch, ARMBuildAttrs::AllowFPv3A,
896 /* OverwriteExisting= */ false);
897 S.setAttributeItem(ARMBuildAttrs::Advanced_SIMD_arch,
898 ARMBuildAttrs::AllowNeon,
899 /* OverwriteExisting= */ false);
900 break;
901
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);
910 break;
911
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);
918 break;
919
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()
926 break;
927
928 case ARM::FK_SOFTVFP:
929 case ARM::FK_NONE:
930 break;
931
932 default:
933 report_fatal_error("Unknown FPU: " + Twine(FPU));
934 break;
935 }
936 }
937
finishAttributeSection()938 void ARMTargetELFStreamer::finishAttributeSection() {
939 ARMELFStreamer &S = getStreamer();
940
941 if (FPU != ARM::FK_INVALID)
942 emitFPUDefaultAttributes();
943
944 if (Arch != ARM::ArchKind::INVALID)
945 emitArchDefaultAttributes();
946
947 if (S.Contents.empty())
948 return;
949
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
954 // (2.3.7.4):
955 //
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."
960 //
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));
965 };
966 llvm::sort(S.Contents, LessTag);
967
968 S.emitAttributesSection(CurrentVendor, ".ARM.attributes",
969 ELF::SHT_ARM_ATTRIBUTES, AttributeSection);
970
971 FPU = ARM::FK_INVALID;
972 }
973
emitLabel(MCSymbol * Symbol)974 void ARMTargetELFStreamer::emitLabel(MCSymbol *Symbol) {
975 ARMELFStreamer &Streamer = getStreamer();
976 if (!Streamer.IsThumb)
977 return;
978
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);
983 }
984
985 void
AnnotateTLSDescriptorSequence(const MCSymbolRefExpr * S)986 ARMTargetELFStreamer::AnnotateTLSDescriptorSequence(const MCSymbolRefExpr *S) {
987 getStreamer().EmitFixup(S, FK_Data_4);
988 }
989
emitThumbSet(MCSymbol * Symbol,const MCExpr * Value)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);
995 return;
996 }
997 }
998
999 getStreamer().emitThumbFunc(Symbol);
1000 getStreamer().emitAssignment(Symbol, Value);
1001 }
1002
emitInst(uint32_t Inst,char Suffix)1003 void ARMTargetELFStreamer::emitInst(uint32_t Inst, char Suffix) {
1004 getStreamer().emitInst(Inst, Suffix);
1005 }
1006
reset()1007 void ARMTargetELFStreamer::reset() { AttributeSection = nullptr; }
1008
finishImpl()1009 void ARMELFStreamer::finishImpl() {
1010 MCTargetStreamer &TS = *getTargetStreamer();
1011 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1012 ATS.finishAttributeSection();
1013
1014 MCELFStreamer::finishImpl();
1015 }
1016
reset()1017 void ARMELFStreamer::reset() {
1018 MCTargetStreamer &TS = *getTargetStreamer();
1019 ARMTargetStreamer &ATS = static_cast<ARMTargetStreamer &>(TS);
1020 ATS.reset();
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
1027 // do the same here
1028 getAssembler().setELFHeaderEFlags(ELF::EF_ARM_EABI_VER5);
1029 }
1030
SwitchToEHSection(StringRef Prefix,unsigned Type,unsigned Flags,SectionKind Kind,const MCSymbol & Fn)1031 inline void ARMELFStreamer::SwitchToEHSection(StringRef Prefix,
1032 unsigned Type,
1033 unsigned Flags,
1034 SectionKind Kind,
1035 const MCSymbol &Fn) {
1036 const MCSectionELF &FnSection =
1037 static_cast<const MCSectionELF &>(Fn.getSection());
1038
1039 // Create the name for new section
1040 StringRef FnSecName(FnSection.getName());
1041 SmallString<128> EHSecName(Prefix);
1042 if (FnSecName != ".text") {
1043 EHSecName += FnSecName;
1044 }
1045
1046 // Get .ARM.extab or .ARM.exidx section
1047 const MCSymbolELF *Group = FnSection.getGroup();
1048 if (Group)
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()));
1054
1055 assert(EHSection && "Failed to get the required EH section");
1056
1057 // Switch to .ARM.extab or .ARM.exidx section
1058 SwitchSection(EHSection);
1059 emitCodeAlignment(4);
1060 }
1061
SwitchToExTabSection(const MCSymbol & FnStart)1062 inline void ARMELFStreamer::SwitchToExTabSection(const MCSymbol &FnStart) {
1063 SwitchToEHSection(".ARM.extab", ELF::SHT_PROGBITS, ELF::SHF_ALLOC,
1064 SectionKind::getData(), FnStart);
1065 }
1066
SwitchToExIdxSection(const MCSymbol & 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);
1071 }
1072
EmitFixup(const MCExpr * Expr,MCFixupKind Kind)1073 void ARMELFStreamer::EmitFixup(const MCExpr *Expr, MCFixupKind Kind) {
1074 MCDataFragment *Frag = getOrCreateDataFragment();
1075 Frag->getFixups().push_back(MCFixup::create(Frag->getContents().size(), Expr,
1076 Kind));
1077 }
1078
EHReset()1079 void ARMELFStreamer::EHReset() {
1080 ExTab = nullptr;
1081 FnStart = nullptr;
1082 Personality = nullptr;
1083 PersonalityIndex = ARM::EHABI::NUM_PERSONALITY_INDEX;
1084 FPReg = ARM::SP;
1085 FPOffset = 0;
1086 SPOffset = 0;
1087 PendingOffset = 0;
1088 UsedFP = false;
1089 CantUnwind = false;
1090
1091 Opcodes.clear();
1092 UnwindOpAsm.Reset();
1093 }
1094
emitFnStart()1095 void ARMELFStreamer::emitFnStart() {
1096 assert(FnStart == nullptr);
1097 FnStart = getContext().createTempSymbol();
1098 emitLabel(FnStart);
1099 }
1100
emitFnEnd()1101 void ARMELFStreamer::emitFnEnd() {
1102 assert(FnStart && ".fnstart must precedes .fnend");
1103
1104 // Emit unwind opcodes if there is no .handlerdata directive
1105 if (!ExTab && !CantUnwind)
1106 FlushUnwindOpcodes(true);
1107
1108 // Emit the exception index table entry
1109 SwitchToExIdxSection(*FnStart);
1110
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
1115 // routine.
1116 if (PersonalityIndex < ARM::EHABI::NUM_PERSONALITY_INDEX && !IsAndroid)
1117 EmitPersonalityFixup(GetAEABIUnwindPersonalityName(PersonalityIndex));
1118
1119 const MCSymbolRefExpr *FnStartRef =
1120 MCSymbolRefExpr::create(FnStart,
1121 MCSymbolRefExpr::VK_ARM_PREL31,
1122 getContext());
1123
1124 emitValue(FnStartRef, 4);
1125
1126 if (CantUnwind) {
1127 emitInt32(ARM::EHABI::EXIDX_CANTUNWIND);
1128 } else if (ExTab) {
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,
1133 getContext());
1134 emitValue(ExTabEntryRef, 4);
1135 } else {
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] |
1144 Opcodes[1] << 8 |
1145 Opcodes[2] << 16 |
1146 Opcodes[3] << 24;
1147 emitIntValue(Intval, Opcodes.size());
1148 }
1149
1150 // Switch to the section containing FnStart
1151 SwitchSection(&FnStart->getSection());
1152
1153 // Clean exception handling frame information
1154 EHReset();
1155 }
1156
emitCantUnwind()1157 void ARMELFStreamer::emitCantUnwind() { CantUnwind = true; }
1158
1159 // Add the R_ARM_NONE fixup at the same position
EmitPersonalityFixup(StringRef Name)1160 void ARMELFStreamer::EmitPersonalityFixup(StringRef Name) {
1161 const MCSymbol *PersonalitySym = getContext().getOrCreateSymbol(Name);
1162
1163 const MCSymbolRefExpr *PersonalityRef = MCSymbolRefExpr::create(
1164 PersonalitySym, MCSymbolRefExpr::VK_ARM_NONE, getContext());
1165
1166 visitUsedExpr(*PersonalityRef);
1167 MCDataFragment *DF = getOrCreateDataFragment();
1168 DF->getFixups().push_back(MCFixup::create(DF->getContents().size(),
1169 PersonalityRef,
1170 MCFixup::getKindForSize(4, false)));
1171 }
1172
FlushPendingOffset()1173 void ARMELFStreamer::FlushPendingOffset() {
1174 if (PendingOffset != 0) {
1175 UnwindOpAsm.EmitSPOffset(-PendingOffset);
1176 PendingOffset = 0;
1177 }
1178 }
1179
FlushUnwindOpcodes(bool NoHandlerData)1180 void ARMELFStreamer::FlushUnwindOpcodes(bool NoHandlerData) {
1181 // Emit the unwind opcode to restore $sp.
1182 if (UsedFP) {
1183 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1184 int64_t LastRegSaveSPOffset = SPOffset - PendingOffset;
1185 UnwindOpAsm.EmitSPOffset(LastRegSaveSPOffset - FPOffset);
1186 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1187 } else {
1188 FlushPendingOffset();
1189 }
1190
1191 // Finalize the unwind opcode sequence
1192 UnwindOpAsm.Finalize(PersonalityIndex, Opcodes);
1193
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
1196 // section.
1197 if (NoHandlerData && PersonalityIndex == ARM::EHABI::AEABI_UNWIND_CPP_PR0)
1198 return;
1199
1200 // Switch to .ARM.extab section.
1201 SwitchToExTabSection(*FnStart);
1202
1203 // Create .ARM.extab label for offset in .ARM.exidx
1204 assert(!ExTab);
1205 ExTab = getContext().createTempSymbol();
1206 emitLabel(ExTab);
1207
1208 // Emit personality
1209 if (Personality) {
1210 const MCSymbolRefExpr *PersonalityRef =
1211 MCSymbolRefExpr::create(Personality,
1212 MCSymbolRefExpr::VK_ARM_PREL31,
1213 getContext());
1214
1215 emitValue(PersonalityRef, 4);
1216 }
1217
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;
1226 emitInt32(Intval);
1227 }
1228
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.
1233 //
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)
1237 emitInt32(0);
1238 }
1239
emitHandlerData()1240 void ARMELFStreamer::emitHandlerData() { FlushUnwindOpcodes(false); }
1241
emitPersonality(const MCSymbol * Per)1242 void ARMELFStreamer::emitPersonality(const MCSymbol *Per) {
1243 Personality = Per;
1244 UnwindOpAsm.setPersonality(Per);
1245 }
1246
emitPersonalityIndex(unsigned Index)1247 void ARMELFStreamer::emitPersonalityIndex(unsigned Index) {
1248 assert(Index < ARM::EHABI::NUM_PERSONALITY_INDEX && "invalid index");
1249 PersonalityIndex = Index;
1250 }
1251
emitSetFP(unsigned NewFPReg,unsigned NewSPReg,int64_t Offset)1252 void ARMELFStreamer::emitSetFP(unsigned NewFPReg, unsigned NewSPReg,
1253 int64_t Offset) {
1254 assert((NewSPReg == ARM::SP || NewSPReg == FPReg) &&
1255 "the operand of .setfp directive should be either $sp or $fp");
1256
1257 UsedFP = true;
1258 FPReg = NewFPReg;
1259
1260 if (NewSPReg == ARM::SP)
1261 FPOffset = SPOffset + Offset;
1262 else
1263 FPOffset += Offset;
1264 }
1265
emitMovSP(unsigned Reg,int64_t 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");
1270
1271 FlushPendingOffset();
1272
1273 FPReg = Reg;
1274 FPOffset = SPOffset + Offset;
1275
1276 const MCRegisterInfo *MRI = getContext().getRegisterInfo();
1277 UnwindOpAsm.EmitSetSP(MRI->getEncodingValue(FPReg));
1278 }
1279
emitPad(int64_t Offset)1280 void ARMELFStreamer::emitPad(int64_t Offset) {
1281 // Track the change of the $sp offset
1282 SPOffset -= Offset;
1283
1284 // To squash multiple .pad directives, we should delay the unwind opcode
1285 // until the .save, .vsave, .handlerdata, or .fnend directives.
1286 PendingOffset -= Offset;
1287 }
1288
emitRegSave(const SmallVectorImpl<unsigned> & RegList,bool IsVector)1289 void ARMELFStreamer::emitRegSave(const SmallVectorImpl<unsigned> &RegList,
1290 bool IsVector) {
1291 // Collect the registers in the register list
1292 unsigned Count = 0;
1293 uint32_t Mask = 0;
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) {
1300 Mask |= Bit;
1301 ++Count;
1302 }
1303 }
1304
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);
1310
1311 // Emit the opcode
1312 FlushPendingOffset();
1313 if (IsVector)
1314 UnwindOpAsm.EmitVFPRegSave(Mask);
1315 else
1316 UnwindOpAsm.EmitRegSave(Mask);
1317 }
1318
emitUnwindRaw(int64_t Offset,const SmallVectorImpl<uint8_t> & Opcodes)1319 void ARMELFStreamer::emitUnwindRaw(int64_t Offset,
1320 const SmallVectorImpl<uint8_t> &Opcodes) {
1321 FlushPendingOffset();
1322 SPOffset = SPOffset - Offset;
1323 UnwindOpAsm.EmitRaw(Opcodes);
1324 }
1325
1326 namespace llvm {
1327
createARMTargetAsmStreamer(MCStreamer & S,formatted_raw_ostream & OS,MCInstPrinter * InstPrint,bool isVerboseAsm)1328 MCTargetStreamer *createARMTargetAsmStreamer(MCStreamer &S,
1329 formatted_raw_ostream &OS,
1330 MCInstPrinter *InstPrint,
1331 bool isVerboseAsm) {
1332 return new ARMTargetAsmStreamer(S, OS, *InstPrint, isVerboseAsm);
1333 }
1334
createARMNullTargetStreamer(MCStreamer & S)1335 MCTargetStreamer *createARMNullTargetStreamer(MCStreamer &S) {
1336 return new ARMTargetStreamer(S);
1337 }
1338
createARMObjectTargetStreamer(MCStreamer & S,const MCSubtargetInfo & STI)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);
1345 }
1346
createARMELFStreamer(MCContext & Context,std::unique_ptr<MCAsmBackend> TAB,std::unique_ptr<MCObjectWriter> OW,std::unique_ptr<MCCodeEmitter> Emitter,bool RelaxAll,bool IsThumb,bool IsAndroid)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,
1352 bool IsAndroid) {
1353 ARMELFStreamer *S =
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);
1360
1361 if (RelaxAll)
1362 S->getAssembler().setRelaxAll(true);
1363 return S;
1364 }
1365
1366 } // end namespace llvm
1367