Skip to main content

Module elf

Module elf 

Source
Expand description

ELF64, little-endian, for x86-64 and AArch64: relocatable objects (ET_REL) and static executables (ET_EXEC).

§What the writer produces

A relocatable object holds the object’s sections in order (section header i + 1 is the model’s section i), then one .rela<name> section per section with relocations, an empty .note.GNU-stack marking whether the stack must be executable, .symtab (with .symtab_shndx when a section index exceeds 16 bits), .strtab, and .shstrtab. The symbol table starts with the null symbol, then one STT_SECTION symbol for each section a relocation targets directly, then the object’s local symbols, then the rest, each group in model order; sh_info is the index of the first non-local symbol. String tables share the bytes of names that are suffixes of other names. Section counts and indices past 0xff00 use ELF’s extended numbering.

An executable maps its file headers read-only on the page(s) just below its lowest section, then one PT_LOAD per run of sections with the same permissions, each aligned to the page size with its file offset congruent to its address. A PT_GNU_STACK header marks the stack non-executable unless executable_stack is set. There is no interpreter and no dynamic section: the program is fully static. Section headers and a symbol table are written too, so tools can name what they disassemble.

The output depends only on the object: the same object always gives the same bytes.

§What the reader accepts

Exactly the files the model can represent: ELF64 little-endian ET_REL or ET_EXEC for x86-64 or AArch64, with SHT_RELA relocations of the kinds in X86_64Reloc and Aarch64Reloc. It drops what carries no meaning in the model (STT_SECTION symbols, which become RelocationTarget::Section; LLVM’s .llvm_addrsig hint) and refuses everything else it cannot represent exactly (COMDAT groups, SHT_REL, dynamic sections, unknown section, symbol, or relocation types) with a ReadError.

Functions§

code_address
The address executable loads its code at: one page above 4 MiB (0x40_0000), the traditional base of a static Linux executable, with the file headers on the page(s) below it.
executable
Builds a static executable from machine code: the one-call path to a program the OS can run.
read
Reads an ELF file into an object, with the default Limits.
read_with_limits
Reads an ELF file into an object, with the given Limits.
write
Writes an object as an ELF file and returns the bytes.
write_into
Writes an object as an ELF file, appending the bytes to out, so one buffer can be reused across many objects. On error, out is left as it was.