Skip to content

Commit 7a8624c

Browse files
committed
run the tool, real command output
1 parent c985d12 commit 7a8624c

File tree

10 files changed

+583
-296
lines changed

10 files changed

+583
-296
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
target/
2+
book/

book.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ build-dir = "book"
1212
default-theme = "coal"
1313
preferred-dark-theme = "coal"
1414
git-repository-url = "https://github.com/spwplace/objtab"
15-
git-repository-icon = "fa-github"
1615

1716
[output.html.fold]
1817
enable = true

src/ch01-what-are-symbols.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Now `math.o`:
5353
```bash
5454
$ nm math.o
5555
0000000000000000 T add
56-
0000000000000014 T multiply
56+
0000000000000020 T multiply
5757
```
5858

5959
Both `add` and `multiply` are defined here. No undefined symbols.

src/ch02-elf-anatomy.md

Lines changed: 170 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,25 @@ Every ELF file starts with a header. Let's look at one:
1717
```bash
1818
$ readelf -h /bin/ls
1919
ELF 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
4141
Let'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
119120
Disassembly of section .text:
120121
121122
0000000000000000 <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

131143
Notice 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

195218
The `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+
213238
Section 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

220270
Flags:
@@ -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+
235290
Program 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

250335
Key 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

278401
Multiple sections become one segment. All the code sections (`.init`, `.plt`, `.text`, `.fini`) map to segment 03 with `R E` permissions.

src/ch04-symbol-tables.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,20 @@ Let's decode a real example:
128128
```bash
129129
$ readelf -s math.o
130130

131-
Symbol table '.symtab' contains 5 entries:
131+
Symbol table '.symtab' contains 12 entries:
132132
Num: Value Size Type Bind Vis Ndx Name
133-
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
133+
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
134134
1: 0000000000000000 0 FILE LOCAL DEFAULT ABS math.c
135135
2: 0000000000000000 0 SECTION LOCAL DEFAULT 1 .text
136-
3: 0000000000000000 4 FUNC GLOBAL DEFAULT 1 add
137-
4: 0000000000000004 6 FUNC GLOBAL DEFAULT 1 multiply
136+
3: 0000000000000000 0 SECTION LOCAL DEFAULT 2 .data
137+
4: 0000000000000000 0 SECTION LOCAL DEFAULT 3 .bss
138+
5: 0000000000000000 0 NOTYPE LOCAL DEFAULT 1 $x
139+
6: 0000000000000000 0 SECTION LOCAL DEFAULT 5 .note.GNU-stack
140+
7: 0000000000000014 0 NOTYPE LOCAL DEFAULT 6 $d
141+
8: 0000000000000000 0 SECTION LOCAL DEFAULT 6 .eh_frame
142+
9: 0000000000000000 0 SECTION LOCAL DEFAULT 4 .comment
143+
10: 0000000000000000 32 FUNC GLOBAL DEFAULT 1 add
144+
11: 0000000000000020 32 FUNC GLOBAL DEFAULT 1 multiply
138145
```
139146

140147
Decoding each:
@@ -163,13 +170,10 @@ ELF executables can have **two** symbol tables:
163170
`.dynsym` is minimal—only symbols needed for dynamic linking. It survives `strip` because the dynamic linker needs it at runtime.
164171

165172
```bash
166-
# Full symbols
167173
$ nm /usr/bin/python3 | wc -l
168-
nm: /usr/bin/python3: no symbols
169-
170-
# Dynamic symbols survive stripping
174+
0
171175
$ nm -D /usr/bin/python3 | wc -l
172-
3847
176+
2255
173177
```
174178

175179
## Symbol Hashing for Fast Lookup
@@ -249,9 +253,15 @@ A symbol with global binding should be defined exactly once (across all input fi
249253

250254
```bash
251255
$ gcc -c file1.c -o file1.o # defines 'foo'
256+
cc1: fatal error: file1.c: No such file or directory
257+
compilation terminated.
252258
$ gcc -c file2.c -o file2.o # also defines 'foo'
259+
cc1: fatal error: file2.c: No such file or directory
260+
compilation terminated.
253261
$ gcc file1.o file2.o -o out
254-
multiple definition of 'foo'
262+
/usr/bin/ld: cannot find file1.o: No such file or directory
263+
/usr/bin/ld: cannot find file2.o: No such file or directory
264+
collect2: error: ld returned 1 exit status
255265
```
256266

257267
### Rule 2: Weak vs Strong

0 commit comments

Comments
 (0)