LLVM 23.0.0git
COFFAsmParser.cpp
Go to the documentation of this file.
1//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
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
11#include "llvm/ADT/Twine.h"
13#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCStreamer.h"
19#include "llvm/Support/SMLoc.h"
21#include <cassert>
22#include <cstdint>
23#include <limits>
24
25using namespace llvm;
26
27namespace {
28
29class COFFAsmParser : public MCAsmParserExtension {
30 template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
31 void addDirectiveHandler(StringRef Directive) {
32 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
33 this, HandleDirective<COFFAsmParser, HandlerMethod>);
34 getParser().addDirectiveHandler(Directive, Handler);
35 }
36
37 bool parseSectionSwitch(StringRef Section, unsigned Characteristics);
38
39 bool parseSectionSwitch(StringRef Section, unsigned Characteristics,
40 StringRef COMDATSymName, COFF::COMDATType Type,
41 unsigned UniqueID);
42
43 bool parseSectionName(StringRef &SectionName);
44 bool parseSectionFlags(StringRef SectionName, StringRef FlagsString,
45 unsigned *Flags);
46 void Initialize(MCAsmParser &Parser) override {
47 // Call the base implementation.
49
50 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveText>(".text");
51 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveData>(".data");
52 addDirectiveHandler<&COFFAsmParser::parseSectionDirectiveBSS>(".bss");
53 addDirectiveHandler<&COFFAsmParser::parseDirectiveSection>(".section");
54 addDirectiveHandler<&COFFAsmParser::parseDirectivePushSection>(
55 ".pushsection");
56 addDirectiveHandler<&COFFAsmParser::parseDirectivePopSection>(
57 ".popsection");
58 addDirectiveHandler<&COFFAsmParser::parseDirectiveDef>(".def");
59 addDirectiveHandler<&COFFAsmParser::parseDirectiveScl>(".scl");
60 addDirectiveHandler<&COFFAsmParser::parseDirectiveType>(".type");
61 addDirectiveHandler<&COFFAsmParser::parseDirectiveEndef>(".endef");
62 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecRel32>(".secrel32");
63 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymIdx>(".symidx");
64 addDirectiveHandler<&COFFAsmParser::parseDirectiveSafeSEH>(".safeseh");
65 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecIdx>(".secidx");
66 addDirectiveHandler<&COFFAsmParser::parseDirectiveLinkOnce>(".linkonce");
67 addDirectiveHandler<&COFFAsmParser::parseDirectiveRVA>(".rva");
68 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(".weak");
69 addDirectiveHandler<&COFFAsmParser::parseDirectiveSymbolAttribute>(
70 ".weak_anti_dep");
71 addDirectiveHandler<&COFFAsmParser::parseDirectiveCGProfile>(".cg_profile");
72 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecNum>(".secnum");
73 addDirectiveHandler<&COFFAsmParser::parseDirectiveSecOffset>(".secoffset");
74
75 // Win64 EH directives.
76 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveStartProc>(
77 ".seh_proc");
78 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProc>(
79 ".seh_endproc");
80 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc>(
81 ".seh_endfunclet");
82 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveSplitChained>(
83 ".seh_splitchained");
84 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandler>(
85 ".seh_handler");
86 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveHandlerData>(
87 ".seh_handlerdata");
88 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveAllocStack>(
89 ".seh_stackalloc");
90 addDirectiveHandler<&COFFAsmParser::parseSEHDirectiveEndProlog>(
91 ".seh_endprologue");
92 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveBeginEpilog>(
93 ".seh_startepilogue");
94 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndEpilog>(
95 ".seh_endepilogue");
96 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveUnwindV2Start>(
97 ".seh_unwindv2start");
98 addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveUnwindVersion>(
99 ".seh_unwindversion");
100 }
101
102 bool parseSectionDirectiveText(StringRef, SMLoc) {
103 return parseSectionSwitch(".text", COFF::IMAGE_SCN_CNT_CODE |
106 }
107
108 bool parseSectionDirectiveData(StringRef, SMLoc) {
109 return parseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
112 }
113
114 bool parseSectionDirectiveBSS(StringRef, SMLoc) {
115 return parseSectionSwitch(".bss", COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
118 }
119
120 bool parseDirectiveSection(StringRef, SMLoc);
121 bool parseSectionArguments(StringRef, SMLoc);
122 bool parseDirectivePushSection(StringRef, SMLoc);
123 bool parseDirectivePopSection(StringRef, SMLoc);
124 bool parseDirectiveDef(StringRef, SMLoc);
125 bool parseDirectiveScl(StringRef, SMLoc);
126 bool parseDirectiveType(StringRef, SMLoc);
127 bool parseDirectiveEndef(StringRef, SMLoc);
128 bool parseDirectiveSecRel32(StringRef, SMLoc);
129 bool parseDirectiveSecIdx(StringRef, SMLoc);
130 bool parseDirectiveSafeSEH(StringRef, SMLoc);
131 bool parseDirectiveSymIdx(StringRef, SMLoc);
132 bool parseCOMDATType(COFF::COMDATType &Type);
133 bool parseDirectiveLinkOnce(StringRef, SMLoc);
134 bool parseDirectiveRVA(StringRef, SMLoc);
135 bool parseDirectiveCGProfile(StringRef, SMLoc);
136 bool parseDirectiveSecNum(StringRef, SMLoc);
137 bool parseDirectiveSecOffset(StringRef, SMLoc);
138
139 // Win64 EH directives.
140 bool parseSEHDirectiveStartProc(StringRef, SMLoc);
141 bool parseSEHDirectiveEndProc(StringRef, SMLoc);
142 bool parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc);
143 bool parseSEHDirectiveSplitChained(StringRef, SMLoc);
144 bool parseSEHDirectiveHandler(StringRef, SMLoc);
145 bool parseSEHDirectiveHandlerData(StringRef, SMLoc);
146 bool parseSEHDirectiveAllocStack(StringRef, SMLoc);
147 bool parseSEHDirectiveEndProlog(StringRef, SMLoc);
148 bool ParseSEHDirectiveBeginEpilog(StringRef, SMLoc);
149 bool ParseSEHDirectiveEndEpilog(StringRef, SMLoc);
150 bool ParseSEHDirectiveUnwindV2Start(StringRef, SMLoc);
151 bool ParseSEHDirectiveUnwindVersion(StringRef, SMLoc);
152
153 bool parseAtUnwindOrAtExcept(bool &unwind, bool &except);
154 bool parseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
155
156public:
157 COFFAsmParser() = default;
158};
159
160} // end anonymous namespace.
161
162bool COFFAsmParser::parseSectionFlags(StringRef SectionName,
163 StringRef FlagsString, unsigned *Flags) {
164 enum {
165 None = 0,
166 Alloc = 1 << 0,
167 Code = 1 << 1,
168 Load = 1 << 2,
169 InitData = 1 << 3,
170 Shared = 1 << 4,
171 NoLoad = 1 << 5,
172 NoRead = 1 << 6,
173 NoWrite = 1 << 7,
174 Discardable = 1 << 8,
175 Info = 1 << 9,
176 };
177
178 bool ReadOnlyRemoved = false;
179 unsigned SecFlags = None;
180
181 for (char FlagChar : FlagsString) {
182 switch (FlagChar) {
183 case 'a':
184 // Ignored.
185 break;
186
187 case 'b': // bss section
188 SecFlags |= Alloc;
189 if (SecFlags & InitData)
190 return TokError("conflicting section flags 'b' and 'd'.");
191 SecFlags &= ~Load;
192 break;
193
194 case 'd': // data section
195 SecFlags |= InitData;
196 if (SecFlags & Alloc)
197 return TokError("conflicting section flags 'b' and 'd'.");
198 SecFlags &= ~NoWrite;
199 if ((SecFlags & NoLoad) == 0)
200 SecFlags |= Load;
201 break;
202
203 case 'n': // section is not loaded
204 SecFlags |= NoLoad;
205 SecFlags &= ~Load;
206 break;
207
208 case 'D': // discardable
209 SecFlags |= Discardable;
210 break;
211
212 case 'r': // read-only
213 ReadOnlyRemoved = false;
214 SecFlags |= NoWrite;
215 if ((SecFlags & Code) == 0)
216 SecFlags |= InitData;
217 if ((SecFlags & NoLoad) == 0)
218 SecFlags |= Load;
219 break;
220
221 case 's': // shared section
222 SecFlags |= Shared | InitData;
223 SecFlags &= ~NoWrite;
224 if ((SecFlags & NoLoad) == 0)
225 SecFlags |= Load;
226 break;
227
228 case 'w': // writable
229 SecFlags &= ~NoWrite;
230 ReadOnlyRemoved = true;
231 break;
232
233 case 'x': // executable section
234 SecFlags |= Code;
235 if ((SecFlags & NoLoad) == 0)
236 SecFlags |= Load;
237 if (!ReadOnlyRemoved)
238 SecFlags |= NoWrite;
239 break;
240
241 case 'y': // not readable
242 SecFlags |= NoRead | NoWrite;
243 break;
244
245 case 'i': // info
246 SecFlags |= Info;
247 break;
248
249 default:
250 return TokError("unknown flag");
251 }
252 }
253
254 *Flags = 0;
255
256 if (SecFlags == None)
257 SecFlags = InitData;
258
259 if (SecFlags & Code)
261 if (SecFlags & InitData)
263 if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
265 if (SecFlags & NoLoad)
267 if ((SecFlags & Discardable) ||
270 if ((SecFlags & NoRead) == 0)
272 if ((SecFlags & NoWrite) == 0)
274 if (SecFlags & Shared)
276 if (SecFlags & Info)
278
279 return false;
280}
281
282/// ParseDirectiveSymbolAttribute
283/// ::= { ".weak", ... } [ identifier ( , identifier )* ]
284bool COFFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
285 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
286 .Case(".weak", MCSA_Weak)
287 .Case(".weak_anti_dep", MCSA_WeakAntiDep)
288 .Default(MCSA_Invalid);
289 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
290 if (getLexer().isNot(AsmToken::EndOfStatement)) {
291 while (true) {
292 MCSymbol *Sym;
293
294 if (getParser().parseSymbol(Sym))
295 return TokError("expected identifier in directive");
296
297 getStreamer().emitSymbolAttribute(Sym, Attr);
298
299 if (getLexer().is(AsmToken::EndOfStatement))
300 break;
301
302 if (getLexer().isNot(AsmToken::Comma))
303 return TokError("unexpected token in directive");
304 Lex();
305 }
306 }
307
308 Lex();
309 return false;
310}
311
312bool COFFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
314}
315
316bool COFFAsmParser::parseSectionSwitch(StringRef Section,
317 unsigned Characteristics) {
318 return parseSectionSwitch(Section, Characteristics, "", (COFF::COMDATType)0,
320}
321
322bool COFFAsmParser::parseSectionSwitch(StringRef Section,
323 unsigned Characteristics,
324 StringRef COMDATSymName,
326 unsigned UniqueID) {
327 if (getLexer().isNot(AsmToken::EndOfStatement))
328 return TokError("unexpected token in section switching directive");
329 Lex();
330
331 getStreamer().switchSection(getContext().getCOFFSection(
332 Section, Characteristics, COMDATSymName, Type, UniqueID));
333
334 return false;
335}
336
337bool COFFAsmParser::parseSectionName(StringRef &SectionName) {
338 if (!getLexer().is(AsmToken::Identifier) && !getLexer().is(AsmToken::String))
339 return true;
340
341 SectionName = getTok().getIdentifier();
342 Lex();
343 return false;
344}
345
346bool COFFAsmParser::parseDirectiveSection(StringRef directive, SMLoc loc) {
347 return parseSectionArguments(directive, loc);
348}
349
350// .section name [, "flags"] [, identifier [ identifier ], identifier]
351// .pushsection <same as above>
352//
353// Supported flags:
354// a: Ignored.
355// b: BSS section (uninitialized data)
356// d: data section (initialized data)
357// n: "noload" section (removed by linker)
358// D: Discardable section
359// r: Readable section
360// s: Shared section
361// w: Writable section
362// x: Executable section
363// y: Not-readable section (clears 'r')
364//
365// Subsections are not supported.
366bool COFFAsmParser::parseSectionArguments(StringRef, SMLoc) {
367 StringRef SectionName;
368
369 if (parseSectionName(SectionName))
370 return TokError("expected identifier in directive");
371
375
376 if (getLexer().is(AsmToken::Comma)) {
377 Lex();
378
379 if (getLexer().isNot(AsmToken::String))
380 return TokError("expected string in directive");
381
382 StringRef FlagsStr = getTok().getStringContents();
383 Lex();
384
385 if (parseSectionFlags(SectionName, FlagsStr, &Flags))
386 return true;
387 }
388
390 StringRef COMDATSymName;
391 if (getLexer().is(AsmToken::Comma) &&
392 getLexer().peekTok().getString() != "unique") {
394 Lex();
395
397
398 if (!getLexer().is(AsmToken::Identifier))
399 return TokError("expected comdat type such as 'discard' or 'largest' "
400 "after protection bits");
401
402 if (parseCOMDATType(Type))
403 return true;
404
405 if (getLexer().isNot(AsmToken::Comma))
406 return TokError("expected comma in directive");
407 Lex();
408
409 if (getParser().parseIdentifier(COMDATSymName))
410 return TokError("expected identifier in directive");
411 }
412
413 int64_t UniqueID = MCSection::NonUniqueID;
414 if (maybeParseUniqueID(UniqueID))
415 return true;
416
417 if (getLexer().isNot(AsmToken::EndOfStatement))
418 return TokError("unexpected token in directive");
419
420 if (Flags & COFF::IMAGE_SCN_CNT_CODE) {
421 const Triple &T = getContext().getTargetTriple();
422 if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
424 }
425 parseSectionSwitch(SectionName, Flags, COMDATSymName, Type, UniqueID);
426 return false;
427}
428
429bool COFFAsmParser::parseDirectivePushSection(StringRef directive, SMLoc loc) {
430 getStreamer().pushSection();
431
432 if (parseSectionArguments(directive, loc)) {
433 getStreamer().popSection();
434 return true;
435 }
436
437 return false;
438}
439
440bool COFFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
441 if (!getStreamer().popSection())
442 return TokError(".popsection without corresponding .pushsection");
443 return false;
444}
445
446bool COFFAsmParser::parseDirectiveDef(StringRef, SMLoc) {
447 MCSymbol *Sym;
448
449 if (getParser().parseSymbol(Sym))
450 return TokError("expected identifier in directive");
451
452 getStreamer().beginCOFFSymbolDef(Sym);
453
454 Lex();
455 return false;
456}
457
458bool COFFAsmParser::parseDirectiveScl(StringRef, SMLoc) {
459 int64_t SymbolStorageClass;
460 if (getParser().parseAbsoluteExpression(SymbolStorageClass))
461 return true;
462
463 if (getLexer().isNot(AsmToken::EndOfStatement))
464 return TokError("unexpected token in directive");
465
466 Lex();
467 getStreamer().emitCOFFSymbolStorageClass(SymbolStorageClass);
468 return false;
469}
470
471bool COFFAsmParser::parseDirectiveType(StringRef, SMLoc) {
472 int64_t Type;
473 if (getParser().parseAbsoluteExpression(Type))
474 return true;
475
476 if (getLexer().isNot(AsmToken::EndOfStatement))
477 return TokError("unexpected token in directive");
478
479 Lex();
480 getStreamer().emitCOFFSymbolType(Type);
481 return false;
482}
483
484bool COFFAsmParser::parseDirectiveEndef(StringRef, SMLoc) {
485 Lex();
486 getStreamer().endCOFFSymbolDef();
487 return false;
488}
489
490bool COFFAsmParser::parseDirectiveSecRel32(StringRef, SMLoc) {
492 if (getParser().parseSymbol(Symbol))
493 return TokError("expected identifier in directive");
494
495 int64_t Offset = 0;
496 SMLoc OffsetLoc;
497 if (getLexer().is(AsmToken::Plus)) {
498 OffsetLoc = getLexer().getLoc();
499 if (getParser().parseAbsoluteExpression(Offset))
500 return true;
501 }
502
503 if (getLexer().isNot(AsmToken::EndOfStatement))
504 return TokError("unexpected token in directive");
505
506 if (Offset < 0 || Offset > std::numeric_limits<uint32_t>::max())
507 return Error(
508 OffsetLoc,
509 "invalid '.secrel32' directive offset, can't be less "
510 "than zero or greater than std::numeric_limits<uint32_t>::max()");
511
512 Lex();
513 getStreamer().emitCOFFSecRel32(Symbol, Offset);
514 return false;
515}
516
517bool COFFAsmParser::parseDirectiveRVA(StringRef, SMLoc) {
518 auto parseOp = [&]() -> bool {
520 if (getParser().parseSymbol(Symbol))
521 return TokError("expected identifier in directive");
522
523 int64_t Offset = 0;
524 SMLoc OffsetLoc;
525 if (getLexer().is(AsmToken::Plus) || getLexer().is(AsmToken::Minus)) {
526 OffsetLoc = getLexer().getLoc();
527 if (getParser().parseAbsoluteExpression(Offset))
528 return true;
529 }
530
531 if (Offset < std::numeric_limits<int32_t>::min() ||
532 Offset > std::numeric_limits<int32_t>::max())
533 return Error(OffsetLoc, "invalid '.rva' directive offset, can't be less "
534 "than -2147483648 or greater than "
535 "2147483647");
536
537 getStreamer().emitCOFFImgRel32(Symbol, Offset);
538 return false;
539 };
540
541 if (getParser().parseMany(parseOp))
542 return addErrorSuffix(" in directive");
543 return false;
544}
545
546bool COFFAsmParser::parseDirectiveSafeSEH(StringRef, SMLoc) {
548 if (getParser().parseSymbol(Symbol))
549 return TokError("expected identifier in directive");
550
551 if (getLexer().isNot(AsmToken::EndOfStatement))
552 return TokError("unexpected token in directive");
553
554 Lex();
555 getStreamer().emitCOFFSafeSEH(Symbol);
556 return false;
557}
558
559bool COFFAsmParser::parseDirectiveSecIdx(StringRef, SMLoc) {
561 if (getParser().parseSymbol(Symbol))
562 return TokError("expected identifier in directive");
563
564 if (getLexer().isNot(AsmToken::EndOfStatement))
565 return TokError("unexpected token in directive");
566
567 Lex();
568 getStreamer().emitCOFFSectionIndex(Symbol);
569 return false;
570}
571
572bool COFFAsmParser::parseDirectiveSymIdx(StringRef, SMLoc) {
574 if (getParser().parseSymbol(Symbol))
575 return TokError("expected identifier in directive");
576
577 if (getLexer().isNot(AsmToken::EndOfStatement))
578 return TokError("unexpected token in directive");
579
580 Lex();
581 getStreamer().emitCOFFSymbolIndex(Symbol);
582 return false;
583}
584
585bool COFFAsmParser::parseDirectiveSecNum(StringRef, SMLoc) {
587 if (getParser().parseSymbol(Symbol))
588 return TokError("expected identifier in directive");
589
590 if (getLexer().isNot(AsmToken::EndOfStatement))
591 return TokError("unexpected token in directive");
592
593 Lex();
594 getStreamer().emitCOFFSecNumber(Symbol);
595 return false;
596}
597
598bool COFFAsmParser::parseDirectiveSecOffset(StringRef, SMLoc) {
600 if (getParser().parseSymbol(Symbol))
601 return TokError("expected identifier in directive");
602
603 if (getLexer().isNot(AsmToken::EndOfStatement))
604 return TokError("unexpected token in directive");
605
606 Lex();
607 getStreamer().emitCOFFSecOffset(Symbol);
608 return false;
609}
610
611/// ::= [ identifier ]
612bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
613 StringRef TypeId = getTok().getIdentifier();
614
615 Type = StringSwitch<COFF::COMDATType>(TypeId)
617 .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY)
618 .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE)
619 .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH)
620 .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE)
621 .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST)
622 .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST)
623 .Default((COFF::COMDATType)0);
624
625 if (Type == 0)
626 return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
627
628 Lex();
629
630 return false;
631}
632
633/// ParseDirectiveLinkOnce
634/// ::= .linkonce [ identifier ]
635bool COFFAsmParser::parseDirectiveLinkOnce(StringRef, SMLoc Loc) {
637 if (getLexer().is(AsmToken::Identifier))
638 if (parseCOMDATType(Type))
639 return true;
640
641 const MCSectionCOFF *Current =
642 static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());
643
645 return Error(Loc, "cannot make section associative with .linkonce");
646
648 return Error(Loc, Twine("section '") + Current->getName() +
649 "' is already linkonce");
650
651 Current->setSelection(Type);
652
653 if (getLexer().isNot(AsmToken::EndOfStatement))
654 return TokError("unexpected token in directive");
655
656 return false;
657}
658
659bool COFFAsmParser::parseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
661 if (getParser().parseSymbol(Symbol))
662 return true;
663
664 if (getLexer().isNot(AsmToken::EndOfStatement))
665 return TokError("unexpected token in directive");
666
667 Lex();
668 getStreamer().emitWinCFIStartProc(Symbol, Loc);
669 return false;
670}
671
672bool COFFAsmParser::parseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
673 Lex();
674 getStreamer().emitWinCFIEndProc(Loc);
675 return false;
676}
677
678bool COFFAsmParser::parseSEHDirectiveEndFuncletOrFunc(StringRef, SMLoc Loc) {
679 Lex();
680 getStreamer().emitWinCFIFuncletOrFuncEnd(Loc);
681 return false;
682}
683
684bool COFFAsmParser::parseSEHDirectiveSplitChained(StringRef, SMLoc Loc) {
685 Lex();
686 getStreamer().emitWinCFISplitChained(Loc);
687 return false;
688}
689
690bool COFFAsmParser::parseSEHDirectiveHandler(StringRef, SMLoc Loc) {
691 MCSymbol *handler;
692 if (getParser().parseSymbol(handler))
693 return true;
694
695 if (getLexer().isNot(AsmToken::Comma))
696 return TokError("you must specify one or both of @unwind or @except");
697 Lex();
698 bool unwind = false, except = false;
699 if (parseAtUnwindOrAtExcept(unwind, except))
700 return true;
701 if (getLexer().is(AsmToken::Comma)) {
702 Lex();
703 if (parseAtUnwindOrAtExcept(unwind, except))
704 return true;
705 }
706 if (getLexer().isNot(AsmToken::EndOfStatement))
707 return TokError("unexpected token in directive");
708
709 Lex();
710 getStreamer().emitWinEHHandler(handler, unwind, except, Loc);
711 return false;
712}
713
714bool COFFAsmParser::parseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
715 Lex();
716 getStreamer().emitWinEHHandlerData();
717 return false;
718}
719
720bool COFFAsmParser::parseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
721 int64_t Size;
722 if (getParser().parseAbsoluteExpression(Size))
723 return true;
724
725 if (getLexer().isNot(AsmToken::EndOfStatement))
726 return TokError("unexpected token in directive");
727
728 Lex();
729 getStreamer().emitWinCFIAllocStack(Size, Loc);
730 return false;
731}
732
733bool COFFAsmParser::parseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
734 Lex();
735 getStreamer().emitWinCFIEndProlog(Loc);
736 return false;
737}
738
739bool COFFAsmParser::ParseSEHDirectiveBeginEpilog(StringRef, SMLoc Loc) {
740 Lex();
741 getStreamer().emitWinCFIBeginEpilogue(Loc);
742 return false;
743}
744
745bool COFFAsmParser::ParseSEHDirectiveEndEpilog(StringRef, SMLoc Loc) {
746 Lex();
747 getStreamer().emitWinCFIEndEpilogue(Loc);
748 return false;
749}
750
751bool COFFAsmParser::ParseSEHDirectiveUnwindV2Start(StringRef, SMLoc Loc) {
752 Lex();
753 getStreamer().emitWinCFIUnwindV2Start(Loc);
754 return false;
755}
756
757bool COFFAsmParser::ParseSEHDirectiveUnwindVersion(StringRef, SMLoc Loc) {
758 int64_t Version;
759 if (getParser().parseIntToken(Version, "expected unwind version number"))
760 return true;
761
762 if ((Version < 1) || (Version > UINT8_MAX))
763 return Error(Loc, "invalid unwind version");
764
765 if (getLexer().isNot(AsmToken::EndOfStatement))
766 return TokError("unexpected token in directive");
767
768 Lex();
769 getStreamer().emitWinCFIUnwindVersion(Version, Loc);
770 return false;
771}
772
773bool COFFAsmParser::parseAtUnwindOrAtExcept(bool &unwind, bool &except) {
774 StringRef identifier;
775 if (getLexer().isNot(AsmToken::At) && getLexer().isNot(AsmToken::Percent))
776 return TokError("a handler attribute must begin with '@' or '%'");
777 SMLoc startLoc = getLexer().getLoc();
778 Lex();
779 if (getParser().parseIdentifier(identifier))
780 return Error(startLoc, "expected @unwind or @except");
781 if (identifier == "unwind")
782 unwind = true;
783 else if (identifier == "except")
784 except = true;
785 else
786 return Error(startLoc, "expected @unwind or @except");
787 return false;
788}
789
790MCAsmParserExtension *llvm::createCOFFAsmParser() { return new COFFAsmParser; }
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
AMDGPU Prepare AGPR Alloc
Analysis containing CSE Info
Definition CSEInfo.cpp:27
static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, bool *UseLastGroup)
#define T
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
bool parseDirectiveCGProfile(StringRef, SMLoc)
parseDirectiveCGProfile ::= .cg_profile identifier, identifier, <number>
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
static bool isImplicitlyDiscardable(StringRef Name)
unsigned getCharacteristics() const
void setSelection(int Selection) const
static constexpr unsigned NonUniqueID
Definition MCSection.h:522
StringRef getName() const
Definition MCSection.h:587
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
const char SectionName[]
@ IMAGE_SCN_MEM_SHARED
Definition COFF.h:334
@ IMAGE_SCN_LNK_REMOVE
Definition COFF.h:308
@ IMAGE_SCN_CNT_CODE
Definition COFF.h:303
@ IMAGE_SCN_MEM_READ
Definition COFF.h:336
@ IMAGE_SCN_MEM_EXECUTE
Definition COFF.h:335
@ IMAGE_SCN_CNT_UNINITIALIZED_DATA
Definition COFF.h:305
@ IMAGE_SCN_MEM_DISCARDABLE
Definition COFF.h:331
@ IMAGE_SCN_LNK_INFO
Definition COFF.h:307
@ IMAGE_SCN_MEM_16BIT
Definition COFF.h:312
@ IMAGE_SCN_CNT_INITIALIZED_DATA
Definition COFF.h:304
@ IMAGE_SCN_LNK_COMDAT
Definition COFF.h:309
@ IMAGE_SCN_MEM_WRITE
Definition COFF.h:337
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition COFF.h:218
@ IMAGE_COMDAT_SELECT_NODUPLICATES
Definition COFF.h:455
@ IMAGE_COMDAT_SELECT_LARGEST
Definition COFF.h:460
@ IMAGE_COMDAT_SELECT_NEWEST
Definition COFF.h:461
@ IMAGE_COMDAT_SELECT_SAME_SIZE
Definition COFF.h:457
@ IMAGE_COMDAT_SELECT_ASSOCIATIVE
Definition COFF.h:459
@ IMAGE_COMDAT_SELECT_EXACT_MATCH
Definition COFF.h:458
@ IMAGE_COMDAT_SELECT_ANY
Definition COFF.h:456
LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)
Get symbol classification by parsing the name of a symbol.
Definition Symbol.cpp:75
NodeAddr< CodeNode * > Code
Definition RDFGraph.h:388
Context & getContext() const
Definition BasicBlock.h:99
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
@ Offset
Definition DWP.cpp:532
MCAsmParserExtension * createCOFFAsmParser()
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
@ MCSA_Weak
.weak
@ MCSA_WeakAntiDep
.weak_anti_dep (COFF)
@ MCSA_Invalid
Not a valid directive.