LLVM: lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
40
41using namespace llvm;
42
43namespace {
44
45class AArch64ELFStreamer;
46
48 formatted_raw_ostream &OS;
49 std::string VendorTag;
50
51 void emitInst(uint32_t Inst) override;
52
53 void emitDirectiveVariantPCS(MCSymbol *Symbol) override {
54 OS << "\t.variant_pcs\t" << Symbol->getName() << "\n";
55 }
56
57 void emitDirectiveArch(StringRef Name) override {
58 OS << "\t.arch\t" << Name << "\n";
59 }
60
61 void emitDirectiveArchExtension(StringRef Name) override {
62 OS << "\t.arch_extension\t" << Name << "\n";
63 }
64
65 void emitARM64WinCFIAllocStack(unsigned Size) override {
66 OS << "\t.seh_stackalloc\t" << Size << "\n";
67 }
68 void emitARM64WinCFISaveR19R20X(int Offset) override {
69 OS << "\t.seh_save_r19r20_x\t" << Offset << "\n";
70 }
71 void emitARM64WinCFISaveFPLR(int Offset) override {
72 OS << "\t.seh_save_fplr\t" << Offset << "\n";
73 }
74 void emitARM64WinCFISaveFPLRX(int Offset) override {
75 OS << "\t.seh_save_fplr_x\t" << Offset << "\n";
76 }
77 void emitARM64WinCFISaveReg(unsigned Reg, int Offset) override {
78 OS << "\t.seh_save_reg\tx" << Reg << ", " << Offset << "\n";
79 }
80 void emitARM64WinCFISaveRegX(unsigned Reg, int Offset) override {
81 OS << "\t.seh_save_reg_x\tx" << Reg << ", " << Offset << "\n";
82 }
83 void emitARM64WinCFISaveRegP(unsigned Reg, int Offset) override {
84 OS << "\t.seh_save_regp\tx" << Reg << ", " << Offset << "\n";
85 }
86 void emitARM64WinCFISaveRegPX(unsigned Reg, int Offset) override {
87 OS << "\t.seh_save_regp_x\tx" << Reg << ", " << Offset << "\n";
88 }
89 void emitARM64WinCFISaveLRPair(unsigned Reg, int Offset) override {
90 OS << "\t.seh_save_lrpair\tx" << Reg << ", " << Offset << "\n";
91 }
92 void emitARM64WinCFISaveFReg(unsigned Reg, int Offset) override {
93 OS << "\t.seh_save_freg\td" << Reg << ", " << Offset << "\n";
94 }
95 void emitARM64WinCFISaveFRegX(unsigned Reg, int Offset) override {
96 OS << "\t.seh_save_freg_x\td" << Reg << ", " << Offset << "\n";
97 }
98 void emitARM64WinCFISaveFRegP(unsigned Reg, int Offset) override {
99 OS << "\t.seh_save_fregp\td" << Reg << ", " << Offset << "\n";
100 }
101 void emitARM64WinCFISaveFRegPX(unsigned Reg, int Offset) override {
102 OS << "\t.seh_save_fregp_x\td" << Reg << ", " << Offset << "\n";
103 }
104 void emitARM64WinCFISetFP() override { OS << "\t.seh_set_fp\n"; }
105 void emitARM64WinCFIAddFP(unsigned Size) override {
106 OS << "\t.seh_add_fp\t" << Size << "\n";
107 }
108 void emitARM64WinCFINop() override { OS << "\t.seh_nop\n"; }
109 void emitARM64WinCFISaveNext() override { OS << "\t.seh_save_next\n"; }
110 void emitARM64WinCFIPrologEnd() override { OS << "\t.seh_endprologue\n"; }
111 void emitARM64WinCFIEpilogStart() override { OS << "\t.seh_startepilogue\n"; }
112 void emitARM64WinCFIEpilogEnd() override { OS << "\t.seh_endepilogue\n"; }
113 void emitARM64WinCFITrapFrame() override { OS << "\t.seh_trap_frame\n"; }
114 void emitARM64WinCFIMachineFrame() override { OS << "\t.seh_pushframe\n"; }
115 void emitARM64WinCFIContext() override { OS << "\t.seh_context\n"; }
116 void emitARM64WinCFIECContext() override { OS << "\t.seh_ec_context\n"; }
117 void emitARM64WinCFIClearUnwoundToCall() override {
118 OS << "\t.seh_clear_unwound_to_call\n";
119 }
120 void emitARM64WinCFIPACSignLR() override {
121 OS << "\t.seh_pac_sign_lr\n";
122 }
123
124 void emitARM64WinCFISaveAnyRegI(unsigned Reg, int Offset) override {
125 OS << "\t.seh_save_any_reg\tx" << Reg << ", " << Offset << "\n";
126 }
127 void emitARM64WinCFISaveAnyRegIP(unsigned Reg, int Offset) override {
128 OS << "\t.seh_save_any_reg_p\tx" << Reg << ", " << Offset << "\n";
129 }
130 void emitARM64WinCFISaveAnyRegD(unsigned Reg, int Offset) override {
131 OS << "\t.seh_save_any_reg\td" << Reg << ", " << Offset << "\n";
132 }
133 void emitARM64WinCFISaveAnyRegDP(unsigned Reg, int Offset) override {
134 OS << "\t.seh_save_any_reg_p\td" << Reg << ", " << Offset << "\n";
135 }
136 void emitARM64WinCFISaveAnyRegQ(unsigned Reg, int Offset) override {
137 OS << "\t.seh_save_any_reg\tq" << Reg << ", " << Offset << "\n";
138 }
139 void emitARM64WinCFISaveAnyRegQP(unsigned Reg, int Offset) override {
140 OS << "\t.seh_save_any_reg_p\tq" << Reg << ", " << Offset << "\n";
141 }
142 void emitARM64WinCFISaveAnyRegIX(unsigned Reg, int Offset) override {
143 OS << "\t.seh_save_any_reg_x\tx" << Reg << ", " << Offset << "\n";
144 }
145 void emitARM64WinCFISaveAnyRegIPX(unsigned Reg, int Offset) override {
146 OS << "\t.seh_save_any_reg_px\tx" << Reg << ", " << Offset << "\n";
147 }
148 void emitARM64WinCFISaveAnyRegDX(unsigned Reg, int Offset) override {
149 OS << "\t.seh_save_any_reg_x\td" << Reg << ", " << Offset << "\n";
150 }
151 void emitARM64WinCFISaveAnyRegDPX(unsigned Reg, int Offset) override {
152 OS << "\t.seh_save_any_reg_px\td" << Reg << ", " << Offset << "\n";
153 }
154 void emitARM64WinCFISaveAnyRegQX(unsigned Reg, int Offset) override {
155 OS << "\t.seh_save_any_reg_x\tq" << Reg << ", " << Offset << "\n";
156 }
157 void emitARM64WinCFISaveAnyRegQPX(unsigned Reg, int Offset) override {
158 OS << "\t.seh_save_any_reg_px\tq" << Reg << ", " << Offset << "\n";
159 }
160 void emitARM64WinCFIAllocZ(int Offset) override {
161 OS << "\t.seh_allocz\t" << Offset << "\n";
162 }
163 void emitARM64WinCFISaveZReg(unsigned Reg, int Offset) override {
164 OS << "\t.seh_save_zreg\tz" << Reg << ", " << Offset << "\n";
165 }
166 void emitARM64WinCFISavePReg(unsigned Reg, int Offset) override {
167 OS << "\t.seh_save_preg\tp" << Reg << ", " << Offset << "\n";
168 }
169
170 void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value,
171 std::string String) override {
172
173
174
175 if (unsigned(-1) == Value && "" == String) {
176 assert(0 && "Arguments error");
177 return;
178 }
179
181
182 switch (VendorID) {
184 if (unsigned(-1) != Value) {
185 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
187 }
189 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << String;
192 }
193 break;
194
196 switch (Tag) {
197 default:
198 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
199
200
202 break;
206 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// "
209 break;
210 }
211 break;
212
214 switch (Tag) {
215 default:
216 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value;
217
218
220 break;
223 OS << "\t.aeabi_attribute" << "\t" << Tag << ", " << Value << "\t// "
226 break;
227 }
228 break;
229 }
230 OS << "\n";
231 }
232
233 void emitAttributesSubsection(
234 StringRef SubsectionName,
237
238
239
240
242
243 assert((0 == Optional || 1 == Optional) &&
245 assert((0 == ParameterType || 1 == ParameterType) &&
247
248 std::string SubsectionTag = ".aeabi_subsection";
250 StringRef ParameterStr = getTypeStr(ParameterType);
251
252 switch (SubsectionID) {
254
255 break;
256 }
259 "subsection .aeabi-pauthabi should be marked as "
260 "required and not as optional");
262 "subsection .aeabi-pauthabi should be "
263 "marked as uleb128 and not as ntbs");
264 break;
265 }
268 "subsection .aeabi_feature_and_bits should be "
269 "marked as optional and not as required");
271 "subsection .aeabi_feature_and_bits should "
272 "be marked as uleb128 and not as ntbs");
273 break;
274 }
275 }
276 OS << "\t" << SubsectionTag << "\t" << SubsectionName << ", " << OptionalStr
277 << ", " << ParameterStr;
278
279
281 ParameterType);
282 OS << "\n";
283 }
284
285public:
286 AArch64TargetAsmStreamer(MCStreamer &S, formatted_raw_ostream &OS);
287};
288
289AArch64TargetAsmStreamer::AArch64TargetAsmStreamer(MCStreamer &S,
292
293void AArch64TargetAsmStreamer::emitInst(uint32_t Inst) {
295}
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310class AArch64ELFStreamer : public MCELFStreamer {
311public:
312 friend AArch64TargetELFStreamer;
313 AArch64ELFStreamer(MCContext &Context, std::unique_ptr TAB,
314 std::unique_ptr OW,
315 std::unique_ptr Emitter)
318 LastEMS(EMS_None) {
319 auto *TO = getContext().getTargetOptions();
320 ImplicitMapSyms = TO && TO->ImplicitMapSyms;
321 }
322
323 void changeSection(MCSection *Section, uint32_t Subsection = 0) override {
324
325
326
327 LastMappingSymbols[getCurrentSection().first] = LastEMS;
328 auto It = LastMappingSymbols.find(Section);
329 if (It != LastMappingSymbols.end())
330 LastEMS = It->second;
331 else if (ImplicitMapSyms)
332 LastEMS = Section->isText() ? EMS_A64 : EMS_Data;
333 else
334 LastEMS = EMS_None;
335
337
338
341 }
342
343
344 void reset() override {
346 LastMappingSymbols.clear();
347 LastEMS = EMS_None;
348 }
349
350
351
352
354 const MCSubtargetInfo &STI) override {
355 emitA64MappingSymbol();
356 MCELFStreamer::emitInstruction(Inst, STI);
357 }
358
359
360
361 void emitInst(uint32_t Inst) {
362 char Buffer[4];
363
364
365
366
367 for (char &C : Buffer) {
368 C = uint8_t(Inst);
369 Inst >>= 8;
370 }
371
372 emitA64MappingSymbol();
373 MCELFStreamer::emitBytes(StringRef(Buffer, 4));
374 }
375
376
377
378
379 void emitBytes(StringRef Data) override {
380 emitDataMappingSymbol();
381 MCELFStreamer::emitBytes(Data);
382 }
383
384
385
386
387 void emitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) override {
388 emitDataMappingSymbol();
389 MCELFStreamer::emitValueImpl(Value, Size, Loc);
390 }
391
392 void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
393 SMLoc Loc) override {
394 emitDataMappingSymbol();
396 }
397
398private:
399 enum ElfMappingSymbol {
400 EMS_None,
401 EMS_A64,
402 EMS_Data
403 };
404
405 void emitDataMappingSymbol() {
406 if (LastEMS == EMS_Data)
407 return;
408 emitMappingSymbol("$d");
409 LastEMS = EMS_Data;
410 }
411
412 void emitA64MappingSymbol() {
413 if (LastEMS == EMS_A64)
414 return;
415 emitMappingSymbol("$x");
416 LastEMS = EMS_A64;
417 }
418
419 MCSymbol *emitMappingSymbol(StringRef Name) {
421 static_cast<MCSymbolELF *>(getContext().createLocalSymbol(Name));
422 emitLabel(Symbol);
424 }
425
426 DenseMap<const MCSection *, ElfMappingSymbol> LastMappingSymbols;
427 ElfMappingSymbol LastEMS;
428 bool ImplicitMapSyms;
429};
430}
431
432AArch64ELFStreamer &AArch64TargetELFStreamer::getStreamer() {
433 return static_cast<AArch64ELFStreamer &>(Streamer);
434}
435
436void AArch64TargetELFStreamer::emitAttributesSubsection(
440 ParameterType);
441}
442
443void AArch64TargetELFStreamer::emitAttribute(StringRef VendorName, unsigned Tag,
445 std::string String) {
446 if (unsigned(-1) != Value)
450}
451
452void AArch64TargetELFStreamer::emitInst(uint32_t Inst) {
453 getStreamer().emitInst(Inst);
454}
455
456void AArch64TargetELFStreamer::emitDirectiveVariantPCS(MCSymbol *Symbol) {
457 getStreamer().getAssembler().registerSymbol(*Symbol);
459}
460
461void AArch64TargetELFStreamer::finish() {
463 AArch64ELFStreamer &S = getStreamer();
464 MCContext &Ctx = S.getContext();
465 auto &Asm = S.getAssembler();
466
467 S.emitAttributesSection(AttributeSection, ".ARM.attributes",
469
470
471
472
473
474
475
476
477 if (S.ImplicitMapSyms) {
478 auto &Syms = Asm.getSymbols();
479 const size_t NumSyms = Syms.size();
480 DenseMap<MCSection *, std::pair<size_t, MCSymbol *>> EndMapSym;
481 for (MCSection &Sec : Asm) {
482 S.switchSection(&Sec);
483 if (S.LastEMS == (Sec.isText() ? AArch64ELFStreamer::EMS_Data
484 : AArch64ELFStreamer::EMS_A64))
486 {&Sec, {NumSyms, S.emitMappingSymbol(Sec.isText() ? "$x" : "$d")}});
487 }
488 if (Syms.size() != NumSyms) {
490 Syms.truncate(NumSyms);
491
493 if (!Sym->isInSection())
494 continue;
495 auto It = EndMapSym.find(&Sym->getSection());
496 if (It != EndMapSym.end())
497 It->second.first = I;
498 }
499 SmallVector<size_t, 0> Idx;
502 if (!Sym->isInSection())
503 continue;
504 auto It = EndMapSym.find(&Sym->getSection());
505
506
507 if (It != EndMapSym.end() && I == It->second.first) {
508 NewSyms.push_back(It->second.second);
510 }
511 }
512 Syms = std::move(NewSyms);
513
514
515 for (auto &F : S.getWriter().getFileNames())
517 }
518 }
519
520
521
522
523
524
525 if (any_of(Asm, [](const MCSection &Sec) {
526 return static_cast<const MCSectionELF &>(Sec).getFlags() &
528 })) {
530 static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection());
531 bool Empty = true;
532 for (auto &F : *Text) {
533 if (F.getSize()) {
535 break;
536 }
537 }
540 }
541
542 MCSectionELF *MemtagSec = nullptr;
543 for (const MCSymbol &Symbol : Asm.symbols()) {
544 auto &Sym = static_cast<const MCSymbolELF &>(Symbol);
545 if (Sym.isMemtag()) {
546 MemtagSec = Ctx.getELFSection(".memtag.globals.static",
548 break;
549 }
550 }
551 if (!MemtagSec)
552 return;
553
554
555
556 S.switchSection(MemtagSec);
558 for (const MCSymbol &Symbol : Asm.symbols()) {
559 auto &Sym = static_cast<const MCSymbolELF &>(Symbol);
560 if (!Sym.isMemtag())
561 continue;
563 S.emitRelocDirective(*Zero, "BFD_RELOC_NONE", SRE);
564 }
565}
566
567MCTargetStreamer *
570 return new AArch64TargetAsmStreamer(S, OS);
571}
572
575 std::unique_ptr &&TAB,
576 std::unique_ptr &&OW,
577 std::unique_ptr &&Emitter) {
578 return new AArch64ELFStreamer(Context, std::move(TAB), std::move(OW),
580}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
dxil DXContainer Global Emitter
This file defines the DenseMap class.
static uint32_t getFlags(const Symbol *Sym)
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
virtual void emitAttributesSubsection(StringRef VendorName, AArch64BuildAttributes::SubsectionOptional IsOptional, AArch64BuildAttributes::SubsectionType ParameterType)
Build attributes implementation.
virtual void emitAttribute(StringRef VendorName, unsigned Tag, unsigned Value, std::string String)
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCObjectFileInfo * getObjectFileInfo() const
MCSectionELF * getELFSection(const Twine &Section, unsigned Type, unsigned Flags)
void changeSection(MCSection *Section, uint32_t Subsection=0) override
This is called by popSection and switchSection, if the current section changes.
void reset() override
state management
This is an instance of a target assembly language printer that converts an MCInst to valid target ass...
void emitFill(const MCExpr &NumBytes, uint64_t FillValue, SMLoc Loc=SMLoc()) override
Emit Size bytes worth of the value specified by FillValue.
Streaming machine code generation interface.
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
void push_back(const T &Elt)
Triple - Helper class for working with autoconf configuration names.
static Twine utohexstr(uint64_t Val)
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
StringRef getPauthABITagsStr(unsigned PauthABITag)
StringRef getOptionalStr(unsigned Optional)
VendorID
AArch64 build attributes vendors IDs (a.k.a subsection name)
StringRef getSubsectionTypeUnknownError()
StringRef getSubsectionOptionalUnknownError()
VendorID getVendorID(StringRef const Vendor)
StringRef getTypeStr(unsigned Type)
StringRef getFeatureAndBitsTagsStr(unsigned FeatureAndBitsTag)
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
@ SHT_AARCH64_MEMTAG_GLOBALS_STATIC
@ STO_AARCH64_VARIANT_PCS
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
MCStreamer * createAArch64ELFStreamer(const Triple &, MCContext &Context, std::unique_ptr< MCAsmBackend > &&TAB, std::unique_ptr< MCObjectWriter > &&OW, std::unique_ptr< MCCodeEmitter > &&Emitter)
Definition AArch64ELFStreamer.cpp:574
MCTargetStreamer * createAArch64AsmTargetStreamer(MCStreamer &S, formatted_raw_ostream &OS, MCInstPrinter *InstPrint)
Definition AArch64ELFStreamer.cpp:568
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionAddr VTableAddr uintptr_t uintptr_t Data
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.