summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-11-17 20:27:10 +0000
committerRui Ueyama <ruiu@google.com>2016-11-17 20:27:10 +0000
commitedf75e799233d9de94bd7012cc2d90cf7d40d77a (patch)
tree5d0c91d983e4e3b1166a4d1c601703b50bf9e1a0
parente4521c35230e15939dec2133fc8fa89270958dde (diff)
downloadbcm5719-llvm-edf75e799233d9de94bd7012cc2d90cf7d40d77a.tar.gz
bcm5719-llvm-edf75e799233d9de94bd7012cc2d90cf7d40d77a.zip
Allow SIZEOF() command on nonexistent section.
Linker script doesn't create a section if it has no content. So the following script doesn't create .norelocs section if it doesn't have any .rel* sections. .norelocs : { *(.rel*) } Later, if you assert that the size of .norelocs is 0, LLD printed out an error message, because it didn't allow calling SIZEOF() on nonexistent sections. This patch allows SIZEOF() on nonexistent sections, so that you can do something like this. ASSERT(SIZEOF(.norelocs), "shouldn't contain .rel sections!") Note that this behavior is compatible with GNU. Differential Revision: https://reviews.llvm.org/D26810 llvm-svn: 287257
-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