diff options
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/ScriptParser.cpp | 47 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/noload.s | 2 |
2 files changed, 33 insertions, 16 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 61e682cdc9b..4a44944fe7e 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -76,6 +76,7 @@ private: BytesDataCommand *readBytesDataCommand(StringRef Tok); uint32_t readFill(); uint32_t parseFill(StringRef Tok); + void readSectionAddressType(OutputSectionCommand *Cmd); OutputSectionCommand *readOutputSectionDescription(StringRef OutSec); std::vector<StringRef> readOutputSectionPhdrs(); InputSectionDescription *readInputSectionDescription(StringRef Tok); @@ -563,26 +564,42 @@ uint32_t ScriptParser::readFill() { return V; } -OutputSectionCommand * -ScriptParser::readOutputSectionDescription(StringRef OutSec) { - OutputSectionCommand *Cmd = - Script->createOutputSectionCommand(OutSec, getCurrentLocation()); - - if (peek() != ":") { - // Read an address expression. - // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html - if (peek() != "(") - Cmd->AddrExpr = readExpr(); - - // Read a section type. Currently, only NOLOAD is supported. - // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html - if (consume("(")) { - expect("NOLOAD"); +// Reads an expression and/or the special directive "(NOLOAD)" for an +// output section definition. +// +// An output section name can be followed by an address expression +// and/or by "(NOLOAD)". This grammar is not LL(1) because "(" can be +// interpreted as either the beginning of some expression or "(NOLOAD)". +// +// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html +// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html +void ScriptParser::readSectionAddressType(OutputSectionCommand *Cmd) { + if (consume("(")) { + if (consume("NOLOAD")) { expect(")"); Cmd->Noload = true; + return; } + Cmd->AddrExpr = readExpr(); + expect(")"); + } else { + Cmd->AddrExpr = readExpr(); } + if (consume("(")) { + expect("NOLOAD"); + expect(")"); + Cmd->Noload = true; + } +} + +OutputSectionCommand * +ScriptParser::readOutputSectionDescription(StringRef OutSec) { + OutputSectionCommand *Cmd = + Script->createOutputSectionCommand(OutSec, getCurrentLocation()); + + if (peek() != ":") + readSectionAddressType(Cmd); expect(":"); if (consume("AT")) diff --git a/lld/test/ELF/linkerscript/noload.s b/lld/test/ELF/linkerscript/noload.s index 8b235d01512..9d0e085a050 100644 --- a/lld/test/ELF/linkerscript/noload.s +++ b/lld/test/ELF/linkerscript/noload.s @@ -2,7 +2,7 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o # RUN: echo "SECTIONS { \ # RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \ -# RUN: .data_noload_b 0x10000 (NOLOAD) : { *(.data_noload_b) } };" > %t.script +# RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script # RUN: ld.lld -o %t --script %t.script %t.o # RUN: llvm-readobj --symbols -sections %t |