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" 19c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola#include "llvm/Support/ELF.h" 205146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarusing namespace llvm; 215146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 225146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarnamespace { 235146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 245146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarclass ELFAsmParser : public MCAsmParserExtension { 251edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar template<bool (ELFAsmParser::*Handler)(StringRef, SMLoc)> 261edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar void AddDirectiveHandler(StringRef Directive) { 271edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar getParser().AddDirectiveHandler(this, Directive, 281edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar HandleDirective<ELFAsmParser, Handler>); 291edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar } 301edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar 315146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar bool ParseSectionSwitch(StringRef Section, unsigned Type, 325146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar unsigned Flags, SectionKind Kind); 33a04663ecb25b42b6cc588d81675d37ff8b78bfe8Joerg Sonnenberger bool SeenIdent; 345146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 355146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarpublic: 3693c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger ELFAsmParser() : SeenIdent(false) { 3793c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger BracketExpressionsSupported = true; 3893c65e6e661eda75711363bdd5ca15909920e1f0Joerg Sonnenberger } 395146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 405146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar virtual void Initialize(MCAsmParser &Parser) { 415146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar // Call the base implementation. 425146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar this->MCAsmParserExtension::Initialize(Parser); 435146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 441edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data"); 451edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text"); 46f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss"); 47f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata"); 48f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata"); 49f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss"); 50cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach AddDirectiveHandler< 51cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel"); 52cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach AddDirectiveHandler< 53cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro"); 54cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach AddDirectiveHandler< 55cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); 56cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach AddDirectiveHandler< 57cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); 581edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); 59cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach AddDirectiveHandler< 60cc866d5d2df281de969004b6f37486f57f0a84f9Jim Grosbach &ELFAsmParser::ParseDirectivePushSection>(".pushsection"); 617768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); 621edf6ca2cbb4b01db44683d5e9479a240cfcf497Daniel Dunbar AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); 631674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); 64e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); 6561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola AddDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident"); 6688182132470527e27231f09b25a885893e528c66Rafael Espindola AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver"); 676a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer AddDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version"); 68484291c27319668ad99cb87def000254357736fbRafael Espindola AddDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref"); 69f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak"); 70f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local"); 71f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach AddDirectiveHandler< 72f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected"); 73f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach AddDirectiveHandler< 74f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal"); 75f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach AddDirectiveHandler< 76f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden"); 775146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 785146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 79d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is 80d80781b98b771d370730ab7c630018f23e202b57Rafael Espindola // the best way for us to get access to it? 815146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar bool ParseSectionDirectiveData(StringRef, SMLoc) { 82c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data", ELF::SHT_PROGBITS, 831c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE |ELF::SHF_ALLOC, 845146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar SectionKind::getDataRel()); 855146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 865146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar bool ParseSectionDirectiveText(StringRef, SMLoc) { 87c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".text", ELF::SHT_PROGBITS, 881c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_EXECINSTR | 891c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, SectionKind::getText()); 905146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar } 91f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveBSS(StringRef, SMLoc) { 92c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".bss", ELF::SHT_NOBITS, 931c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE | 941c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, SectionKind::getBSS()); 95f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 96f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveRoData(StringRef, SMLoc) { 97c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS, 981c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC, 99f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnly()); 100f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 101f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveTData(StringRef, SMLoc) { 102c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS, 1031c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1041c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_TLS | ELF::SHF_WRITE, 105f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getThreadData()); 106f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 107f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveTBSS(StringRef, SMLoc) { 108c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS, 1091c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1101c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_TLS | ELF::SHF_WRITE, 111f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getThreadBSS()); 112f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 113f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRel(StringRef, SMLoc) { 114c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS, 1151c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1161c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 117f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getDataRel()); 118f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 119f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) { 120c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS, 1211c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1221c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 123f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnlyWithRel()); 124f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 125f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) { 126c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS, 1271c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1281c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 129f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getReadOnlyWithRelLocal()); 130f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 131f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) { 132c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS, 1331c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_ALLOC | 1341c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_WRITE, 135f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming SectionKind::getDataRel()); 136f525c2a8af8c0c8def845635f93e4268bf95387aMatt Fleming } 1377768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola bool ParseDirectivePushSection(StringRef, SMLoc); 1387768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola bool ParseDirectivePopSection(StringRef, SMLoc); 13921444efae03be297faf5bdb8f16567765307fa9dEli Friedman bool ParseDirectiveSection(StringRef, SMLoc); 14021444efae03be297faf5bdb8f16567765307fa9dEli Friedman bool ParseDirectiveSize(StringRef, SMLoc); 1411674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer bool ParseDirectivePrevious(StringRef, SMLoc); 142e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer bool ParseDirectiveType(StringRef, SMLoc); 14361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola bool ParseDirectiveIdent(StringRef, SMLoc); 14488182132470527e27231f09b25a885893e528c66Rafael Espindola bool ParseDirectiveSymver(StringRef, SMLoc); 1456a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer bool ParseDirectiveVersion(StringRef, SMLoc); 146484291c27319668ad99cb87def000254357736fbRafael Espindola bool ParseDirectiveWeakref(StringRef, SMLoc); 147f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach bool ParseDirectiveSymbolAttribute(StringRef, SMLoc); 14834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 14934e3d0cfe525b3067856c8978174fec75223b16aRafael Espindolaprivate: 15034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola bool ParseSectionName(StringRef &SectionName); 1515146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar}; 1525146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 1535146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 1545146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 155f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ParseDirectiveSymbolAttribute 156f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] 157f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbachbool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { 158f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive) 159f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".weak", MCSA_Weak) 160f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".local", MCSA_Local) 161f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".hidden", MCSA_Hidden) 162f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".internal", MCSA_Internal) 163f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Case(".protected", MCSA_Protected) 164f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach .Default(MCSA_Invalid); 165f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); 166f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::EndOfStatement)) { 167f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach for (;;) { 168f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach StringRef Name; 169f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 170f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getParser().ParseIdentifier(Name)) 171f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("expected identifier in directive"); 172f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 173f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 174f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 175f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach getStreamer().EmitSymbolAttribute(Sym, Attr); 176f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 177f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().is(AsmToken::EndOfStatement)) 178f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach break; 179f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 180f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach if (getLexer().isNot(AsmToken::Comma)) 181f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return TokError("unexpected token in directive"); 182f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 183f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 184f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach } 185f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 186f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach Lex(); 187f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach return false; 188f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach} 189f2a35fbd60fbb86465ad2fb4d801cd5c240decd7Jim Grosbach 1905146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarbool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type, 1915146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar unsigned Flags, SectionKind Kind) { 1925146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar if (getLexer().isNot(AsmToken::EndOfStatement)) 1935146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar return TokError("unexpected token in section switching directive"); 1945146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar Lex(); 1955146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 1965146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar getStreamer().SwitchSection(getContext().getELFSection( 1975146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar Section, Type, Flags, Kind)); 1985146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 1995146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar return false; 2005146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 2015146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 20221444efae03be297faf5bdb8f16567765307fa9dEli Friedmanbool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) { 203f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman StringRef Name; 204f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getParser().ParseIdentifier(Name)) 205f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("expected identifier in directive"); 2062de0572caec55e3779857cae0bbcd962af2e495dDmitri Gribenko MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 207f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 208f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getLexer().isNot(AsmToken::Comma)) 209f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("unexpected token in directive"); 210f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman Lex(); 211f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 212f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman const MCExpr *Expr; 213f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getParser().ParseExpression(Expr)) 214f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return true; 215f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 216f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman if (getLexer().isNot(AsmToken::EndOfStatement)) 217f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return TokError("unexpected token in directive"); 218f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 219f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman getStreamer().EmitELFSize(Sym, Expr); 220f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman return false; 221f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman} 222f82ccf5a0db4df07354f80b8feca454ed90776d5Eli Friedman 22334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindolabool ELFAsmParser::ParseSectionName(StringRef &SectionName) { 22434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola // A section name can contain -, so we cannot just use 22534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola // ParseIdentifier. 22634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SMLoc FirstLoc = getLexer().getLoc(); 22734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola unsigned Size = 0; 22834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 229184640e96e391ecfc4621156907b29f132c14959Rafael Espindola if (getLexer().is(AsmToken::String)) { 230184640e96e391ecfc4621156907b29f132c14959Rafael Espindola SectionName = getTok().getIdentifier(); 231184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 232184640e96e391ecfc4621156907b29f132c14959Rafael Espindola return false; 233184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } 234184640e96e391ecfc4621156907b29f132c14959Rafael Espindola 23534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola for (;;) { 23634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola StringRef Tmp; 23734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola unsigned CurSize; 23834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 23934e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SMLoc PrevLoc = getLexer().getLoc(); 24034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (getLexer().is(AsmToken::Minus)) { 24134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola CurSize = 1; 24234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola Lex(); // Consume the "-". 243184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else if (getLexer().is(AsmToken::String)) { 244184640e96e391ecfc4621156907b29f132c14959Rafael Espindola CurSize = getTok().getIdentifier().size() + 2; 245184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 246184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else if (getLexer().is(AsmToken::Identifier)) { 247184640e96e391ecfc4621156907b29f132c14959Rafael Espindola CurSize = getTok().getIdentifier().size(); 248184640e96e391ecfc4621156907b29f132c14959Rafael Espindola Lex(); 249184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } else { 25034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola break; 251184640e96e391ecfc4621156907b29f132c14959Rafael Espindola } 25234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 25334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola Size += CurSize; 25434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola SectionName = StringRef(FirstLoc.getPointer(), Size); 25534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 25634e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola // Make sure the following token is adjacent. 25734e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer()) 25834e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola break; 25934e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola } 26034e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (Size == 0) 26134e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola return true; 26234e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 26334e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola return false; 26434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola} 26534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 26625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindolastatic SectionKind computeSectionKind(unsigned Flags) { 2671c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_EXECINSTR) 26825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getText(); 2691c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Flags & ELF::SHF_TLS) 27025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getThreadData(); 27125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return SectionKind::getDataRel(); 27225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola} 27325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 2746b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindolastatic int parseSectionFlags(StringRef flagsStr) { 2756b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola int flags = 0; 2766b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 2776b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola for (unsigned i = 0; i < flagsStr.size(); i++) { 2786b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola switch (flagsStr[i]) { 2796b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'a': 2801c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_ALLOC; 2816b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2826b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'x': 2831c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_EXECINSTR; 2846b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2856b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'w': 2861c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_WRITE; 2876b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2886b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'M': 2891c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_MERGE; 2906b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2916b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'S': 2921c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_STRINGS; 2936b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2946b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'T': 2951c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_TLS; 2966b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 2976b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'c': 2981c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::XCORE_SHF_CP_SECTION; 2996b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3006b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'd': 3011c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::XCORE_SHF_DP_SECTION; 3026b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3036b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola case 'G': 3041c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola flags |= ELF::SHF_GROUP; 3056b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola break; 3066b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola default: 3076b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola return -1; 3086b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola } 3096b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola } 3106b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3116b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola return flags; 3126b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola} 3136b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3147768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolabool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { 3157768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PushSection(); 3167768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 3177768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola if (ParseDirectiveSection(s, loc)) { 3187768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PopSection(); 3197768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return true; 3207768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola } 3217768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 3227768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return false; 3237768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola} 3247768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 3257768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindolabool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { 3267768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola if (!getStreamer().PopSection()) 3277768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return TokError(".popsection without corresponding .pushsection"); 3287768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return false; 3297768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola} 3307768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola 33121444efae03be297faf5bdb8f16567765307fa9dEli Friedman// FIXME: This is a work in progress. 33221444efae03be297faf5bdb8f16567765307fa9dEli Friedmanbool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { 33321444efae03be297faf5bdb8f16567765307fa9dEli Friedman StringRef SectionName; 33434e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola 33534e3d0cfe525b3067856c8978174fec75223b16aRafael Espindola if (ParseSectionName(SectionName)) 33621444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("expected identifier in directive"); 33721444efae03be297faf5bdb8f16567765307fa9dEli Friedman 33821444efae03be297faf5bdb8f16567765307fa9dEli Friedman StringRef TypeName; 33921444efae03be297faf5bdb8f16567765307fa9dEli Friedman int64_t Size = 0; 3402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef GroupName; 3416b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola unsigned Flags = 0; 3426b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3436b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola // Set the defaults first. 3446b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola if (SectionName == ".fini" || SectionName == ".init" || 3456b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola SectionName == ".rodata") 3461c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola Flags |= ELF::SHF_ALLOC; 3476b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola if (SectionName == ".fini" || SectionName == ".init") 3481c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola Flags |= ELF::SHF_EXECINSTR; 3496b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 35021444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().is(AsmToken::Comma)) { 35121444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 35221444efae03be297faf5bdb8f16567765307fa9dEli Friedman 35321444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().isNot(AsmToken::String)) 35421444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("expected string in directive"); 35521444efae03be297faf5bdb8f16567765307fa9dEli Friedman 3566b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola StringRef FlagsStr = getTok().getStringContents(); 35721444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 35821444efae03be297faf5bdb8f16567765307fa9dEli Friedman 3596b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola int extraFlags = parseSectionFlags(FlagsStr); 3606b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola if (extraFlags < 0) 3616b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola return TokError("unknown flag"); 3626b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola Flags |= extraFlags; 3636b8e4357ecb77a97e08557896f06fd45550c9e46Rafael Espindola 3641c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola bool Mergeable = Flags & ELF::SHF_MERGE; 3651c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola bool Group = Flags & ELF::SHF_GROUP; 366f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 367f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) { 368f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Mergeable) 369f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("Mergeable section must specify the type"); 370f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Group) 371f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("Group section must specify the type"); 372f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola } else { 373f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola Lex(); 374d4a352609f0ebe8bdea2f70d4e0efae9b5db778eRafael Espindola if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) 375d4a352609f0ebe8bdea2f70d4e0efae9b5db778eRafael Espindola return TokError("expected '@' or '%' before type"); 376f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 37721444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 378f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getParser().ParseIdentifier(TypeName)) 379f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected identifier in directive"); 380f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola 381f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Mergeable) { 382f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 383f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected the entry size"); 38421444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 385f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getParser().ParseAbsoluteExpression(Size)) 386f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return true; 387f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Size <= 0) 388f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("entry size must be positive"); 389f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola } 39021444efae03be297faf5bdb8f16567765307fa9dEli Friedman 391f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (Group) { 392f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 393f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return TokError("expected group name"); 394f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola Lex(); 395f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getParser().ParseIdentifier(GroupName)) 396f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola return true; 39721444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().is(AsmToken::Comma)) { 39821444efae03be297faf5bdb8f16567765307fa9dEli Friedman Lex(); 399f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola StringRef Linkage; 400f4b0f3e616272556e8a94d86edd2e4e597183cd6Rafael Espindola if (getParser().ParseIdentifier(Linkage)) 40121444efae03be297faf5bdb8f16567765307fa9dEli Friedman return true; 4022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Linkage != "comdat") 4032ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola return TokError("Linkage must be 'comdat'"); 40421444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 40521444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 40621444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 40721444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 40821444efae03be297faf5bdb8f16567765307fa9dEli Friedman 40921444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (getLexer().isNot(AsmToken::EndOfStatement)) 41021444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("unexpected token in directive"); 41121444efae03be297faf5bdb8f16567765307fa9dEli Friedman 412c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola unsigned Type = ELF::SHT_PROGBITS; 41321444efae03be297faf5bdb8f16567765307fa9dEli Friedman 41421444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (!TypeName.empty()) { 41521444efae03be297faf5bdb8f16567765307fa9dEli Friedman if (TypeName == "init_array") 416c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_INIT_ARRAY; 41721444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "fini_array") 418c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_FINI_ARRAY; 41921444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "preinit_array") 420c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_PREINIT_ARRAY; 42121444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "nobits") 422c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_NOBITS; 42321444efae03be297faf5bdb8f16567765307fa9dEli Friedman else if (TypeName == "progbits") 424c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_PROGBITS; 42598976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola else if (TypeName == "note") 426c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola Type = ELF::SHT_NOTE; 4270cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola else if (TypeName == "unwind") 4280cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola Type = ELF::SHT_X86_64_UNWIND; 42921444efae03be297faf5bdb8f16567765307fa9dEli Friedman else 43021444efae03be297faf5bdb8f16567765307fa9dEli Friedman return TokError("unknown section type"); 43121444efae03be297faf5bdb8f16567765307fa9dEli Friedman } 43221444efae03be297faf5bdb8f16567765307fa9dEli Friedman 43325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola SectionKind Kind = computeSectionKind(Flags); 43421444efae03be297faf5bdb8f16567765307fa9dEli Friedman getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type, 4352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Flags, Kind, Size, 4362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupName)); 43721444efae03be297faf5bdb8f16567765307fa9dEli Friedman return false; 43821444efae03be297faf5bdb8f16567765307fa9dEli Friedman} 43921444efae03be297faf5bdb8f16567765307fa9dEli Friedman 4401674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramerbool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { 4411674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer const MCSection *PreviousSection = getStreamer().getPreviousSection(); 4427768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola if (PreviousSection == NULL) 4437768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola return TokError(".previous without corresponding .section"); 4447768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().SwitchSection(PreviousSection); 4451674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer 4461674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer return false; 4471674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer} 4481674b0b0e4972b844833f253286cbf99a6e99d6eBenjamin Kramer 449e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer/// ParseDirectiveELFType 450e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer/// ::= .type identifier , @attribute 451e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencerbool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) { 452e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer StringRef Name; 453e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (getParser().ParseIdentifier(Name)) 454e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("expected identifier in directive"); 455e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 456e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer // Handle the identifier as the key symbol. 457e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 458e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 459e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (getLexer().isNot(AsmToken::Comma)) 460e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("unexpected token in '.type' directive"); 461e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer Lex(); 462e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 463d4a352609f0ebe8bdea2f70d4e0efae9b5db778eRafael Espindola if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At)) 464d4a352609f0ebe8bdea2f70d4e0efae9b5db778eRafael Espindola return TokError("expected '@' or '%' before type"); 465e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer Lex(); 466e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 467e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer StringRef Type; 468e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer SMLoc TypeLoc; 469e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 470e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer TypeLoc = getLexer().getLoc(); 471e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (getParser().ParseIdentifier(Type)) 472e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("expected symbol type in directive"); 473e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 474e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type) 475e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Case("function", MCSA_ELF_TypeFunction) 476e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Case("object", MCSA_ELF_TypeObject) 477e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Case("tls_object", MCSA_ELF_TypeTLS) 478e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Case("common", MCSA_ELF_TypeCommon) 479e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Case("notype", MCSA_ELF_TypeNoType) 480e13a0ff8ac6c86a04397801061e1a702d4e0eab1Rafael Espindola .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject) 481a0c17a495b12debcb7f206993bbc6020e2e6e8dfRoman Divacky .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction) 482e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer .Default(MCSA_Invalid); 483e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 484e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (Attr == MCSA_Invalid) 485e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return Error(TypeLoc, "unsupported attribute in '.type' directive"); 486e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 487e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer if (getLexer().isNot(AsmToken::EndOfStatement)) 488e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return TokError("unexpected token in '.type' directive"); 489e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 490e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer Lex(); 491e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 492e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer getStreamer().EmitSymbolAttribute(Sym, Attr); 493e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 494e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer return false; 495e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer} 496e90ea139f47752eb122af756a5714ef0b3756298Michael J. Spencer 49761e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola/// ParseDirectiveIdent 49861e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola/// ::= .ident string 49961e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindolabool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { 50061e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola if (getLexer().isNot(AsmToken::String)) 50161e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola return TokError("unexpected token in '.ident' directive"); 50261e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 50361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola StringRef Data = getTok().getIdentifier(); 50461e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 50561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola Lex(); 50661e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 50761e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola const MCSection *Comment = 508c85dca66e68c9fa6ffa8471c64113b12d8d94fb1Rafael Espindola getContext().getELFSection(".comment", ELF::SHT_PROGBITS, 5091c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_MERGE | 5101c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola ELF::SHF_STRINGS, 51161e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola SectionKind::getReadOnly(), 5122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1, ""); 51361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 5147768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PushSection(); 51561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola getStreamer().SwitchSection(Comment); 516a04663ecb25b42b6cc588d81675d37ff8b78bfe8Joerg Sonnenberger if (!SeenIdent) { 51761e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola getStreamer().EmitIntValue(0, 1); 518a04663ecb25b42b6cc588d81675d37ff8b78bfe8Joerg Sonnenberger SeenIdent = true; 519a04663ecb25b42b6cc588d81675d37ff8b78bfe8Joerg Sonnenberger } 52061e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola getStreamer().EmitBytes(Data, 0); 52161e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola getStreamer().EmitIntValue(0, 1); 5227768a9dce14431018133cd586f5c8ce3e057f069Rafael Espindola getStreamer().PopSection(); 52361e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola return false; 52461e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola} 52561e3b91da711659c3cca5c4c6026a4b2aea322b4Rafael Espindola 52688182132470527e27231f09b25a885893e528c66Rafael Espindola/// ParseDirectiveSymver 52788182132470527e27231f09b25a885893e528c66Rafael Espindola/// ::= .symver foo, bar2@zed 52888182132470527e27231f09b25a885893e528c66Rafael Espindolabool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { 52988182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name; 53088182132470527e27231f09b25a885893e528c66Rafael Espindola if (getParser().ParseIdentifier(Name)) 53188182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected identifier in directive"); 53288182132470527e27231f09b25a885893e528c66Rafael Espindola 53388182132470527e27231f09b25a885893e528c66Rafael Espindola if (getLexer().isNot(AsmToken::Comma)) 53488182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected a comma"); 53588182132470527e27231f09b25a885893e528c66Rafael Espindola 53688182132470527e27231f09b25a885893e528c66Rafael Espindola Lex(); 53788182132470527e27231f09b25a885893e528c66Rafael Espindola 53888182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef AliasName; 53988182132470527e27231f09b25a885893e528c66Rafael Espindola if (getParser().ParseIdentifier(AliasName)) 54088182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected identifier in directive"); 54188182132470527e27231f09b25a885893e528c66Rafael Espindola 54288182132470527e27231f09b25a885893e528c66Rafael Espindola if (AliasName.find('@') == StringRef::npos) 54388182132470527e27231f09b25a885893e528c66Rafael Espindola return TokError("expected a '@' in the name"); 54488182132470527e27231f09b25a885893e528c66Rafael Espindola 54588182132470527e27231f09b25a885893e528c66Rafael Espindola MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 54688182132470527e27231f09b25a885893e528c66Rafael Espindola MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 54788182132470527e27231f09b25a885893e528c66Rafael Espindola const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext()); 54888182132470527e27231f09b25a885893e528c66Rafael Espindola 54988182132470527e27231f09b25a885893e528c66Rafael Espindola getStreamer().EmitAssignment(Alias, Value); 55088182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 55188182132470527e27231f09b25a885893e528c66Rafael Espindola} 55288182132470527e27231f09b25a885893e528c66Rafael Espindola 5536a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer/// ParseDirectiveVersion 5546a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer/// ::= .version string 5556a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramerbool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) { 5566a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer if (getLexer().isNot(AsmToken::String)) 5576a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer return TokError("unexpected token in '.version' directive"); 5586a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 5596a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer StringRef Data = getTok().getIdentifier(); 5606a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 5616a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer Lex(); 5626a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 5636a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer const MCSection *Note = 5646a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getContext().getELFSection(".note", ELF::SHT_NOTE, 0, 5656a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer SectionKind::getReadOnly()); 5666a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 5676a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().PushSection(); 5686a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().SwitchSection(Note); 5696a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(Data.size()+1, 4); // namesz. 5706a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description). 5716a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(1, 4); // type = NT_VERSION. 5726a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitBytes(Data, 0); // name. 5736a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitIntValue(0, 1); // terminate the string. 5746a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment. 5756a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer getStreamer().PopSection(); 5766a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer return false; 5776a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer} 5786a80f9da8c2cb2cbf931ec8cf2a72b5f288c1bc6Benjamin Kramer 579484291c27319668ad99cb87def000254357736fbRafael Espindola/// ParseDirectiveWeakref 580484291c27319668ad99cb87def000254357736fbRafael Espindola/// ::= .weakref foo, bar 581484291c27319668ad99cb87def000254357736fbRafael Espindolabool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) { 582484291c27319668ad99cb87def000254357736fbRafael Espindola // FIXME: Share code with the other alias building directives. 583484291c27319668ad99cb87def000254357736fbRafael Espindola 584484291c27319668ad99cb87def000254357736fbRafael Espindola StringRef AliasName; 585484291c27319668ad99cb87def000254357736fbRafael Espindola if (getParser().ParseIdentifier(AliasName)) 586484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected identifier in directive"); 587484291c27319668ad99cb87def000254357736fbRafael Espindola 588484291c27319668ad99cb87def000254357736fbRafael Espindola if (getLexer().isNot(AsmToken::Comma)) 589484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected a comma"); 590484291c27319668ad99cb87def000254357736fbRafael Espindola 591484291c27319668ad99cb87def000254357736fbRafael Espindola Lex(); 592484291c27319668ad99cb87def000254357736fbRafael Espindola 593484291c27319668ad99cb87def000254357736fbRafael Espindola StringRef Name; 594484291c27319668ad99cb87def000254357736fbRafael Espindola if (getParser().ParseIdentifier(Name)) 595484291c27319668ad99cb87def000254357736fbRafael Espindola return TokError("expected identifier in directive"); 596484291c27319668ad99cb87def000254357736fbRafael Espindola 597484291c27319668ad99cb87def000254357736fbRafael Espindola MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName); 598484291c27319668ad99cb87def000254357736fbRafael Espindola 599484291c27319668ad99cb87def000254357736fbRafael Espindola MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 600484291c27319668ad99cb87def000254357736fbRafael Espindola 601484291c27319668ad99cb87def000254357736fbRafael Espindola getStreamer().EmitWeakReference(Alias, Sym); 602484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 603484291c27319668ad99cb87def000254357736fbRafael Espindola} 604484291c27319668ad99cb87def000254357736fbRafael Espindola 6055146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbarnamespace llvm { 6065146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 6075146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel DunbarMCAsmParserExtension *createELFAsmParser() { 6085146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar return new ELFAsmParser; 6095146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 6105146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar 6115146a0970df05711ec85cd1d54c79feb0df4fcfcDaniel Dunbar} 612