diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index bac8382f477d..b28877e3e22c 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -58,6 +58,7 @@ struct Configuration { bool ZNow = false; ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; + uint64_t EntryAddr = -1; }; extern Configuration *Config; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 53be66c55f11..2d7d75ce39ac 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -201,7 +201,11 @@ template void LinkerDriver::link(opt::InputArgList &Args) { // Add entry symbol. if (Config->Entry.empty()) Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start"; - Config->EntrySym = Symtab.addUndefined(Config->Entry); + + // Set either EntryAddr (if S is a number) or EntrySym (otherwise). + StringRef S = Config->Entry; + if (S.getAsInteger(0, Config->EntryAddr)) + Config->EntrySym = Symtab.addUndefined(S); // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol // is magical and is used to produce a R_386_GOTPC relocation. diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 4307b48f0344..4861dc1729d1 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -648,9 +648,12 @@ template void Writer::writeHeader() { EHdr->e_type = Config->Shared ? ET_DYN : ET_EXEC; EHdr->e_machine = FirstObj.getEMachine(); EHdr->e_version = EV_CURRENT; - if (Config->EntrySym) + if (Config->EntrySym) { if (auto *E = dyn_cast>(Config->EntrySym->repl())) EHdr->e_entry = getSymVA(*E); + } else if (Config->EntryAddr != uint64_t(-1)) { + EHdr->e_entry = Config->EntryAddr; + } EHdr->e_phoff = sizeof(Elf_Ehdr); EHdr->e_shoff = SectionHeaderOff; EHdr->e_ehsize = sizeof(Elf_Ehdr); diff --git a/lld/test/elf2/entry.s b/lld/test/elf2/entry.s index b933560942a9..5f85f9e480b5 100644 --- a/lld/test/elf2/entry.s +++ b/lld/test/elf2/entry.s @@ -2,5 +2,16 @@ # RUN: not ld.lld2 %t1 -o %t2 # RUN: ld.lld2 %t1 -o %t2 -e _end -.globl _end; +# RUN: ld.lld2 %t1 -o %t2 -e 4096 +# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s +# RUN: ld.lld2 %t1 -o %t2 -e 0xcafe +# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=HEX %s +# RUN: ld.lld2 %t1 -o %t2 -e 0777 +# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s + +# DEC: Entry: 0x1000 +# HEX: Entry: 0xCAFE +# OCT: Entry: 0x1FF + +.globl _end _end: