From e662436114879dec3617387ac99bb4d357f38930 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Sun, 29 Oct 2017 22:31:48 +0000 Subject: [PATCH] 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 llvm-svn: 316877 --- lld/ELF/Writer.cpp | 37 +++++++++++++++++-------------------- lld/test/ELF/edata-no-bss.s | 18 ++++++++++++++++++ 2 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 lld/test/ELF/edata-no-bss.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 1d2a4d2..b9ac65d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -915,37 +915,34 @@ template void Writer::setReservedSymbolSections() { 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) diff --git a/lld/test/ELF/edata-no-bss.s b/lld/test/ELF/edata-no-bss.s new file mode 100644 index 0000000..5127c471 --- /dev/null +++ b/lld/test/ELF/edata-no-bss.s @@ -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 -- 2.7.4