mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[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
This commit is contained in:
@@ -107,6 +107,7 @@ struct Configuration {
|
||||
bool GcSections;
|
||||
bool GdbIndex;
|
||||
bool GnuHash = false;
|
||||
bool HasEntry = false;
|
||||
bool ICF;
|
||||
bool Mips64EL = false;
|
||||
bool MipsN32Abi = false;
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
29
lld/test/ELF/gc-sections-keep-shared-start.s
Normal file
29
lld/test/ELF/gc-sections-keep-shared-start.s
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user