summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp15
-rw-r--r--lld/ELF/MarkLive.cpp3
-rw-r--r--lld/ELF/Writer.cpp9
-rw-r--r--lld/test/ELF/linkerscript/linkerscript.s8
5 files changed, 22 insertions, 14 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 22e260b1df1..eb08649032f 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -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;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 516970ac53a..5b2d0bf47dc 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -695,22 +695,21 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// 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 452fc29ab91..4fde1fdb5c5 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -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)
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index b97ad99a448..d059c107110 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1278,9 +1278,12 @@ 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>();
- 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 c103739c745..718e1d2d35d 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
OpenPOWER on IntegriCloud