forked from OSchip/llvm-project
				
			Set entry address to 0x0 if no _start symbol
Differential revision: https://reviews.llvm.org/D23925 llvm-svn: 280912
This commit is contained in:
		
							parent
							
								
									6c55f0e35e
								
							
						
					
					
						commit
						3967ea05a9
					
				| 
						 | 
					@ -127,7 +127,7 @@ struct Configuration {
 | 
				
			||||||
  ELFKind EKind = ELFNoneKind;
 | 
					  ELFKind EKind = ELFNoneKind;
 | 
				
			||||||
  uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
 | 
					  uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
 | 
				
			||||||
  uint16_t EMachine = llvm::ELF::EM_NONE;
 | 
					  uint16_t EMachine = llvm::ELF::EM_NONE;
 | 
				
			||||||
  uint64_t EntryAddr = -1;
 | 
					  uint64_t EntryAddr = 0;
 | 
				
			||||||
  uint64_t ImageBase;
 | 
					  uint64_t ImageBase;
 | 
				
			||||||
  uint64_t ZStackSize = -1;
 | 
					  uint64_t ZStackSize = -1;
 | 
				
			||||||
  unsigned LtoJobs;
 | 
					  unsigned LtoJobs;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -575,11 +575,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
 | 
				
			||||||
  Config->Mips64EL =
 | 
					  Config->Mips64EL =
 | 
				
			||||||
      (Config->EMachine == EM_MIPS && Config->EKind == ELF64LEKind);
 | 
					      (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.
 | 
					  // Default output filename is "a.out" by the Unix tradition.
 | 
				
			||||||
  if (Config->OutputFile.empty())
 | 
					  if (Config->OutputFile.empty())
 | 
				
			||||||
    Config->OutputFile = "a.out";
 | 
					    Config->OutputFile = "a.out";
 | 
				
			||||||
| 
						 | 
					@ -588,13 +583,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
 | 
				
			||||||
  for (auto *Arg : Args.filtered(OPT_trace_symbol))
 | 
					  for (auto *Arg : Args.filtered(OPT_trace_symbol))
 | 
				
			||||||
    Symtab.trace(Arg->getValue());
 | 
					    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.
 | 
					  // Initialize Config->ImageBase.
 | 
				
			||||||
  if (auto *Arg = Args.getLastArg(OPT_image_base)) {
 | 
					  if (auto *Arg = Args.getLastArg(OPT_image_base)) {
 | 
				
			||||||
    StringRef S = Arg->getValue();
 | 
					    StringRef S = Arg->getValue();
 | 
				
			||||||
| 
						 | 
					@ -606,8 +594,27 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
 | 
				
			||||||
    Config->ImageBase = Config->Pic ? 0 : Target->DefaultImageBase;
 | 
					    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)
 | 
					  for (std::unique_ptr<InputFile> &F : Files)
 | 
				
			||||||
    Symtab.addFile(std::move(F));
 | 
					    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)
 | 
					  if (HasError)
 | 
				
			||||||
    return; // There were duplicate symbols or incompatible files
 | 
					    return; // There were duplicate symbols or incompatible files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1186,9 +1186,7 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
 | 
				
			||||||
template <class ELFT> static typename ELFT::uint getEntryAddr() {
 | 
					template <class ELFT> static typename ELFT::uint getEntryAddr() {
 | 
				
			||||||
  if (Symbol *S = Config->EntrySym)
 | 
					  if (Symbol *S = Config->EntrySym)
 | 
				
			||||||
    return S->body()->getVA<ELFT>();
 | 
					    return S->body()->getVA<ELFT>();
 | 
				
			||||||
  if (Config->EntryAddr != uint64_t(-1))
 | 
					  return Config->EntryAddr;
 | 
				
			||||||
    return Config->EntryAddr;
 | 
					 | 
				
			||||||
  return 0;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template <class ELFT> static uint8_t getELFEncoding() {
 | 
					template <class ELFT> static uint8_t getELFEncoding() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ _start:
 | 
				
			||||||
// CHECK-NEXT:    Section: .rel.plt
 | 
					// CHECK-NEXT:    Section: .rel.plt
 | 
				
			||||||
// CHECK-NEXT:  }
 | 
					// CHECK-NEXT:  }
 | 
				
			||||||
// CHECK-NEXT:  Symbol {
 | 
					// CHECK-NEXT:  Symbol {
 | 
				
			||||||
// CHECK-NEXT:    Name: _start (6)
 | 
					// CHECK-NEXT:    Name: _start (38)
 | 
				
			||||||
// CHECK-NEXT:    Value: 0x11008
 | 
					// CHECK-NEXT:    Value: 0x11008
 | 
				
			||||||
// CHECK-NEXT:    Size: 0
 | 
					// CHECK-NEXT:    Size: 0
 | 
				
			||||||
// CHECK-NEXT:    Binding: Global
 | 
					// CHECK-NEXT:    Binding: Global
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,15 +69,6 @@
 | 
				
			||||||
# CHECK-NEXT:    Section: Undefined
 | 
					# CHECK-NEXT:    Section: Undefined
 | 
				
			||||||
# CHECK-NEXT:  }
 | 
					# CHECK-NEXT:  }
 | 
				
			||||||
# CHECK-NEXT:  Symbol {
 | 
					# 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:    Name: _edata
 | 
				
			||||||
# CHECK-NEXT:    Value: 0x12002
 | 
					# CHECK-NEXT:    Value: 0x12002
 | 
				
			||||||
# CHECK-NEXT:    Size: 0
 | 
					# CHECK-NEXT:    Size: 0
 | 
				
			||||||
| 
						 | 
					@ -104,6 +95,15 @@
 | 
				
			||||||
# CHECK-NEXT:    Other: 0
 | 
					# CHECK-NEXT:    Other: 0
 | 
				
			||||||
# CHECK-NEXT:    Section: Absolute
 | 
					# CHECK-NEXT:    Section: Absolute
 | 
				
			||||||
# CHECK-NEXT:  }
 | 
					# 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: ]
 | 
					# CHECK-NEXT: ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.global _start,_end,_etext,_edata
 | 
					.global _start,_end,_etext,_edata
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
 | 
					# 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: ld.lld %t1 -o %t2 -e entry
 | 
				
			||||||
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
 | 
					# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
 | 
				
			||||||
# RUN: ld.lld %t1 -shared -o %t2 -e entry
 | 
					# RUN: ld.lld %t1 -shared -o %t2 -e entry
 | 
				
			||||||
| 
						 | 
					@ -11,6 +12,7 @@
 | 
				
			||||||
# RUN: ld.lld %t1 -o %t2 -e 0777
 | 
					# RUN: ld.lld %t1 -o %t2 -e 0777
 | 
				
			||||||
# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
 | 
					# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# NOENTRY: Entry: 0x0
 | 
				
			||||||
# SYM: Entry: 0x11000
 | 
					# SYM: Entry: 0x11000
 | 
				
			||||||
# DSO: Entry: 0x1000
 | 
					# DSO: Entry: 0x1000
 | 
				
			||||||
# DEC: Entry: 0x1000
 | 
					# DEC: Entry: 0x1000
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,8 +54,9 @@
 | 
				
			||||||
# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
 | 
					# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SIMPLE:      0000000000000160         .foo    00000000 .hidden _end_sec
 | 
					# 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: 0000000000000160         *ABS*   00000000 _end_sec_abs
 | 
				
			||||||
 | 
					# SIMPLE-NEXT: 0000000000001048         .text   00000000 _start
 | 
				
			||||||
# SIMPLE-NEXT: 0000000000000158         .foo    00000000 begin_foo
 | 
					# SIMPLE-NEXT: 0000000000000158         .foo    00000000 begin_foo
 | 
				
			||||||
# SIMPLE-NEXT: 0000000000000160         .foo    00000000 end_foo
 | 
					# SIMPLE-NEXT: 0000000000000160         .foo    00000000 end_foo
 | 
				
			||||||
# SIMPLE-NEXT: 0000000000000008         .foo    00000000 size_foo_1
 | 
					# SIMPLE-NEXT: 0000000000000008         .foo    00000000 size_foo_1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@
 | 
				
			||||||
# RUN: mkdir -p %t.dir/build
 | 
					# RUN: mkdir -p %t.dir/build
 | 
				
			||||||
# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
 | 
					# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
 | 
				
			||||||
# RUN: cd %t.dir
 | 
					# 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
 | 
					# RUN: cpio -t < repro.cpio | FileCheck %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# CHECK: repro/response.txt
 | 
					# CHECK: repro/response.txt
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,15 +19,6 @@
 | 
				
			||||||
// CHECK-NEXT:     Section: Undefined (0x0)
 | 
					// CHECK-NEXT:     Section: Undefined (0x0)
 | 
				
			||||||
// CHECK-NEXT:   }
 | 
					// CHECK-NEXT:   }
 | 
				
			||||||
// CHECK-NEXT:   Symbol {
 | 
					// 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:     Name: CommonStrong_with_CommonStrong
 | 
				
			||||||
// CHECK-NEXT:     Value:
 | 
					// CHECK-NEXT:     Value:
 | 
				
			||||||
// CHECK-NEXT:     Size: 63
 | 
					// CHECK-NEXT:     Size: 63
 | 
				
			||||||
| 
						 | 
					@ -315,6 +306,15 @@
 | 
				
			||||||
// CHECK-NEXT:     Other: 0
 | 
					// CHECK-NEXT:     Other: 0
 | 
				
			||||||
// CHECK-NEXT:     Section: Undefined
 | 
					// CHECK-NEXT:     Section: Undefined
 | 
				
			||||||
// CHECK-NEXT:   }
 | 
					// 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: ]
 | 
					// CHECK-NEXT: ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.globl _start
 | 
					.globl _start
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,3 @@
 | 
				
			||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 | 
					# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 | 
				
			||||||
# RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
 | 
					# RUN: ld.lld %t -o %t2 2>&1
 | 
				
			||||||
# CHECK: undefined symbol: _start
 | 
					 | 
				
			||||||
# REQUIRES: x86
 | 
					# REQUIRES: x86
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue