@@ -17,25 +17,25 @@ Every ELF file starts with a header. Let's look at one:
1717``` bash
1818$ readelf -h /bin/ls
1919ELF Header:
20- Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
20+ Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
2121 Class: ELF64
2222 Data: 2' s complement, little endian
2323 Version: 1 (current)
2424 OS/ABI: UNIX - System V
2525 ABI Version: 0
26- Type: DYN (Position-Independent Executable)
27- Machine: Advanced Micro Devices X86-64
26+ Type: DYN (Position-Independent Executable file )
27+ Machine: AArch64
2828 Version: 0x1
29- Entry point address: 0x6ab0
29+ Entry point address: 0x65c0
3030 Start of program headers: 64 (bytes into file)
31- Start of section headers: 140224 (bytes into file)
31+ Start of section headers: 197720 (bytes into file)
3232 Flags: 0x0
3333 Size of this header: 64 (bytes)
3434 Size of program headers: 56 (bytes)
35- Number of program headers: 13
35+ Number of program headers: 12
3636 Size of section headers: 64 (bytes)
37- Number of section headers: 30
38- Section header string table index: 29
37+ Number of section headers: 29
38+ Section header string table index: 28
3939```
4040
4141Let' s break this down:
@@ -114,18 +114,30 @@ Your compiled functions live here. This section is:
114114```bash
115115$ objdump -d math.o
116116
117- math.o: file format elf64-x86-64
117+ math.o: file format elf64-littleaarch64
118+
118119
119120Disassembly of section .text:
120121
1211220000000000000000 <add>:
122- 0: 8d 04 37 lea (%rdi,%rsi,1),%eax
123- 3: c3 ret
124-
125- 0000000000000004 <multiply>:
126- 4: 89 f8 mov %edi,%eax
127- 6: 0f af c6 imul %esi,%eax
128- 9: c3 ret
123+ 0: d10043ff sub sp, sp, #0x10
124+ 4: b9000fe0 str w0, [sp, #12]
125+ 8: b9000be1 str w1, [sp, #8]
126+ c: b9400fe1 ldr w1, [sp, #12]
127+ 10: b9400be0 ldr w0, [sp, #8]
128+ 14: 0b000020 add w0, w1, w0
129+ 18: 910043ff add sp, sp, #0x10
130+ 1c: d65f03c0 ret
131+
132+ 0000000000000020 <multiply>:
133+ 20: d10043ff sub sp, sp, #0x10
134+ 24: b9000fe0 str w0, [sp, #12]
135+ 28: b9000be1 str w1, [sp, #8]
136+ 2c: b9400fe1 ldr w1, [sp, #12]
137+ 30: b9400be0 ldr w0, [sp, #8]
138+ 34: 1b007c20 mul w0, w1, w0
139+ 38: 910043ff add sp, sp, #0x10
140+ 3c: d65f03c0 ret
129141```
130142
131143Notice the addresses start at 0. These are relative offsets—final addresses are determined during linking.
@@ -170,13 +182,20 @@ The symbol table! We covered this in Chapter 1. `.symtab` contains the structure
170182``` bash
171183$ readelf -s math.o
172184
173- Symbol table ' .symtab' contains 5 entries:
185+ Symbol table ' .symtab' contains 12 entries:
174186 Num: Value Size Type Bind Vis Ndx Name
175- 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
187+ 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
176188 1: 0000000000000000 0 FILE LOCAL DEFAULT ABS math.c
177189 2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
178- 3: 0000000000000000 4 FUNC GLOBAL DEFAULT 1 add
179- 4: 0000000000000004 6 FUNC GLOBAL DEFAULT 1 multiply
190+ 3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .data
191+ 4: 0000000000000000 0 SECTION LOCAL DEFAULT 3 .bss
192+ 5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 $x
193+ 6: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .note.GNU-stack
194+ 7: 0000000000000014 0 NOTYPE LOCAL DEFAULT 6 $d
195+ 8: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .eh_frame
196+ 9: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .comment
197+ 10: 0000000000000000 32 FUNC GLOBAL DEFAULT 1 add
198+ 11: 0000000000000020 32 FUNC GLOBAL DEFAULT 1 multiply
180199```
181200
182201### ` .rel.text ` and ` .rela.text ` — Relocations
@@ -186,10 +205,14 @@ When code references something that isn't known yet (a function in another file,
186205``` bash
187206$ readelf -r main.o
188207
189- Relocation section ' .rela.text' at offset 0x1d0 contains 2 entries:
208+ Relocation section ' .rela.text' at offset 0x218 contains 2 entries:
209+ Offset Info Type Sym. Value Sym. Name + Addend
210+ 000000000010 000b0000011b R_AARCH64_CALL26 0000000000000000 add + 0
211+ 000000000020 000c0000011b R_AARCH64_CALL26 0000000000000000 multiply + 0
212+
213+ Relocation section ' .rela.eh_frame' at offset 0x248 contains 1 entry:
190214 Offset Info Type Sym. Value Sym. Name + Addend
191- 000000000011 000500000004 R_X86_64_PLT32 0000000000000000 add - 4
192- 000000000020 000600000004 R_X86_64_PLT32 0000000000000000 multiply - 4
215+ 00000000001c 000200000105 R_AARCH64_PREL32 0000000000000000 .text + 0
193216```
194217
195218The ` main.o ` file has two relocations: calls to ` add ` and ` multiply ` that need to be resolved.
@@ -210,11 +233,38 @@ Each section has flags describing its properties:
210233
211234``` bash
212235$ readelf -S math.o
236+ There are 11 section headers, starting at offset 0x2a8:
237+
213238Section Headers:
214- [Nr] Name Type Address Off Size ES Flg Lk Inf Al
215- [ 1] .text PROGBITS 0000000000000000 000040 00000a 00 AX 0 0 1
216- [ 2] .data PROGBITS 0000000000000000 00004a 000000 00 WA 0 0 1
217- [ 3] .bss NOBITS 0000000000000000 00004a 000000 00 WA 0 0 1
239+ [Nr] Name Type Address Offset
240+ Size EntSize Flags Link Info Align
241+ [ 0] NULL 0000000000000000 00000000
242+ 0000000000000000 0000000000000000 0 0 0
243+ [ 1] .text PROGBITS 0000000000000000 00000040
244+ 0000000000000040 0000000000000000 AX 0 0 4
245+ [ 2] .data PROGBITS 0000000000000000 00000080
246+ 0000000000000000 0000000000000000 WA 0 0 1
247+ [ 3] .bss NOBITS 0000000000000000 00000080
248+ 0000000000000000 0000000000000000 WA 0 0 1
249+ [ 4] .comment PROGBITS 0000000000000000 00000080
250+ 0000000000000013 0000000000000001 MS 0 0 1
251+ [ 5] .note.GNU-stack PROGBITS 0000000000000000 00000093
252+ 0000000000000000 0000000000000000 0 0 1
253+ [ 6] .eh_frame PROGBITS 0000000000000000 00000098
254+ 0000000000000048 0000000000000000 A 0 0 8
255+ [ 7] .rela.eh_frame RELA 0000000000000000 00000220
256+ 0000000000000030 0000000000000018 I 8 6 8
257+ [ 8] .symtab SYMTAB 0000000000000000 000000e0
258+ 0000000000000120 0000000000000018 9 10 8
259+ [ 9] .strtab STRTAB 0000000000000000 00000200
260+ 000000000000001b 0000000000000000 0 0 1
261+ [10] .shstrtab STRTAB 0000000000000000 00000250
262+ 0000000000000054 0000000000000000 0 0 1
263+ Key to Flags:
264+ W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
265+ L (link order), O (extra OS processing required), G (group), T (TLS),
266+ C (compressed), x (unknown), o (OS specific), E (exclude),
267+ D (mbind), p (processor specific)
218268```
219269
220270Flags:
@@ -232,19 +282,54 @@ For executables and shared libraries, program headers describe memory mapping:
232282
233283``` bash
234284$ readelf -l /bin/ls
285+
286+ Elf file type is DYN (Position-Independent Executable file)
287+ Entry point 0x65c0
288+ There are 12 program headers, starting at offset 64
289+
235290Program Headers:
236- Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
237- PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0002d8 0x0002d8 R 0x8
238- INTERP 0x000318 0x0000000000000318 0x0000000000000318 0x00001c 0x00001c R 0x1
239- LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003510 0x003510 R 0x1000
240- LOAD 0x004000 0x0000000000004000 0x0000000000004000 0x013471 0x013471 R E 0x1000
241- LOAD 0x018000 0x0000000000018000 0x0000000000018000 0x004fe8 0x004fe8 R 0x1000
242- LOAD 0x01d900 0x000000000001e900 0x000000000001e900 0x001288 0x002548 RW 0x1000
243- DYNAMIC 0x01e3f8 0x000000000001f3f8 0x000000000001f3f8 0x000200 0x000200 RW 0x8
244- NOTE 0x000338 0x0000000000000338 0x0000000000000338 0x000030 0x000030 R 0x8
245- GNU_EH_FRAME 0x01b28c 0x000000000001b28c 0x000000000001b28c 0x0003ec 0x0003ec R 0x4
246- GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
247- GNU_RELRO 0x01d900 0x000000000001e900 0x000000000001e900 0x001700 0x001700 R 0x1
291+ Type Offset VirtAddr PhysAddr
292+ FileSiz MemSiz Flags Align
293+ PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
294+ 0x00000000000002a0 0x00000000000002a0 R 0x8
295+ INTERP 0x0000000000000324 0x0000000000000324 0x0000000000000324
296+ 0x000000000000001b 0x000000000000001b R 0x1
297+ [Requesting program interpreter: /lib/ld-linux-aarch64.so.1]
298+ LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
299+ 0x0000000000024f58 0x0000000000024f58 R E 0x10000
300+ LOAD 0x000000000002ef20 0x000000000003ef20 0x000000000003ef20
301+ 0x0000000000001390 0x0000000000002698 RW 0x10000
302+ DYNAMIC 0x000000000002f908 0x000000000003f908 0x000000000003f908
303+ 0x0000000000000230 0x0000000000000230 RW 0x8
304+ NOTE 0x00000000000002e0 0x00000000000002e0 0x00000000000002e0
305+ 0x0000000000000020 0x0000000000000020 R 0x8
306+ NOTE 0x0000000000000300 0x0000000000000300 0x0000000000000300
307+ 0x0000000000000024 0x0000000000000024 R 0x4
308+ NOTE 0x0000000000024f38 0x0000000000024f38 0x0000000000024f38
309+ 0x0000000000000020 0x0000000000000020 R 0x4
310+ GNU_PROPERTY 0x00000000000002e0 0x00000000000002e0 0x00000000000002e0
311+ 0x0000000000000020 0x0000000000000020 R 0x8
312+ GNU_EH_FRAME 0x0000000000020c8c 0x0000000000020c8c 0x0000000000020c8c
313+ 0x00000000000009fc 0x00000000000009fc R 0x4
314+ GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
315+ 0x0000000000000000 0x0000000000000000 RW 0x10
316+ GNU_RELRO 0x000000000002ef20 0x000000000003ef20 0x000000000003ef20
317+ 0x00000000000010e0 0x00000000000010e0 R 0x1
318+
319+ Section to Segment mapping:
320+ Segment Sections...
321+ 00
322+ 01 .interp
323+ 02 .note.gnu.property .note.gnu.build-id .interp .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .note.ABI-tag
324+ 03 .init_array .fini_array .data.rel.ro .dynamic .got .data .bss
325+ 04 .dynamic
326+ 05 .note.gnu.property
327+ 06 .note.gnu.build-id
328+ 07 .note.ABI-tag
329+ 08 .note.gnu.property
330+ 09 .eh_frame_hdr
331+ 10
332+ 11 .init_array .fini_array .data.rel.ro .dynamic .got
248333```
249334
250335Key segment types:
@@ -263,16 +348,54 @@ The linker groups sections into segments:
263348
264349``` bash
265350$ readelf -l /bin/ls
266- ...
351+
352+ Elf file type is DYN (Position-Independent Executable file)
353+ Entry point 0x65c0
354+ There are 12 program headers, starting at offset 64
355+
356+ Program Headers:
357+ Type Offset VirtAddr PhysAddr
358+ FileSiz MemSiz Flags Align
359+ PHDR 0x0000000000000040 0x0000000000000040 0x0000000000000040
360+ 0x00000000000002a0 0x00000000000002a0 R 0x8
361+ INTERP 0x0000000000000324 0x0000000000000324 0x0000000000000324
362+ 0x000000000000001b 0x000000000000001b R 0x1
363+ [Requesting program interpreter: /lib/ld-linux-aarch64.so.1]
364+ LOAD 0x0000000000000000 0x0000000000000000 0x0000000000000000
365+ 0x0000000000024f58 0x0000000000024f58 R E 0x10000
366+ LOAD 0x000000000002ef20 0x000000000003ef20 0x000000000003ef20
367+ 0x0000000000001390 0x0000000000002698 RW 0x10000
368+ DYNAMIC 0x000000000002f908 0x000000000003f908 0x000000000003f908
369+ 0x0000000000000230 0x0000000000000230 RW 0x8
370+ NOTE 0x00000000000002e0 0x00000000000002e0 0x00000000000002e0
371+ 0x0000000000000020 0x0000000000000020 R 0x8
372+ NOTE 0x0000000000000300 0x0000000000000300 0x0000000000000300
373+ 0x0000000000000024 0x0000000000000024 R 0x4
374+ NOTE 0x0000000000024f38 0x0000000000024f38 0x0000000000024f38
375+ 0x0000000000000020 0x0000000000000020 R 0x4
376+ GNU_PROPERTY 0x00000000000002e0 0x00000000000002e0 0x00000000000002e0
377+ 0x0000000000000020 0x0000000000000020 R 0x8
378+ GNU_EH_FRAME 0x0000000000020c8c 0x0000000000020c8c 0x0000000000020c8c
379+ 0x00000000000009fc 0x00000000000009fc R 0x4
380+ GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
381+ 0x0000000000000000 0x0000000000000000 RW 0x10
382+ GNU_RELRO 0x000000000002ef20 0x000000000003ef20 0x000000000003ef20
383+ 0x00000000000010e0 0x00000000000010e0 R 0x1
384+
267385 Section to Segment mapping:
268386 Segment Sections...
269- 00
270- 01 .interp
271- 02 .interp .note.gnu.property .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
272- 03 .init .plt .text .fini
273- 04 .rodata .eh_frame_hdr .eh_frame
274- 05 .init_array .fini_array .data.rel.ro .dynamic .got .data .bss
275- ...
387+ 00
388+ 01 .interp
389+ 02 .note.gnu.property .note.gnu.build-id .interp .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame .note.ABI-tag
390+ 03 .init_array .fini_array .data.rel.ro .dynamic .got .data .bss
391+ 04 .dynamic
392+ 05 .note.gnu.property
393+ 06 .note.gnu.build-id
394+ 07 .note.ABI-tag
395+ 08 .note.gnu.property
396+ 09 .eh_frame_hdr
397+ 10
398+ 11 .init_array .fini_array .data.rel.ro .dynamic .got
276399```
277400
278401Multiple sections become one segment. All the code sections (` .init ` , ` .plt ` , ` .text ` , ` .fini ` ) map to segment 03 with ` R E ` permissions.
0 commit comments