Rather than using the defined values for _start
(program entry point) and __executable_start
(base address of the executable at runtime), I'm trying to compute them at runtime. For example
Symbol Address
------ -------
__executable_start 0x55756fb24000
_start 0x55756fb250a0
Shared Object Address
------------- -------
<empty> 0x55756fb24000
linux-vdso.so.1 0x7ffe151ca000
/lib/x86_64-linux-gnu/libc.so.6 0x7f676be40000
/lib64/ld-linux-x86-64.so.2 0x7f676c045000
Computed Symbol Address
--------------- -------
executable_start 0x55756fb24000
start 0x55756fb250a0
However, running the exact same code on godbolt
produces this output:
(notice the main executable base address is 0x0)
Symbol Address
------ -------
__executable_start 0x400000
_start 0x401060
Shared Object Address
------------- -------
<empty> 0x0
linux-vdso.so.1 0x7ffc3a57e000
/lib/x86_64-linux-gnu/libc.so.6 0x7ff83f39f000
/lib64/ld-linux-x86-64.so.2 0x7ff83f593000
Computed Symbol Address
--------------- -------
executable_start (nil)
https://godbolt.org/z/djTYEqYKd
#define _GNU_SOURCE
#include <stdio.h>
#include <link.h>
extern char __executable_start;
extern char _start;
unsigned long executable_start;
void* start;
int callback(struct dl_phdr_info *info, size_t size, void *data)
{
printf("%-32s 0x%lx\n", (!info->dlpi_name[0])?"<empty>":info->dlpi_name, (unsigned long)info->dlpi_addr);
// if name is empty, it's the main executable ...
if (info->dlpi_name[0] == '\0')
{
executable_start = info->dlpi_addr;
}
return 0;
}
int main(int argc, char *argv[])
{
printf("\nSymbol Address\n");
printf("------ -------\n");
printf("__executable_start %p\n", &__executable_start);
printf("_start %p\n", &_start);
printf("\nShared Object Address\n");
printf("------------- -------\n");
dl_iterate_phdr(&callback, NULL);
printf("\nComputed Symbol Address\n");
printf("--------------- -------\n");
printf("executable_start %p\n", (void*)executable_start);
if (executable_start)
{
void *start = (Elf64_Ehdr*)((Elf64_Ehdr*)executable_start)->e_entry;
printf("start %p\n", executable_start + start);
}
return 0;
}
Question
Why does the godbolt
build return 0x0 as the base address?