Search notes:

ELF

Object files

Object files are created by the assembler and/or link editor.

Types of object files

There are three main types of object files
Relocatable file Code and data, used to link with other object files to produce an executable or shared object file.
Executable file A program that can be executed. The file specifies how exec creates a program's process image.
Shared object file Code and data. It is used to 1) either by the link editor (ld) to create other object files by combining it with other relocatable and shared objects, 2) or the dynamic linker combines it with an executable file when creating the process image.

Structure of an object file

An object file consists of
  • ELF header, which describes how the object file is organized. See struct Elf64_Ehdr.
  • Program header table, which tells the system how to create a process image. Optional for relocatable and shared object files (See struct Elf64_Phdr)
  • Sections (relocatable and shared object files)
  • Segments (executable file)
  • Section header table, which describes the sections (every section has an entry in the section header table). Optional for executable files, required when the object file is used for linking.

Sections vs Segments

Sections store the data that is required for linking and relocation.
Segments contain the information that is needed when the file is executed.
A segment contains one or more sections.
See also struct Elf64_Shdr.

Special Sections

.bss SHT_NOBITS SHF_ALLOC + SHF_WRITE Uninitialized data that occupies no space in the object file but is initialized with 0 when the program is executed. Compare with .data
.comment SHT_PROGBITS Version control information
.data SHT_PROGBITS SHF_ALLOC + SHF_WRITE Initialized data. Compare with .bss
.data1 SHT_PROGBITS SHF_ALLOC + SHF_WRITE Similar to .data?
.debug SHT_PROGBITS Information for symbolic debugging. Format is unspecified. See also .line
.dynamic SHT_DYNAMIC SHF_ALLOC + SHF_WRITE Information for dynamic linking. Whether SHF_WRITE is specified is processor specific.
.dynstr SHT_STRTAB SHF_ALLOC Strings needed for dynamic linking (typically strings that represent the names associated with symbol table entries)
.dynsym SHT_DYNSYM SHF_ALLOC The dynamic symbol table
.fini SHT_PROGBITS SHF_ALLOC + SHF_EXECINSTR Code that is executed when the program finishes. Compare with .init
.got SHT_PROGBITS see below Global offset table
.hash SHT_HASH SHF_ALLOC Symbol hash table
.init SHT_PROGBITS SHF_ALLOC + SHF_EXECINSTR Compare with .fini
.interp SHT_PROGBITS SHF_ALLOC The path of the program interpreter. SHF_ALLOC only set if the file has a loadable segment that includes the section.
.line SHT_PROGBITS Line number information for symbolic debugging. Format is unspecified. See also .debug
.note SHT_NOTE
.plt SHT_PROGBITS see below Procedure linkage table.
.rel<name> SHT_REL see below Relocation information. <name> specifies the section to which the relocation table is applied (for example .rel.text)
.rela<name> SHT_RELA see below
.rodata SHT_PROGBITS SHF_ALLOC Read-only data
.rodata1 SHT_PROGBITS SHF_ALLOC
.shstrtab SHT_STRTAB Section names
.strtab SHT_STRTAB SHF_ALLOC Strings, typically associated with symbol table entries. SHF_ALLOC is only set if the file has a loadable segment that includes the symbol string table.
.symtab SHT_SYMTAB SHF_ALLOC Symbol table. SHF_ALLOC is only set if the file has a loadable segment that includes the symbol table.
.text SHT_PROGBITS SHF_ALLOC + SHF_EXECINSTR The text are the executable instruactions of the program.
.eh_frame ? ? GCC specific. When compiling a C program with GCC, the .eh_frame section is produced unless the -fno-asynchronous-unwind-tables option is used (C++ also -fno-exceptions?)

Base address

(When executed?): Executable and shared object files have a base address which is the lowest virtual address associated withthe memory image of the program's object file.
Base addresses are used to relocate the memory image of the program during dynamic linking.
During execution, the base address is calculated from three values:
  • Memory load address,
  • Maximum page size
  • Lowest virtual address of a program's loadable segment

ELF Interpreter

When the kernel executes an ELF executable, it maps the executable into userspace memory and searches for section named .interp
If this section (which stores the path ofan interpreter) is present, the intepreter is also mapped into userspace memory and control is passed to it.
The interpreter then performs the linking required to be able to start the program.

Some interpreters

The source file tcc.h of the TinyCC compiler suggests that there are different ELF interpreters depending on the environment:
/* name of ELF interpreter */
#ifndef CONFIG_TCC_ELFINTERP
# if TARGETOS_FreeBSD
#  define CONFIG_TCC_ELFINTERP "/libexec/ld-elf.so.1"
# elif TARGETOS_FreeBSD_kernel
#  if defined(TCC_TARGET_X86_64)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-kfreebsd-x86-64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld.so.1"
#  endif
# elif TARGETOS_DragonFly
#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld-elf.so.2"
# elif TARGETOS_NetBSD
#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.elf_so"
# elif TARGETOS_OpenBSD
#  define CONFIG_TCC_ELFINTERP "/usr/libexec/ld.so"
# elif defined __GNU__
#  define CONFIG_TCC_ELFINTERP "/lib/ld.so"
# elif defined(TCC_TARGET_PE)
#  define CONFIG_TCC_ELFINTERP "-"
# elif defined(TCC_UCLIBC)
#  define CONFIG_TCC_ELFINTERP "/lib/ld-uClibc.so.0" /* is there a uClibc for x86_64 ? */
# elif defined TCC_TARGET_ARM64
#  if defined(TCC_MUSL)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-aarch64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux-aarch64.so.1"
#  endif
# elif defined(TCC_TARGET_X86_64)
#  if defined(TCC_MUSL)
#   define CONFIG_TCC_ELFINTERP "/lib/ld-musl-x86_64.so.1"
#  else
#   define CONFIG_TCC_ELFINTERP "/lib64/ld-linux-x86-64.so.2"
#  endif
# elif defined(TCC_TARGET_RISCV64)
#  define CONFIG_TCC_ELFINTERP "/lib/ld-linux-riscv64-lp64d.so.1"
# elif !defined(TCC_ARM_EABI)
#  if defined(TCC_MUSL)
#   if defined(TCC_TARGET_I386)
#     define CONFIG_TCC_ELFINTERP "/lib/ld-musl-i386.so.1"
#    else
#     define CONFIG_TCC_ELFINTERP "/lib/ld-musl-arm.so.1"
#    endif
#  else
#   define CONFIG_TCC_ELFINTERP "/lib/ld-linux.so.2"
#  endif
# endif

TODO

/proc/$PID/auxv

See also

readelf shows information stored in an ELF file.
Linux kernel source file fs/binfmt_elf.c with functions to load ELF format executables as used on SVr4 machines.
elf.h defines standard ELF types, structures and macros.
sysdeps/x86_64/elf/start.S contains x86-64 ABI compliant startup code.
DWARF
Documentation/userspace-api/ELF.rst documents some Linux-specifici ELF idiosyncrasies.

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/Linux/EL...', 1758209552, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/Linux/ELF/index(204): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78