diff options
| -rw-r--r-- | lld/ELF/LinkerScript.cpp | 2 | ||||
| -rw-r--r-- | lld/ELF/LinkerScript.h | 1 | ||||
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 18 | ||||
| -rw-r--r-- | lld/test/ELF/linkerscript/noload.s | 46 |
4 files changed, 63 insertions, 4 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index afa5417dbea..b31ae68089a 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -431,6 +431,8 @@ void LinkerScript::processCommands(OutputSectionFactory &Factory) { if (OutputSection *Sec = Cmd->Sec) { assert(Sec->SectionIndex == INT_MAX); Sec->SectionIndex = I; + if (Cmd->Noload) + Sec->Type = SHT_NOBITS; SecToCommand[Sec] = Cmd; } } diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index ae71f74c228..1d4c736763f 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -134,6 +134,7 @@ struct OutputSectionCommand : BaseCommand { ConstraintKind Constraint = ConstraintKind::NoConstraint; std::string Location; std::string MemoryRegionName; + bool Noload = false; template <class ELFT> void finalize(); template <class ELFT> void writeTo(uint8_t *Buf); diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index fc6b8e337f4..61e682cdc9b 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -568,10 +568,20 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) { OutputSectionCommand *Cmd = Script->createOutputSectionCommand(OutSec, getCurrentLocation()); - // Read an address expression. - // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html - if (peek() != ":") - Cmd->AddrExpr = readExpr(); + 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"); + expect(")"); + Cmd->Noload = true; + } + } expect(":"); diff --git a/lld/test/ELF/linkerscript/noload.s b/lld/test/ELF/linkerscript/noload.s new file mode 100644 index 00000000000..8b235d01512 --- /dev/null +++ b/lld/test/ELF/linkerscript/noload.s @@ -0,0 +1,46 @@ +# REQUIRES: x86 +# 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: ld.lld -o %t --script %t.script %t.o +# RUN: llvm-readobj --symbols -sections %t + +# CHECK: Section { +# CHECK-NEXT: Index: 2 +# CHECK-NEXT: Name: .data_noload_a +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x0 +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: 4096 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } +# CHECK-NEXT: Section { +# CHECK-NEXT: Index: 3 +# CHECK-NEXT: Name: .data_noload_b +# CHECK-NEXT: Type: SHT_NOBITS +# CHECK-NEXT: Flags [ +# CHECK-NEXT: SHF_ALLOC +# CHECK-NEXT: SHF_WRITE +# CHECK-NEXT: ] +# CHECK-NEXT: Address: 0x10000 +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: Size: 4096 +# CHECK-NEXT: Link: 0 +# CHECK-NEXT: Info: 0 +# CHECK-NEXT: AddressAlignment: 1 +# CHECK-NEXT: EntrySize: 0 +# CHECK-NEXT: } + +.section .data_noload_a,"aw",@progbits +.zero 4096 + +.section .data_noload_b,"aw",@progbits +.zero 4096 |

