LD arch/x86/realmode/rm/realmode.elf
ld.lld: warning: cannot find entry symbol _start; defaulting to 0x1000
This is with a few workarounds in place to link with LLD, so I wouldn't be surprise if once they're fixed, this quickly becomes unreproducible.
lld/ELF/Writer.cpp:
// The entry point address is chosen in the following ways.
//
// 1. the '-e' entry command-line option;
// 2. the ENTRY(symbol) command in a linker control script;
// 3. the value of the symbol _start, if present;
// 4. the number represented by the entry symbol, if it is a number;
// 5. the address of the first byte of the .text section, if present;
// 6. the address 0.
static uint64_t getEntryAddr() {
// Case 1, 2 or 3
if (Symbol *B = Symtab->find(Config->Entry))
return B->getVA();
// Case 4
uint64_t Addr;
if (to_integer(Config->Entry, Addr))
return Addr;
// Case 5
if (OutputSection *Sec = findSection(".text")) {
if (Config->WarnMissingEntry)
warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
utohexstr(Sec->Addr));
return Sec->Addr;
}
// Case 6
if (Config->WarnMissingEntry)
warn("cannot find entry symbol " + Config->Entry +
"; not setting start address");
return 0;
}
So I assume the kernel does one of the above for arm64, which is why we don't see this warning there. Maybe we just need to do that for x86_64 as well?
Or just disable the warning if the resulting code is still correct.
$ nm vmlinux | grep 'T _start$'
$ readelf -t vmlinux | grep text
[ 1] .text
PROGBITS PROGBITS ffffffff81000000 0000000000200000 0
0000000000e01941 0000000000000000 0 4096
[0000000000000006]: ALLOC, EXEC
So maybe just best to disable the warning?
lld/ELF/Driver.cpp has:
Config->WarnMissingEntry =
(!Config->Entry.empty() || (!Config->Shared && !Config->Relocatable));
but I'm not sure how to set Config->Entry.empty(). -e '' just presents the error:
ld.lld: error: cannot find linker script -e
cc @rui314 @GeorgiiR
Is it possible to get the LLD --reproduce file for this?
(Actually, we use the getEntryAddr() value for ELF file header:
https://github.com/llvm-mirror/lld/blob/master/ELF/Writer.cpp#L2348
I wonder what is the GNU linkers behavior is, I would expect to see a warning too).
I guess this needs an addition of -z max-page-size=4096 (Hex for 0x1000) in LDFLAGS_realmode.elf line in arch/x86/realmode/rm/Makefile.
UPDATE: This did not work.
By the way, I can still reproduce this warning with -O2, linux-next-next-20190730, clang version 10.0.0 (366783) and lld.
For the config and buildlog see #623
Still occurs with kernel 5.3.1 and LLVM/clang-9.0.0 on x86_64
BUILDSTDERR: ld.lld: warning: -r and --gc-sections may not be used together, disabling --gc-sections
BUILDSTDERR: ld.lld: warning: -r and --icf may not be used together, disabling --icf
LD arch/x86/realmode/rm/realmode.elf
BUILDSTDERR: ld.lld: warning: cannot find entry symbol _start; defaulting to 0x1000
RELOCS arch/x86/realmode/rm/realmode.relocs
arch/x86/realmode/rm/Makefile:
49 LDFLAGS_realmode.elf := -m elf_i386 --emit-relocs -T
50 CPPFLAGS_realmode.lds += -P -C -I$(objtree)/$(obj)
Sounds like maybe an ENTRY(<symbol>) in arch/x86/realmode/rm/realmode.lds.S would help?
$ make CC=clang -j71 defconfig
$ make CC=clang -j71
$ readelf -h arch/x86/realmode/rm/realmode.elf | grep Entry
Entry point address: 0x1000
I suspect this needs to be backported to 5.4, and 4.19 at least.
Most helpful comment
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?id=6a181e333954a26f46596b36f82abd14743570fd