[PATCH] D26810: Allow SIZEOF() command on nonexistent section.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 17 12:26:47 PST 2016


ruiu created this revision.
ruiu added a reviewer: phosek.
ruiu added a subscriber: llvm-commits.

Linker script doesn't create a section if it has no content. So you may
create an empty section .norelocs with the following script if don't
have any .rel* secitons.

  .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.


https://reviews.llvm.org/D26810

Files:
  ELF/LinkerScript.cpp
  ELF/LinkerScript.h
  test/ELF/linkerscript/sizeof.s


Index: test/ELF/linkerscript/sizeof.s
===================================================================
--- test/ELF/linkerscript/sizeof.s
+++ 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:
Index: ELF/LinkerScript.h
===================================================================
--- ELF/LinkerScript.h
+++ ELF/LinkerScript.h
@@ -195,6 +195,7 @@
   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 @@
   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;
 
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -868,6 +868,20 @@
   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 @@
   }
   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();


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D26810.78401.patch
Type: text/x-patch
Size: 3004 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161117/a99df1f7/attachment.bin>


More information about the llvm-commits mailing list