I learned from this link Why is address 0x400000 chosen as a start of text segment in x86_64 ABI? that 64-bit Linux process start address by default should be 0x400000, but on my Ubuntu, I only found my bash
process starts from a very high base address (0x55971cea6000).
Any one knows why? and how does dynamic linker choose the start address for a 64-bit process?
$ uname -r 5.15.0-25-generic $ cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=22.04 DISTRIB_CODENAME=jammy DISTRIB_DESCRIPTION="Ubuntu 22.04 LTS" ... $ file /usr/bin/bash /usr/bin/bash: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=33a5554034feb2af38e8c75872058883b2988bc5, for GNU/Linux 3.2.0, stripped $ ld -verbose | grep -i text-segment PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS; $ cat maps 55971ce77000-55971cea6000 r--p 00000000 08:02 153 /usr/bin/bash 55971cea6000-55971cf85000 r-xp 0002f000 08:02 153 /usr/bin/bash 55971cf85000-55971cfbf000 r--p 0010e000 08:02 153 /usr/bin/bash 55971cfc0000-55971cfc4000 r--p 00148000 08:02 153 /usr/bin/bash 55971cfc4000-55971cfcd000 rw-p 0014c000 08:02 153 /usr/bin/bash 55971cfcd000-55971cfd8000 rw-p 00000000 00:00 0 ... $ readelf -h /usr/bin/bash 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 (Position-Independent Executable file) Machine: Advanced Micro Devices X86-64 Version: 0x1 Entry point address: 0x32eb0 Start of program headers: 64 (bytes into file) Start of section headers: 1394600 (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: 30 Section header string table index: 29
Advertisement
Answer
I learned from this link Why is address 0x400000 chosen as a start of text segment in x86_64
That address is used for executables (ELF
type ET_EXEC
).
I only found my bash process starts from a very high base address (0x55971cea6000). Any one knows why?
Because your bash
is (newer) position-independent executable (ELF
type ET_DYN
). It behaves much like a shared library, and is relocated to random address at runtime.
The 0x55971cea6000
address you found will vary from one execution to another. In contrast, ET_EXEC
executables can only run correctly when loaded at their “linked at” address (typically 0x400000
).
how does dynamic linker choose the start address for a 64-bit process?
The dynamic linker doesn’t choose the start address of the executable — the kernel does (by the time the dynamic linker starts running, the executable has already been mmap
ed into memory).
The kernel looks at the .e_type
in the ELF
header and .p_vaddr
field of the first program header and goes from there. IFF .e_type == ET_EXEC
, then the kernel maps executable segments at their .p_vaddr
addresses. For ET_DYN
, if ASLR is in effect, the kernel performs mmap
s at a random address.