[lld] r253637 - [ELF] Define symbols "_end" and "end" if referenced.
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 19 18:32:36 PST 2015
Author: ikudrin
Date: Thu Nov 19 20:32:35 2015
New Revision: 253637
URL: http://llvm.org/viewvc/llvm-project?rev=253637&view=rev
Log:
[ELF] Define symbols "_end" and "end" if referenced.
These symbols are expected to point to the end of the data segment.
Implements http://llvm.org/pr25528.
Differential Revision: http://reviews.llvm.org/D14833
Added:
lld/trunk/test/ELF/end-preserve.s
lld/trunk/test/ELF/end-update.s
lld/trunk/test/ELF/end.s
Modified:
lld/trunk/ELF/Symbols.cpp
lld/trunk/ELF/Symbols.h
lld/trunk/ELF/Writer.cpp
lld/trunk/test/ELF/entry.s
Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=253637&r1=253636&r2=253637&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Thu Nov 19 20:32:35 2015
@@ -85,6 +85,7 @@ std::unique_ptr<InputFile> Lazy::getMemb
}
template <class ELFT> static void doInitSymbols() {
+ DefinedAbsolute<ELFT>::End.setBinding(STB_GLOBAL);
DefinedAbsolute<ELFT>::IgnoreUndef.setBinding(STB_WEAK);
DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN);
Undefined<ELFT>::Optional.setVisibility(STV_HIDDEN);
Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=253637&r1=253636&r2=253637&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Thu Nov 19 20:32:35 2015
@@ -177,9 +177,14 @@ template <class ELFT> class DefinedAbsol
public:
static Elf_Sym IgnoreUndef;
+ // The following symbols must be added early to reserve their places
+ // in symbol tables. The value of the symbols are set when all sections
+ // are finalized and their addresses are determined.
+
+ // The content for _end and end symbols.
+ static Elf_Sym End;
+
// The content for _gp symbol for MIPS target.
- // The symbol has to be added early to reserve a place in symbol tables.
- // The value of the symbol is computed later by Writer.
static Elf_Sym MipsGp;
DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
@@ -194,6 +199,9 @@ template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::IgnoreUndef;
template <class ELFT>
+typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::End;
+
+template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::MipsGp;
template <class ELFT> class DefinedCommon : public Defined<ELFT> {
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=253637&r1=253636&r2=253637&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Thu Nov 19 20:32:35 2015
@@ -623,6 +623,23 @@ template <class ELFT> void Writer<ELFT>:
if (!isOutputDynamic())
Symtab.addIgnoredSym("__tls_get_addr");
+ // 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.
+ // The order of the sections can be affected by linker script,
+ // so it is hard to predict which section will be the last one.
+ // So, if this symbol is referenced, we just add the placeholder here
+ // and update its value later.
+ if (Symtab.find("_end"))
+ Symtab.addAbsoluteSym("_end", DefinedAbsolute<ELFT>::End);
+
+ // If there is an undefined symbol "end", we should initialize it
+ // with the same value as "_end". In any other case it should stay intact,
+ // because it is an allowable name for a user symbol.
+ if (SymbolBody *B = Symtab.find("end"))
+ if (B->isUndefined())
+ Symtab.addAbsoluteSym("end", DefinedAbsolute<ELFT>::End);
+
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
@@ -879,6 +896,10 @@ template <class ELFT> void Writer<ELFT>:
SectionHeaderOff = RoundUpToAlignment(FileOff, ELFT::Is64Bits ? 8 : 4);
FileSize = SectionHeaderOff + getNumSections() * sizeof(Elf_Shdr);
+ // Update "_end" and "end" symbols so that they
+ // point to the end of the data segment.
+ DefinedAbsolute<ELFT>::End.st_value = VA;
+
// Update MIPS _gp absolute symbol so that it points to the static data.
if (Config->EMachine == EM_MIPS)
DefinedAbsolute<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
Added: lld/trunk/test/ELF/end-preserve.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/end-preserve.s?rev=253637&view=auto
==============================================================================
--- lld/trunk/test/ELF/end-preserve.s (added)
+++ lld/trunk/test/ELF/end-preserve.s Thu Nov 19 20:32:35 2015
@@ -0,0 +1,16 @@
+// Should preserve the value of the "end" symbol if it is defined.
+// 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-nm %t | FileCheck %s
+
+// CHECK: 0000000000000005 A end
+
+.global _start,end
+end = 5
+.text
+_start:
+ nop
+.bss
+ .space 6
Added: lld/trunk/test/ELF/end-update.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/end-update.s?rev=253637&view=auto
==============================================================================
--- lld/trunk/test/ELF/end-update.s (added)
+++ lld/trunk/test/ELF/end-update.s Thu Nov 19 20:32:35 2015
@@ -0,0 +1,29 @@
+// Should set the value of the "end" symbol if it is undefined.
+// 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
+
+// CHECK: Sections [
+// CHECK: Name: .bss
+// CHECK-NEXT: Type:
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address: 0x12000
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 6
+// CHECK: ]
+// CHECK: Symbols [
+// CHECK: Name: end
+// CHECK-NEXT: Value: 0x12006
+// CHECK: ]
+
+.global _start,end
+.text
+_start:
+ nop
+.bss
+ .space 6
Added: lld/trunk/test/ELF/end.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/end.s?rev=253637&view=auto
==============================================================================
--- lld/trunk/test/ELF/end.s (added)
+++ lld/trunk/test/ELF/end.s Thu Nov 19 20:32:35 2015
@@ -0,0 +1,79 @@
+// Should set the value of the "_end" symbol to the end of the data segment.
+// REQUIRES: x86
+
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+
+// By default, the .bss section is the latest section of the data segment.
+// RUN: ld.lld %t.o -o %t
+// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=DEFAULT
+
+// DEFAULT: Sections [
+// DEFAULT: Name: .bss
+// DEFAULT-NEXT: Type:
+// DEFAULT-NEXT: Flags [
+// DEFAULT-NEXT: SHF_ALLOC
+// DEFAULT-NEXT: SHF_WRITE
+// DEFAULT-NEXT: ]
+// DEFAULT-NEXT: Address: 0x12002
+// DEFAULT-NEXT: Offset:
+// DEFAULT-NEXT: Size: 6
+// DEFAULT: ]
+// DEFAULT: Symbols [
+// DEFAULT: Name: _end
+// DEFAULT-NEXT: Value: 0x12008
+// DEFAULT: ]
+
+// If there is no .bss section, "_end" should point to the end of the .data section.
+// RUN: echo "SECTIONS { \
+// RUN: /DISCARD/ : { *(.bss) } }" > %t.script
+// RUN: ld.lld %t.o --script %t.script -o %t
+// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=NOBSS
+
+// NOBSS: Sections [
+// NOBSS: Name: .data
+// NOBSS-NEXT: Type:
+// NOBSS-NEXT: Flags [
+// NOBSS-NEXT: SHF_ALLOC
+// NOBSS-NEXT: SHF_WRITE
+// NOBSS-NEXT: ]
+// NOBSS-NEXT: Address: 0x12000
+// NOBSS-NEXT: Offset:
+// NOBSS-NEXT: Size: 2
+// NOBSS: ]
+// NOBSS: Symbols [
+// NOBSS: Name: _end
+// NOBSS-NEXT: Value: 0x12002
+// NOBSS: ]
+
+// If the layout of the sections is changed, "_end" should point to the end of allocated address space.
+// RUN: echo "SECTIONS { \
+// RUN: .bss : { *(.bss) } \
+// RUN: .data : { *(.data) } \
+// RUN: .text : { *(.text) } }" > %t.script
+// RUN: ld.lld %t.o --script %t.script -o %t
+// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=TEXTATEND
+
+// TEXTATEND: Sections [
+// TEXTATEND: Name: .text
+// TEXTATEND-NEXT: Type:
+// TEXTATEND-NEXT: Flags [
+// TEXTATEND-NEXT: SHF_ALLOC
+// TEXTATEND-NEXT: SHF_EXECINSTR
+// TEXTATEND-NEXT: ]
+// TEXTATEND-NEXT: Address: 0x12000
+// TEXTATEND-NEXT: Offset:
+// TEXTATEND-NEXT: Size: 1
+// TEXTATEND: ]
+// TEXTATEND: Symbols [
+// TEXTATEND: Name: _end
+// TEXTATEND-NEXT: Value: 0x12001
+// TEXTATEND: ]
+
+.global _start,_end
+.text
+_start:
+ nop
+.data
+ .word 1
+.bss
+ .space 6
Modified: lld/trunk/test/ELF/entry.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/entry.s?rev=253637&r1=253636&r2=253637&view=diff
==============================================================================
--- lld/trunk/test/ELF/entry.s (original)
+++ lld/trunk/test/ELF/entry.s Thu Nov 19 20:32:35 2015
@@ -1,6 +1,6 @@
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
# RUN: not ld.lld %t1 -o %t2
-# RUN: ld.lld %t1 -o %t2 -e _end
+# RUN: ld.lld %t1 -o %t2 -e entry
# RUN: ld.lld %t1 -o %t2 -e 4096
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s
@@ -13,5 +13,5 @@
# HEX: Entry: 0xCAFE
# OCT: Entry: 0x1FF
-.globl _end
-_end:
+.globl entry
+entry:
More information about the llvm-commits
mailing list