Topics Top articles New articles Updated articles Top users New users New discussions Top discussions New comments+ New article
Running:outputs:
readelf -h hello_world.o
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: REL (Relocatable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 64 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 64 (bytes)
Number of section headers: 7
Section header string table index: 3
Running:outputs:
readelf -h hello_world.out
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: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x4000b0
Start of program headers: 64 (bytes into file)
Start of section headers: 272 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 2
Size of section headers: 64 (bytes)
Number of section headers: 6
Section header string table index: 3
Bytes in the object file:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 01 00 3e 00 01 00 00 00 00 00 00 00 00 00 00 00 |..>.............|
00000020 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000030 00 00 00 00 40 00 00 00 00 00 40 00 07 00 03 00 |....@.....@.....|
Executable:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 3e 00 01 00 00 00 b0 00 40 00 00 00 00 00 |..>.......@.....|
00000020 40 00 00 00 00 00 00 00 10 01 00 00 00 00 00 00 |@...............|
00000030 00 00 00 00 40 00 38 00 02 00 40 00 06 00 03 00 |....@.8...@.....|
Structure represented:
# define EI_NIDENT 16
typedef struct {
unsigned char e_ident[EI_NIDENT];
Elf64_Half e_type;
Elf64_Half e_machine;
Elf64_Word e_version;
Elf64_Addr e_entry;
Elf64_Off e_phoff;
Elf64_Off e_shoff;
Elf64_Word e_flags;
Elf64_Half e_ehsize;
Elf64_Half e_phentsize;
Elf64_Half e_phnum;
Elf64_Half e_shentsize;
Elf64_Half e_shnum;
Elf64_Half e_shstrndx;
} Elf64_Ehdr;
Manual breakdown:
- 0 0:
EI_MAG
=7f 45 4c 46
=0x7f 'E', 'L', 'F'
: ELF magic number - 0 4:
EI_CLASS
=02
=ELFCLASS64
: 64 bit elf - 0 5:
EI_DATA
=01
=ELFDATA2LSB
: little endian data - 0 6:
EI_VERSION
=01
: format version - 0 7:
EI_OSABI
(only in 2003 Update) =00
=ELFOSABI_NONE
: no extensions. - 0 8:
EI_PAD
= 8x00
: reserved bytes. Must be set to 0. - 1 0:
e_type
=01 00
= 1 (big endian) =ET_REl
: relocatable formatOn the executable it is02 00
forET_EXEC
.Another important possibility for the executable isET_DYN
for PIE executables and shared libraries.ET_DYN
tells the Linux kernel that the code is position independent, and can loaded at a random memory location with ASLR. - 1 2:
e_machine
=3e 00
=62
=EM_X86_64
: AMD64 architecture - 1 4:
e_version
=01 00 00 00
: must be 1 - 1 8:
e_entry
= 8x00
: execution address entry point, or 0 if not applicable like for the object file since there is no entry point.On the executable, it isb0 00 40 00 00 00 00 00
. The kernel puts the RIP directly on that value when executing. It can be configured by the linker script or-e
. But it will segfault if you set it too low: stackoverflow.com/questions/2187484/why-is-the-elf-execution-entry-point-virtual-address-of-the-form-0x80xxxxx-and-n - 2 0:
e_phoff
= 8x00
: program header table offset, 0 if not present.40 00 00 00
on the executable, i.e. it starts immediately after the ELF header. - 2 8:
e_shoff
=40
7x00
=0x40
: section header table file offset, 0 if not present. - 3 0:
e_flags
=00 00 00 00
Arch specific.i386
docs say:The Intel386 architecture defines no flags; so this member contains zero.
- 3 4:
e_ehsize
=40 00
: size of this elf header. TODO why this field needed? Isn't the size fixed? - 3 6:
e_phentsize
=00 00
: size of each program header, 0 if not present.38 00
on executable: it is 56 bytes long - 3 8:
e_phnum
=00 00
: number of program header entries, 0 if not present.02 00
on executable: there are 2 entries. - 3 A:
e_shentsize
ande_shnum
=40 00 07 00
: section header size and number of entries - 3 E:
e_shstrndx
(Section Header STRing iNDeX
) =03 00
: index of the.shstrtab
section.
Stack Overflow maximum 200 daily reputation limit by Ciro Santilli 35 Updated 2025-01-10 +Created 1970-01-01
Why. Why. Why is there no limit to how much I can help, but there is a limit to how many thanks I can get?
At most, limit it to a single answer to avoid highly publicized events, e.g. an answer being shared on Reddit. But across answers? It makes no sense.
The two ways main ways to overcome this limit are the 15 point answer accept reputation and bounties.
200 reputation per day works out 73k a year BTW.
Contains a lot of different flag masks.
Determines if an executable is a position independent executable (PIE).
Seems to be informational only, since not used by Linux kernel 5.0 or glibc 2.29.
file
5.36 however does use it to display file type as explained at: stackoverflow.com/questions/34519521/why-does-gcc-create-a-shared-object-instead-of-an-executable-binary-according-to/55704865#55704865Only appears in the executable.
Contains information of how the executable should be put into the process virtual memory.
The executable is generated from object files by the linker. The main jobs that the linker does are:
- determine which sections of the object files will go into which segments of the executable.In Binutils, this comes down to parsing a linker script, and dealing with a bunch of defaults.You can get the linker script used with
ld --verbose
, and set a custom one withld -T
. - do relocation according to the
.rela.text
section. This depends on how the multiple sections are put into memory.
readelf -l hello_world.out
gives:Elf file type is EXEC (Executable file)
Entry point 0x4000b0
There are 2 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
LOAD 0x0000000000000000 0x0000000000400000 0x0000000000400000
0x00000000000000d7 0x00000000000000d7 R E 200000
LOAD 0x00000000000000d8 0x00000000006000d8 0x00000000006000d8
0x000000000000000d 0x000000000000000d RW 200000
Section to Segment mapping:
Segment Sections...
00 .text
01 .data
On the ELF header, and:
e_phoff
, e_phnum
and e_phentsize
told us that there are 2 program headers, which start at 0x40
and are 0x38
bytes long each, so they are:00000040 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 |................|
00000050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 |..@.......@.....|
00000060 d7 00 00 00 00 00 00 00 d7 00 00 00 00 00 00 00 |................|
00000070 00 00 20 00 00 00 00 00 |.. ..... |
00000070 01 00 00 00 06 00 00 00 | ........|
00000080 d8 00 00 00 00 00 00 00 d8 00 60 00 00 00 00 00 |..........`.....|
00000090 d8 00 60 00 00 00 00 00 0d 00 00 00 00 00 00 00 |..`.............|
000000a0 0d 00 00 00 00 00 00 00 00 00 20 00 00 00 00 00 |.......... .....|
Structure represented www.sco.com/developers/gabi/2003-12-17/ch5.pheader.html:
typedef struct {
Elf64_Word p_type;
Elf64_Word p_flags;
Elf64_Off p_offset;
Elf64_Addr p_vaddr;
Elf64_Addr p_paddr;
Elf64_Xword p_filesz;
Elf64_Xword p_memsz;
Elf64_Xword p_align;
} Elf64_Phdr;
Breakdown of the first one:
- 40 0:
p_type
=01 00 00 00
=PT_LOAD
: this is a regular segment that will get loaded in memory. - 40 4:
p_flags
=05 00 00 00
= execute and read permissions. No write: we cannot modify the text segment. A classic way to do this in C is with string literals: stackoverflow.com/a/30662565/895245 This allows kernels to do certain optimizations, like sharing the segment amongst processes. - 40 8:
p_offset
= 8x00
TODO: what is this? Standard says:This member gives the offset from the beginning of the file at which the first byte of the segment resides.
But it looks like offsets from the beginning of segments, not file? - 50 0:
p_vaddr
=00 00 40 00 00 00 00 00
: initial virtual memory address to load this segment to - 50 8:
p_paddr
=00 00 40 00 00 00 00 00
: unspecified effect. Intended for systems in which physical addressing matters. TODO example? - 60 0:
p_filesz
=d7 00 00 00 00 00 00 00
: size that the segment occupies in memory. If smaller thanp_memsz
, the OS fills it with zeroes to fit when loading the program. This is how BSS data is implemented to save space on executable files. i368 ABI says onPT_LOAD
:The bytes from the file are mapped to the beginning of the memory segment. If the segment’s memory size (p_memsz) is larger than the file size (p_filesz), the ‘‘extra’’ bytes are defined to hold the value 0 and to follow the segment’s initialized area. The file size may not be larger than the memory size.
- 60 8:
p_memsz
=d7 00 00 00 00 00 00 00
: size that the segment occupies in memory - 70 0:
p_align
=00 00 20 00 00 00 00 00
: 0 or 1 mean no alignment required. TODO why is this required? Why not just usep_addr
directly, and get that right? Docs also say:p_vaddr should equal p_offset, modulo p_align
The second segment (
.data
) is analogous. TODO: why use offset 0x0000d8
and address 0x00000000006000d8
? Why not just use 0
and 0x00000000006000d8
?Then the:section of the
Section to Segment mapping:
readelf
tells us that:- 0 is the
.text
segment. Aha, so this is why it is executable, and not writable - 1 is the
.data
segment.
TODO where does this information come from? stackoverflow.com/questions/23018496/section-to-segment-mapping-in-elf-files
Ciro Santilli does the same via Google searches and Twitter/Reddit searches for himself, you can't invent anything new nowadays:
Kibo was known for his high-volume but thoughtful posts, but achieved Usenet celebrity circa 1991 by writing a small script to grep his entire Usenet feed for instances of his name, and then answering personally whenever and wherever he was mentioned, giving the illusion that he was personally reading the entire feed.
This is good. But it misses some key operations, so much so that makes Ciro not want to learn/use it daily.
The cheapest and most resilient way to publish text content humanity has achieved so far.
Some tests:
- github.com/cirosantilli/jekyll-cheat: cirosantilli.com/jekyll-cheat
- Test with a
.nojekyll
file. - github.com/cirosantilli/test-gh-pages-min: cirosantilli.com/test-gh-pages-min. Minimal version of the above.
The heart/main innovation of GitHub!
Generate a minimal test repo. You should get in the habit of doing this to test stuff out.
#!/usr/bin/env bash
mkdir git-tips
cd git-tips
git init
for i in 1 2 3 4 5; do
echo $i > f
git add f
git commit -m $i
done
git checkout HEAD~2
git checkout -b my-feature
for i in 6 7; do
echo $i > f
git add f
git commit -m $i
done
Pinned article: ourbigbook/introduction-to-the-ourbigbook-project
Welcome to the OurBigBook Project! Our goal is to create the perfect publishing platform for STEM subjects, and get university-level students to write the best free STEM tutorials ever.
Everyone is welcome to create an account and play with the site: ourbigbook.com/go/register. We belive that students themselves can write amazing tutorials, but teachers are welcome too. You can write about anything you want, it doesn't have to be STEM or even educational. Silly test content is very welcome and you won't be penalized in any way. Just keep it legal!
We have two killer features:
- topics: topics group articles by different users with the same title, e.g. here is the topic for the "Fundamental Theorem of Calculus" ourbigbook.com/go/topic/fundamental-theorem-of-calculusArticles of different users are sorted by upvote within each article page. This feature is a bit like:
- a Wikipedia where each user can have their own version of each article
- a Q&A website like Stack Overflow, where multiple people can give their views on a given topic, and the best ones are sorted by upvote. Except you don't need to wait for someone to ask first, and any topic goes, no matter how narrow or broad
This feature makes it possible for readers to find better explanations of any topic created by other writers. And it allows writers to create an explanation in a place that readers might actually find it. - local editing: you can store all your personal knowledge base content locally in a plaintext markup format that can be edited locally and published either:This way you can be sure that even if OurBigBook.com were to go down one day (which we have no plans to do as it is quite cheap to host!), your content will still be perfectly readable as a static site.
- to OurBigBook.com to get awesome multi-user features like topics and likes
- as HTML files to a static website, which you can host yourself for free on many external providers like GitHub Pages, and remain in full control
- Internal cross file references done right:
- Infinitely deep tables of contents:
All our software is open source and hosted at: github.com/ourbigbook/ourbigbook
Further documentation can be found at: docs.ourbigbook.com
Feel free to reach our to us for any help or suggestions: docs.ourbigbook.com/#contact