Search code examples
linuxelf

Why does not entry point address start at 0x400000


On Ubuntu 20.10 x86_64

my sample code:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("helloworld\n");
    return 0;
}

Build: gcc -o test test.c

Show entry point address:

readelf -h ./test

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              DYN (Shared object file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x1060
  Start of program headers:          64 (bytes into file)
  Start of section headers:          14824 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         31
  Section header string table index: 30

Why does entry point address start at 0x1060 ? not 0x40000 ?


Solution

  • The binary is relocatable, and the segments have been packed against each other. The .text segment starts at 0x1050 in the file, and the entry point is relative to its location in the file, not the location it will ultimately be loaded.

    For a non-relocatable file try readelf -h /usr/lib/klibc/bin/sh. This file is simpler in a number of ways, including not using an interpreter but actually being loaded as-is by the kernel.

    We're not in x86 anymore. Relocatable binaries are the default for everything now, not just shared libraries. It's no longer a great pain to do relocatable stuff, and in a certain way it's cheaper than non-relocatable now because we have to emit the vector table anyway because the processor doesn't have 64 bit displacement.

    As Nate Eldredge points out, compiling with -no-pie yields a non-relocatable binary, and I have verified the expected start address appears.