summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2016-10-20 00:07:36 +0000
committerRui Ueyama <ruiu@google.com>2016-10-20 00:07:36 +0000
commit8da7aa0894e96694523c19a24bca7a424963c17b (patch)
tree75681016bcd827acc641292d36bc02839ccf91d9
parent40379746c8a5c70b60e1a9c92badf6f365c798cc (diff)
downloadbcm5719-llvm-8da7aa0894e96694523c19a24bca7a424963c17b.tar.gz
bcm5719-llvm-8da7aa0894e96694523c19a24bca7a424963c17b.zip
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
-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