summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Hosek <phosek@chromium.org>2016-12-07 02:26:16 +0000
committerPetr Hosek <phosek@chromium.org>2016-12-07 02:26:16 +0000
commit2f50fef095298706e7dbe1f47b7d9421c74a790b (patch)
tree992913104cf42b3e7df59a4203455e2afa74723c
parent668bebed6d5abde6d21650fdc271ee887eb9a928 (diff)
downloadbcm5719-llvm-2f50fef095298706e7dbe1f47b7d9421c74a790b.tar.gz
bcm5719-llvm-2f50fef095298706e7dbe1f47b7d9421c74a790b.zip
[ELF] Shared libraries should have entry point
Shared libraries should have entry set following the same rules as for regular binaries. The only difference is that in case the default entry point (_start or __start) isn't found (unless it was set explicitly), we shouldn't give a warning as in case of regular binaries. Differential Revision: https://reviews.llvm.org/D27497 llvm-svn: 288878
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp4
-rw-r--r--lld/ELF/Writer.cpp10
-rw-r--r--lld/test/ELF/gc-sections-keep-shared-start.s29
4 files changed, 38 insertions, 6 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 31ecd264803..874c5c4f988 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -107,6 +107,7 @@ struct Configuration {
bool GcSections;
bool GdbIndex;
bool GnuHash = false;
+ bool HasEntry = false;
bool ICF;
bool Mips64EL = false;
bool MipsN32Abi = false;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index cb27adc2d22..9774c7cc1cb 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -521,6 +521,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
Config->FatalWarnings = Args.hasArg(OPT_fatal_warnings);
+ Config->HasEntry = Args.hasArg(OPT_entry);
Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);
Config->GdbIndex = Args.hasArg(OPT_gdb_index);
Config->ICF = Args.hasArg(OPT_icf);
@@ -786,8 +787,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// It is either "-e <addr>" or "-e <symbol>".
if (!Config->Entry.getAsInteger(0, Config->EntryAddr))
Config->Entry = "";
- } else if (!Config->Shared && !Config->Relocatable &&
- Config->EMachine != EM_AMDGPU) {
+ } else if (!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";
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 98b335e4b14..555fe782bdb 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1410,14 +1410,16 @@ template <class ELFT> typename ELFT::uint Writer<ELFT>::getEntryAddr() {
// Case 4
if (OutputSectionBase *Sec = findSection(".text")) {
- warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
- utohexstr(Sec->Addr));
+ if (!Config->Shared || Config->HasEntry)
+ warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
+ utohexstr(Sec->Addr));
return Sec->Addr;
}
// Case 5
- warn("cannot find entry symbol " + Config->Entry +
- "; not setting start address");
+ if (!Config->Shared || Config->HasEntry)
+ warn("cannot find entry symbol " + Config->Entry +
+ "; not setting start address");
return 0;
}
diff --git a/lld/test/ELF/gc-sections-keep-shared-start.s b/lld/test/ELF/gc-sections-keep-shared-start.s
new file mode 100644
index 00000000000..53b3358cb1f
--- /dev/null
+++ b/lld/test/ELF/gc-sections-keep-shared-start.s
@@ -0,0 +1,29 @@
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+
+# RUN: ld.lld -shared --gc-sections -o %t1 %t
+# RUN: llvm-readobj --elf-output-style=GNU --file-headers --symbols %t1
+# | FileCheck %s
+# CHECK: Entry point address: 0x1000
+# CHECK: 0000000000001000 0 FUNC LOCAL HIDDEN 4 _start
+# CHECK: 0000000000001006 0 FUNC LOCAL HIDDEN 4 internal
+# CHECK: 0000000000001005 0 FUNC GLOBAL DEFAULT 4 foobar
+
+.section .text.start,"ax"
+.globl _start
+.type _start,%function
+.hidden _start
+_start:
+ jmp internal
+
+.section .text.foobar,"ax"
+.globl foobar
+.type foobar,%function
+foobar:
+ ret
+
+.section .text.internal,"ax"
+.globl internal
+.hidden internal
+.type internal,%function
+internal:
+ ret
OpenPOWER on IntegriCloud