forked from OSchip/llvm-project
Allow linker-script-defined entry symbols.
Previously, we were checking the existence of an entry symbol too early. It was done before the linker script processor creates symbols defined in scripts. Fixes bug 30743. llvm-svn: 284676
This commit is contained in:
parent
40379746c8
commit
8da7aa0894
|
@ -69,7 +69,6 @@ struct VersionDefinition {
|
|||
// and such fields have the same name as the corresponding options.
|
||||
// Most fields are initialized by the driver.
|
||||
struct Configuration {
|
||||
Symbol *EntrySym = nullptr;
|
||||
InputFile *FirstElf = nullptr;
|
||||
llvm::StringMap<uint64_t> SectionStartMap;
|
||||
llvm::StringRef DynamicLinker;
|
||||
|
|
|
@ -695,22 +695,21 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
|
|||
// Add the start symbol.
|
||||
// It initializes either Config->Entry or Config->EntryAddr.
|
||||
// Note that AMDGPU binaries have no entries.
|
||||
bool HasEntryAddr = false;
|
||||
if (!Config->Entry.empty()) {
|
||||
// It is either "-e <addr>" or "-e <symbol>".
|
||||
HasEntryAddr = !Config->Entry.getAsInteger(0, Config->EntryAddr);
|
||||
if (!Config->Entry.getAsInteger(0, Config->EntryAddr))
|
||||
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 (!HasEntryAddr && !Config->Entry.empty()) {
|
||||
if (Symtab.find(Config->Entry))
|
||||
Config->EntrySym = Symtab.addUndefined(Config->Entry);
|
||||
else
|
||||
warn("entry symbol " + Config->Entry + " not found, assuming 0");
|
||||
}
|
||||
|
||||
// If an object file defining the entry symbol is in an archive file,
|
||||
// extract the file now.
|
||||
if (Symtab.find(Config->Entry))
|
||||
Symtab.addUndefined(Config->Entry);
|
||||
|
||||
if (HasError)
|
||||
return; // There were duplicate symbols or incompatible files
|
||||
|
|
|
@ -225,8 +225,7 @@ template <class ELFT> void elf::markLive() {
|
|||
};
|
||||
|
||||
// Add GC root symbols.
|
||||
if (Config->EntrySym)
|
||||
MarkSymbol(Config->EntrySym->body());
|
||||
MarkSymbol(Symtab<ELFT>::X->find(Config->Entry));
|
||||
MarkSymbol(Symtab<ELFT>::X->find(Config->Init));
|
||||
MarkSymbol(Symtab<ELFT>::X->find(Config->Fini));
|
||||
for (StringRef S : Config->Undefined)
|
||||
|
|
|
@ -1278,9 +1278,12 @@ template <class ELFT> void Writer<ELFT>::setPhdrs() {
|
|||
}
|
||||
|
||||
template <class ELFT> static typename ELFT::uint getEntryAddr() {
|
||||
if (Symbol *S = Config->EntrySym)
|
||||
return S->body()->getVA<ELFT>();
|
||||
return Config->EntryAddr;
|
||||
if (Config->Entry.empty())
|
||||
return Config->EntryAddr;
|
||||
if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry))
|
||||
return B->getVA<ELFT>();
|
||||
warn("entry symbol " + Config->Entry + " not found, assuming 0");
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ELFT> static uint8_t getELFEncoding() {
|
||||
|
|
|
@ -75,6 +75,14 @@
|
|||
# ENTRY-OVERLOAD: Name: _start
|
||||
# ENTRY-OVERLOAD-NEXT: Value: [[ENTRY]]
|
||||
|
||||
# The entry symbol can be a linker-script-defined symbol.
|
||||
# RUN: echo "ENTRY(foo); foo = 1;" > %t.script
|
||||
# RUN: ld.lld -o %t2 %t.script %t
|
||||
# RUN: llvm-readobj -file-headers -symbols %t2 | \
|
||||
# RUN: FileCheck -check-prefix=ENTRY-SCRIPT %s
|
||||
|
||||
# ENTRY-SCRIPT: Entry: 0x1
|
||||
|
||||
# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) /*/*/ GROUP(\"%t\" )" > %t.script
|
||||
# RUN: ld.lld -o %t2 %t.script
|
||||
# RUN: llvm-readobj %t2 > /dev/null
|
||||
|
|
Loading…
Reference in New Issue