Index: ELF/LinkerScript.h =================================================================== --- ELF/LinkerScript.h +++ ELF/LinkerScript.h @@ -135,6 +135,7 @@ ConstraintKind Constraint = ConstraintKind::NoConstraint; std::string Location; std::string MemoryRegionName; + bool Noload = false; template void writeTo(uint8_t *Buf); template void maybeCompress(); Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -432,6 +432,9 @@ assert(Sec->SectionIndex == INT_MAX); Sec->SectionIndex = I; SecToCommand[Sec] = Cmd; + + if (Cmd->Noload) + Sec->Type = SHT_NOBITS; } } } Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -568,10 +568,20 @@ 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().startswith("(")) + 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(":"); Index: test/ELF/linkerscript/noload.s =================================================================== --- test/ELF/linkerscript/noload.s +++ 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