summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/LinkerScript.cpp17
-rw-r--r--lld/ELF/LinkerScript.h2
-rw-r--r--lld/test/ELF/linkerscript/sizeof.s10
3 files changed, 22 insertions, 7 deletions
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 2b7d246215f..7b18afe7a09 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -868,6 +868,20 @@ const OutputSectionBase *LinkerScript<ELFT>::getOutputSection(StringRef Name) {
return &FakeSec;
}
+// This function is essentially the same as getOutputSection(Name)->Size,
+// but it won't print out an error message if a given section is not found.
+//
+// Linker script does not create an output section if its content is empty.
+// We want to allow SIZEOF(.foo) where .foo is a section which happened to
+// be empty. That is why this function is different from getOutputSection().
+template <class ELFT>
+uint64_t LinkerScript<ELFT>::getOutputSectionSize(StringRef Name) {
+ for (OutputSectionBase *Sec : *OutputSections)
+ if (Sec->getName() == Name)
+ return Sec->Size;
+ return 0;
+}
+
template <class ELFT> uint64_t LinkerScript<ELFT>::getHeaderSize() {
return elf::getHeaderSize<ELFT>();
}
@@ -1719,8 +1733,7 @@ Expr ScriptParser::readPrimary() {
}
if (Tok == "SIZEOF") {
StringRef Name = readParenLiteral();
- return
- [=](uint64_t Dot) { return ScriptBase->getOutputSection(Name)->Size; };
+ return [=](uint64_t Dot) { return ScriptBase->getOutputSectionSize(Name); };
}
if (Tok == "ALIGNOF") {
StringRef Name = readParenLiteral();
diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index 0f10d6b1413..e67935529f2 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -195,6 +195,7 @@ public:
virtual bool isAbsolute(StringRef S) = 0;
virtual const OutputSectionBase *getSymbolSection(StringRef S) = 0;
virtual const OutputSectionBase *getOutputSection(StringRef S) = 0;
+ virtual uint64_t getOutputSectionSize(StringRef S) = 0;
};
// ScriptConfiguration holds linker script parse results.
@@ -245,6 +246,7 @@ public:
bool isAbsolute(StringRef S) override;
const OutputSectionBase *getSymbolSection(StringRef S) override;
const OutputSectionBase *getOutputSection(StringRef S) override;
+ uint64_t getOutputSectionSize(StringRef S) override;
std::vector<OutputSectionBase *> *OutputSections;
diff --git a/lld/test/ELF/linkerscript/sizeof.s b/lld/test/ELF/linkerscript/sizeof.s
index 57e0ad7693e..4618f79d3db 100644
--- a/lld/test/ELF/linkerscript/sizeof.s
+++ b/lld/test/ELF/linkerscript/sizeof.s
@@ -24,17 +24,17 @@
# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
# CHECK-NEXT: 0000000000000018 *ABS* 00000000 _ccc
-## Check that we error out if trying to get size of
-## section that does not exist.
+## SIZEOF(.nonexistent_section) should return 0.
# RUN: echo "SECTIONS { \
# RUN: .aaa : { *(.aaa) } \
# RUN: .bbb : { *(.bbb) } \
# RUN: .ccc : { *(.ccc) } \
# RUN: _aaa = SIZEOF(.foo); \
# RUN: }" > %t.script
-# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \
-# RUN: | FileCheck -check-prefix=ERR %s
-# ERR: undefined section .foo
+# RUN: ld.lld -o %t1 --script %t.script %t
+# RUN: llvm-objdump -t -section-headers %t1 | FileCheck -check-prefix=CHECK2 %s
+
+# CHECK2: 0000000000000000 *ABS* 00000000 _aaa
.global _start
_start:
OpenPOWER on IntegriCloud