Skip to content

Commit 0d7501c

Browse files
Add otool-style printing for Mach-O images
A decoded image could only be inspected through a debugger. Adds printing of the header and every load command, and snapshots the result for each fixture, so decoding a new command extends the snapshot rather than needing another test and a change to how anything is read shows up as a diff. Commands are named by their LC_ spelling rather than the enumeration's, so output can be read next to otool's. That mapping is written out rather than derived from the enumeration names, because several do not follow from them: LC_UNIXTHREAD is one word and LC_VERSION_MIN_MACOSX breaks in places the casing does not. The command sequence each fixture prints was checked against otool before the snapshots were taken. - src/LibObjectFile/MachO/MachOPrinter.cs: the printer - src/LibObjectFile.Tests/Verified: one snapshot per fixture
1 parent 7b687ca commit 0d7501c

10 files changed

Lines changed: 1787 additions & 188 deletions

‎src/LibObjectFile.Tests/MachO/MachOSimpleTests.cs‎

Lines changed: 206 additions & 188 deletions
Large diffs are not rendered by default.

‎src/LibObjectFile.Tests/MachO/MachOTestBase.cs‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
using System;
66
using System.IO;
7+
using System.Threading.Tasks;
78
using LibObjectFile.MachO;
89
using VerifyMSTest;
10+
using VerifyTests;
911

1012
namespace LibObjectFile.Tests.MachO;
1113

@@ -22,4 +24,10 @@ protected static byte[] WriteToArray(MachOFile file)
2224
return stream.ToArray();
2325
}
2426

