[lld] r284676 - Allow linker-script-defined entry symbols.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 19 17:07:37 PDT 2016


Author: ruiu
Date: Wed Oct 19 19:07:36 2016
New Revision: 284676

URL: http://llvm.org/viewvc/llvm-project?rev=284676&view=rev
Log:
Allow linker-script-defined entry symbols.

Previously, we were checking the existence of an entry symbol
too early. It was done before the linker script processor creates
symbols defined in scripts. Fixes bug 30743.

Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/MarkLive.cpp
    lld/trunk/ELF/Writer.cpp
    lld/trunk/test/ELF/linkerscript/linkerscript.s

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=284676&r1=284675&r2=284676&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Oct 19 19:07:36 2016
@@ -69,7 +69,6 @@ struct VersionDefinition {
 // and such fields have the same name as the corresponding options.
 // Most fields are initialized by the driver.
 struct Configuration {
-  Symbol *EntrySym = nullptr;
   InputFile *FirstElf = nullptr;
   llvm::StringMap<uint64_t> SectionStartMap;
   llvm::StringRef DynamicLinker;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=284676&r1=284675&r2=284676&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Oct 19 19:07:36 2016
@@ -695,22 +695,21 @@ template <class ELFT> void LinkerDriver:
   // Add the start symbol.
   // It initializes either Config->Entry or Config->EntryAddr.
   // Note that AMDGPU binaries have no entries.
-  bool HasEntryAddr = false;
   if (!Config->Entry.empty()) {
     // It is either "-e <addr>" or "-e <symbol>".
-    HasEntryAddr = !Config->Entry.getAsInteger(0, Config->EntryAddr);
+    if (!Config->Entry.getAsInteger(0, Config->EntryAddr))
+      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 (!HasEntryAddr && !Config->Entry.empty()) {
-    if (Symtab.find(Config->Entry))
-      Config->EntrySym = Symtab.addUndefined(Config->Entry);
-    else
-      warn("entry symbol " + Config->Entry + " not found, assuming 0");
-  }
+
+  // If an object file defining the entry symbol is in an archive file,
+  // extract the file now.
+  if (Symtab.find(Config->Entry))
+    Symtab.addUndefined(Config->Entry);
 
   if (HasError)
     return; // There were duplicate symbols or incompatible files

Modified: lld/trunk/ELF/MarkLive.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/MarkLive.cpp?rev=284676&r1=284675&r2=284676&view=diff
==============================================================================
--- lld/trunk/ELF/MarkLive.cpp (original)
+++ lld/trunk/ELF/MarkLive.cpp Wed Oct 19 19:07:36 2016
@@ -225,8 +225,7 @@ template <class ELFT> void elf::markLive
   };
 
   // Add GC root symbols.
-  if (Config->EntrySym)
-    MarkSymbol(Config->EntrySym->body());
+  MarkSymbol(Symtab<ELFT>::X->find(Config->Entry));
   MarkSymbol(Symtab<ELFT>::X->find(Config->Init));
   MarkSymbol(Symtab<ELFT>::X->find(Config->Fini));
   for (StringRef S : Config->Undefined)

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=284676&r1=284675&r2=284676&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Oct 19 19:07:36 2016
@@ -1278,9 +1278,12 @@ template <class ELFT> void Writer<ELFT>:
 }
 
 template <class ELFT> static typename ELFT::uint getEntryAddr() {
-  if (Symbol *S = Config->EntrySym)
-    return S->body()->getVA<ELFT>();
-  return Config->EntryAddr;
+  if (Config->Entry.empty())
+    return Config->EntryAddr;
+  if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry))
+    return B->getVA<ELFT>();
+  warn("entry symbol " + Config->Entry + " not found, assuming 0");
+  return 0;
 }
 
 template <class ELFT> static uint8_t getELFEncoding() {

Modified: lld/trunk/test/ELF/linkerscript/linkerscript.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/linkerscript.s?rev=284676&r1=284675&r2=284676&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/linkerscript.s (original)
+++ lld/trunk/test/ELF/linkerscript/linkerscript.s Wed Oct 19 19:07:36 2016
@@ -75,6 +75,14 @@
 # ENTRY-OVERLOAD: Name: _start
 # ENTRY-OVERLOAD-NEXT: Value: [[ENTRY]]
 
+# The entry symbol can be a linker-script-defined symbol.
+# RUN: echo "ENTRY(foo); foo = 1;" > %t.script
+# RUN: ld.lld -o %t2 %t.script %t
+# RUN: llvm-readobj -file-headers -symbols %t2 | \
+# RUN:   FileCheck -check-prefix=ENTRY-SCRIPT %s
+
+# ENTRY-SCRIPT: Entry: 0x1
+
 # RUN: echo "OUTPUT_FORMAT(elf64-x86-64) /*/*/ GROUP(\"%t\" )" > %t.script
 # RUN: ld.lld -o %t2 %t.script
 # RUN: llvm-readobj %t2 > /dev/null




More information about the llvm-commits mailing list