summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp')
-rw-r--r--contrib/llvm/lib/MC/MCParser/COFFAsmParser.cpp56
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");
OpenPOWER on IntegriCloud