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.
llvm-svn: 284676
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 22e260b..eb08649 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -69,7 +69,6 @@
// 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;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 516970a..5b2d0bf 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -695,22 +695,21 @@
// 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
diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index 452fc29..4fde1fd 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -225,8 +225,7 @@
};
// 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)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index b97ad99..d059c10 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1278,9 +1278,12 @@
}
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() {
diff --git a/lld/test/ELF/linkerscript/linkerscript.s b/lld/test/ELF/linkerscript/linkerscript.s
index c103739..718e1d2 100644
--- a/lld/test/ELF/linkerscript/linkerscript.s
+++ b/lld/test/ELF/linkerscript/linkerscript.s
@@ -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