diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp | 56 |
1 files changed, 40 insertions, 16 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp index 653627a..f411479 100644 --- a/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp @@ -41,7 +41,8 @@ class COFFAsmParser : public MCAsmParserExtension { COFF::COMDATType Type); bool ParseSectionName(StringRef &SectionName); - bool ParseSectionFlags(StringRef FlagsString, unsigned* Flags); + bool ParseSectionFlags(StringRef SectionName, StringRef FlagsString, + unsigned *Flags); void Initialize(MCAsmParser &Parser) override { // Call the base implementation. @@ -155,17 +156,19 @@ static SectionKind computeSectionKind(unsigned Flags) { return SectionKind::getData(); } -bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { +bool COFFAsmParser::ParseSectionFlags(StringRef SectionName, + StringRef FlagsString, unsigned *Flags) { enum { - None = 0, - Alloc = 1 << 0, - Code = 1 << 1, - Load = 1 << 2, - InitData = 1 << 3, - Shared = 1 << 4, - NoLoad = 1 << 5, - NoRead = 1 << 6, - NoWrite = 1 << 7 + None = 0, + Alloc = 1 << 0, + Code = 1 << 1, + Load = 1 << 2, + InitData = 1 << 3, + Shared = 1 << 4, + NoLoad = 1 << 5, + NoRead = 1 << 6, + NoWrite = 1 << 7, + Discardable = 1 << 8, }; bool ReadOnlyRemoved = false; @@ -198,6 +201,10 @@ bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { SecFlags &= ~Load; break; + case 'D': // discardable + SecFlags |= Discardable; + break; + case 'r': // read-only ReadOnlyRemoved = false; SecFlags |= NoWrite; @@ -249,6 +256,9 @@ bool COFFAsmParser::ParseSectionFlags(StringRef FlagsString, unsigned* Flags) { *Flags |= COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; if (SecFlags & NoLoad) *Flags |= COFF::IMAGE_SCN_LNK_REMOVE; + if ((SecFlags & Discardable) || + MCSectionCOFF::isImplicitlyDiscardable(SectionName)) + *Flags |= COFF::IMAGE_SCN_MEM_DISCARDABLE; if ((SecFlags & NoRead) == 0) *Flags |= COFF::IMAGE_SCN_MEM_READ; if ((SecFlags & NoWrite) == 0) @@ -326,7 +336,8 @@ bool COFFAsmParser::ParseSectionName(StringRef &SectionName) { // a: Ignored. // b: BSS section (uninitialized data) // d: data section (initialized data) -// n: Discardable section +// n: "noload" section (removed by linker) +// D: Discardable section // r: Readable section // s: Shared section // w: Writable section @@ -353,7 +364,7 @@ bool COFFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { StringRef FlagsStr = getTok().getStringContents(); Lex(); - if (ParseSectionFlags(FlagsStr, &Flags)) + if (ParseSectionFlags(SectionName, FlagsStr, &Flags)) return true; } @@ -444,13 +455,26 @@ bool COFFAsmParser::ParseDirectiveSecRel32(StringRef, SMLoc) { if (getParser().parseIdentifier(SymbolID)) return TokError("expected identifier in directive"); + int64_t Offset = 0; + SMLoc OffsetLoc; + if (getLexer().is(AsmToken::Plus)) { + OffsetLoc = getLexer().getLoc(); + if (getParser().parseAbsoluteExpression(Offset)) + return true; + } + if (getLexer().isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in directive"); + if (Offset < 0 || Offset > UINT32_MAX) + return Error(OffsetLoc, + "invalid '.secrel32' directive offset, can't be less " + "than zero or greater than UINT32_MAX"); + MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID); Lex(); - getStreamer().EmitCOFFSecRel32(Symbol); + getStreamer().EmitCOFFSecRel32(Symbol, Offset); return false; } @@ -514,8 +538,8 @@ bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) { if (parseCOMDATType(Type)) return true; - const MCSectionCOFF *Current = static_cast<const MCSectionCOFF*>( - getStreamer().getCurrentSection().first); + const MCSectionCOFF *Current = + static_cast<const MCSectionCOFF *>(getStreamer().getCurrentSectionOnly()); if (Type == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) return Error(Loc, "cannot make section associative with .linkonce"); |