Sections vs Segments in the ELF Format
I watched a really great video about writing an ELF file from scratch, byte by byte, to understand the structure of the file format. It kind of left me wanting a bit more, since I still wasn’t sure about some concepts like the difference between sections and segments. I mean, they’re synonyms! Why did they choose that!? Maybe runtime information vs linktime information? Anyways…
An ELF file is made up of a few parts. There is an ELF header, ELF Program headers, ELF Section headers, then just binary data. The ELF header comes first. It doesn’t matter what comes next, since you specify where program and section header tables are in the ELF header. By table, I just mean a sequence of structures, each of which are the same size. A program header table is just a sequence of struct Elf64_Phdr, for example.
ELF Segments are a runtime notion. They are portions of the ELF file that get mapped from the ELF file to memory when you start up the program. An ELF Segment is simply a contiguous block of the ELF file described by one ELF Program header. The ELF Program headers are used by the kernel to map the portion of the file that the program headers reference to memory at runtime.
An ELF Section is contiguous block of the ELF file that is described by an ELF Section header, used for linkers, debuggers etc. The memory ELF Sections reference in the ELF file can also be part of segments. ELF Sections headers have nothing to do with runtime, in fact, you can strip all the section header information with:
strip —strip-section-headers ./executableIf you run that stripped executable, it will run perfectly.
An ELF Section can be code, data, or information about the code, like symbols used by linkers. Here is an example of writing an object file, byte by byte. It includes the ELF header, section headers, a symbol table, code, a section header string table and a string table. All of that allows gcc to link with a main.c that calls the function described in that object file.
I only really understood the format once I wrote it out myself. I really recommend watching the elf by hand video, then writing an object file in a similar fashion and get gcc to link with it. Doing it in C is really handy, since you can include elf.h and that header comes with all the structs you need. If you don’t know any assembly, I included print function at print_string.s and you can use the following to get the binary form:
as print_string.s -c -o print_string.o
objdump -S print_string.oThis is an example object file layout:
Note that you can’t run this file, because the OS has no idea how to map code and data to memory when the program starts.
Try writing it by hand using elf.h! It can be annoying to get all the sections right if you do do it by hand, so good luck.



