Index: ELF/Driver.cpp =================================================================== --- ELF/Driver.cpp +++ ELF/Driver.cpp @@ -575,11 +575,6 @@ Config->Mips64EL = (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind); - // Add entry symbol. Note that AMDGPU binaries have no entry points. - if (Config->Entry.empty() && !Config->Shared && !Config->Relocatable && - Config->EMachine != EM_AMDGPU) - Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start"; - // Default output filename is "a.out" by the Unix tradition. if (Config->OutputFile.empty()) Config->OutputFile = "a.out"; @@ -593,8 +588,10 @@ StringRef S = Config->Entry; if (S.getAsInteger(0, Config->EntryAddr)) Config->EntrySym = Symtab.addUndefined(S); + } else if (Config->Entry.empty() && !Config->Shared && !Config->Relocatable && + Config->EMachine != EM_AMDGPU) { + Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start"; } - // Initialize Config->ImageBase. if (auto *Arg = Args.getLastArg(OPT_image_base)) { StringRef S = Arg->getValue(); Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -201,6 +201,10 @@ return {S, Config->DefaultSymbolVersion}; } +static bool isEntryName(StringRef Name) { + return !Name.empty() && Name == Config->Entry; +} + // Find an existing symbol or create and insert a new one. template std::pair SymbolTable::insert(StringRef &Name) { @@ -255,6 +259,10 @@ error("TLS attribute mismatch for symbol: " + conflictMsg(S->body(), File)); + if (WasInserted && isEntryName(Name)) { + Config->EntrySym = S; + S->IsUsedInRegularObj = true; + } return {S, WasInserted}; } @@ -502,24 +510,27 @@ Symbol *S; bool WasInserted; StringRef Name = Sym.getName(); - std::tie(S, WasInserted) = insert(Name); - if (WasInserted) { - replaceBody(S, *F, Sym, SymbolBody::UnknownType); - return; - } - if (!S->body()->isUndefined()) - return; + if (!isEntryName(Name)) { + std::tie(S, WasInserted) = insert(Name); + if (WasInserted) { + replaceBody(S, *F, Sym, SymbolBody::UnknownType); + return; + } + if (!S->body()->isUndefined()) + return; - // Weak undefined symbols should not fetch members from archives. If we were - // to keep old symbol we would not know that an archive member was available - // if a strong undefined symbol shows up afterwards in the link. If a strong - // undefined symbol never shows up, this lazy symbol will get to the end of - // the link and must be treated as the weak undefined one. We already marked - // this symbol as used when we added it to the symbol table, but we also need - // to preserve its type. FIXME: Move the Type field to Symbol. - if (S->isWeak()) { - replaceBody(S, *F, Sym, S->body()->Type); - return; + // Weak undefined symbols should not fetch members from archives. If we were + // to keep old symbol we would not know that an archive member was available + // if a strong undefined symbol shows up afterwards in the link. If a strong + // undefined symbol never shows up, this lazy symbol will get to the end of + // the link and must be treated as the weak undefined one. We already marked + // this symbol as used when we added it to the symbol table, but we also + // need + // to preserve its type. FIXME: Move the Type field to Symbol. + if (S->isWeak()) { + replaceBody(S, *F, Sym, S->body()->Type); + return; + } } MemoryBufferRef MBRef = F->getMember(&Sym); if (!MBRef.getBuffer().empty()) @@ -530,22 +541,24 @@ void SymbolTable::addLazyObject(StringRef Name, LazyObjectFile &Obj) { Symbol *S; bool WasInserted; - std::tie(S, WasInserted) = insert(Name); - if (WasInserted) { - replaceBody(S, Name, Obj, SymbolBody::UnknownType); - return; - } - if (!S->body()->isUndefined()) - return; + if (!isEntryName(Name)) { + std::tie(S, WasInserted) = insert(Name); + if (WasInserted) { + replaceBody(S, Name, Obj, SymbolBody::UnknownType); + return; + } + if (!S->body()->isUndefined()) + return; - // See comment for addLazyArchive above. - if (S->isWeak()) { - replaceBody(S, Name, Obj, S->body()->Type); - } else { - MemoryBufferRef MBRef = Obj.getBuffer(); - if (!MBRef.getBuffer().empty()) - addFile(createObjectFile(MBRef)); + // See comment for addLazyArchive above. + if (S->isWeak()) { + replaceBody(S, Name, Obj, S->body()->Type); + return; + } } + MemoryBufferRef MBRef = Obj.getBuffer(); + if (!MBRef.getBuffer().empty()) + addFile(createObjectFile(MBRef)); } // Process undefined (-u) flags by loading lazy symbols named by those flags. Index: test/ELF/arm-gnu-ifunc.s =================================================================== --- test/ELF/arm-gnu-ifunc.s +++ test/ELF/arm-gnu-ifunc.s @@ -70,7 +70,7 @@ // CHECK-NEXT: Section: .rel.plt // CHECK-NEXT: } // CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: _start (6) +// CHECK-NEXT: Name: _start (38) // CHECK-NEXT: Value: 0x11008 // CHECK-NEXT: Size: 0 // CHECK-NEXT: Binding: Global Index: test/ELF/edata-etext.s =================================================================== --- test/ELF/edata-etext.s +++ test/ELF/edata-etext.s @@ -69,15 +69,6 @@ # CHECK-NEXT: Section: Undefined # CHECK-NEXT: } # CHECK-NEXT: Symbol { -# CHECK-NEXT: Name: _start -# CHECK-NEXT: Value: 0x11000 -# CHECK-NEXT: Size: 0 -# CHECK-NEXT: Binding: Global -# CHECK-NEXT: Type: None -# CHECK-NEXT: Other: 0 -# CHECK-NEXT: Section: .text -# CHECK-NEXT: } -# CHECK-NEXT: Symbol { # CHECK-NEXT: Name: _edata # CHECK-NEXT: Value: 0x12002 # CHECK-NEXT: Size: 0 @@ -104,6 +95,15 @@ # CHECK-NEXT: Other: 0 # CHECK-NEXT: Section: Absolute # CHECK-NEXT: } +# CHECK-NEXT: Symbol { +# CHECK-NEXT: Name: _start (20) +# CHECK-NEXT: Value: 0x11000 +# CHECK-NEXT: Size: 0 +# CHECK-NEXT: Binding: Global (0x1) +# CHECK-NEXT: Type: None (0x0) +# CHECK-NEXT: Other: 0 +# CHECK-NEXT: Section: .text (0x1) +# CHECK-NEXT: } # CHECK-NEXT: ] .global _start,_end,_etext,_edata Index: test/ELF/entry.s =================================================================== --- test/ELF/entry.s +++ test/ELF/entry.s @@ -1,5 +1,6 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1 -# RUN: not ld.lld %t1 -o %t2 +# RUN: ld.lld %t1 -o %t2 +# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=NOENTRY %s # RUN: ld.lld %t1 -o %t2 -e entry # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s # RUN: ld.lld %t1 -shared -o %t2 -e entry @@ -11,6 +12,7 @@ # RUN: ld.lld %t1 -o %t2 -e 0777 # RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s +# NOENTRY: Entry: 0x0 # SYM: Entry: 0x11000 # DSO: Entry: 0x1000 # DEC: Entry: 0x1000 Index: test/ELF/linkerscript/symbols-synthetic.s =================================================================== --- test/ELF/linkerscript/symbols-synthetic.s +++ test/ELF/linkerscript/symbols-synthetic.s @@ -51,7 +51,8 @@ # RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t # SIMPLE: 0000000000000160 .foo 00000000 .hidden _end_sec -# SIMPLE: 0000000000000158 .foo 00000000 _begin_sec +# SIMPLE-NEXT: 0000000000000158 .foo 00000000 _begin_sec +# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start # SIMPLE-NEXT: 0000000000000158 .foo 00000000 begin_foo # SIMPLE-NEXT: 0000000000000160 .foo 00000000 end_foo # SIMPLE-NEXT: 0000000000000008 .foo 00000000 size_foo_1 Index: test/ELF/reproduce-windows.s =================================================================== --- test/ELF/reproduce-windows.s +++ test/ELF/reproduce-windows.s @@ -5,7 +5,7 @@ # RUN: mkdir -p %t.dir/build # RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux # RUN: cd %t.dir -# RUN: not ld.lld build/foo.o --reproduce repro +# RUN: ld.lld build/foo.o --reproduce repro # RUN: cpio -t < repro.cpio | FileCheck %s # CHECK: repro/response.txt Index: test/ELF/resolution.s =================================================================== --- test/ELF/resolution.s +++ test/ELF/resolution.s @@ -19,15 +19,6 @@ // CHECK-NEXT: Section: Undefined (0x0) // CHECK-NEXT: } // CHECK-NEXT: Symbol { -// CHECK-NEXT: Name: _start -// CHECK-NEXT: Value: -// CHECK-NEXT: Size: 0 -// CHECK-NEXT: Binding: Global -// CHECK-NEXT: Type: None -// CHECK-NEXT: Other: 0 -// CHECK-NEXT: Section: .text -// CHECK-NEXT: } -// CHECK-NEXT: Symbol { // CHECK-NEXT: Name: CommonStrong_with_CommonStrong // CHECK-NEXT: Value: // CHECK-NEXT: Size: 63 @@ -315,6 +306,15 @@ // CHECK-NEXT: Other: 0 // CHECK-NEXT: Section: Undefined // CHECK-NEXT: } +// CHECK-NEXT: Symbol { +// CHECK-NEXT: Name: _start (929) +// CHECK-NEXT: Value: 0x11000 +// CHECK-NEXT: Size: 0 +// CHECK-NEXT: Binding: Global (0x1) +// CHECK-NEXT: Type: None (0x0) +// CHECK-NEXT: Other: 0 +// CHECK-NEXT: Section: .text (0x1) +// CHECK-NEXT: } // CHECK-NEXT: ] .globl _start Index: test/ELF/undef-start.s =================================================================== --- test/ELF/undef-start.s +++ test/ELF/undef-start.s @@ -1,4 +1,3 @@ # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t -# RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s -# CHECK: undefined symbol: _start +# RUN: ld.lld %t -o %t2 2>&1 # REQUIRES: x86