Constructing an image from segments

ELF program headers describe loadable file regions, virtual addresses, permissions and sizes. Extra memory beyond a segment’s file bytes is zero-filled. Loading is not an undifferentiated copy of all file bytes to identically numbered addresses.

A successful Linux execve replaces the calling process’s image rather than inherently creating another process. Process creation and image loading are separate operations, even when a user experiences both as starting a program.

References: [1] [2]

Cooperation with the dynamic linker

A dynamically linked ELF file can specify an interpreter in PT_INTERP. System loading and that dynamic linker cooperate to map dependencies, perform applicable relocations and prepare execution. This is neither compiler-only work nor a complete reload on every function call.

Some function bindings can be deferred until first use or completed at startup. Linux LD_BIND_NOW requests immediate binding. These choices change when lookup happens without removing interface or address requirements.

References: [2] [3] [4]

Dependency lookup and initialization have rules

The Linux dynamic linker distinguishes dependency paths containing a slash from names requiring search. RUNPATH normally applies to direct dependencies, not every descendant, while $ORIGIN names the relevant executable or shared object’s directory rather than the current working directory.

Mapped and relocated shared objects can also run initializers. ELF rules describe dependencies and initialization arrays, but dependency cycles need not have a defined order. Finding files, loading images, completing initialization and application success remain separate states.

References: [4] [3]