diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -798,14 +798,13 @@ // Tries to read the special directive for an output section definition which // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)", "(OVERLAY)", and // "(TYPE=)". +// Also supports nesting special directives as (FOO (BAR)), as ld.bfd does. +// Unknown directives are simply skipped over. // Tok1 and Tok2 are next 2 tokens peeked. See comment for // readSectionAddressType below. bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) { if (tok1 != "(") return false; - if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" && - tok2 != "OVERLAY" && tok2 != "TYPE") - return false; expect("("); if (consume("NOLOAD")) { @@ -826,10 +825,15 @@ cmd->type = readExpr()().getValue(); } cmd->typeIsSet = true; - } else { - skip(); // This is "COPY", "INFO" or "OVERLAY". + } else if (consume("COPY") || consume("INFO") || consume("OVERLAY")) { cmd->nonAlloc = true; + } else { + skip(); } + + if (peek() == "(" && !readSectionDirective(cmd, "(", peek2())) + return false; + expect(")"); return true; } diff --git a/lld/test/ELF/linkerscript/custom-section-type.s b/lld/test/ELF/linkerscript/custom-section-type.s --- a/lld/test/ELF/linkerscript/custom-section-type.s +++ b/lld/test/ELF/linkerscript/custom-section-type.s @@ -61,7 +61,7 @@ #--- a.lds SECTIONS { progbits (TYPE=SHT_PROGBITS) : { BYTE(1) } - note (TYPE = SHT_NOTE) : { BYTE(7) *(note) } + note (FOOBAR (TYPE = SHT_NOTE)) : { BYTE(7) *(note) } nobits ( TYPE=SHT_NOBITS) : { BYTE(8) } init_array (TYPE=SHT_INIT_ARRAY ) : { QUAD(myinit) } fini_array (TYPE=SHT_FINI_ARRAY) : { QUAD(15) }