Set entry address to 0x0 if no _start symbol
authorEugene Leviant <evgeny.leviant@gmail.com>
Thu, 8 Sep 2016 08:57:51 +0000 (08:57 +0000)
committerEugene Leviant <evgeny.leviant@gmail.com>
Thu, 8 Sep 2016 08:57:51 +0000 (08:57 +0000)
Differential revision: https://reviews.llvm.org/D23925

llvm-svn: 280912

lld/ELF/Config.h
lld/ELF/Driver.cpp
lld/ELF/Writer.cpp
lld/test/ELF/arm-gnu-ifunc.s
lld/test/ELF/edata-etext.s
lld/test/ELF/entry.s
lld/test/ELF/linkerscript/symbols-synthetic.s
lld/test/ELF/reproduce-windows.s
lld/test/ELF/resolution.s
lld/test/ELF/undef-start.s

index f06fe1b..4d7cf3e 100644 (file)
@@ -127,7 +127,7 @@ struct Configuration {
   ELFKind EKind = ELFNoneKind;
   uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
   uint16_t EMachine = llvm::ELF::EM_NONE;
-  uint64_t EntryAddr = -1;
+  uint64_t EntryAddr = 0;
   uint64_t ImageBase;
   uint64_t ZStackSize = -1;
   unsigned LtoJobs;
index 22482eb..9e5d77a 100644 (file)
@@ -575,11 +575,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   Config->Mips64EL =
       (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind);
 
-  // Add entry symbol. Note that AMDGPU binaries have no entry points.
-  if (Config->Entry.empty() && !Config->Shared && !Config->Relocatable &&
-      Config->EMachine != EM_AMDGPU)
-    Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
-
   // Default output filename is "a.out" by the Unix tradition.
   if (Config->OutputFile.empty())
     Config->OutputFile = "a.out";
@@ -588,13 +583,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
   for (auto *Arg : Args.filtered(OPT_trace_symbol))
     Symtab.trace(Arg->getValue());
 
-  // Set either EntryAddr (if S is a number) or EntrySym (otherwise).
-  if (!Config->Entry.empty()) {
-    StringRef S = Config->Entry;
-    if (S.getAsInteger(0, Config->EntryAddr))
-      Config->EntrySym = Symtab.addUndefined(S);
-  }
-
   // Initialize Config->ImageBase.
   if (auto *Arg = Args.getLastArg(OPT_image_base)) {
     StringRef S = Arg->getValue();
@@ -606,8 +594,27 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
     Config->ImageBase = Config->Pic ? 0 : Target->DefaultImageBase;
   }
 
+  // Add all files to the symbol table. After this, the symbol table
+  // contains all known names except a few linker-synthesized symbols.
   for (std::unique_ptr<InputFile> &F : Files)
     Symtab.addFile(std::move(F));
+
+  // Add the start symbol.
+  // It initializes either Config->Entry or Config->EntryAddr.
+  // Note that AMDGPU binaries have no entries.
+  if (!Config->Entry.empty()) {
+    // It is either "-e <addr>" or "-e <symbol>".
+    if (Config->Entry.getAsInteger(0, Config->EntryAddr))
+      Config->EntrySym = Symtab.addUndefined(Config->Entry);
+  } else if (!Config->Shared && !Config->Relocatable &&
+             Config->EMachine != EM_AMDGPU) {
+    // -e was not specified. Use the default start symbol name
+    // if it is resolvable.
+    Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
+    if (Symtab.find(Config->Entry))
+      Config->EntrySym = Symtab.addUndefined(Config->Entry);
+  }
+
   if (HasError)
     return; // There were duplicate symbols or incompatible files
 
index b1c08d1..ba58330 100644 (file)
@@ -1186,9 +1186,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
 template <class ELFT> static typename ELFT::uint getEntryAddr() {
   if (Symbol *S = Config->EntrySym)
     return S->body()->getVA<ELFT>();
-  if (Config->EntryAddr != uint64_t(-1))
-    return Config->EntryAddr;
-  return 0;
+  return Config->EntryAddr;
 }
 
 template <class ELFT> static uint8_t getELFEncoding() {
index c1e8a71..d5a5976 100644 (file)
@@ -70,7 +70,7 @@ _start:
 // CHECK-NEXT:    Section: .rel.plt
 // CHECK-NEXT:  }
 // CHECK-NEXT:  Symbol {
-// CHECK-NEXT:    Name: _start (6)
+// CHECK-NEXT:    Name: _start (38)
 // CHECK-NEXT:    Value: 0x11008
 // CHECK-NEXT:    Size: 0
 // CHECK-NEXT:    Binding: Global
index e0538d6..7b6d9b1 100644 (file)
 # 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:    Other: 0
 # CHECK-NEXT:    Section: Absolute
 # CHECK-NEXT:  }
+# CHECK-NEXT:  Symbol {
+# CHECK-NEXT:    Name: _start (20)
+# CHECK-NEXT:    Value: 0x11000
+# CHECK-NEXT:    Size: 0
+# CHECK-NEXT:    Binding: Global (0x1)
+# CHECK-NEXT:    Type: None (0x0)
+# CHECK-NEXT:    Other: 0
+# CHECK-NEXT:    Section: .text (0x1)
+# CHECK-NEXT:  }
 # CHECK-NEXT: ]
 
 .global _start,_end,_etext,_edata
index 6175c76..9dc3552 100644 (file)
@@ -1,5 +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
+# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=NOENTRY %s
 # RUN: ld.lld %t1 -o %t2 -e entry
 # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
 # RUN: ld.lld %t1 -shared -o %t2 -e entry
@@ -11,6 +12,7 @@
 # RUN: ld.lld %t1 -o %t2 -e 0777
 # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
 
+# NOENTRY: Entry: 0x0
 # SYM: Entry: 0x11000
 # DSO: Entry: 0x1000
 # DEC: Entry: 0x1000
index 9a3389c..a30c97d 100644 (file)
@@ -54,8 +54,9 @@
 # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
 
 # SIMPLE:      0000000000000160         .foo    00000000 .hidden _end_sec
-# SIMPLE:      0000000000000158         .foo    00000000 _begin_sec
+# SIMPLE-NEXT: 0000000000000158         .foo    00000000 _begin_sec
 # SIMPLE-NEXT: 0000000000000160         *ABS*   00000000 _end_sec_abs
+# SIMPLE-NEXT: 0000000000001048         .text   00000000 _start
 # SIMPLE-NEXT: 0000000000000158         .foo    00000000 begin_foo
 # SIMPLE-NEXT: 0000000000000160         .foo    00000000 end_foo
 # SIMPLE-NEXT: 0000000000000008         .foo    00000000 size_foo_1
index 74fc695..b0be517 100644 (file)
@@ -5,7 +5,7 @@
 # RUN: mkdir -p %t.dir/build
 # RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
 # RUN: cd %t.dir
-# RUN: not ld.lld build/foo.o --reproduce repro
+# RUN: ld.lld build/foo.o --reproduce repro
 # RUN: cpio -t < repro.cpio | FileCheck %s
 
 # CHECK: repro/response.txt
index 5596212..e635f2b 100644 (file)
 // CHECK-NEXT:     Section: Undefined (0x0)
 // CHECK-NEXT:   }
 // CHECK-NEXT:   Symbol {
-// CHECK-NEXT:     Name: _start
-// CHECK-NEXT:     Value:
-// 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: CommonStrong_with_CommonStrong
 // CHECK-NEXT:     Value:
 // CHECK-NEXT:     Size: 63
 // CHECK-NEXT:     Other: 0
 // CHECK-NEXT:     Section: Undefined
 // CHECK-NEXT:   }
+// CHECK-NEXT:  Symbol {
+// CHECK-NEXT:    Name: _start (929)
+// CHECK-NEXT:    Value: 0x11000
+// CHECK-NEXT:    Size: 0
+// CHECK-NEXT:    Binding: Global (0x1)
+// CHECK-NEXT:    Type: None (0x0)
+// CHECK-NEXT:    Other: 0
+// CHECK-NEXT:    Section: .text (0x1)
+// CHECK-NEXT:  }
 // CHECK-NEXT: ]
 
 .globl _start
index bf1d898..590d0a8 100644 (file)
@@ -1,4 +1,3 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
-# RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
-# CHECK: undefined symbol: _start
+# RUN: ld.lld %t -o %t2 2>&1
 # REQUIRES: x86