1
2
3
4
5
6
7
8
9
10
11
12
13 package macho
14
15 import "strconv"
16
17
18 type FileHeader struct {
19 Magic uint32
20 Cpu Cpu
21 SubCpu uint32
22 Type Type
23 Ncmd uint32
24 Cmdsz uint32
25 Flags uint32
26 }
27
28 const (
29 fileHeaderSize32 = 7 * 4
30 fileHeaderSize64 = 8 * 4
31 )
32
33 const (
34 Magic32 uint32 = 0xfeedface
35 Magic64 uint32 = 0xfeedfacf
36 MagicFat uint32 = 0xcafebabe
37 )
38
39
40 type Type uint32
41
42 const (
43 TypeObj Type = 1
44 TypeExec Type = 2
45 TypeDylib Type = 6
46 TypeBundle Type = 8
47 )
48
49 var typeStrings = []intName{
50 {uint32(TypeObj), "Obj"},
51 {uint32(TypeExec), "Exec"},
52 {uint32(TypeDylib), "Dylib"},
53 {uint32(TypeBundle), "Bundle"},
54 }
55
56 func (t Type) String() string { return stringName(uint32(t), typeStrings, false) }
57 func (t Type) GoString() string { return stringName(uint32(t), typeStrings, true) }
58
59
60 type Cpu uint32
61
62 const cpuArch64 = 0x01000000
63
64 const (
65 Cpu386 Cpu = 7
66 CpuAmd64 Cpu = Cpu386 | cpuArch64
67 CpuArm Cpu = 12
68 CpuArm64 Cpu = CpuArm | cpuArch64
69 CpuPpc Cpu = 18
70 CpuPpc64 Cpu = CpuPpc | cpuArch64
71 )
72
73 var cpuStrings = []intName{
74 {uint32(Cpu386), "Cpu386"},
75 {uint32(CpuAmd64), "CpuAmd64"},
76 {uint32(CpuArm), "CpuArm"},
77 {uint32(CpuArm64), "CpuArm64"},
78 {uint32(CpuPpc), "CpuPpc"},
79 {uint32(CpuPpc64), "CpuPpc64"},
80 }
81
82 func (i Cpu) String() string { return stringName(uint32(i), cpuStrings, false) }
83 func (i Cpu) GoString() string { return stringName(uint32(i), cpuStrings, true) }
84
85
86 type LoadCmd uint32
87
88 const (
89 LoadCmdSegment LoadCmd = 0x1
90 LoadCmdSymtab LoadCmd = 0x2
91 LoadCmdThread LoadCmd = 0x4
92 LoadCmdUnixThread LoadCmd = 0x5
93 LoadCmdDysymtab LoadCmd = 0xb
94 LoadCmdDylib LoadCmd = 0xc
95 LoadCmdDylinker LoadCmd = 0xf
96 LoadCmdSegment64 LoadCmd = 0x19
97 LoadCmdRpath LoadCmd = 0x8000001c
98 )
99
100 var cmdStrings = []intName{
101 {uint32(LoadCmdSegment), "LoadCmdSegment"},
102 {uint32(LoadCmdThread), "LoadCmdThread"},
103 {uint32(LoadCmdUnixThread), "LoadCmdUnixThread"},
104 {uint32(LoadCmdDylib), "LoadCmdDylib"},
105 {uint32(LoadCmdSegment64), "LoadCmdSegment64"},
106 {uint32(LoadCmdRpath), "LoadCmdRpath"},
107 }
108
109 func (i LoadCmd) String() string { return stringName(uint32(i), cmdStrings, false) }
110 func (i LoadCmd) GoString() string { return stringName(uint32(i), cmdStrings, true) }
111
112 type (
113
114 Segment32 struct {
115 Cmd LoadCmd
116 Len uint32
117 Name [16]byte
118 Addr uint32
119 Memsz uint32
120 Offset uint32
121 Filesz uint32
122 Maxprot uint32
123 Prot uint32
124 Nsect uint32
125 Flag uint32
126 }
127
128
129 Segment64 struct {
130 Cmd LoadCmd
131 Len uint32
132 Name [16]byte
133 Addr uint64
134 Memsz uint64
135 Offset uint64
136 Filesz uint64
137 Maxprot uint32
138 Prot uint32
139 Nsect uint32
140 Flag uint32
141 }
142
143
144 SymtabCmd struct {
145 Cmd LoadCmd
146 Len uint32
147 Symoff uint32
148 Nsyms uint32
149 Stroff uint32
150 Strsize uint32
151 }
152
153
154 DysymtabCmd struct {
155 Cmd LoadCmd
156 Len uint32
157 Ilocalsym uint32
158 Nlocalsym uint32
159 Iextdefsym uint32
160 Nextdefsym uint32
161 Iundefsym uint32
162 Nundefsym uint32
163 Tocoffset uint32
164 Ntoc uint32
165 Modtaboff uint32
166 Nmodtab uint32
167 Extrefsymoff uint32
168 Nextrefsyms uint32
169 Indirectsymoff uint32
170 Nindirectsyms uint32
171 Extreloff uint32
172 Nextrel uint32
173 Locreloff uint32
174 Nlocrel uint32
175 }
176
177
178 DylibCmd struct {
179 Cmd LoadCmd
180 Len uint32
181 Name uint32
182 Time uint32
183 CurrentVersion uint32
184 CompatVersion uint32
185 }
186
187
188 RpathCmd struct {
189 Cmd LoadCmd
190 Len uint32
191 Path uint32
192 }
193
194
195 Thread struct {
196 Cmd LoadCmd
197 Len uint32
198 Type uint32
199 Data []uint32
200 }
201 )
202
203 const (
204 FlagNoUndefs uint32 = 0x1
205 FlagIncrLink uint32 = 0x2
206 FlagDyldLink uint32 = 0x4
207 FlagBindAtLoad uint32 = 0x8
208 FlagPrebound uint32 = 0x10
209 FlagSplitSegs uint32 = 0x20
210 FlagLazyInit uint32 = 0x40
211 FlagTwoLevel uint32 = 0x80
212 FlagForceFlat uint32 = 0x100
213 FlagNoMultiDefs uint32 = 0x200
214 FlagNoFixPrebinding uint32 = 0x400
215 FlagPrebindable uint32 = 0x800
216 FlagAllModsBound uint32 = 0x1000
217 FlagSubsectionsViaSymbols uint32 = 0x2000
218 FlagCanonical uint32 = 0x4000
219 FlagWeakDefines uint32 = 0x8000
220 FlagBindsToWeak uint32 = 0x10000
221 FlagAllowStackExecution uint32 = 0x20000
222 FlagRootSafe uint32 = 0x40000
223 FlagSetuidSafe uint32 = 0x80000
224 FlagNoReexportedDylibs uint32 = 0x100000
225 FlagPIE uint32 = 0x200000
226 FlagDeadStrippableDylib uint32 = 0x400000
227 FlagHasTLVDescriptors uint32 = 0x800000
228 FlagNoHeapExecution uint32 = 0x1000000
229 FlagAppExtensionSafe uint32 = 0x2000000
230 )
231
232
233 type Section32 struct {
234 Name [16]byte
235 Seg [16]byte
236 Addr uint32
237 Size uint32
238 Offset uint32
239 Align uint32
240 Reloff uint32
241 Nreloc uint32
242 Flags uint32
243 Reserve1 uint32
244 Reserve2 uint32
245 }
246
247
248 type Section64 struct {
249 Name [16]byte
250 Seg [16]byte
251 Addr uint64
252 Size uint64
253 Offset uint32
254 Align uint32
255 Reloff uint32
256 Nreloc uint32
257 Flags uint32
258 Reserve1 uint32
259 Reserve2 uint32
260 Reserve3 uint32
261 }
262
263
264 type Nlist32 struct {
265 Name uint32
266 Type uint8
267 Sect uint8
268 Desc uint16
269 Value uint32
270 }
271
272
273 type Nlist64 struct {
274 Name uint32
275 Type uint8
276 Sect uint8
277 Desc uint16
278 Value uint64
279 }
280
281
282 type Regs386 struct {
283 AX uint32
284 BX uint32
285 CX uint32
286 DX uint32
287 DI uint32
288 SI uint32
289 BP uint32
290 SP uint32
291 SS uint32
292 FLAGS uint32
293 IP uint32
294 CS uint32
295 DS uint32
296 ES uint32
297 FS uint32
298 GS uint32
299 }
300
301
302 type RegsAMD64 struct {
303 AX uint64
304 BX uint64
305 CX uint64
306 DX uint64
307 DI uint64
308 SI uint64
309 BP uint64
310 SP uint64
311 R8 uint64
312 R9 uint64
313 R10 uint64
314 R11 uint64
315 R12 uint64
316 R13 uint64
317 R14 uint64
318 R15 uint64
319 IP uint64
320 FLAGS uint64
321 CS uint64
322 FS uint64
323 GS uint64
324 }
325
326 type intName struct {
327 i uint32
328 s string
329 }
330
331 func stringName(i uint32, names []intName, goSyntax bool) string {
332 for _, n := range names {
333 if n.i == i {
334 if goSyntax {
335 return "macho." + n.s
336 }
337 return n.s
338 }
339 }
340 return strconv.FormatUint(uint64(i), 10)
341 }
342
View as plain text