[lld] r316877 - ELF: Correctly set edata if there are no .bss sections.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Sun Oct 29 15:31:48 PDT 2017


Author: pcc
Date: Sun Oct 29 15:31:48 2017
New Revision: 316877

URL: http://llvm.org/viewvc/llvm-project?rev=316877&view=rev
Log:
ELF: Correctly set edata if there are no .bss sections.

edata needs to be set to the end of the last mapped initialized
section. We were previously mishandling the case where there were no
non-mapped sections by setting it to the end of the last section in
the output file.

Differential Revision: https://reviews.llvm.org/D39399

Added:
    lld/trunk/test/ELF/edata-no-bss.s
Modified:
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=316877&r1=316876&r2=316877&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Sun Oct 29 15:31:48 2017
@@ -915,37 +915,34 @@ template <class ELFT> void Writer<ELFT>:
       LastRO = P;
   }
 
-  // _end is the first location after the uninitialized data region.
-  if (Last) {
-    if (ElfSym::End1)
-      ElfSym::End1->Section = Last->LastSec;
-    if (ElfSym::End2)
-      ElfSym::End2->Section = Last->LastSec;
-  }
-
-  // _etext is the first location after the last read-only loadable segment.
   if (LastRO) {
+    // _etext is the first location after the last read-only loadable segment.
     if (ElfSym::Etext1)
       ElfSym::Etext1->Section = LastRO->LastSec;
     if (ElfSym::Etext2)
       ElfSym::Etext2->Section = LastRO->LastSec;
   }
 
-  // _edata points to the end of the last non SHT_NOBITS section.
-  if (LastRW) {
-    size_t I = 0;
-    for (; I < OutputSections.size(); ++I)
-      if (OutputSections[I] == LastRW->FirstSec)
-        break;
-
-    for (; I < OutputSections.size(); ++I)
-      if (OutputSections[I]->Type == SHT_NOBITS)
+  if (Last) {
+    // _edata points to the end of the last mapped initialized section.
+    OutputSection *Edata = nullptr;
+    for (OutputSection *OS : OutputSections) {
+      if (OS->Type != SHT_NOBITS)
+        Edata = OS;
+      if (OS == Last->LastSec)
         break;
+    }
 
     if (ElfSym::Edata1)
-      ElfSym::Edata1->Section = OutputSections[I - 1];
+      ElfSym::Edata1->Section = Edata;
     if (ElfSym::Edata2)
-      ElfSym::Edata2->Section = OutputSections[I - 1];
+      ElfSym::Edata2->Section = Edata;
+
+    // _end is the first location after the uninitialized data region.
+    if (ElfSym::End1)
+      ElfSym::End1->Section = Last->LastSec;
+    if (ElfSym::End2)
+      ElfSym::End2->Section = Last->LastSec;
   }
 
   if (ElfSym::Bss)

Added: lld/trunk/test/ELF/edata-no-bss.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/edata-no-bss.s?rev=316877&view=auto
==============================================================================
--- lld/trunk/test/ELF/edata-no-bss.s (added)
+++ lld/trunk/test/ELF/edata-no-bss.s Sun Oct 29 15:31:48 2017
@@ -0,0 +1,18 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t --gc-sections
+# RUN: llvm-objdump -t -section-headers %t | FileCheck %s
+
+# CHECK: .data         00000008 0000000000202000 DATA
+
+# CHECK: 0000000000202008         .data                 00000000 _edata
+
+.text
+.globl _start
+_start:
+.long .data - .
+
+.data
+.quad 0
+
+.globl _edata




More information about the llvm-commits mailing list