summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp2
-rw-r--r--lld/ELF/LinkerScript.h1
-rw-r--r--lld/ELF/ScriptParser.cpp18
-rw-r--r--lld/test/ELF/linkerscript/noload.s46
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
OpenPOWER on IntegriCloud