LLVM  4.0.0
COFFAsmParser.cpp
Go to the documentation of this file.
1 //===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCRegisterInfo.h"
20 #include "llvm/MC/MCSectionCOFF.h"
21 #include "llvm/MC/MCStreamer.h"
22 #include "llvm/Support/COFF.h"
23 using namespace llvm;
24 
25 namespace {
26 
27 class COFFAsmParser : public MCAsmParserExtension {
28  template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
29  void addDirectiveHandler(StringRef Directive) {
30  MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
31  this, HandleDirective<COFFAsmParser, HandlerMethod>);
32  getParser().addDirectiveHandler(Directive, Handler);
33  }
34 
35  bool ParseSectionSwitch(StringRef Section,
36  unsigned Characteristics,
38 
39  bool ParseSectionSwitch(StringRef Section, unsigned Characteristics,
40  SectionKind Kind, StringRef COMDATSymName,
42 
43  bool ParseSectionName(StringRef &SectionName);
44  bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString,
45  unsigned *Flags);
46 
47  void Initialize(MCAsmParser &Parser) override {
48  // Call the base implementation.
50 
51  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text");
52  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data");
53  addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss");
54  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section");
55  addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def");
56  addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl");
57  addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type");
58  addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef");
59  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32");
60  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx");
61  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSafeSEH>(".safeseh");
62  addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce");
63 
64  // Win64 EH directives.
65  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>(
66  ".seh_proc");
67  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>(
68  ".seh_endproc");
69  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>(
70  ".seh_startchained");
71  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>(
72  ".seh_endchained");
73  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>(
74  ".seh_handler");
75  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
76  ".seh_handlerdata");
77  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
78  ".seh_pushreg");
79  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
80  ".seh_setframe");
81  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
82  ".seh_stackalloc");
83  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
84  ".seh_savereg");
85  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
86  ".seh_savexmm");
87  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
88  ".seh_pushframe");
89  addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
90  ".seh_endprologue");
91  addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
92  }
93 
94  bool ParseSectionDirectiveText(StringRef, SMLoc) {
95  return ParseSectionSwitch(".text",
100  }
101  bool ParseSectionDirectiveData(StringRef, SMLoc) {
102  return ParseSectionSwitch(".data", COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
106  }
107  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
108  return ParseSectionSwitch(".bss",
113  }
114 
115  bool ParseDirectiveSection(StringRef, SMLoc);
116  bool ParseDirectiveDef(StringRef, SMLoc);
117  bool ParseDirectiveScl(StringRef, SMLoc);
118  bool ParseDirectiveType(StringRef, SMLoc);
119  bool ParseDirectiveEndef(StringRef, SMLoc);
120  bool ParseDirectiveSecRel32(StringRef, SMLoc);
121  bool ParseDirectiveSecIdx(StringRef, SMLoc);
122  bool ParseDirectiveSafeSEH(StringRef, SMLoc);
123  bool parseCOMDATType(COFF::COMDATType &Type);
124  bool ParseDirectiveLinkOnce(StringRef, SMLoc);
125 
126  // Win64 EH directives.
127  bool ParseSEHDirectiveStartProc(StringRef, SMLoc);
128  bool ParseSEHDirectiveEndProc(StringRef, SMLoc);
129  bool ParseSEHDirectiveStartChained(StringRef, SMLoc);
130  bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
131  bool ParseSEHDirectiveHandler(StringRef, SMLoc);
132  bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
133  bool ParseSEHDirectivePushReg(StringRef, SMLoc);
134  bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
135  bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
136  bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
137  bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
138  bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
139  bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);
140 
141  bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
142  bool ParseSEHRegisterNumber(unsigned &RegNo);
143  bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc);
144 public:
145  COFFAsmParser() {}
146 };
147 
148 } // end annonomous namespace.
149 
151  if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
152  return SectionKind::getText();
153  if (Flags & COFF::IMAGE_SCN_MEM_READ &&
154  (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0)
155  return SectionKind::getReadOnly();
156  return SectionKind::getData();
157 }
158 
159 bool COFFAsmParser::ParseSectionFlags(StringRef SectionName,
160  StringRef FlagsString, unsigned *Flags) {
161  enum {
162  None = 0,
163  Alloc = 1 << 0,
164  Code = 1 << 1,
165  Load = 1 << 2,
166  InitData = 1 << 3,
167  Shared = 1 << 4,
168  NoLoad = 1 << 5,
169  NoRead = 1 << 6,
170  NoWrite = 1 << 7,
171  Discardable = 1 << 8,
172  };
173 
174  bool ReadOnlyRemoved = false;
175  unsigned SecFlags = None;
176 
177  for (char FlagChar : FlagsString) {
178  switch (FlagChar) {
179  case 'a':
180  // Ignored.
181  break;
182 
183  case 'b': // bss section
184  SecFlags |= Alloc;
185  if (SecFlags & InitData)
186  return TokError("conflicting section flags 'b' and 'd'.");
187  SecFlags &= ~Load;
188  break;
189 
190  case 'd': // data section
191  SecFlags |= InitData;
192  if (SecFlags & Alloc)
193  return TokError("conflicting section flags 'b' and 'd'.");
194  SecFlags &= ~NoWrite;
195  if ((SecFlags & NoLoad) == 0)
196  SecFlags |= Load;
197  break;
198 
199  case 'n': // section is not loaded
200  SecFlags |= NoLoad;
201  SecFlags &= ~Load;
202  break;
203 
204  case 'D': // discardable
205  SecFlags |= Discardable;
206  break;
207 
208  case 'r': // read-only
209  ReadOnlyRemoved = false;
210  SecFlags |= NoWrite;
211  if ((SecFlags & Code) == 0)
212  SecFlags |= InitData;
213  if ((SecFlags & NoLoad) == 0)
214  SecFlags |= Load;
215  break;
216 
217  case 's': // shared section
218  SecFlags |= Shared | InitData;
219  SecFlags &= ~NoWrite;
220  if ((SecFlags & NoLoad) == 0)
221  SecFlags |= Load;
222  break;
223 
224  case 'w': // writable
225  SecFlags &= ~NoWrite;
226  ReadOnlyRemoved = true;
227  break;
228 
229  case 'x': // executable section
230  SecFlags |= Code;
231  if ((SecFlags & NoLoad) == 0)
232  SecFlags |= Load;
233  if (!ReadOnlyRemoved)
234  SecFlags |= NoWrite;
235  break;
236 
237  case 'y': // not readable
238  SecFlags |= NoRead | NoWrite;
239  break;
240 
241  default:
242  return TokError("unknown flag");
243  }
244  }
245 
246  *Flags = 0;
247 
248  if (SecFlags == None)
249  SecFlags = InitData;
250 
251  if (SecFlags & Code)
253  if (SecFlags & InitData)
255  if ((SecFlags & Alloc) && (SecFlags & Load) == 0)
257  if (SecFlags & NoLoad)
258  *Flags |= COFF::IMAGE_SCN_LNK_REMOVE;
259  if ((SecFlags & Discardable) ||
262  if ((SecFlags & NoRead) == 0)
263  *Flags |= COFF::IMAGE_SCN_MEM_READ;
264  if ((SecFlags & NoWrite) == 0)
265  *Flags |= COFF::IMAGE_SCN_MEM_WRITE;
266  if (SecFlags & Shared)
267  *Flags |= COFF::IMAGE_SCN_MEM_SHARED;
268 
269  return false;
270 }
271 
272 /// ParseDirectiveSymbolAttribute
273 /// ::= { ".weak", ... } [ identifier ( , identifier )* ]
274 bool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
275  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
276  .Case(".weak", MCSA_Weak)
278  assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
279  if (getLexer().isNot(AsmToken::EndOfStatement)) {
280  for (;;) {
281  StringRef Name;
282 
283  if (getParser().parseIdentifier(Name))
284  return TokError("expected identifier in directive");
285 
286  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
287 
288  getStreamer().EmitSymbolAttribute(Sym, Attr);
289 
290  if (getLexer().is(AsmToken::EndOfStatement))
291  break;
292 
293  if (getLexer().isNot(AsmToken::Comma))
294  return TokError("unexpected token in directive");
295  Lex();
296  }
297  }
298 
299  Lex();
300  return false;
301 }
302 
303 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
304  unsigned Characteristics,
305  SectionKind Kind) {
306  return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0);
307 }
308 
309 bool COFFAsmParser::ParseSectionSwitch(StringRef Section,
310  unsigned Characteristics,
311  SectionKind Kind,
312  StringRef COMDATSymName,
314  if (getLexer().isNot(AsmToken::EndOfStatement))
315  return TokError("unexpected token in section switching directive");
316  Lex();
317 
318  getStreamer().SwitchSection(getContext().getCOFFSection(
319  Section, Characteristics, Kind, COMDATSymName, Type));
320 
321  return false;
322 }
323 
324 bool COFFAsmParser::ParseSectionName(StringRef &SectionName) {
325  if (!getLexer().is(AsmToken::Identifier))
326  return true;
327 
328  SectionName = getTok().getIdentifier();
329  Lex();
330  return false;
331 }
332 
333 // .section name [, "flags"] [, identifier [ identifier ], identifier]
334 //
335 // Supported flags:
336 // a: Ignored.
337 // b: BSS section (uninitialized data)
338 // d: data section (initialized data)
339 // n: "noload" section (removed by linker)
340 // D: Discardable section
341 // r: Readable section
342 // s: Shared section
343 // w: Writable section
344 // x: Executable section
345 // y: Not-readable section (clears 'r')
346 //
347 // Subsections are not supported.
348 bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
350 
351  if (ParseSectionName(SectionName))
352  return TokError("expected identifier in directive");
353 
354  unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
357 
358  if (getLexer().is(AsmToken::Comma)) {
359  Lex();
360 
361  if (getLexer().isNot(AsmToken::String))
362  return TokError("expected string in directive");
363 
364  StringRef FlagsStr = getTok().getStringContents();
365  Lex();
366 
367  if (ParseSectionFlags(SectionName, FlagsStr, &Flags))
368  return true;
369  }
370 
372  StringRef COMDATSymName;
373  if (getLexer().is(AsmToken::Comma)) {
375  Lex();
376 
378 
379  if (!getLexer().is(AsmToken::Identifier))
380  return TokError("expected comdat type such as 'discard' or 'largest' "
381  "after protection bits");
382 
383  if (parseCOMDATType(Type))
384  return true;
385 
386  if (getLexer().isNot(AsmToken::Comma))
387  return TokError("expected comma in directive");
388  Lex();
389 
390  if (getParser().parseIdentifier(COMDATSymName))
391  return TokError("expected identifier in directive");
392  }
393 
394  if (getLexer().isNot(AsmToken::EndOfStatement))
395  return TokError("unexpected token in directive");
396 
397  SectionKind Kind = computeSectionKind(Flags);
398  if (Kind.isText()) {
399  const Triple &T = getContext().getObjectFileInfo()->getTargetTriple();
400  if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb)
401  Flags |= COFF::IMAGE_SCN_MEM_16BIT;
402  }
403  ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type);
404  return false;
405 }
406 
407 bool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) {
408  StringRef SymbolName;
409 
410  if (getParser().parseIdentifier(SymbolName))
411  return TokError("expected identifier in directive");
412 
413  MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
414 
415  getStreamer().BeginCOFFSymbolDef(Sym);
416 
417  Lex();
418  return false;
419 }
420 
421 bool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) {
422  int64_t SymbolStorageClass;
423  if (getParser().parseAbsoluteExpression(SymbolStorageClass))
424  return true;
425 
426  if (getLexer().isNot(AsmToken::EndOfStatement))
427  return TokError("unexpected token in directive");
428 
429  Lex();
430  getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass);
431  return false;
432 }
433 
434 bool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
435  int64_t Type;
436  if (getParser().parseAbsoluteExpression(Type))
437  return true;
438 
439  if (getLexer().isNot(AsmToken::EndOfStatement))
440  return TokError("unexpected token in directive");
441 
442  Lex();
443  getStreamer().EmitCOFFSymbolType(Type);
444  return false;
445 }
446 
447 bool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) {
448  Lex();
449  getStreamer().EndCOFFSymbolDef();
450  return false;
451 }
452 
453 bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) {
454  StringRef SymbolID;
455  if (getParser().parseIdentifier(SymbolID))
456  return TokError("expected identifier in directive");
457 
458  int64_t Offset = 0;
459  SMLoc OffsetLoc;
460  if (getLexer().is(AsmToken::Plus)) {
461  OffsetLoc = getLexer().getLoc();
462  if (getParser().parseAbsoluteExpression(Offset))
463  return true;
464  }
465 
466  if (getLexer().isNot(AsmToken::EndOfStatement))
467  return TokError("unexpected token in directive");
468 
469  if (Offset < 0 || Offset > UINT32_MAX)
470  return Error(OffsetLoc,
471  "invalid '.secrel32' directive offset, can't be less "
472  "than zero or greater than UINT32_MAX");
473 
474  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
475 
476  Lex();
477  getStreamer().EmitCOFFSecRel32(Symbol, Offset);
478  return false;
479 }
480 
481 bool COFFAsmParser::ParseDirectiveSafeSEH(StringRef, SMLoc) {
482  StringRef SymbolID;
483  if (getParser().parseIdentifier(SymbolID))
484  return TokError("expected identifier in directive");
485 
486  if (getLexer().isNot(AsmToken::EndOfStatement))
487  return TokError("unexpected token in directive");
488 
489  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
490 
491  Lex();
492  getStreamer().EmitCOFFSafeSEH(Symbol);
493  return false;
494 }
495 
496 bool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) {
497  StringRef SymbolID;
498  if (getParser().parseIdentifier(SymbolID))
499  return TokError("expected identifier in directive");
500 
501  if (getLexer().isNot(AsmToken::EndOfStatement))
502  return TokError("unexpected token in directive");
503 
504  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
505 
506  Lex();
507  getStreamer().EmitCOFFSectionIndex(Symbol);
508  return false;
509 }
510 
511 /// ::= [ identifier ]
512 bool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) {
513  StringRef TypeId = getTok().getIdentifier();
514 
515  Type = StringSwitch<COFF::COMDATType>(TypeId)
516  .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES)
524 
525  if (Type == 0)
526  return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'"));
527 
528  Lex();
529 
530  return false;
531 }
532 
533 /// ParseDirectiveLinkOnce
534 /// ::= .linkonce [ identifier ]
535 bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
537  if (getLexer().is(AsmToken::Identifier))
538  if (parseCOMDATType(Type))
539  return true;
540 
541  const MCSectionCOFF *Current =
542  static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly());
543 
545  return Error(Loc, "cannot make section associative with .linkonce");
546 
548  return Error(Loc, Twine("section '") + Current->getSectionName() +
549  "' is already linkonce");
550 
551  Current->setSelection(Type);
552 
553  if (getLexer().isNot(AsmToken::EndOfStatement))
554  return TokError("unexpected token in directive");
555 
556  return false;
557 }
558 
559 bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
560  StringRef SymbolID;
561  if (getParser().parseIdentifier(SymbolID))
562  return true;
563 
564  if (getLexer().isNot(AsmToken::EndOfStatement))
565  return TokError("unexpected token in directive");
566 
567  MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
568 
569  Lex();
570  getStreamer().EmitWinCFIStartProc(Symbol);
571  return false;
572 }
573 
574 bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
575  Lex();
576  getStreamer().EmitWinCFIEndProc();
577  return false;
578 }
579 
580 bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
581  Lex();
582  getStreamer().EmitWinCFIStartChained();
583  return false;
584 }
585 
586 bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
587  Lex();
588  getStreamer().EmitWinCFIEndChained();
589  return false;
590 }
591 
592 bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
593  StringRef SymbolID;
594  if (getParser().parseIdentifier(SymbolID))
595  return true;
596 
597  if (getLexer().isNot(AsmToken::Comma))
598  return TokError("you must specify one or both of @unwind or @except");
599  Lex();
600  bool unwind = false, except = false;
601  if (ParseAtUnwindOrAtExcept(unwind, except))
602  return true;
603  if (getLexer().is(AsmToken::Comma)) {
604  Lex();
605  if (ParseAtUnwindOrAtExcept(unwind, except))
606  return true;
607  }
608  if (getLexer().isNot(AsmToken::EndOfStatement))
609  return TokError("unexpected token in directive");
610 
611  MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
612 
613  Lex();
614  getStreamer().EmitWinEHHandler(handler, unwind, except);
615  return false;
616 }
617 
618 bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
619  Lex();
620  getStreamer().EmitWinEHHandlerData();
621  return false;
622 }
623 
624 bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
625  unsigned Reg = 0;
626  if (ParseSEHRegisterNumber(Reg))
627  return true;
628 
629  if (getLexer().isNot(AsmToken::EndOfStatement))
630  return TokError("unexpected token in directive");
631 
632  Lex();
633  getStreamer().EmitWinCFIPushReg(Reg);
634  return false;
635 }
636 
637 bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
638  unsigned Reg = 0;
639  int64_t Off;
640  if (ParseSEHRegisterNumber(Reg))
641  return true;
642  if (getLexer().isNot(AsmToken::Comma))
643  return TokError("you must specify a stack pointer offset");
644 
645  Lex();
646  SMLoc startLoc = getLexer().getLoc();
647  if (getParser().parseAbsoluteExpression(Off))
648  return true;
649 
650  if (Off & 0x0F)
651  return Error(startLoc, "offset is not a multiple of 16");
652 
653  if (getLexer().isNot(AsmToken::EndOfStatement))
654  return TokError("unexpected token in directive");
655 
656  Lex();
657  getStreamer().EmitWinCFISetFrame(Reg, Off);
658  return false;
659 }
660 
661 bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
662  int64_t Size;
663  SMLoc startLoc = getLexer().getLoc();
664  if (getParser().parseAbsoluteExpression(Size))
665  return true;
666 
667  if (Size & 7)
668  return Error(startLoc, "size is not a multiple of 8");
669 
670  if (getLexer().isNot(AsmToken::EndOfStatement))
671  return TokError("unexpected token in directive");
672 
673  Lex();
674  getStreamer().EmitWinCFIAllocStack(Size);
675  return false;
676 }
677 
678 bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
679  unsigned Reg = 0;
680  int64_t Off;
681  if (ParseSEHRegisterNumber(Reg))
682  return true;
683  if (getLexer().isNot(AsmToken::Comma))
684  return TokError("you must specify an offset on the stack");
685 
686  Lex();
687  SMLoc startLoc = getLexer().getLoc();
688  if (getParser().parseAbsoluteExpression(Off))
689  return true;
690 
691  if (Off & 7)
692  return Error(startLoc, "size is not a multiple of 8");
693 
694  if (getLexer().isNot(AsmToken::EndOfStatement))
695  return TokError("unexpected token in directive");
696 
697  Lex();
698  // FIXME: Err on %xmm* registers
699  getStreamer().EmitWinCFISaveReg(Reg, Off);
700  return false;
701 }
702 
703 // FIXME: This method is inherently x86-specific. It should really be in the
704 // x86 backend.
705 bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
706  unsigned Reg = 0;
707  int64_t Off;
708  if (ParseSEHRegisterNumber(Reg))
709  return true;
710  if (getLexer().isNot(AsmToken::Comma))
711  return TokError("you must specify an offset on the stack");
712 
713  Lex();
714  SMLoc startLoc = getLexer().getLoc();
715  if (getParser().parseAbsoluteExpression(Off))
716  return true;
717 
718  if (getLexer().isNot(AsmToken::EndOfStatement))
719  return TokError("unexpected token in directive");
720 
721  if (Off & 0x0F)
722  return Error(startLoc, "offset is not a multiple of 16");
723 
724  Lex();
725  // FIXME: Err on non-%xmm* registers
726  getStreamer().EmitWinCFISaveXMM(Reg, Off);
727  return false;
728 }
729 
730 bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
731  bool Code = false;
732  StringRef CodeID;
733  if (getLexer().is(AsmToken::At)) {
734  SMLoc startLoc = getLexer().getLoc();
735  Lex();
736  if (!getParser().parseIdentifier(CodeID)) {
737  if (CodeID != "code")
738  return Error(startLoc, "expected @code");
739  Code = true;
740  }
741  }
742 
743  if (getLexer().isNot(AsmToken::EndOfStatement))
744  return TokError("unexpected token in directive");
745 
746  Lex();
747  getStreamer().EmitWinCFIPushFrame(Code);
748  return false;
749 }
750 
751 bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
752  Lex();
753  getStreamer().EmitWinCFIEndProlog();
754  return false;
755 }
756 
757 bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
758  StringRef identifier;
759  if (getLexer().isNot(AsmToken::At))
760  return TokError("a handler attribute must begin with '@'");
761  SMLoc startLoc = getLexer().getLoc();
762  Lex();
763  if (getParser().parseIdentifier(identifier))
764  return Error(startLoc, "expected @unwind or @except");
765  if (identifier == "unwind")
766  unwind = true;
767  else if (identifier == "except")
768  except = true;
769  else
770  return Error(startLoc, "expected @unwind or @except");
771  return false;
772 }
773 
774 bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
775  SMLoc startLoc = getLexer().getLoc();
776  if (getLexer().is(AsmToken::Percent)) {
777  const MCRegisterInfo *MRI = getContext().getRegisterInfo();
778  SMLoc endLoc;
779  unsigned LLVMRegNo;
780  if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
781  return true;
782 
783 #if 0
784  // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
785  // violation so this validation code is disabled.
786 
787  // Check that this is a non-volatile register.
788  const unsigned *NVRegs = TAI.getCalleeSavedRegs();
789  unsigned i;
790  for (i = 0; NVRegs[i] != 0; ++i)
791  if (NVRegs[i] == LLVMRegNo)
792  break;
793  if (NVRegs[i] == 0)
794  return Error(startLoc, "expected non-volatile register");
795 #endif
796 
797  int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
798  if (SEHRegNo < 0)
799  return Error(startLoc,"register can't be represented in SEH unwind info");
800  RegNo = SEHRegNo;
801  }
802  else {
803  int64_t n;
804  if (getParser().parseAbsoluteExpression(n))
805  return true;
806  if (n > 15)
807  return Error(startLoc, "register number is too high");
808  RegNo = n;
809  }
810 
811  return false;
812 }
813 
814 namespace llvm {
815 
817  return new COFFAsmParser;
818 }
819 
820 }
MachineLoop * L
const NoneType None
Definition: None.h:23
static SectionKind getData()
Definition: SectionKind.h:202
size_t i
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
Not a valid directive.
Definition: MCDirectives.h:20
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:66
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
void setSelection(int Selection) const
static SectionKind computeSectionKind(unsigned Flags)
This represents a section on Windows.
Definition: MCSectionCOFF.h:24
static SectionKind getBSS()
Definition: SectionKind.h:198
struct fuzzer::@269 Flags
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
Definition: StringSwitch.h:244
Reg
All possible values of the reg field in the ModR/M byte.
int getSEHRegNum(unsigned RegNum) const
Map a target register to an equivalent SEH register number.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const T &Value)
Definition: StringSwitch.h:74
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
Definition: Triple.h:270
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
unsigned const MachineRegisterInfo * MRI
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
bool isText() const
Definition: SectionKind.h:119
uint32_t Offset
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:23
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:70
MCAsmParserExtension * createCOFFAsmParser()
unsigned getCharacteristics() const
Definition: MCSectionCOFF.h:70
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
StringRef getSectionName() const
Definition: MCSectionCOFF.h:69
MCSymbolAttr
Definition: MCDirectives.h:19
SymbolStorageClass
Storage class tells where and what the symbol represents.
Definition: Support/COFF.h:171
COFFYAML::WeakExternalCharacteristics Characteristics
Definition: COFFYAML.cpp:270
const char SectionName[]
Definition: AMDGPUPTNote.h:24
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isImplicitlyDiscardable(StringRef Name)
Definition: MCSectionCOFF.h:87
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Represents a location in source code.
Definition: SMLoc.h:24
static SectionKind getReadOnly()
Definition: SectionKind.h:182
static SectionKind getText()
Definition: SectionKind.h:180