[lld] r262019 - Description of symbols is avalable here:

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 08:12:14 PST 2016


The Linux manual page of "end" says about the symbols as follows.

  etext  This is the first address past the end of the text segment (the
program code).
  edata  This is the first address past the end of the initialized data
segment.

Is your implementation correct? Your implementation seems like this.

  etext is the last address past the end of any writable segment
  edata is the last address past the end of any initialized data segment

On Fri, Feb 26, 2016 at 6:36 AM, George Rimar via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list