diff options
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 15 | ||||
-rw-r--r-- | lld/ELF/MarkLive.cpp | 3 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 9 | ||||
-rw-r--r-- | lld/test/ELF/linkerscript/linkerscript.s | 8 |
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 |