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;
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";
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();
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<InputFile> &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 <addr>" or "-e <symbol>".
+ 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
template <class ELFT> static typename ELFT::uint getEntryAddr() {
if (Symbol *S = Config->EntrySym)
return S->body()->getVA<ELFT>();
- if (Config->EntryAddr != uint64_t(-1))
- return Config->EntryAddr;
- return 0;
+ return Config->EntryAddr;
}
template <class ELFT> static uint8_t getELFEncoding() {
// 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
# 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
# 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
# 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
# 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
# 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
# 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
// 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
// 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
# 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