Index: ELF/ScriptLexer.h =================================================================== --- ELF/ScriptLexer.h +++ ELF/ScriptLexer.h @@ -29,6 +29,7 @@ bool atEOF(); StringRef next(); StringRef peek(); + StringRef peek2(); void skip(); bool consume(StringRef Tok); void expect(StringRef Expect); Index: ELF/ScriptLexer.cpp =================================================================== --- ELF/ScriptLexer.cpp +++ ELF/ScriptLexer.cpp @@ -244,6 +244,13 @@ return Tok; } +StringRef ScriptLexer::peek2() { + if (Pos + 1 < Tokens.size()) + return Tokens[Pos + 1]; + setError("unexpected EOF"); + return ""; +} + bool ScriptLexer::consume(StringRef Tok) { if (peek() == Tok) { skip(); Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -711,27 +711,18 @@ // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html void ScriptParser::readSectionAddressType(OutputSection *Cmd) { - if (consume("(")) { - if (consume("NOLOAD")) { - expect(")"); - Cmd->Noload = true; - return; - } - if (consume("COPY") || consume("INFO") || consume("OVERLAY")) { - expect(")"); - Cmd->NonAlloc = true; - return; - } - Cmd->AddrExpr = readExpr(); - expect(")"); - } else { + if (peek() != "(" || (peek2() != "NOLOAD" && peek2() != "COPY" && + peek2() != "INFO" && peek2() != "OVERLAY")) Cmd->AddrExpr = readExpr(); - } if (consume("(")) { - expect("NOLOAD"); + if (consume("NOLOAD")) + Cmd->Noload = true; + else if (consume("COPY") || consume("INFO") || consume("OVERLAY")) + Cmd->NonAlloc = true; + else + setError("unknown section directive: " + next()); expect(")"); - Cmd->Noload = true; } } Index: test/ELF/linkerscript/info-section-type.s =================================================================== --- test/ELF/linkerscript/info-section-type.s +++ test/ELF/linkerscript/info-section-type.s @@ -29,5 +29,14 @@ # RUN: ld.lld -o %t --script %t.script %t.o # RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC +# RUN: echo "SECTIONS { .bar 0x20000 (INFO) : { *(.foo) } };" > %t.script +# RUN: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj -sections %t | FileCheck %s --check-prefix=NONALLOC + +# RUN: echo "SECTIONS { .bar 0x20000 (BAR) : { *(.foo) } };" > %t.script +# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 |\ +# RUN: FileCheck %s --check-prefix=UNKNOWN +# UNKNOWN: unknown section directive: BAR + .section .foo,"a",@progbits .zero 1