diff options
| author | Rui Ueyama <ruiu@google.com> | 2015-10-14 22:20:57 +0000 |
|---|---|---|
| committer | Rui Ueyama <ruiu@google.com> | 2015-10-14 22:20:57 +0000 |
| commit | 2b675074feda2e8d643909c5fa9ab2bcb67c8581 (patch) | |
| tree | c439f573e4bbf0caf20c0366bbb61197883d653f | |
| parent | f9e0b253ad605a429526b54ffdfcf121deaf082c (diff) | |
| download | bcm5719-llvm-2b675074feda2e8d643909c5fa9ab2bcb67c8581.tar.gz bcm5719-llvm-2b675074feda2e8d643909c5fa9ab2bcb67c8581.zip | |
ELF2: Support --entry=<addr>.
If an argument for --entry is a number, that's not a symbol name but
an absolute address. If that's the case, the address is directly set
to ELF header's e_entry.
llvm-svn: 250334
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 6 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 5 | ||||
| -rw-r--r-- | lld/test/elf2/entry.s | 13 |
4 files changed, 22 insertions, 3 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index bac8382f477..b28877e3e22 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 53be66c55f1..2d7d75ce39a 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -201,7 +201,11 @@ template <class ELFT> 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 4307b48f034..4861dc1729d 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -648,9 +648,12 @@ template <class ELFT> void Writer<ELFT>::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<ELFSymbolBody<ELFT>>(Config->EntrySym->repl())) EHdr->e_entry = getSymVA<ELFT>(*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 b933560942a..5f85f9e480b 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: |

