17d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer//===- COFFAsmParser.cpp - COFF Assembly Parser ---------------------------===// 27d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// 37d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// The LLVM Compiler Infrastructure 47d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// 57d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// This file is distributed under the University of Illinois Open Source 67d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// License. See LICENSE.TXT for details. 77d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer// 87d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer//===----------------------------------------------------------------------===// 97d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 107d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCParser/MCAsmParserExtension.h" 11f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach#include "llvm/ADT/StringSwitch.h" 127d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/ADT/Twine.h" 137d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCAsmInfo.h" 147d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCContext.h" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h" 16cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/MC/MCObjectFileInfo.h" 177d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCParser/MCAsmLexer.h" 180e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#include "llvm/MC/MCRegisterInfo.h" 197d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCSectionCOFF.h" 207d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/MC/MCStreamer.h" 2194b9550a32d189704a8eae55505edf62662c0534Evan Cheng#include "llvm/MC/MCTargetAsmParser.h" 227d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer#include "llvm/Support/COFF.h" 237d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerusing namespace llvm; 247d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 257d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencernamespace { 267d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 277d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerclass COFFAsmParser : public MCAsmParserExtension { 28171192f149dce679cd520f85ffced4789448b017Eli Bendersky template<bool (COFFAsmParser::*HandlerMethod)(StringRef, SMLoc)> 29cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach void addDirectiveHandler(StringRef Directive) { 30171192f149dce679cd520f85ffced4789448b017Eli Bendersky MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 31171192f149dce679cd520f85ffced4789448b017Eli Bendersky this, HandleDirective<COFFAsmParser, HandlerMethod>); 32cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach getParser().addDirectiveHandler(Directive, Handler); 337d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer } 347d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 357d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseSectionSwitch(StringRef Section, 367d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer unsigned Characteristics, 377d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer SectionKind Kind); 387d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 390ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling bool ParseSectionSwitch(StringRef Section, unsigned Characteristics, 400ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling SectionKind Kind, StringRef COMDATSymName, 41cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines COFF::COMDATType Type); 420ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 43a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck bool ParseSectionName(StringRef &SectionName); 44a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); 45a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Initialize(MCAsmParser &Parser) override { 477d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer // Call the base implementation. 487d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer MCAsmParserExtension::Initialize(Parser); 497d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 50cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveText>(".text"); 51cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveData>(".data"); 52cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSectionDirectiveBSS>(".bss"); 53a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck addDirectiveHandler<&COFFAsmParser::ParseDirectiveSection>(".section"); 54cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveDef>(".def"); 55cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveScl>(".scl"); 56cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveType>(".type"); 57cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveEndef>(".endef"); 58cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecRel32>(".secrel32"); 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines addDirectiveHandler<&COFFAsmParser::ParseDirectiveSecIdx>(".secidx"); 6080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck addDirectiveHandler<&COFFAsmParser::ParseDirectiveLinkOnce>(".linkonce"); 61fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 62fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis // Win64 EH directives. 63cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartProc>( 64fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_proc"); 65cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProc>( 66fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_endproc"); 67cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveStartChained>( 68fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_startchained"); 69cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndChained>( 70fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_endchained"); 71cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandler>( 72fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_handler"); 73cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>( 74fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_handlerdata"); 75cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>( 76fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_pushreg"); 77cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>( 78fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_setframe"); 79cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>( 80fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_stackalloc"); 81cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>( 82fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_savereg"); 83cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>( 84fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_savexmm"); 85cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>( 86fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_pushframe"); 87cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>( 88fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis ".seh_endprologue"); 89cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); 907d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer } 917d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 927d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseSectionDirectiveText(StringRef, SMLoc) { 937d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return ParseSectionSwitch(".text", 947d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer COFF::IMAGE_SCN_CNT_CODE 957d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_EXECUTE 967d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_READ, 977d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer SectionKind::getText()); 987d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer } 997d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseSectionDirectiveData(StringRef, SMLoc) { 1007d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return ParseSectionSwitch(".data", 1017d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer COFF::IMAGE_SCN_CNT_INITIALIZED_DATA 1027d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_READ 1037d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_WRITE, 1047d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer SectionKind::getDataRel()); 1057d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer } 1067d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 1077d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return ParseSectionSwitch(".bss", 1087d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA 1097d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_READ 1107d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer | COFF::IMAGE_SCN_MEM_WRITE, 1117d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer SectionKind::getBSS()); 1127d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer } 1137d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 114a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck bool ParseDirectiveSection(StringRef, SMLoc); 1157d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseDirectiveDef(StringRef, SMLoc); 1167d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseDirectiveScl(StringRef, SMLoc); 1177d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseDirectiveType(StringRef, SMLoc); 1187d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer bool ParseDirectiveEndef(StringRef, SMLoc); 1198f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola bool ParseDirectiveSecRel32(StringRef, SMLoc); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool ParseDirectiveSecIdx(StringRef, SMLoc); 121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool parseCOMDATType(COFF::COMDATType &Type); 12280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck bool ParseDirectiveLinkOnce(StringRef, SMLoc); 1237d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 124fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis // Win64 EH directives. 125fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveStartProc(StringRef, SMLoc); 126fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveEndProc(StringRef, SMLoc); 127fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveStartChained(StringRef, SMLoc); 128fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveEndChained(StringRef, SMLoc); 129fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveHandler(StringRef, SMLoc); 130fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveHandlerData(StringRef, SMLoc); 1313b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectivePushReg(StringRef, SMLoc); 1323b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectiveSetFrame(StringRef, SMLoc); 1333b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectiveAllocStack(StringRef, SMLoc); 1343b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectiveSaveReg(StringRef, SMLoc); 1353b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc); 1363b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHDirectivePushFrame(StringRef, SMLoc); 137fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseSEHDirectiveEndProlog(StringRef, SMLoc); 138fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 139fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except); 1403b32d0240c820a8aa829a950628586512a406ea0Charles Davis bool ParseSEHRegisterNumber(unsigned &RegNo); 141f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach bool ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc); 1427d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerpublic: 1437d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer COFFAsmParser() {} 1447d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer}; 1457d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 1467d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} // end annonomous namespace. 1477d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 148a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieckstatic SectionKind computeSectionKind(unsigned Flags) { 149a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE) 150a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return SectionKind::getText(); 151a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (Flags & COFF::IMAGE_SCN_MEM_READ && 152a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck (Flags & COFF::IMAGE_SCN_MEM_WRITE) == 0) 153a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return SectionKind::getReadOnly(); 154a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return SectionKind::getDataRel(); 155a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck} 156a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 157a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieckbool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { 158a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck enum { 159a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck None = 0, 160a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Alloc = 1 << 0, 161a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Code = 1 << 1, 162a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Load = 1 << 2, 163a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck InitData = 1 << 3, 164a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Shared = 1 << 4, 165a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck NoLoad = 1 << 5, 166a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck NoRead = 1 << 6, 167a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck NoWrite = 1 << 7 168a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck }; 169a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 170a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck bool ReadOnlyRemoved = false; 171a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck unsigned SecFlags = None; 172a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 173cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines for (char FlagChar : FlagsString) { 174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines switch (FlagChar) { 175a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'a': 176a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck // Ignored. 177a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 178a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 179a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'b': // bss section 180a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Alloc; 181a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & InitData) 182a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("conflicting section flags 'b' and 'd'."); 183a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags &= ~Load; 184a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 185a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 186a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'd': // data section 187a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= InitData; 188a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & Alloc) 189a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("conflicting section flags 'b' and 'd'."); 190a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags &= ~NoWrite; 191a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoLoad) == 0) 192a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Load; 193a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 194a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 195a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'n': // section is not loaded 196a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= NoLoad; 197a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags &= ~Load; 198a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 199a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 200a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'r': // read-only 201a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck ReadOnlyRemoved = false; 202a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= NoWrite; 203a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & Code) == 0) 204a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= InitData; 205a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoLoad) == 0) 206a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Load; 207a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 208a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 209a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 's': // shared section 210a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Shared | InitData; 211a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags &= ~NoWrite; 212a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoLoad) == 0) 213a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Load; 214a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 215a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 216a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'w': // writable 217a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags &= ~NoWrite; 218a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck ReadOnlyRemoved = true; 219a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 220a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 221a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'x': // executable section 222a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Code; 223a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoLoad) == 0) 224a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= Load; 225a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (!ReadOnlyRemoved) 226a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= NoWrite; 227a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 228a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 229a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck case 'y': // not readable 230a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags |= NoRead | NoWrite; 231a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck break; 232a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 233a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck default: 234a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("unknown flag"); 235a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck } 236a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck } 237a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 238a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags = 0; 239a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 240a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags == None) 241a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SecFlags = InitData; 242a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 243a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & Code) 244a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE; 245a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & InitData) 246a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_CNT_INITIALIZED_DATA; 247a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & Alloc) && (SecFlags & Load) == 0) 248a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; 249a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & NoLoad) 250a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_LNK_REMOVE; 251a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoRead) == 0) 252a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_MEM_READ; 253a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if ((SecFlags & NoWrite) == 0) 254a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_MEM_WRITE; 255a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (SecFlags & Shared) 256a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck *Flags |= COFF::IMAGE_SCN_MEM_SHARED; 257a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 258a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return false; 259a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck} 260a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 261f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ParseDirectiveSymbolAttribute 262f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ::= { ".weak", ... } [ identifier ( , identifier )* ] 263f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbachbool COFFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 264f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 265f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".weak", MCSA_Weak) 266f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Default(MCSA_Invalid); 267f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 268f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) { 269f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach for (;;) { 270f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach StringRef Name; 271f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 272cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 273f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("expected identifier in directive"); 274f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 275f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 276f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 277f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach getStreamer().EmitSymbolAttribute(Sym, Attr); 278f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 279f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().is(AsmToken::EndOfStatement)) 280f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach break; 281f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 282f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::Comma)) 283f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("unexpected token in directive"); 284f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 285f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 286f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 287f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 288f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 289f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return false; 290f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach} 291f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 2927d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerbool COFFAsmParser::ParseSectionSwitch(StringRef Section, 2937d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer unsigned Characteristics, 2947d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer SectionKind Kind) { 295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ParseSectionSwitch(Section, Characteristics, Kind, "", (COFF::COMDATType)0); 2960ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling} 2970ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 2980ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendlingbool COFFAsmParser::ParseSectionSwitch(StringRef Section, 2990ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling unsigned Characteristics, 3000ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling SectionKind Kind, 3010ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling StringRef COMDATSymName, 302cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines COFF::COMDATType Type) { 3037d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer if (getLexer().isNot(AsmToken::EndOfStatement)) 3047d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return TokError("unexpected token in section switching directive"); 3057d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer Lex(); 3067d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 3077d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer getStreamer().SwitchSection(getContext().getCOFFSection( 308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Section, Characteristics, Kind, COMDATSymName, Type)); 3097d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 3107d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return false; 3117d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 3127d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 313a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieckbool COFFAsmParser::ParseSectionName(StringRef &SectionName) { 314ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg if (!getLexer().is(AsmToken::Identifier)) 315ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg return true; 316ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg 317ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg SectionName = getTok().getIdentifier(); 318ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg Lex(); 319ab887bf52c99c2c9a4346b6dea2b8118e18a4282Hans Wennborg return false; 320a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck} 321a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 3220ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling// .section name [, "flags"] [, identifier [ identifier ], identifier] 323a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// 324a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// Supported flags: 325a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// a: Ignored. 326a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// b: BSS section (uninitialized data) 327a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// d: data section (initialized data) 328a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// n: Discardable section 329a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// r: Readable section 330a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// s: Shared section 331a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// w: Writable section 332a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// x: Executable section 333a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// y: Not-readable section (clears 'r') 334a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// 335a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck// Subsections are not supported. 336a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieckbool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { 337a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck StringRef SectionName; 338a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 339a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (ParseSectionName(SectionName)) 340a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("expected identifier in directive"); 341a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 342a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck unsigned Flags = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA | 343a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck COFF::IMAGE_SCN_MEM_READ | 344a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck COFF::IMAGE_SCN_MEM_WRITE; 345a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 346a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (getLexer().is(AsmToken::Comma)) { 347a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Lex(); 348a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 349a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (getLexer().isNot(AsmToken::String)) 350a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("expected string in directive"); 351a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 352a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck StringRef FlagsStr = getTok().getStringContents(); 353a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck Lex(); 354a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 355a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (ParseSectionFlags(FlagsStr, &Flags)) 356a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return true; 357a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck } 358a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 359cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines COFF::COMDATType Type = (COFF::COMDATType)0; 3600ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling StringRef COMDATSymName; 3610ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling if (getLexer().is(AsmToken::Comma)) { 362cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Type = COFF::IMAGE_COMDAT_SELECT_ANY;; 3630ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling Lex(); 3640ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 3650ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling Flags |= COFF::IMAGE_SCN_LNK_COMDAT; 3660ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 367cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (parseCOMDATType(Type)) 3680ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return true; 3690ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 3700ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling if (getLexer().isNot(AsmToken::Comma)) 3710ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return TokError("expected comma in directive"); 3720ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling Lex(); 3730ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 3740ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling if (getParser().parseIdentifier(COMDATSymName)) 3750ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return TokError("expected identifier in directive"); 3760ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling } 3770ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 378a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck if (getLexer().isNot(AsmToken::EndOfStatement)) 379a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return TokError("unexpected token in directive"); 380a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 381a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck SectionKind Kind = computeSectionKind(Flags); 382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Kind.isText()) { 383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const Triple &T = getContext().getObjectFileInfo()->getTargetTriple(); 384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (T.getArch() == Triple::arm || T.getArch() == Triple::thumb) 385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Flags |= COFF::IMAGE_SCN_MEM_16BIT; 386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 387cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines ParseSectionSwitch(SectionName, Flags, Kind, COMDATSymName, Type); 388a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck return false; 389a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck} 390a6d343a688073664b3a80aa117e0d3cbecf28014Nico Rieck 3917d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerbool COFFAsmParser::ParseDirectiveDef(StringRef, SMLoc) { 3927d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer StringRef SymbolName; 3937d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 394cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(SymbolName)) 3957d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return TokError("expected identifier in directive"); 3967d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 3977d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName); 3987d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 3997d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer getStreamer().BeginCOFFSymbolDef(Sym); 4007d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4017d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer Lex(); 4027d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return false; 4037d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 4047d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4057d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerbool COFFAsmParser::ParseDirectiveScl(StringRef, SMLoc) { 4067d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer int64_t SymbolStorageClass; 407cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(SymbolStorageClass)) 4087d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return true; 4097d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4107d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer if (getLexer().isNot(AsmToken::EndOfStatement)) 4117d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return TokError("unexpected token in directive"); 4127d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4137d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer Lex(); 4147d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer getStreamer().EmitCOFFSymbolStorageClass(SymbolStorageClass); 4157d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return false; 4167d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 4177d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4187d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerbool COFFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 4197d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer int64_t Type; 420cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Type)) 4217d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return true; 4227d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4237d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer if (getLexer().isNot(AsmToken::EndOfStatement)) 4247d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return TokError("unexpected token in directive"); 4257d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4267d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer Lex(); 4277d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer getStreamer().EmitCOFFSymbolType(Type); 4287d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return false; 4297d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 4307d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4317d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencerbool COFFAsmParser::ParseDirectiveEndef(StringRef, SMLoc) { 4327d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer Lex(); 4337d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer getStreamer().EndCOFFSymbolDef(); 4347d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return false; 4357d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 4367d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 4378f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindolabool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { 4388f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola StringRef SymbolID; 439cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(SymbolID)) 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TokError("expected identifier in directive"); 4418f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola 4428f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola if (getLexer().isNot(AsmToken::EndOfStatement)) 4438f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola return TokError("unexpected token in directive"); 4448f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola 4458f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); 4468f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola 4478f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola Lex(); 4488f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola getStreamer().EmitCOFFSecRel32(Symbol); 4498f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola return false; 4508f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola} 4518f7d12ccfd8feb258bdf4e582592bc00beacc7c6Rafael Espindola 45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool COFFAsmParser::ParseDirectiveSecIdx(StringRef, SMLoc) { 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef SymbolID; 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getParser().parseIdentifier(SymbolID)) 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TokError("expected identifier in directive"); 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::EndOfStatement)) 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TokError("unexpected token in directive"); 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); 46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lex(); 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getStreamer().EmitCOFFSectionIndex(Symbol); 46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= [ identifier ] 468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool COFFAsmParser::parseCOMDATType(COFF::COMDATType &Type) { 4690ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling StringRef TypeId = getTok().getIdentifier(); 47080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 4710ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling Type = StringSwitch<COFF::COMDATType>(TypeId) 4720ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("one_only", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES) 4730ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("discard", COFF::IMAGE_COMDAT_SELECT_ANY) 4740ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("same_size", COFF::IMAGE_COMDAT_SELECT_SAME_SIZE) 4750ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("same_contents", COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH) 4760ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("associative", COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 4770ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("largest", COFF::IMAGE_COMDAT_SELECT_LARGEST) 4780ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Case("newest", COFF::IMAGE_COMDAT_SELECT_NEWEST) 4790ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling .Default((COFF::COMDATType)0); 48080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 4810ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling if (Type == 0) 4820ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return TokError(Twine("unrecognized COMDAT type '" + TypeId + "'")); 48380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 4840ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling Lex(); 48580646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 4860ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return false; 4870ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling} 4880ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 4890ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling/// ParseDirectiveLinkOnce 490cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// ::= .linkonce [ identifier ] 4910ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendlingbool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { 4920ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling COFF::COMDATType Type = COFF::IMAGE_COMDAT_SELECT_ANY; 4930ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling if (getLexer().is(AsmToken::Identifier)) 494cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (parseCOMDATType(Type)) 4950ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling return true; 4960ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 4970ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>( 4980ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling getStreamer().getCurrentSection().first); 4990ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 500cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) 501cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return Error(Loc, "cannot make section associative with .linkonce"); 5020ae07098f7d2ad5a1868d448d0b1b4eef2a3b091Bill Wendling 50380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck if (Current->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) 50480646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck return Error(Loc, Twine("section '") + Current->getSectionName() + 50580646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck "' is already linkonce"); 50680646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 507cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Current->setSelection(Type); 50880646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 50980646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck if (getLexer().isNot(AsmToken::EndOfStatement)) 51080646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck return TokError("unexpected token in directive"); 51180646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 51280646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck return false; 51380646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck} 51480646283796b20c6a1b7d8eb69ce6f0478d54383Nico Rieck 515fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) { 516309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis StringRef SymbolID; 517cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(SymbolID)) 518fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return true; 519fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 520fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 521fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return TokError("unexpected token in directive"); 522fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 523309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis MCSymbol *Symbol = getContext().GetOrCreateSymbol(SymbolID); 524309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis 525fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 526cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIStartProc(Symbol); 527fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 528fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 529fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 530fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) { 531fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 532cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIEndProc(); 533fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 534fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 535fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 536fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) { 537fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 538cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIStartChained(); 539fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 540fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 541fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 542fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) { 543fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 544cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIEndChained(); 545fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 546fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 547fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 548fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) { 549309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis StringRef SymbolID; 550cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(SymbolID)) 551fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return true; 552fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 553309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis if (getLexer().isNot(AsmToken::Comma)) 554309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis return TokError("you must specify one or both of @unwind or @except"); 555309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis Lex(); 556fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis bool unwind = false, except = false; 557309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis if (ParseAtUnwindOrAtExcept(unwind, except)) 558309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis return true; 559fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis if (getLexer().is(AsmToken::Comma)) { 560fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 561309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis if (ParseAtUnwindOrAtExcept(unwind, except)) 562fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return true; 563fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis } 564fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 565fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return TokError("unexpected token in directive"); 566fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 567309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis MCSymbol *handler = getContext().GetOrCreateSymbol(SymbolID); 568309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis 569fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 570cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinEHHandler(handler, unwind, except); 571fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 572fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 573fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 574fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) { 575fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinEHHandlerData(); 577fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 578fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 579fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 580fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) { 5813b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned Reg; 5823b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (ParseSEHRegisterNumber(Reg)) 5833b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 5843b32d0240c820a8aa829a950628586512a406ea0Charles Davis 5853b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 5863b32d0240c820a8aa829a950628586512a406ea0Charles Davis return TokError("unexpected token in directive"); 5873b32d0240c820a8aa829a950628586512a406ea0Charles Davis 5883b32d0240c820a8aa829a950628586512a406ea0Charles Davis Lex(); 589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIPushReg(Reg); 5903b32d0240c820a8aa829a950628586512a406ea0Charles Davis return false; 591fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 592fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 593fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) { 5943b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned Reg; 5953b32d0240c820a8aa829a950628586512a406ea0Charles Davis int64_t Off; 5963b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (ParseSEHRegisterNumber(Reg)) 5973b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 598410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis if (getLexer().isNot(AsmToken::Comma)) 599410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis return TokError("you must specify a stack pointer offset"); 600410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis 601410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis Lex(); 6023b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc startLoc = getLexer().getLoc(); 603cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Off)) 6043b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 6053b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6063b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (Off & 0x0F) 6073b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc, "offset is not a multiple of 16"); 6083b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6093b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 6103b32d0240c820a8aa829a950628586512a406ea0Charles Davis return TokError("unexpected token in directive"); 6113b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6123b32d0240c820a8aa829a950628586512a406ea0Charles Davis Lex(); 613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFISetFrame(Reg, Off); 6143b32d0240c820a8aa829a950628586512a406ea0Charles Davis return false; 615fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 616fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 61716e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davisbool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) { 61816e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis int64_t Size; 6193b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc startLoc = getLexer().getLoc(); 620cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Size)) 62116e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis return true; 62216e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis 6233b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (Size & 7) 6243b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc, "size is not a multiple of 8"); 6253b32d0240c820a8aa829a950628586512a406ea0Charles Davis 62616e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 62716e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis return TokError("unexpected token in directive"); 62816e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis 62916e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis Lex(); 630cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIAllocStack(Size); 63116e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis return false; 632fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 633fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 634fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) { 6353b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned Reg; 6363b32d0240c820a8aa829a950628586512a406ea0Charles Davis int64_t Off; 6373b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (ParseSEHRegisterNumber(Reg)) 6383b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 639575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis if (getLexer().isNot(AsmToken::Comma)) 640410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis return TokError("you must specify an offset on the stack"); 641575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis 642575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis Lex(); 6433b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc startLoc = getLexer().getLoc(); 644cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Off)) 6453b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 6463b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6473b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (Off & 7) 6483b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc, "size is not a multiple of 8"); 6493b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6503b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 6513b32d0240c820a8aa829a950628586512a406ea0Charles Davis return TokError("unexpected token in directive"); 6523b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6533b32d0240c820a8aa829a950628586512a406ea0Charles Davis Lex(); 6543b32d0240c820a8aa829a950628586512a406ea0Charles Davis // FIXME: Err on %xmm* registers 655cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFISaveReg(Reg, Off); 6563b32d0240c820a8aa829a950628586512a406ea0Charles Davis return false; 657fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 658fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 6593b32d0240c820a8aa829a950628586512a406ea0Charles Davis// FIXME: This method is inherently x86-specific. It should really be in the 6603b32d0240c820a8aa829a950628586512a406ea0Charles Davis// x86 backend. 661fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) { 6623b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned Reg; 6633b32d0240c820a8aa829a950628586512a406ea0Charles Davis int64_t Off; 6643b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (ParseSEHRegisterNumber(Reg)) 6653b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 666575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis if (getLexer().isNot(AsmToken::Comma)) 667410ef2b263e92d3de1b2acff7437059400daed7dCharles Davis return TokError("you must specify an offset on the stack"); 668575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis 669575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis Lex(); 6703b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc startLoc = getLexer().getLoc(); 671cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Off)) 6723b32d0240c820a8aa829a950628586512a406ea0Charles Davis return true; 6733b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6743b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 6753b32d0240c820a8aa829a950628586512a406ea0Charles Davis return TokError("unexpected token in directive"); 6763b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6773b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (Off & 0x0F) 6783b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc, "offset is not a multiple of 16"); 6793b32d0240c820a8aa829a950628586512a406ea0Charles Davis 6803b32d0240c820a8aa829a950628586512a406ea0Charles Davis Lex(); 6813b32d0240c820a8aa829a950628586512a406ea0Charles Davis // FIXME: Err on non-%xmm* registers 682cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFISaveXMM(Reg, Off); 6833b32d0240c820a8aa829a950628586512a406ea0Charles Davis return false; 684fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 685fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 68616e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davisbool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) { 68747268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis bool Code = false; 68816e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis StringRef CodeID; 68947268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis if (getLexer().is(AsmToken::At)) { 69047268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis SMLoc startLoc = getLexer().getLoc(); 69147268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis Lex(); 692cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (!getParser().parseIdentifier(CodeID)) { 69347268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis if (CodeID != "code") 69447268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis return Error(startLoc, "expected @code"); 69547268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis Code = true; 69647268164f3d660f6357cc3a59d510efe3bc9152fCharles Davis } 69716e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis } 69816e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis 69916e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis if (getLexer().isNot(AsmToken::EndOfStatement)) 70016e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis return TokError("unexpected token in directive"); 70116e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis 70216e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis Lex(); 703cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIPushFrame(Code); 70416e1b3fcf6f389a6354b5e744730f25bfc0c04c2Charles Davis return false; 705fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 706fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 707fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) { 708fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis Lex(); 709cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitWinCFIEndProlog(); 710fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 711fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 712fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 713fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davisbool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) { 714fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis StringRef identifier; 715309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis if (getLexer().isNot(AsmToken::At)) 716309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis return TokError("a handler attribute must begin with '@'"); 717fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis SMLoc startLoc = getLexer().getLoc(); 718309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis Lex(); 719cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(identifier)) 720fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return Error(startLoc, "expected @unwind or @except"); 721309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis if (identifier == "unwind") 722fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis unwind = true; 723309213279e5d95826d97b2ab2178db5ddea0ed80Charles Davis else if (identifier == "except") 724fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis except = true; 725fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis else 726fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return Error(startLoc, "expected @unwind or @except"); 727fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis return false; 728fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis} 729fbc539ff37ddd08c2480be9185e7a40919ce8940Charles Davis 7303b32d0240c820a8aa829a950628586512a406ea0Charles Davisbool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) { 7313b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc startLoc = getLexer().getLoc(); 732575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis if (getLexer().is(AsmToken::Percent)) { 73399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling const MCRegisterInfo *MRI = getContext().getRegisterInfo(); 7343b32d0240c820a8aa829a950628586512a406ea0Charles Davis SMLoc endLoc; 7353b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned LLVMRegNo; 7363b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc)) 737575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis return true; 7383b32d0240c820a8aa829a950628586512a406ea0Charles Davis 7390e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#if 0 7400e6a052331f674dd70e28af41f654a7874405eabEvan Cheng // FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering 7410e6a052331f674dd70e28af41f654a7874405eabEvan Cheng // violation so this validation code is disabled. 7420e6a052331f674dd70e28af41f654a7874405eabEvan Cheng 7433b32d0240c820a8aa829a950628586512a406ea0Charles Davis // Check that this is a non-volatile register. 7441be0e271a07925b928ba89848934f1ea6f1854e2Evan Cheng const unsigned *NVRegs = TAI.getCalleeSavedRegs(); 7453b32d0240c820a8aa829a950628586512a406ea0Charles Davis unsigned i; 7463b32d0240c820a8aa829a950628586512a406ea0Charles Davis for (i = 0; NVRegs[i] != 0; ++i) 7473b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (NVRegs[i] == LLVMRegNo) 7483b32d0240c820a8aa829a950628586512a406ea0Charles Davis break; 7493b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (NVRegs[i] == 0) 7503b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc, "expected non-volatile register"); 7510e6a052331f674dd70e28af41f654a7874405eabEvan Cheng#endif 7523b32d0240c820a8aa829a950628586512a406ea0Charles Davis 75399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo); 7543b32d0240c820a8aa829a950628586512a406ea0Charles Davis if (SEHRegNo < 0) 7553b32d0240c820a8aa829a950628586512a406ea0Charles Davis return Error(startLoc,"register can't be represented in SEH unwind info"); 7563b32d0240c820a8aa829a950628586512a406ea0Charles Davis RegNo = SEHRegNo; 7573b32d0240c820a8aa829a950628586512a406ea0Charles Davis } 758575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis else { 759575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis int64_t n; 760cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(n)) 761575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis return true; 762575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis if (n > 15) 763575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis return Error(startLoc, "register number is too high"); 7643b32d0240c820a8aa829a950628586512a406ea0Charles Davis RegNo = n; 765575630ccb8a267405146a0c14fba7a5b74e1e4c3Charles Davis } 7663b32d0240c820a8aa829a950628586512a406ea0Charles Davis 7673b32d0240c820a8aa829a950628586512a406ea0Charles Davis return false; 7683b32d0240c820a8aa829a950628586512a406ea0Charles Davis} 7693b32d0240c820a8aa829a950628586512a406ea0Charles Davis 7707d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencernamespace llvm { 7717d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 7727d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. SpencerMCAsmParserExtension *createCOFFAsmParser() { 7737d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer return new COFFAsmParser; 7747d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 7757d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer 7767d4900416af3813aa9473e6ec2f0497ad5d208ddMichael J. Spencer} 777