27+
protected async Task VerifyMachO(MachOFile file, string name)
28+
{
29+
var writer = new StringWriter();
30+
file.Print(writer);
31+
await Verifier.Verify(writer.ToString()).UseParameters(name);
32+
}
2533
}
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
Mach header:
2+
magic MH_MAGIC_64
3+
cputype Arm64
4+
cpusubtype 0x00000000
5+
filetype Execute
6+
ncmds 17
7+
sizeofcmds 1192
8+
flags 0x200085 NoUndefs, DyldLink, TwoLevel, PositionIndependent
9+
10+
Load command 0
11+
cmd LC_SEGMENT_64
12+
cmdsize 72
13+
segname __PAGEZERO
14+
vmaddr 0x00000000
15+
vmsize 0x100000000
16+
fileoff 0
17+
filesize 0
18+
maxprot ---
19+
initprot ---
20+
nsects 0
21+
flags 0x0
22+
Load command 1
23+
cmd LC_SEGMENT_64
24+
cmdsize 392
25+
segname __TEXT
26+
vmaddr 0x100000000
27+
vmsize 0x00004000
28+
fileoff 0
29+
filesize 16384
30+
maxprot r-x
31+
initprot r-x
32+
nsects 4
33+
flags 0x0
34+
Section
35+
sectname __text
36+
segname __TEXT
37+
addr 0x1000004e8
38+
size 0x00000064
39+
offset 1256
40+
align 2^2 (4)
41+
reloff 0
42+
nreloc 0
43+
type Regular
44+
attributes SomeInstructions, PureInstructions
45+
reserved1 0
46+
reserved2 0
47+
Section
48+
sectname __stubs
49+
segname __TEXT
50+
addr 0x10000054c
51+
size 0x0000000c
52+
offset 1356
53+
align 2^2 (4)
54+
reloff 0
55+
nreloc 0
56+
type SymbolStubs
57+
attributes SomeInstructions, PureInstructions
58+
reserved1 1
59+
reserved2 12
60+
Section
61+
sectname __cstring
62+
segname __TEXT
63+
addr 0x100000558
64+
size 0x00000010
65+
offset 1368
66+
align 2^0 (1)
67+
reloff 0
68+
nreloc 0
69+
type CStringLiterals
70+
attributes (none)
71+
reserved1 0
72+
reserved2 0
73+
Section
74+
sectname __unwind_info
75+
segname __TEXT
76+
addr 0x100000568
77+
size 0x0000103c
78+
offset 1384
79+
align 2^2 (4)
80+
reloff 0
81+
nreloc 0
82+
type Regular
83+
attributes (none)
84+
reserved1 0
85+
reserved2 0
86+
Load command 2
87+
cmd LC_SEGMENT_64
88+
cmdsize 152
89+
segname __DATA_CONST
90+
vmaddr 0x100004000
91+
vmsize 0x00004000
92+
fileoff 16384
93+
filesize 16384
94+
maxprot rw-
95+
initprot rw-
96+
nsects 1
97+
flags 0x10
98+
Section
99+
sectname __got
100+
segname __DATA_CONST
101+
addr 0x100004000
102+
size 0x00000008
103+
offset 16384
104+
align 2^3 (8)
105+
reloff 0
106+
nreloc 0
107+
type NonLazySymbolPointers
108+
attributes (none)
109+
reserved1 0
110+
reserved2 0
111+
Load command 3
112+
cmd LC_SEGMENT_64
113+
cmdsize 152
114+
segname __DATA
115+
vmaddr 0x100008000
116+
vmsize 0x00004000
117+
fileoff 32768
118+
filesize 16384
119+
maxprot rw-
120+
initprot rw-
121+
nsects 1
122+
flags 0x0
123+
Section
124+
sectname __data
125+
segname __DATA
126+
addr 0x100008000
127+
size 0x00000004
128+
offset 32768
129+
align 2^2 (4)
130+
reloff 0
131+
nreloc 0
132+
type Regular
133+
attributes (none)
134+
reserved1 0
135+
reserved2 0
136+
Load command 4
137+
cmd LC_SEGMENT_64
138+
cmdsize 72
139+
segname __LINKEDIT
140+
vmaddr 0x10000c000
141+
vmsize 0x000003b0
142+
fileoff 49152
143+
filesize 944
144+
maxprot r--
145+
initprot r--
146+
nsects 0
147+
flags 0x0
148+
Load command 5
149+
cmd LC_DYLD_CHAINED_FIXUPS
150+
cmdsize 16
151+
dataoff 49152
152+
datasize 96
153+
Load command 6
154+
cmd LC_DYLD_EXPORTS_TRIE
155+
cmdsize 16
156+
dataoff 49248
157+
datasize 88
158+
Load command 7
159+
cmd LC_SYMTAB
160+
cmdsize 24
161+
symoff 49344
162+
nsyms 6
163+
stroff 49448
164+
strsize 88
165+
Load command 8
166+
cmd LC_DYSYMTAB
167+
cmdsize 80
168+
nlocalsym 0
169+
nextdefsym 4
170+
nundefsym 2
171+
indirectsymoff 49440
172+
nindirectsyms 2
173+
Load command 9
174+
cmd LC_LOAD_DYLINKER
175+
cmdsize 32
176+
path /usr/lib/dyld
177+
Load command 10
178+
cmd LC_UUID
179+
cmdsize 24
180+
uuid 4C4C4468-5555-3144-A159-D3B12CF35C25
181+
Load command 11
182+
cmd LC_BUILD_VERSION
183+
cmdsize 32
184+
platform MacOS
185+
minos 12.0.0
186+
sdk 12.0.0
187+
ntools 1
188+
tool Lld
189+
version 22.1.8
190+
Load command 12
191+
cmd LC_MAIN
192+
cmdsize 24
193+
entryoff 1280
194+
stacksize 0
195+
Load command 13
196+
cmd LC_LOAD_DYLIB
197+
cmdsize 56
198+
name /usr/lib/libSystem.B.dylib
199+
timestamp 0
200+
current version 1336.61.1
201+
compatibility version 1.0.0
202+
Load command 14
203+
cmd LC_FUNCTION_STARTS
204+
cmdsize 16
205+
dataoff 49336
206+
datasize 8
207+
Load command 15
208+
cmd LC_DATA_IN_CODE
209+
cmdsize 16
210+
dataoff 49344
211+
datasize 0
212+
Load command 16
213+
cmd LC_CODE_SIGNATURE
214+
cmdsize 16
215+
dataoff 49536
216+
datasize 560
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
Mach header:
2+
magic MH_MAGIC
3+
cputype X86
4+
cpusubtype 0x00000003
5+
filetype Execute
6+
ncmds 16
7+
sizeofcmds 720
8+
flags 0x218085 NoUndefs, DyldLink, TwoLevel, WeakDefines, BindsToWeak, PositionIndependent
9+
10+
Load command 0
11+
cmd LC_SEGMENT
12+
cmdsize 56
13+
segname __PAGEZERO
14+
vmaddr 0x00000000
15+
vmsize 0x00001000
16+
fileoff 0
17+
filesize 0
18+
maxprot ---
19+
initprot ---
20+
nsects 0
21+
flags 0x0
22+
Load command 1
23+
cmd LC_SEGMENT
24+
cmdsize 124
25+
segname __TEXT
26+
vmaddr 0x00001000
27+
vmsize 0x00001000
28+
fileoff 0
29+
filesize 4096
30+
maxprot rwx
31+
initprot r-x
32+
nsects 1
33+
flags 0x0
34+
Section
35+
sectname __text
36+
segname __TEXT
37+
addr 0x00001800
38+
size 0x00000006
39+
offset 2048
40+
align 2^2 (4)
41+
reloff 0
42+
nreloc 0
43+
type Regular
44+
attributes SomeInstructions, PureInstructions
45+
reserved1 0
46+
reserved2 0
47+
Load command 2
48+
cmd LC_SEGMENT
49+
cmdsize 124
50+
segname __DATA
51+
vmaddr 0x00002000
52+
vmsize 0x00001000
53+
fileoff 4096
54+
filesize 4096
55+
maxprot rwx
56+
initprot rw-
57+
nsects 1
58+
flags 0x0
59+
Section
60+
sectname __data
61+
segname __DATA
62+
addr 0x00002000
63+
size 0x00000004
64+
offset 4096
65+
align 2^2 (4)
66+
reloff 0
67+
nreloc 0
68+
type Regular
69+
attributes (none)
70+
reserved1 0
71+
reserved2 0
72+
Load command 3
73+
cmd LC_SEGMENT
74+
cmdsize 56
75+
segname __LINKEDIT
76+
vmaddr 0x00003000
77+
vmsize 0x00001000
78+
fileoff 8192
79+
filesize 64
80+
maxprot rwx
81+
initprot r--
82+
nsects 0
83+
flags 0x0
84+
Load command 4
85+
cmd LC_DYLD_INFO_ONLY
86+
cmdsize 48
87+
rebase_off 0
88+
rebase_size 0
89+
bind_off 0
90+
bind_size 0
91+
lazy_bind_off 0
92+
lazy_bind_size 0
93+
export_off 0
94+
export_size 0
95+
Load command 5
96+
cmd LC_SYMTAB
97+
cmdsize 24
98+
symoff 8192
99+
nsyms 2
100+
stroff 8216
101+
strsize 32
102+
Load command 6
103+
cmd LC_DYSYMTAB
104+
cmdsize 80
105+
nlocalsym 0
106+
nextdefsym 2
107+
nundefsym 0
108+
indirectsymoff 0
109+
nindirectsyms 0
110+
Load command 7
111+
cmd LC_LOAD_DYLINKER
112+
cmdsize 28
113+
path /usr/lib/dyld
114+
Load command 8
115+
cmd LC_UUID
116+
cmdsize 24
117+
uuid 4D4F4445-524E-3332-4249-540000000002
118+
Load command 9
119+
cmd LC_VERSION_MIN_MACOSX
120+
cmdsize 16
121+
version 10.7.0
122+
sdk 10.7.0
123+
Load command 10
124+
cmd LC_SOURCE_VERSION
125+
cmdsize 16
126+
version 0.0.0.0
127+
Load command 11
128+
cmd LC_MAIN
129+
cmdsize 24
130+
entryoff 2048
131+
stacksize 0
132+
Load command 12
133+
cmd LC_FUNCTION_STARTS
134+
cmdsize 16
135+
dataoff 8248
136+
datasize 8
137+
Load command 13
138+
cmd LC_DATA_IN_CODE
139+
cmdsize 16
140+
dataoff 8256
141+
datasize 0
142+
Load command 14
143+
cmd LC_DYLIB_CODE_SIGN_DRS
144+
cmdsize 16
145+
dataoff 8256
146+
datasize 0
147+
Load command 15
148+
cmd LC_LOAD_DYLIB
149+
cmdsize 52
150+
name /usr/lib/libSystem.B.dylib
151+
timestamp 2
152+
current version 79.9.1
153+
compatibility version 1.0.0

0 commit comments

Comments
 (0)