0

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?

vengy
  • 1,548
  • 10
  • 18

0 Answers0