<div dir="ltr"><div>The Linux manual page of "end" says about the symbols as follows.</div><div><br></div><div> etext This is the first address past the end of the text segment (the program code).</div><div> edata This is the first address past the end of the initialized data segment.</div><div><br></div><div>Is your implementation correct? Your implementation seems like this.</div><div><br></div><div> etext is the last address past the end of any writable segment</div><div> edata is the last address past the end of any initialized data segment</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 26, 2016 at 6:36 AM, George Rimar via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: grimar<br>
Date: Fri Feb 26 08:36:36 2016<br>
New Revision: 262019<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=262019&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=262019&view=rev</a><br>
Log:<br>
Description of symbols is avalable here:<br>
<a href="https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html" rel="noreferrer" target="_blank">https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html</a><br>
<br>
It is said that:<br>
_etext - The address of _etext is the first<br>
location after the last read-only loadable segment.<br>
<br>
_edata - The address of _edata is the first<br>
location after the last read-write loadable segment.<br>
<br>
_end - If the address of _edata is greater than the address<br>
of _etext, the address of _end is same as the address of _edata.<br>
<br>
In real life _end and _edata has different values for that case.<br>
Both gold/bfd set _edata to the end of the last non SHT_NOBITS section.<br>
This patch do the same for consistency.<br>
<br>
It should fix the <a href="https://llvm.org/bugs/show_bug.cgi?id=26729" rel="noreferrer" target="_blank">https://llvm.org/bugs/show_bug.cgi?id=26729</a>.<br>
<br>
Differential revision: <a href="http://reviews.llvm.org/D17601" rel="noreferrer" target="_blank">http://reviews.llvm.org/D17601</a><br>
<br>
Added:<br>
lld/trunk/test/ELF/edata-etext.s<br>
Modified:<br>
lld/trunk/ELF/Symbols.cpp<br>
lld/trunk/ELF/Symbols.h<br>
lld/trunk/ELF/Writer.cpp<br>
<br>
Modified: lld/trunk/ELF/Symbols.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=262019&r1=262018&r2=262019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=262019&r1=262018&r2=262019&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Symbols.cpp (original)<br>
+++ lld/trunk/ELF/Symbols.cpp Fri Feb 26 08:36:36 2016<br>
@@ -214,6 +214,8 @@ std::unique_ptr<InputFile> Lazy::getMemb<br>
}<br>
<br>
template <class ELFT> static void doInitSymbols() {<br>
+ ElfSym<ELFT>::Etext.setBinding(STB_GLOBAL);<br>
+ ElfSym<ELFT>::Edata.setBinding(STB_GLOBAL);<br>
ElfSym<ELFT>::End.setBinding(STB_GLOBAL);<br>
ElfSym<ELFT>::Ignored.setBinding(STB_WEAK);<br>
ElfSym<ELFT>::Ignored.setVisibility(STV_HIDDEN);<br>
<br>
Modified: lld/trunk/ELF/Symbols.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=262019&r1=262018&r2=262019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=262019&r1=262018&r2=262019&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Symbols.h (original)<br>
+++ lld/trunk/ELF/Symbols.h Fri Feb 26 08:36:36 2016<br>
@@ -346,6 +346,12 @@ template <class ELFT> struct ElfSym {<br>
// output file's symbol table. It has weak binding and can be substituted.<br>
static Elf_Sym Ignored;<br>
<br>
+ // The content for _etext and etext symbols.<br>
+ static Elf_Sym Etext;<br>
+<br>
+ // The content for _edata and edata symbols.<br>
+ static Elf_Sym Edata;<br>
+<br>
// The content for _end and end symbols.<br>
static Elf_Sym End;<br>
<br>
@@ -359,6 +365,8 @@ template <class ELFT> struct ElfSym {<br>
};<br>
<br>
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::Ignored;<br>
+template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::Etext;<br>
+template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::Edata;<br>
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::End;<br>
template <class ELFT> typename ElfSym<ELFT>::Elf_Sym ElfSym<ELFT>::MipsGp;<br>
template <class ELFT><br>
<br>
Modified: lld/trunk/ELF/Writer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=262019&r1=262018&r2=262019&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=262019&r1=262018&r2=262019&view=diff</a><br>
==============================================================================<br>
--- lld/trunk/ELF/Writer.cpp (original)<br>
+++ lld/trunk/ELF/Writer.cpp Fri Feb 26 08:36:36 2016<br>
@@ -914,20 +914,30 @@ template <class ELFT> void Writer<ELFT>:<br>
if (!isOutputDynamic())<br>
Symtab.addIgnored("__tls_get_addr");<br>
<br>
+ auto Define = [this](StringRef Name, StringRef Alias, Elf_Sym &Sym) {<br>
+ if (Symtab.find(Name))<br>
+ Symtab.addAbsolute(Name, Sym);<br>
+ if (SymbolBody *B = Symtab.find(Alias))<br>
+ if (B->isUndefined())<br>
+ Symtab.addAbsolute(Alias, Sym);<br>
+ };<br>
+<br>
// If the "_end" symbol is referenced, it is expected to point to the address<br>
// right after the data segment. Usually, this symbol points to the end<br>
// of .bss section or to the end of .data section if .bss section is absent.<br>
// We don't know the final address of _end yet, so just add a symbol here,<br>
// and fix ElfSym<ELFT>::End.st_value later.<br>
- if (Symtab.find("_end"))<br>
- Symtab.addAbsolute("_end", ElfSym<ELFT>::End);<br>
-<br>
// Define "end" as an alias to "_end" if it is used but not defined.<br>
// We don't want to define that unconditionally because we don't want to<br>
// break programs that uses "end" as a regular symbol.<br>
- if (SymbolBody *B = Symtab.find("end"))<br>
- if (B->isUndefined())<br>
- Symtab.addAbsolute("end", ElfSym<ELFT>::End);<br>
+ // The similar history with _etext/etext and _edata/edata:<br>
+ // Address of _etext is the first location after the last read-only loadable<br>
+ // segment. Address of _edata points to the end of the last non SHT_NOBITS<br>
+ // section. That is how gold/bfd do. We update the values for these symbols<br>
+ // later, after assigning sections to segments.<br>
+ Define("_end", "end", ElfSym<ELFT>::End);<br>
+ Define("_etext", "etext", ElfSym<ELFT>::Etext);<br>
+ Define("_edata", "edata", ElfSym<ELFT>::Edata);<br>
}<br>
<br>
// Sort input sections by section name suffixes for<br>
@@ -1454,6 +1464,17 @@ template <class ELFT> void Writer<ELFT>:<br>
// Update MIPS _gp absolute symbol so that it points to the static data.<br>
if (Config->EMachine == EM_MIPS)<br>
ElfSym<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();<br>
+<br>
+ // _etext points to location after the last read-only loadable segment.<br>
+ // _edata points to the end of the last non SHT_NOBITS section.<br>
+ for (OutputSectionBase<ELFT> *Sec : OutputSections) {<br>
+ if (!(Sec->getFlags() & SHF_ALLOC))<br>
+ continue;<br>
+ if (!(Sec->getFlags() & SHF_WRITE))<br>
+ ElfSym<ELFT>::Etext.st_value = Sec->getVA() + Sec->getSize();<br>
+ if (Sec->getType() != SHT_NOBITS)<br>
+ ElfSym<ELFT>::Edata.st_value = Sec->getVA() + Sec->getSize();<br>
+ }<br>
}<br>
<br>
template <class ELFT> void Writer<ELFT>::writeHeader() {<br>
<br>
Added: lld/trunk/test/ELF/edata-etext.s<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/edata-etext.s?rev=262019&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/edata-etext.s?rev=262019&view=auto</a><br>
==============================================================================<br>
--- lld/trunk/test/ELF/edata-etext.s (added)<br>
+++ lld/trunk/test/ELF/edata-etext.s Fri Feb 26 08:36:36 2016<br>
@@ -0,0 +1,117 @@<br>
+# REQUIRES: x86<br>
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o<br>
+# RUN: ld.lld %t.o -o %t<br>
+# RUN: llvm-readobj -sections -symbols %t | FileCheck %s<br>
+<br>
+## This checks that:<br>
+## 1) Address of _etext is the first location after the last read-only loadable segment.<br>
+## 2) Address of _edata points to the end of the last non SHT_NOBITS section.<br>
+## That is how gold/bfd do. At the same time specs says: "If the address of _edata is<br>
+## greater than the address of _etext, the address of _end is same as the address<br>
+## of _edata." (<a href="https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html" rel="noreferrer" target="_blank">https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html</a>).<br>
+## 3) Address of _end is different from _edata because of 2.<br>
+# CHECK: Section {<br>
+# CHECK: Index: 1<br>
+# CHECK: Name: .text<br>
+# CHECK-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-NEXT: Flags [<br>
+# CHECK-NEXT: SHF_ALLOC<br>
+# CHECK-NEXT: SHF_EXECINSTR<br>
+# CHECK-NEXT: ]<br>
+# CHECK-NEXT: Address: 0x11000<br>
+# CHECK-NEXT: Offset: 0x1000<br>
+# CHECK-NEXT: Size: 1<br>
+# CHECK-NEXT: Link:<br>
+# CHECK-NEXT: Info:<br>
+# CHECK-NEXT: AddressAlignment:<br>
+# CHECK-NEXT: EntrySize: 0<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Section {<br>
+# CHECK-NEXT: Index: 2<br>
+# CHECK-NEXT: Name: .data<br>
+# CHECK-NEXT: Type: SHT_PROGBITS<br>
+# CHECK-NEXT: Flags [<br>
+# CHECK-NEXT: SHF_ALLOC<br>
+# CHECK-NEXT: SHF_WRITE<br>
+# CHECK-NEXT: ]<br>
+# CHECK-NEXT: Address: 0x12000<br>
+# CHECK-NEXT: Offset: 0x2000<br>
+# CHECK-NEXT: Size: 2<br>
+# CHECK-NEXT: Link:<br>
+# CHECK-NEXT: Info:<br>
+# CHECK-NEXT: AddressAlignment:<br>
+# CHECK-NEXT: EntrySize:<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Section {<br>
+# CHECK-NEXT: Index: 3<br>
+# CHECK-NEXT: Name: .bss<br>
+# CHECK-NEXT: Type: SHT_NOBITS<br>
+# CHECK-NEXT: Flags [<br>
+# CHECK-NEXT: SHF_ALLOC<br>
+# CHECK-NEXT: SHF_WRITE<br>
+# CHECK-NEXT: ]<br>
+# CHECK-NEXT: Address: 0x12004<br>
+# CHECK-NEXT: Offset: 0x2002<br>
+# CHECK-NEXT: Size: 6<br>
+# CHECK-NEXT: Link:<br>
+# CHECK-NEXT: Info:<br>
+# CHECK-NEXT: AddressAlignment:<br>
+# CHECK-NEXT: EntrySize:<br>
+# CHECK-NEXT: }<br>
+# CHECK: Symbols [<br>
+# CHECK-NEXT: Symbol {<br>
+# CHECK-NEXT: Name:<br>
+# CHECK-NEXT: Value: 0x0<br>
+# CHECK-NEXT: Size: 0<br>
+# CHECK-NEXT: Binding: Local<br>
+# CHECK-NEXT: Type: None<br>
+# CHECK-NEXT: Other: 0<br>
+# CHECK-NEXT: Section: Undefined<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Symbol {<br>
+# CHECK-NEXT: Name: _start<br>
+# CHECK-NEXT: Value: 0x11000<br>
+# CHECK-NEXT: Size: 0<br>
+# CHECK-NEXT: Binding: Global<br>
+# CHECK-NEXT: Type: None<br>
+# CHECK-NEXT: Other: 0<br>
+# CHECK-NEXT: Section: .text<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Symbol {<br>
+# CHECK-NEXT: Name: _edata<br>
+# CHECK-NEXT: Value: 0x12002<br>
+# CHECK-NEXT: Size: 0<br>
+# CHECK-NEXT: Binding: Global<br>
+# CHECK-NEXT: Type: None<br>
+# CHECK-NEXT: Other: 0<br>
+# CHECK-NEXT: Section: Absolute<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Symbol {<br>
+# CHECK-NEXT: Name: _end<br>
+# CHECK-NEXT: Value: 0x1200A<br>
+# CHECK-NEXT: Size: 0<br>
+# CHECK-NEXT: Binding: Global<br>
+# CHECK-NEXT: Type: None<br>
+# CHECK-NEXT: Other: 0<br>
+# CHECK-NEXT: Section: Absolute<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: Symbol {<br>
+# CHECK-NEXT: Name: _etext<br>
+# CHECK-NEXT: Value: 0x11001<br>
+# CHECK-NEXT: Size: 0<br>
+# CHECK-NEXT: Binding: Global<br>
+# CHECK-NEXT: Type: None<br>
+# CHECK-NEXT: Other: 0<br>
+# CHECK-NEXT: Section: Absolute<br>
+# CHECK-NEXT: }<br>
+# CHECK-NEXT: ]<br>
+<br>
+.global _start,_end,_etext,_edata<br>
+.text<br>
+_start:<br>
+ nop<br>
+.data<br>
+ .word 1<br>
+.bss<br>
+ .align 4<br>
+ .space 6<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>