15146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar//===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===// 25146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// 35146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// The LLVM Compiler Infrastructure 45146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// 55146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// This file is distributed under the University of Illinois Open Source 65146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// License. See LICENSE.TXT for details. 75146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar// 85146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar//===----------------------------------------------------------------------===// 95146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 105146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar#include "llvm/MC/MCParser/MCAsmParserExtension.h" 11e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer#include "llvm/ADT/StringSwitch.h" 12dc1ad22d5351fca6885ba4ecb18967f8ada7d42aEli Friedman#include "llvm/ADT/Twine.h" 1321444efae03be297faf5bdb8f16567765307fa9dEli Friedman#include "llvm/MC/MCAsmInfo.h" 145146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar#include "llvm/MC/MCContext.h" 1588182132470527e27231f09b25a885893e528c66Rafael Espindola#include "llvm/MC/MCExpr.h" 165146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar#include "llvm/MC/MCParser/MCAsmLexer.h" 1721444efae03be297faf5bdb8f16567765307fa9dEli Friedman#include "llvm/MC/MCSectionELF.h" 1821444efae03be297faf5bdb8f16567765307fa9dEli Friedman#include "llvm/MC/MCStreamer.h" 19bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer#include "llvm/MC/MCSymbol.h" 20c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h" 215146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarusing namespace llvm; 225146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 235146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarnamespace { 245146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 255146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarclass ELFAsmParser : public MCAsmParserExtension { 26171192f149dce679cd520f85ffced4789448b017Eli Bendersky template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)> 27cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach void addDirectiveHandler(StringRef Directive) { 28171192f149dce679cd520f85ffced4789448b017Eli Bendersky MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair( 29171192f149dce679cd520f85ffced4789448b017Eli Bendersky this, HandleDirective<ELFAsmParser, HandlerMethod>); 30171192f149dce679cd520f85ffced4789448b017Eli Bendersky 31cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach getParser().addDirectiveHandler(Directive, Handler); 321edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar } 331edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar 34c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags, 35c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola SectionKind Kind); 365146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 375146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarpublic: 38c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola ELFAsmParser() { BracketExpressionsSupported = true; } 395146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void Initialize(MCAsmParser &Parser) override { 415146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar // Call the base implementation. 425146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar this->MCAsmParserExtension::Initialize(Parser); 435146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 44cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); 45cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); 46cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); 47cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); 48cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); 49cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); 50cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 51cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); 52cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 53cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); 54cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 55cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); 56cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 57cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); 58cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); 59cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 60cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); 61cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); 62cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); 63cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); 64cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); 65cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); 66cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); 67cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); 68cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); 69cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); 70cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); 71cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 72f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); 73cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 74f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); 75cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach addDirectiveHandler< 76f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); 77df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection"); 785146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 795146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 80d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is 81d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola // the best way for us to get access to it? 825146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar bool ParseSectionDirectiveData(StringRef, SMLoc) { 83c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data", ELF::SHT_PROGBITS, 841c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE |ELF::SHF_ALLOC, 855146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar SectionKind::getDataRel()); 865146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 875146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar bool ParseSectionDirectiveText(StringRef, SMLoc) { 88c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".text", ELF::SHT_PROGBITS, 891c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_EXECINSTR | 901c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, SectionKind::getText()); 915146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 92f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 93c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".bss", ELF::SHT_NOBITS, 941c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE | 951c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, SectionKind::getBSS()); 96f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 97f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveRoData(StringRef, SMLoc) { 98c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS, 991c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, 100f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnly()); 101f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 102f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveTData(StringRef, SMLoc) { 103c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS, 1041c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1051c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_TLS | ELF::SHF_WRITE, 106f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getThreadData()); 107f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 108f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveTBSS(StringRef, SMLoc) { 109c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS, 1101c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1111c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_TLS | ELF::SHF_WRITE, 112f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getThreadBSS()); 113f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 114f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRel(StringRef, SMLoc) { 115c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS, 1161c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1171c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 118f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getDataRel()); 119f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 120f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) { 121c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS, 1221c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1231c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 124f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnlyWithRel()); 125f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 126f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) { 127c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS, 1281c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1291c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 130f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnlyWithRelLocal()); 131f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 132f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) { 133c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS, 1341c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1351c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 136f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getDataRel()); 137f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 1387768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola bool ParseDirectivePushSection(StringRef, SMLoc); 1397768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola bool ParseDirectivePopSection(StringRef, SMLoc); 14021444efae03be297faf5bdb8f16567765307fa9dEli Friedman bool ParseDirectiveSection(StringRef, SMLoc); 14121444efae03be297faf5bdb8f16567765307fa9dEli Friedman bool ParseDirectiveSize(StringRef, SMLoc); 1421674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer bool ParseDirectivePrevious(StringRef, SMLoc); 143e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer bool ParseDirectiveType(StringRef, SMLoc); 14461e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola bool ParseDirectiveIdent(StringRef, SMLoc); 14588182132470527e27231f09b25a885893e528c66Rafael Espindola bool ParseDirectiveSymver(StringRef, SMLoc); 1466a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer bool ParseDirectiveVersion(StringRef, SMLoc); 147484291c27319668ad99cb87def000254357736fbRafael Espindola bool ParseDirectiveWeakref(StringRef, SMLoc); 148f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); 149df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne bool ParseDirectiveSubsection(StringRef, SMLoc); 15034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 15134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindolaprivate: 15234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola bool ParseSectionName(StringRef &SectionName); 153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines bool ParseSectionArguments(bool IsPush, SMLoc loc); 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned parseSunStyleSectionFlags(); 1555146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar}; 1565146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 1575146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 1585146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 159f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ParseDirectiveSymbolAttribute 160f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] 161f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbachbool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 162f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 163f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".weak", MCSA_Weak) 164f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".local", MCSA_Local) 165f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".hidden", MCSA_Hidden) 166f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".internal", MCSA_Internal) 167f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".protected", MCSA_Protected) 168f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Default(MCSA_Invalid); 169f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 170f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) { 171f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach for (;;) { 172f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach StringRef Name; 173f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 174cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 175f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("expected identifier in directive"); 176f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 177f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 178f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 179f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach getStreamer().EmitSymbolAttribute(Sym, Attr); 180f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 181f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().is(AsmToken::EndOfStatement)) 182f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach break; 183f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 184f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::Comma)) 185f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("unexpected token in directive"); 186f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 187f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 188f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 189f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 190f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 191f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return false; 192f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach} 193f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 1945146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarbool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, 1955146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar unsigned Flags, SectionKind Kind) { 196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *Subsection = nullptr; 197df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getLexer().isNot(AsmToken::EndOfStatement)) { 198df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getParser().parseExpression(Subsection)) 199df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return true; 200df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 2015146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 2025146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar getStreamer().SwitchSection(getContext().getELFSection( 203df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne Section, Type, Flags, Kind), 204df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne Subsection); 2055146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 2065146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar return false; 2075146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 2085146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 20921444efae03be297faf5bdb8f16567765307fa9dEli Friedmanbool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { 210f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman StringRef Name; 211cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 212f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("expected identifier in directive"); 2132de0572caec55e3779857cae0bbcd962af2e495dDmitri Gribenko MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 214f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 215f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getLexer().isNot(AsmToken::Comma)) 216f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("unexpected token in directive"); 217f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman Lex(); 218f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 219f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman const MCExpr *Expr; 220cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseExpression(Expr)) 221f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return true; 222f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 223f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getLexer().isNot(AsmToken::EndOfStatement)) 224f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("unexpected token in directive"); 225f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 226f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman getStreamer().EmitELFSize(Sym, Expr); 227f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return false; 228f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman} 229f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 23034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindolabool ELFAsmParser::ParseSectionName(StringRef &SectionName) { 23134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola // A section name can contain -, so we cannot just use 232cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach // parseIdentifier. 23334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SMLoc FirstLoc = getLexer().getLoc(); 23434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola unsigned Size = 0; 23534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 236184640e96e391ecfc4621156907b29f132c14959Rafael Espindola if (getLexer().is(AsmToken::String)) { 237184640e96e391ecfc4621156907b29f132c14959Rafael Espindola SectionName = getTok().getIdentifier(); 238184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 239184640e96e391ecfc4621156907b29f132c14959Rafael Espindola return false; 240184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } 241184640e96e391ecfc4621156907b29f132c14959Rafael Espindola 24234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola for (;;) { 24334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola unsigned CurSize; 24434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 24534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SMLoc PrevLoc = getLexer().getLoc(); 24634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (getLexer().is(AsmToken::Minus)) { 24734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola CurSize = 1; 24834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola Lex(); // Consume the "-". 249184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else if (getLexer().is(AsmToken::String)) { 250184640e96e391ecfc4621156907b29f132c14959Rafael Espindola CurSize = getTok().getIdentifier().size() + 2; 251184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 252184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else if (getLexer().is(AsmToken::Identifier)) { 253184640e96e391ecfc4621156907b29f132c14959Rafael Espindola CurSize = getTok().getIdentifier().size(); 254184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 255184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else { 25634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola break; 257184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } 25834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 25934e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola Size += CurSize; 26034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SectionName = StringRef(FirstLoc.getPointer(), Size); 26134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 26234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola // Make sure the following token is adjacent. 26334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) 26434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola break; 26534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola } 26634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (Size == 0) 26734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola return true; 26834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 26934e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola return false; 27034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola} 27134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic SectionKind computeSectionKind(unsigned Flags, unsigned ElemSize) { 2731c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_EXECINSTR) 27425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getText(); 2751c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_TLS) 27625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getThreadData(); 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Flags & ELF::SHF_MERGE) { 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Flags & ELF::SHF_STRINGS) { 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (ElemSize) { 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 1: 28336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeable1ByteCString(); 28436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 2: 28536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeable2ByteCString(); 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 4: 28736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeable4ByteCString(); 28836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 28936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 29036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (ElemSize) { 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 4: 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeableConst4(); 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 8: 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeableConst8(); 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case 16: 29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return SectionKind::getMergeableConst16(); 29936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getDataRel(); 30425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola} 30525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 306766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramerstatic unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { 307766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer unsigned flags = 0; 3086b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3096b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola for (unsigned i = 0; i < flagsStr.size(); i++) { 3106b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola switch (flagsStr[i]) { 3116b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'a': 3121c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_ALLOC; 3136b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 314766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer case 'e': 315766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer flags |= ELF::SHF_EXCLUDE; 316766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer break; 3176b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'x': 3181c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_EXECINSTR; 3196b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3206b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'w': 3211c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_WRITE; 3226b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3236b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'M': 3241c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_MERGE; 3256b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3266b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'S': 3271c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_STRINGS; 3286b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3296b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'T': 3301c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_TLS; 3316b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3326b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'c': 3331c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::XCORE_SHF_CP_SECTION; 3346b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3356b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'd': 3361c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::XCORE_SHF_DP_SECTION; 3376b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3386b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'G': 3391c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_GROUP; 3406b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 341bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer case '?': 342bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer *UseLastGroup = true; 343bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer break; 3446b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola default: 345766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer return -1U; 3466b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola } 3476b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola } 3486b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3496b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola return flags; 3506b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola} 3516b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned ELFAsmParser::parseSunStyleSectionFlags() { 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned flags = 0; 35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines while (getLexer().is(AsmToken::Hash)) { 35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lex(); // Eat the #. 35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!getLexer().is(AsmToken::Identifier)) 35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return -1U; 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 36036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef flagId = getTok().getIdentifier(); 36136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (flagId == "alloc") 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines flags |= ELF::SHF_ALLOC; 36336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (flagId == "execinstr") 36436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines flags |= ELF::SHF_EXECINSTR; 36536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (flagId == "write") 36636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines flags |= ELF::SHF_WRITE; 36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else if (flagId == "tls") 36836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines flags |= ELF::SHF_TLS; 36936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 37036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return -1U; 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lex(); // Eat the flag. 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!getLexer().is(AsmToken::Comma)) 37536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 37636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lex(); // Eat the comma. 37736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 37836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return flags; 37936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 3827768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolabool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { 3837768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PushSection(); 3847768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (ParseSectionArguments(/*IsPush=*/true, loc)) { 3867768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PopSection(); 3877768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return true; 3887768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola } 3897768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 3907768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return false; 3917768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola} 3927768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 3937768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolabool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { 3947768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola if (!getStreamer().PopSection()) 3957768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return TokError(".popsection without corresponding .pushsection"); 3967768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return false; 3977768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola} 3987768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 39921444efae03be297faf5bdb8f16567765307fa9dEli Friedman// FIXME: This is a work in progress. 400cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { 401cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return ParseSectionArguments(/*IsPush=*/false, loc); 402df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne} 403df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 404cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { 40521444efae03be297faf5bdb8f16567765307fa9dEli Friedman StringRef SectionName; 40634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 40734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (ParseSectionName(SectionName)) 40821444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("expected identifier in directive"); 40921444efae03be297faf5bdb8f16567765307fa9dEli Friedman 41021444efae03be297faf5bdb8f16567765307fa9dEli Friedman StringRef TypeName; 41121444efae03be297faf5bdb8f16567765307fa9dEli Friedman int64_t Size = 0; 4122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef GroupName; 4136b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola unsigned Flags = 0; 414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *Subsection = nullptr; 415bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer bool UseLastGroup = false; 4166b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 4176b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola // Set the defaults first. 4186b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola if (SectionName == ".fini" || SectionName == ".init" || 4196b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola SectionName == ".rodata") 4201c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola Flags |= ELF::SHF_ALLOC; 4216b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola if (SectionName == ".fini" || SectionName == ".init") 4221c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola Flags |= ELF::SHF_EXECINSTR; 4236b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 42421444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().is(AsmToken::Comma)) { 42521444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 42621444efae03be297faf5bdb8f16567765307fa9dEli Friedman 427df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (IsPush && getLexer().isNot(AsmToken::String)) { 428df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getParser().parseExpression(Subsection)) 429df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return true; 430df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getLexer().isNot(AsmToken::Comma)) 431df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne goto EndStmt; 432df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne Lex(); 433df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 43421444efae03be297faf5bdb8f16567765307fa9dEli Friedman 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned extraFlags; 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (getLexer().isNot(AsmToken::String)) { 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax() 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines || getLexer().isNot(AsmToken::Hash)) 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TokError("expected string in directive"); 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines extraFlags = parseSunStyleSectionFlags(); 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines StringRef FlagsStr = getTok().getStringContents(); 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Lex(); 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup); 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44721444efae03be297faf5bdb8f16567765307fa9dEli Friedman 448766f25306af343fb2784350cb4d8cd9ca180f0d3Benjamin Kramer if (extraFlags == -1U) 4496b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola return TokError("unknown flag"); 4506b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola Flags |= extraFlags; 4516b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 4521c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola bool Mergeable = Flags & ELF::SHF_MERGE; 4531c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola bool Group = Flags & ELF::SHF_GROUP; 454bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer if (Group && UseLastGroup) 455bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer return TokError("Section cannot specifiy a group name while also acting " 456bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer "as a member of the last group"); 457f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 458f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) { 459f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Mergeable) 460f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("Mergeable section must specify the type"); 461f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Group) 462f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("Group section must specify the type"); 463f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola } else { 464f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola Lex(); 46560c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || 46660c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer getLexer().is(AsmToken::String)) { 46760c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer if (!getLexer().is(AsmToken::String)) 46860c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer Lex(); 46960c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer } else 47060c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer return TokError("expected '@<type>', '%<type>' or \"<type>\""); 471f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 472cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(TypeName)) 473f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected identifier in directive"); 474f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 475f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Mergeable) { 476f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 477f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected the entry size"); 47821444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 479cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseAbsoluteExpression(Size)) 480f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return true; 481f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Size <= 0) 482f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("entry size must be positive"); 483f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola } 48421444efae03be297faf5bdb8f16567765307fa9dEli Friedman 485f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Group) { 486f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 487f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected group name"); 488f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola Lex(); 489cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(GroupName)) 490f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return true; 49121444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().is(AsmToken::Comma)) { 49221444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 493f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola StringRef Linkage; 494cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Linkage)) 49521444efae03be297faf5bdb8f16567765307fa9dEli Friedman return true; 4962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Linkage != "comdat") 4972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola return TokError("Linkage must be 'comdat'"); 49821444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 49921444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 50021444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 50121444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 50221444efae03be297faf5bdb8f16567765307fa9dEli Friedman 503df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter CollingbourneEndStmt: 50421444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().isNot(AsmToken::EndOfStatement)) 50521444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("unexpected token in directive"); 50621444efae03be297faf5bdb8f16567765307fa9dEli Friedman 507c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola unsigned Type = ELF::SHT_PROGBITS; 50821444efae03be297faf5bdb8f16567765307fa9dEli Friedman 50942edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger if (TypeName.empty()) { 51042edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger if (SectionName.startswith(".note")) 51142edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger Type = ELF::SHT_NOTE; 51242edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger else if (SectionName == ".init_array") 51342edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger Type = ELF::SHT_INIT_ARRAY; 51442edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger else if (SectionName == ".fini_array") 51542edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger Type = ELF::SHT_FINI_ARRAY; 51642edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger else if (SectionName == ".preinit_array") 51742edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger Type = ELF::SHT_PREINIT_ARRAY; 51842edeb1ba8aabcbe0e5cc846d9e5f2a9e2261292Joerg Sonnenberger } else { 51921444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (TypeName == "init_array") 520c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_INIT_ARRAY; 52121444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "fini_array") 522c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_FINI_ARRAY; 52321444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "preinit_array") 524c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_PREINIT_ARRAY; 52521444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "nobits") 526c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_NOBITS; 52721444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "progbits") 528c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_PROGBITS; 52998976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola else if (TypeName == "note") 530c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_NOTE; 5310cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola else if (TypeName == "unwind") 5320cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola Type = ELF::SHT_X86_64_UNWIND; 53321444efae03be297faf5bdb8f16567765307fa9dEli Friedman else 53421444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("unknown section type"); 53521444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 53621444efae03be297faf5bdb8f16567765307fa9dEli Friedman 537bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer if (UseLastGroup) { 538bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer MCSectionSubPair CurrentSection = getStreamer().getCurrentSection(); 539bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer if (const MCSectionELF *Section = 540bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer cast_or_null<MCSectionELF>(CurrentSection.first)) 541bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer if (const MCSymbol *Group = Section->getGroup()) { 542bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer GroupName = Group->getName(); 543bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer Flags |= ELF::SHF_GROUP; 544bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer } 545bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer } 546bcd9b3b6b119420edffd259e5e05c5e0cf5fbc6cDavid Majnemer 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SectionKind Kind = computeSectionKind(Flags, Size); 548cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines const MCSection *ELFSection = getContext().getELFSection( 549cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SectionName, Type, Flags, Kind, Size, GroupName); 550cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().SwitchSection(ELFSection, Subsection); 551cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 552cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getContext().getGenDwarfForAssembly()) { 553cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto &Sections = getContext().getGenDwarfSectionSyms(); 554cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines auto InsertResult = Sections.insert( 555cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines std::make_pair(ELFSection, std::make_pair(nullptr, nullptr))); 556cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (InsertResult.second) { 557cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getContext().getDwarfVersion() <= 2) 558cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Error(loc, "DWARF2 only supports one section per compilation unit"); 559cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 560cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbol *SectionStartSymbol = getContext().CreateTempSymbol(); 561cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getStreamer().EmitLabel(SectionStartSymbol); 562cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines InsertResult.first->second.first = SectionStartSymbol; 563cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 564cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines } 565cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 56621444efae03be297faf5bdb8f16567765307fa9dEli Friedman return false; 56721444efae03be297faf5bdb8f16567765307fa9dEli Friedman} 56821444efae03be297faf5bdb8f16567765307fa9dEli Friedman 5691674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramerbool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 570df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne MCSectionSubPair PreviousSection = getStreamer().getPreviousSection(); 571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (PreviousSection.first == nullptr) 5727768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return TokError(".previous without corresponding .section"); 573df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second); 5741674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer 5751674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer return false; 5761674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer} 5771674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer 578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesstatic MCSymbolAttr MCAttrForString(StringRef Type) { 579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return StringSwitch<MCSymbolAttr>(Type) 580cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction) 581cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject) 582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS) 583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon) 584cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType) 585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Cases("STT_GNU_IFUNC", "gnu_indirect_function", 586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSA_ELF_TypeIndFunction) 587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines .Default(MCSA_Invalid); 589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines} 590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 591e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer/// ParseDirectiveELFType 59260c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE> 59360c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer/// ::= .type identifier , #attribute 594e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer/// ::= .type identifier , @attribute 59560c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer/// ::= .type identifier , %attribute 59660c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer/// ::= .type identifier , "attribute" 597e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencerbool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 598e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer StringRef Name; 599cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 600e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("expected identifier in directive"); 601e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 602e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer // Handle the identifier as the key symbol. 603e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 604e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 605cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // NOTE the comma is optional in all cases. It is only documented as being 606cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // optional in the first case, however, GAS will silently treat the comma as 607cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // optional in all cases. Furthermore, although the documentation states that 608cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS 609cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines // accepts both the upper case name as well as the lower case aliases. 610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().is(AsmToken::Comma)) 611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Lex(); 612e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::Identifier) && 614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getLexer().isNot(AsmToken::Hash) && getLexer().isNot(AsmToken::At) && 615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::String)) 61660c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 61760c81c939755601931bea8dbde174ff52cd904ddDavid Majnemer "'%<type>' or \"<type>\""); 618e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getLexer().isNot(AsmToken::String) && 620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines getLexer().isNot(AsmToken::Identifier)) 621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines Lex(); 622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 623cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines SMLoc TypeLoc = getLexer().getLoc(); 624cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 625cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines StringRef Type; 626cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines if (getParser().parseIdentifier(Type)) 627cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines return TokError("expected symbol type in directive"); 628cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines 629cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines MCSymbolAttr Attr = MCAttrForString(Type); 630e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (Attr == MCSA_Invalid) 631e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return Error(TypeLoc, "unsupported attribute in '.type' directive"); 632e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 633e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (getLexer().isNot(AsmToken::EndOfStatement)) 634e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("unexpected token in '.type' directive"); 635e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer Lex(); 636e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 637e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer getStreamer().EmitSymbolAttribute(Sym, Attr); 638e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 639e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return false; 640e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer} 641e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 64261e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola/// ParseDirectiveIdent 64361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola/// ::= .ident string 64461e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindolabool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 64561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola if (getLexer().isNot(AsmToken::String)) 64661e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola return TokError("unexpected token in '.ident' directive"); 64761e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 64861e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola StringRef Data = getTok().getIdentifier(); 64961e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 65061e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola Lex(); 65161e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 652c7ce3e4f42219003f30382be17d966cb2dfb4e71Rafael Espindola getStreamer().EmitIdent(Data); 65361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola return false; 65461e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola} 65561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 65688182132470527e27231f09b25a885893e528c66Rafael Espindola/// ParseDirectiveSymver 65788182132470527e27231f09b25a885893e528c66Rafael Espindola/// ::= .symver foo, bar2@zed 65888182132470527e27231f09b25a885893e528c66Rafael Espindolabool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 65988182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name; 660cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 66188182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected identifier in directive"); 66288182132470527e27231f09b25a885893e528c66Rafael Espindola 66388182132470527e27231f09b25a885893e528c66Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 66488182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected a comma"); 66588182132470527e27231f09b25a885893e528c66Rafael Espindola 66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // ARM assembly uses @ for a comment... 66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // except when parsing the second parameter of the .symver directive. 66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Force the next symbol to allow @ in the identifier, which is 66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // required for this directive and then reset it to its initial state. 67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier(); 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getLexer().setAllowAtInIdentifier(true); 67288182132470527e27231f09b25a885893e528c66Rafael Espindola Lex(); 67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines getLexer().setAllowAtInIdentifier(AllowAtInIdentifier); 67488182132470527e27231f09b25a885893e528c66Rafael Espindola 67588182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef AliasName; 676cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(AliasName)) 67788182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected identifier in directive"); 67888182132470527e27231f09b25a885893e528c66Rafael Espindola 67988182132470527e27231f09b25a885893e528c66Rafael Espindola if (AliasName.find('@') == StringRef::npos) 68088182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected a '@' in the name"); 68188182132470527e27231f09b25a885893e528c66Rafael Espindola 68288182132470527e27231f09b25a885893e528c66Rafael Espindola MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 68388182132470527e27231f09b25a885893e528c66Rafael Espindola MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 68488182132470527e27231f09b25a885893e528c66Rafael Espindola const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); 68588182132470527e27231f09b25a885893e528c66Rafael Espindola 68688182132470527e27231f09b25a885893e528c66Rafael Espindola getStreamer().EmitAssignment(Alias, Value); 68788182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 68888182132470527e27231f09b25a885893e528c66Rafael Espindola} 68988182132470527e27231f09b25a885893e528c66Rafael Espindola 6906a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer/// ParseDirectiveVersion 6916a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer/// ::= .version string 6926a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramerbool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { 6936a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer if (getLexer().isNot(AsmToken::String)) 6946a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer return TokError("unexpected token in '.version' directive"); 6956a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 6966a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer StringRef Data = getTok().getIdentifier(); 6976a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 6986a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer Lex(); 6996a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 7006a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer const MCSection *Note = 7016a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getContext().getELFSection(".note", ELF::SHT_NOTE, 0, 7026a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer SectionKind::getReadOnly()); 7036a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 7046a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().PushSection(); 7056a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().SwitchSection(Note); 7066a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(Data.size()+1, 4); // namesz. 7076a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description). 7086a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(1, 4); // type = NT_VERSION. 70968ca56285f9b6e82eb16ff8ea02a301f2c489faeEric Christopher getStreamer().EmitBytes(Data); // name. 7106a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(0, 1); // terminate the string. 7116a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment. 7126a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().PopSection(); 7136a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer return false; 7146a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer} 7156a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 716484291c27319668ad99cb87def000254357736fbRafael Espindola/// ParseDirectiveWeakref 717484291c27319668ad99cb87def000254357736fbRafael Espindola/// ::= .weakref foo, bar 718484291c27319668ad99cb87def000254357736fbRafael Espindolabool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { 719484291c27319668ad99cb87def000254357736fbRafael Espindola // FIXME: Share code with the other alias building directives. 720484291c27319668ad99cb87def000254357736fbRafael Espindola 721484291c27319668ad99cb87def000254357736fbRafael Espindola StringRef AliasName; 722cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(AliasName)) 723484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected identifier in directive"); 724484291c27319668ad99cb87def000254357736fbRafael Espindola 725484291c27319668ad99cb87def000254357736fbRafael Espindola if (getLexer().isNot(AsmToken::Comma)) 726484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected a comma"); 727484291c27319668ad99cb87def000254357736fbRafael Espindola 728484291c27319668ad99cb87def000254357736fbRafael Espindola Lex(); 729484291c27319668ad99cb87def000254357736fbRafael Espindola 730484291c27319668ad99cb87def000254357736fbRafael Espindola StringRef Name; 731cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach if (getParser().parseIdentifier(Name)) 732484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected identifier in directive"); 733484291c27319668ad99cb87def000254357736fbRafael Espindola 734484291c27319668ad99cb87def000254357736fbRafael Espindola MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 735484291c27319668ad99cb87def000254357736fbRafael Espindola 736484291c27319668ad99cb87def000254357736fbRafael Espindola MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 737484291c27319668ad99cb87def000254357736fbRafael Espindola 738484291c27319668ad99cb87def000254357736fbRafael Espindola getStreamer().EmitWeakReference(Alias, Sym); 739484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 740484291c27319668ad99cb87def000254357736fbRafael Espindola} 741484291c27319668ad99cb87def000254357736fbRafael Espindola 742df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbournebool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) { 743dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCExpr *Subsection = nullptr; 744df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getLexer().isNot(AsmToken::EndOfStatement)) { 745df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getParser().parseExpression(Subsection)) 746df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return true; 747df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne } 748df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 749df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne if (getLexer().isNot(AsmToken::EndOfStatement)) 750df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return TokError("unexpected token in directive"); 751df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 752df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne getStreamer().SubSection(Subsection); 753df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne return false; 754df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne} 755df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne 7565146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarnamespace llvm { 7575146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 7585146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel DunbarMCAsmParserExtension *createELFAsmParser() { 7595146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar return new ELFAsmParser; 7605146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 7615146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 7625146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 763