summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp24
-rw-r--r--lld/test/ELF/linkerscript/linkerscript-fill.s30
-rw-r--r--lld/test/ELF/linkerscript/sections-padding.s2
3 files changed, 47 insertions, 9 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 3d3b3d6e59f..a83de88489a 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -621,8 +621,9 @@ private:
void readVersionScriptCommand();
SymbolAssignment *readAssignment(StringRef Name);
+ std::vector<uint8_t> readFill();
OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
- std::vector<uint8_t> readOutputSectionFiller();
+ std::vector<uint8_t> readOutputSectionFiller(StringRef Tok);
std::vector<StringRef> readOutputSectionPhdrs();
InputSectionDescription *readInputSectionDescription(StringRef Tok);
Regex readFilePatterns();
@@ -980,6 +981,14 @@ Expr ScriptParser::readAssert() {
};
}
+std::vector<uint8_t> ScriptParser::readFill() {
+ expect("(");
+ std::vector<uint8_t> V = readOutputSectionFiller(next());
+ expect(")");
+ expect(";");
+ return V;
+}
+
OutputSectionCommand *
ScriptParser::readOutputSectionDescription(StringRef OutSec) {
OutputSectionCommand *Cmd = new OutputSectionCommand(OutSec);
@@ -1009,6 +1018,8 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) {
StringRef Tok = next();
if (SymbolAssignment *Assignment = readProvideOrAssignment(Tok))
Cmd->Commands.emplace_back(Assignment);
+ else if (Tok == "FILL")
+ Cmd->Filler = readFill();
else if (Tok == "SORT")
readSort();
else if (peek() == "(")
@@ -1017,7 +1028,8 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) {
setError("unknown command " + Tok);
}
Cmd->Phdrs = readOutputSectionPhdrs();
- Cmd->Filler = readOutputSectionFiller();
+ if (peek().startswith("="))
+ Cmd->Filler = readOutputSectionFiller(next().drop_front());
return Cmd;
}
@@ -1028,13 +1040,9 @@ ScriptParser::readOutputSectionDescription(StringRef OutSec) {
// hexstrings as blobs of arbitrary sizes, while ld.gold handles them
// as 32-bit big-endian values. We will do the same as ld.gold does
// because it's simpler than what ld.bfd does.
-std::vector<uint8_t> ScriptParser::readOutputSectionFiller() {
- if (!peek().startswith("="))
- return {};
-
- StringRef Tok = next();
+std::vector<uint8_t> ScriptParser::readOutputSectionFiller(StringRef Tok) {
uint32_t V;
- if (Tok.substr(1).getAsInteger(0, V)) {
+ if (Tok.getAsInteger(0, V)) {
setError("invalid filler expression: " + Tok);
return {};
}
diff --git a/lld/test/ELF/linkerscript/linkerscript-fill.s b/lld/test/ELF/linkerscript/linkerscript-fill.s
new file mode 100644
index 00000000000..e6d93b8f57c
--- /dev/null
+++ b/lld/test/ELF/linkerscript/linkerscript-fill.s
@@ -0,0 +1,30 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: echo "SECTIONS { \
+# RUN: .out : { \
+# RUN: FILL(0x11111111); \
+# RUN: *(.aaa) \
+# RUN: . += 4; \
+# RUN: *(.bbb) \
+# RUN: . += 4; \
+# RUN: FILL(0x22222222); \
+# RUN: . += 4; \
+# RUN: } \
+# RUN: }; " > %t.script
+# RUN: ld.lld -o %t --script %t.script %t.o
+# RUN: llvm-objdump -s %t | FileCheck %s
+
+# CHECK: Contents of section .out:
+# CHECK-NEXT: 0120 aa222222 22bb2222 22222222 2222
+
+.text
+.globl _start
+_start:
+
+.section .aaa, "a"
+.align 1
+.byte 0xAA
+
+.section .bbb, "a"
+.align 1
+.byte 0xBB
diff --git a/lld/test/ELF/linkerscript/sections-padding.s b/lld/test/ELF/linkerscript/sections-padding.s
index eb7c8d62e16..a209227622d 100644
--- a/lld/test/ELF/linkerscript/sections-padding.s
+++ b/lld/test/ELF/linkerscript/sections-padding.s
@@ -29,7 +29,7 @@
# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \
# RUN: | FileCheck --check-prefix=ERR2 %s
-# ERR2: invalid filler expression: =0x99XX
+# ERR2: invalid filler expression: 0x99XX
.section .mysec.1,"a"
.align 16
OpenPOWER on IntegriCloud