Index: ELF/Config.h =================================================================== --- ELF/Config.h +++ ELF/Config.h @@ -127,7 +127,7 @@ ELFKind EKind = ELFNoneKind; uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL; uint16_t EMachine = llvm::ELF::EM_NONE; - uint64_t EntryAddr = -1; + uint64_t EntryAddr = 0; uint64_t ImageBase; uint64_t ZStackSize = -1; unsigned LtoJobs; 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"; @@ -588,13 +583,6 @@ for (auto *Arg : Args.filtered(OPT_trace_symbol)) Symtab.trace(Arg->getValue()); - // Set either EntryAddr (if S is a number) or EntrySym (otherwise). - if (!Config->Entry.empty()) { - StringRef S = Config->Entry; - if (S.getAsInteger(0, Config->EntryAddr)) - Config->EntrySym = Symtab.addUndefined(S); - } - // Initialize Config->ImageBase. if (auto *Arg = Args.getLastArg(OPT_image_base)) { StringRef S = Arg->getValue(); @@ -606,8 +594,27 @@ Config->ImageBase = Config->Pic ? 0 : Target->DefaultImageBase; } + // Add all files to the symbol table. After this, the symbol table + // contains all known names except a few linker-synthesized symbols. for (std::unique_ptr &F : Files) Symtab.addFile(std::move(F)); + + // Add the start symbol. + // It initializes either Config->Entry or Config->EntryAddr. + // Note that AMDGPU binaries have no entries. + if (!Config->Entry.empty()) { + // It is either "-e " or "-e ". + if (Config->Entry.getAsInteger(0, Config->EntryAddr)) + Config->EntrySym = Symtab.addUndefined(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 (Symtab.find(Config->Entry)) + Config->EntrySym = Symtab.addUndefined(Config->Entry); + } + if (HasError) return; // There were duplicate symbols or incompatible files Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -1186,9 +1186,7 @@ template static typename ELFT::uint getEntryAddr() { if (Symbol *S = Config->EntrySym) return S->body()->getVA(); - if (Config->EntryAddr != uint64_t(-1)) - return Config->EntryAddr; - return 0; + return Config->EntryAddr; } template static uint8_t getELFEncoding() { 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 @@ -54,8 +54,9 @@ # 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: 0000000000000160 *ABS* 00000000 _end_sec_abs +# 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