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