ruby-macho 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,275 +1,352 @@
1
1
  module MachO
2
- # big-endian fat magic
3
- FAT_MAGIC = 0xcafebabe
2
+ # big-endian fat magic
3
+ FAT_MAGIC = 0xcafebabe
4
4
 
5
- # little-endian fat magic
6
- FAT_CIGAM = 0xbebafeca
5
+ # little-endian fat magic
6
+ # this is defined, but should never appear in ruby-macho code because
7
+ # fat headers are always big-endian and therefore always unpacked as such.
8
+ FAT_CIGAM = 0xbebafeca
7
9
 
8
- # 32-bit big-endian magic
9
- MH_MAGIC = 0xfeedface
10
+ # 32-bit big-endian magic
11
+ MH_MAGIC = 0xfeedface
10
12
 
11
- # 32-bit little-endian magic
12
- MH_CIGAM = 0xcefaedfe
13
+ # 32-bit little-endian magic
14
+ MH_CIGAM = 0xcefaedfe
13
15
 
14
- # 64-bit big-endian magic
15
- MH_MAGIC_64 = 0xfeedfacf
16
+ # 64-bit big-endian magic
17
+ MH_MAGIC_64 = 0xfeedfacf
16
18
 
17
- # 64-bit little-endian magic
18
- MH_CIGAM_64 = 0xcffaedfe
19
+ # 64-bit little-endian magic
20
+ MH_CIGAM_64 = 0xcffaedfe
19
21
 
20
- # association of magic numbers to string representations
21
- MH_MAGICS = {
22
- FAT_MAGIC => "FAT_MAGIC",
23
- FAT_CIGAM => "FAT_CIGAM",
24
- MH_MAGIC => "MH_MAGIC",
25
- MH_CIGAM => "MH_CIGAM",
26
- MH_MAGIC_64 => "MH_MAGIC_64",
27
- MH_CIGAM_64 => "MH_CIGAM_64"
28
- }
22
+ # association of magic numbers to string representations
23
+ MH_MAGICS = {
24
+ FAT_MAGIC => "FAT_MAGIC",
25
+ MH_MAGIC => "MH_MAGIC",
26
+ MH_CIGAM => "MH_CIGAM",
27
+ MH_MAGIC_64 => "MH_MAGIC_64",
28
+ MH_CIGAM_64 => "MH_CIGAM_64"
29
+ }
29
30
 
30
- # mask for CPUs with 64-bit architectures (when running a 64-bit ABI?)
31
- CPU_ARCH_ABI64 = 0x01000000
31
+ # mask for CPUs with 64-bit architectures (when running a 64-bit ABI?)
32
+ CPU_ARCH_ABI64 = 0x01000000
32
33
 
33
- # any CPU (unused?)
34
- CPU_TYPE_ANY = -1
35
-
36
- # x86 compatible CPUs
37
- CPU_TYPE_X86 = 0x07
38
-
39
- # i386 and later compatible CPUs
40
- CPU_TYPE_I386 = CPU_TYPE_X86
41
-
42
- # x86_64 (AMD64) compatible CPUs
43
- CPU_TYPE_X86_64 = (CPU_TYPE_X86 | CPU_ARCH_ABI64)
44
-
45
- # PowerPC compatible CPUs (7400 series?)
46
- CPU_TYPE_POWERPC = 0x12
47
-
48
- # PowerPC64 compatible CPUs (970 series?)
49
- CPU_TYPE_POWERPC64 = (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
50
-
51
- # association of cpu types to string representations
52
- CPU_TYPES = {
53
- CPU_TYPE_ANY => "CPU_TYPE_ANY",
54
- CPU_TYPE_X86 => "CPU_TYPE_X86",
55
- CPU_TYPE_I386 => "CPU_TYPE_I386",
56
- CPU_TYPE_X86_64 => "CPU_TYPE_X86_64",
57
- CPU_TYPE_POWERPC => "CPU_TYPE_POWERPC",
58
- CPU_TYPE_POWERPC64 => "CPU_TYPE_POWERPC64"
59
- }
60
-
61
- # mask for CPU subtype capabilities
62
- CPU_SUBTYPE_MASK = 0xff000000
63
-
64
- # 64-bit libraries (undocumented!)
65
- # @see http://llvm.org/docs/doxygen/html/Support_2MachO_8h_source.html
66
- CPU_SUBTYPE_LIB64 = 0x80000000
67
-
68
- # all x86-type CPUs
69
- CPU_SUBTYPE_X86_ALL = 3
70
-
71
- # all x86-type CPUs (what makes this different from CPU_SUBTYPE_X86_ALL?)
72
- CPU_SUBTYPE_X86_ARCH1 = 4
73
-
74
- # association of cpu subtypes to string representations
75
- CPU_SUBTYPES = {
76
- CPU_SUBTYPE_X86_ALL => "CPU_SUBTYPE_X86_ALL",
77
- CPU_SUBTYPE_X86_ARCH1 => "CPU_SUBTYPE_X86_ARCH1"
78
- }
79
-
80
- # relocatable object file
81
- MH_OBJECT = 0x1
82
-
83
- # demand paged executable file
84
- MH_EXECUTE = 0x2
85
-
86
- # fixed VM shared library file
87
- MH_FVMLIB = 0x3
88
-
89
- # core dump file
90
- MH_CORE = 0x4
91
-
92
- # preloaded executable file
93
- MH_PRELOAD = 0x5
94
-
95
- # dynamically bound shared library
96
- MH_DYLIB = 0x6
97
-
98
- # dynamic link editor
99
- MH_DYLINKER = 0x7
100
-
101
- # dynamically bound bundle file
102
- MH_BUNDLE = 0x8
103
-
104
- # shared library stub for static linking only, no section contents
105
- MH_DYLIB_STUB = 0x9
106
-
107
- # companion file with only debug sections
108
- MH_DSYM = 0xa
109
-
110
- # x86_64 kexts
111
- MH_KEXT_BUNDLE = 0xb
112
-
113
- # association of filetypes to string representations
114
- # @api private
115
- MH_FILETYPES = {
116
- MH_OBJECT => "MH_OBJECT",
117
- MH_EXECUTE => "MH_EXECUTE",
118
- MH_FVMLIB => "MH_FVMLIB",
119
- MH_CORE => "MH_CORE",
120
- MH_PRELOAD => "MH_PRELOAD",
121
- MH_DYLIB => "MH_DYLIB",
122
- MH_DYLINKER => "MH_DYLINKER",
123
- MH_BUNDLE => "MH_BUNDLE",
124
- MH_DYLIB_STUB => "MH_DYLIB_STUB",
125
- MH_DSYM => "MH_DSYM",
126
- MH_KEXT_BUNDLE => "MH_KEXT_BUNDLE"
127
- }
128
-
129
- # association of mach header flag symbols to values
130
- # @api private
131
- MH_FLAGS = {
132
- :MH_NOUNDEFS => 0x1,
133
- :MH_INCRLINK => 0x2,
134
- :MH_DYLDLINK => 0x4,
135
- :MH_BINDATLOAD => 0x8,
136
- :MH_PREBOUND => 0x10,
137
- :MH_SPLIT_SEGS => 0x20,
138
- :MH_LAZY_INIT => 0x40,
139
- :MH_TWOLEVEL => 0x80,
140
- :MH_FORCE_FLAT => 0x100,
141
- :MH_NOMULTIDEFS => 0x200,
142
- :MH_NOPREFIXBINDING => 0x400,
143
- :MH_PREBINDABLE => 0x800,
144
- :MH_ALLMODSBOUND => 0x1000,
145
- :MH_SUBSECTIONS_VIA_SYMBOLS => 0x2000,
146
- :MH_CANONICAL => 0x4000,
147
- :MH_WEAK_DEFINES => 0x8000,
148
- :MH_BINDS_TO_WEAK => 0x10000,
149
- :MH_ALLOW_STACK_EXECUTION => 0x20000,
150
- :MH_ROOT_SAFE => 0x40000,
151
- :MH_SETUID_SAFE => 0x80000,
152
- :MH_NO_REEXPORTED_DYLIBS => 0x100000,
153
- :MH_PIE => 0x200000,
154
- :MH_DEAD_STRIPPABLE_DYLIB => 0x400000,
155
- :MH_HAS_TLV_DESCRIPTORS => 0x800000,
156
- :MH_NO_HEAP_EXECUTION => 0x1000000,
157
- :MH_APP_EXTENSION_SAFE => 0x02000000
158
- }
159
-
160
- # Fat binary header structure
161
- # @see MachO::FatArch
162
- class FatHeader < MachOStructure
163
- # @return [Fixnum] the magic number of the header (and file)
164
- attr_reader :magic
165
-
166
- # @return [Fixnum] the number of fat architecture structures following the header
167
- attr_reader :nfat_arch
168
-
169
- FORMAT = "VV"
170
- SIZEOF = 8
171
-
172
- # @api private
173
- def initialize(magic, nfat_arch)
174
- @magic = magic
175
- @nfat_arch = nfat_arch
176
- end
177
- end
178
-
179
- # Fat binary header architecture structure. A Fat binary has one or more of
180
- # these, representing one or more internal Mach-O blobs.
181
- # @see MachO::FatHeader
182
- class FatArch < MachOStructure
183
- # @return [Fixnum] the CPU type of the Mach-O
184
- attr_reader :cputype
185
-
186
- # @return [Fixnum] the CPU subtype of the Mach-O
187
- attr_reader :cpusubtype
188
-
189
- # @return [Fixnum] the file offset to the beginning of the Mach-O data
190
- attr_reader :offset
191
-
192
- # @return [Fixnum] the size, in bytes, of the Mach-O data
193
- attr_reader :size
194
-
195
- # @return [Fixnum] the alignment, as a power of 2
196
- attr_reader :align
197
-
198
- FORMAT = "VVVVV"
199
- SIZEOF = 20
200
-
201
- # @api private
202
- def initialize(cputype, cpusubtype, offset, size, align)
203
- @cputype = cputype
204
- @cpusubtype = cpusubtype
205
- @offset = offset
206
- @size = size
207
- @align = align
208
- end
209
- end
210
-
211
- # 32-bit Mach-O file header structure
212
- class MachHeader < MachOStructure
213
- # @return [Fixnum] the magic number
214
- attr_reader :magic
215
-
216
- # @return [Fixnum] the CPU type of the Mach-O
217
- attr_reader :cputype
218
-
219
- # @return [Fixnum] the CPU subtype of the Mach-O
220
- attr_reader :cpusubtype
221
-
222
- # @return [Fixnum] the file type of the Mach-O
223
- attr_reader :filetype
224
-
225
- # @return [Fixnum] the number of load commands in the Mach-O
226
- attr_reader :ncmds
227
-
228
- # @return [Fixnum] the size of all load commands, in bytes, in the Mach-O
229
- attr_reader :sizeofcmds
230
-
231
- # @return [Fixnum] the header flags associated with the Mach-O
232
- attr_reader :flags
233
-
234
- FORMAT = "VVVVVVV"
235
- SIZEOF = 28
236
-
237
- # @api private
238
- def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
239
- flags)
240
- @magic = magic
241
- @cputype = cputype
242
- @cpusubtype = cpusubtype
243
- @filetype = filetype
244
- @ncmds = ncmds
245
- @sizeofcmds = sizeofcmds
246
- @flags = flags
247
- end
248
-
249
- # @example
250
- # puts "this mach-o has position-independent execution" if header.flag?(:MH_PIE)
251
- # @param flag [Symbol] a mach header flag symbol
252
- # @return [Boolean] true if `flag` is present in the header's flag section
253
- def flag?(flag)
254
- flag = MH_FLAGS[flag]
255
- return false if flag.nil?
256
- flags & flag == flag
257
- end
258
- end
259
-
260
- # 64-bit Mach-O file header structure
261
- class MachHeader64 < MachHeader
262
- # @return [void]
263
- attr_reader :reserved
264
-
265
- FORMAT = "VVVVVVVV"
266
- SIZEOF = 32
267
-
268
- # @api private
269
- def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
270
- flags, reserved)
271
- super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
272
- @reserved = reserved
273
- end
274
- end
34
+ # any CPU (unused?)
35
+ CPU_TYPE_ANY = -1
36
+
37
+ # i386 and later compatible CPUs
38
+ CPU_TYPE_I386 = 0x07
39
+
40
+ # x86_64 (AMD64) compatible CPUs
41
+ CPU_TYPE_X86_64 = (CPU_TYPE_I386 | CPU_ARCH_ABI64)
42
+
43
+ # 32-bit ARM compatible CPUs
44
+ CPU_TYPE_ARM = 0x0c
45
+
46
+ # 64-bit ARM compatible CPUs
47
+ CPU_TYPE_ARM64 = (CPU_TYPE_ARM | CPU_ARCH_ABI64)
48
+
49
+ # PowerPC compatible CPUs
50
+ CPU_TYPE_POWERPC = 0x12
51
+
52
+ # PowerPC64 compatible CPUs
53
+ CPU_TYPE_POWERPC64 = (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
54
+
55
+ # association of cpu types to symbol representations
56
+ CPU_TYPES = {
57
+ CPU_TYPE_ANY => :any,
58
+ CPU_TYPE_I386 => :i386,
59
+ CPU_TYPE_X86_64 => :x86_64,
60
+ CPU_TYPE_ARM => :arm,
61
+ CPU_TYPE_ARM64 => :arm64,
62
+ CPU_TYPE_POWERPC => :ppc,
63
+ CPU_TYPE_POWERPC64 => :ppc64,
64
+ }
65
+
66
+ # mask for CPU subtype capabilities
67
+ CPU_SUBTYPE_MASK = 0xff000000
68
+
69
+ # 64-bit libraries (undocumented!)
70
+ # @see http://llvm.org/docs/doxygen/html/Support_2MachO_8h_source.html
71
+ CPU_SUBTYPE_LIB64 = 0x80000000
72
+
73
+ # the lowest common sub-type for `CPU_TYPE_I386`
74
+ CPU_SUBTYPE_X86_ALL = 3
75
+
76
+ # the lowest common sub-type for `CPU_TYPE_X86_64`
77
+ CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_X86_ALL
78
+
79
+ # the Haskell sub-type for `CPU_TYPE_X86_64`
80
+ CPU_SUBTYPE_X86_64_H = 8
81
+
82
+ # the lowest common sub-type for `CPU_TYPE_ARM`
83
+ CPU_SUBTYPE_ARM_ALL = 0
84
+
85
+ # the v7 sub-type for `CPU_TYPE_ARM`
86
+ CPU_SUBTYPE_ARM_V7 = 9
87
+
88
+ # the v7s sub-type for `CPU_TYPE_ARM`
89
+ CPU_SUBTYPE_ARM_V7S = 11
90
+
91
+ # the v7k sub-type for `CPU_TYPE_ARM`
92
+ CPU_SUBTYPE_ARM_V7K = 12
93
+
94
+ # the v8 sub-type for `CPU_TYPE_ARM`
95
+ CPU_SUBTYPE_ARM_V8 = 13
96
+
97
+ # the lowest common sub-type for `CPU_TYPE_ARM64`
98
+ CPU_SUBTYPE_ARM64_ALL = 0
99
+
100
+ # the v8 sub-type for `CPU_TYPE_ARM64`
101
+ CPU_SUBTYPE_ARM64_V8 = 1
102
+
103
+ # the lowest common sub-type for `CPU_TYPE_POWERPC`
104
+ CPU_SUBTYPE_POWERPC_ALL = 0
105
+
106
+ # the 750 (G3) sub-type for `CPU_TYPE_POWERPC`
107
+ CPU_SUBTYPE_POWERPC_750 = 9
108
+
109
+ # the 7400 (G4) sub-type for `CPU_TYPE_POWERPC`
110
+ CPU_SUBTYPE_POWERPC_7400 = 10
111
+
112
+ # the 7450 (G4 "Voyager") sub-type for `CPU_TYPE_POWERPC`
113
+ CPU_SUBTYPE_POWERPC_7450 = 11
114
+
115
+ # the 970 (G5) sub-type for `CPU_TYPE_POWERPC`
116
+ CPU_SUBTYPE_POWERPC_970 = 100
117
+
118
+ # any CPU sub-type for CPU type `CPU_TYPE_POWERPC64`
119
+ CPU_SUBTYPE_POWERPC64_ALL = CPU_SUBTYPE_POWERPC_ALL
120
+
121
+ # association of CPU types/subtype pairs to symbol representations
122
+ CPU_SUBTYPES = {
123
+ CPU_TYPE_I386 => {
124
+ CPU_SUBTYPE_X86_ALL => :i386,
125
+ }.freeze,
126
+ CPU_TYPE_X86_64 => {
127
+ CPU_SUBTYPE_X86_64_ALL => :x86_64,
128
+ CPU_SUBTYPE_X86_64_H => :x86_64h,
129
+ }.freeze,
130
+ CPU_TYPE_ARM => {
131
+ CPU_SUBTYPE_ARM_ALL => :arm,
132
+ CPU_SUBTYPE_ARM_V7 => :armv7,
133
+ CPU_SUBTYPE_ARM_V7S => :armv7s,
134
+ CPU_SUBTYPE_ARM_V7K => :armv7k,
135
+ CPU_SUBTYPE_ARM_V8 => :armv8,
136
+ }.freeze,
137
+ CPU_TYPE_ARM64 => {
138
+ CPU_SUBTYPE_ARM64_ALL => :arm64,
139
+ CPU_SUBTYPE_ARM64_V8 => :armv8,
140
+ }.freeze,
141
+ CPU_TYPE_POWERPC => {
142
+ CPU_SUBTYPE_POWERPC_ALL => :ppc,
143
+ CPU_SUBTYPE_POWERPC_750 => :ppc750,
144
+ CPU_SUBTYPE_POWERPC_7400 => :ppc7400,
145
+ CPU_SUBTYPE_POWERPC_7450 => :ppc7450,
146
+ CPU_SUBTYPE_POWERPC_970 => :ppc970,
147
+ }.freeze,
148
+ CPU_TYPE_POWERPC64 => {
149
+ CPU_SUBTYPE_POWERPC64_ALL => :ppc64,
150
+ }.freeze,
151
+ }.freeze
152
+
153
+ # relocatable object file
154
+ MH_OBJECT = 0x1
155
+
156
+ # demand paged executable file
157
+ MH_EXECUTE = 0x2
158
+
159
+ # fixed VM shared library file
160
+ MH_FVMLIB = 0x3
161
+
162
+ # core dump file
163
+ MH_CORE = 0x4
164
+
165
+ # preloaded executable file
166
+ MH_PRELOAD = 0x5
167
+
168
+ # dynamically bound shared library
169
+ MH_DYLIB = 0x6
170
+
171
+ # dynamic link editor
172
+ MH_DYLINKER = 0x7
173
+
174
+ # dynamically bound bundle file
175
+ MH_BUNDLE = 0x8
176
+
177
+ # shared library stub for static linking only, no section contents
178
+ MH_DYLIB_STUB = 0x9
179
+
180
+ # companion file with only debug sections
181
+ MH_DSYM = 0xa
182
+
183
+ # x86_64 kexts
184
+ MH_KEXT_BUNDLE = 0xb
185
+
186
+ # association of filetypes to string representations
187
+ # @api private
188
+ MH_FILETYPES = {
189
+ MH_OBJECT => "MH_OBJECT",
190
+ MH_EXECUTE => "MH_EXECUTE",
191
+ MH_FVMLIB => "MH_FVMLIB",
192
+ MH_CORE => "MH_CORE",
193
+ MH_PRELOAD => "MH_PRELOAD",
194
+ MH_DYLIB => "MH_DYLIB",
195
+ MH_DYLINKER => "MH_DYLINKER",
196
+ MH_BUNDLE => "MH_BUNDLE",
197
+ MH_DYLIB_STUB => "MH_DYLIB_STUB",
198
+ MH_DSYM => "MH_DSYM",
199
+ MH_KEXT_BUNDLE => "MH_KEXT_BUNDLE"
200
+ }
201
+
202
+ # association of mach header flag symbols to values
203
+ # @api private
204
+ MH_FLAGS = {
205
+ :MH_NOUNDEFS => 0x1,
206
+ :MH_INCRLINK => 0x2,
207
+ :MH_DYLDLINK => 0x4,
208
+ :MH_BINDATLOAD => 0x8,
209
+ :MH_PREBOUND => 0x10,
210
+ :MH_SPLIT_SEGS => 0x20,
211
+ :MH_LAZY_INIT => 0x40,
212
+ :MH_TWOLEVEL => 0x80,
213
+ :MH_FORCE_FLAT => 0x100,
214
+ :MH_NOMULTIDEFS => 0x200,
215
+ :MH_NOPREFIXBINDING => 0x400,
216
+ :MH_PREBINDABLE => 0x800,
217
+ :MH_ALLMODSBOUND => 0x1000,
218
+ :MH_SUBSECTIONS_VIA_SYMBOLS => 0x2000,
219
+ :MH_CANONICAL => 0x4000,
220
+ :MH_WEAK_DEFINES => 0x8000,
221
+ :MH_BINDS_TO_WEAK => 0x10000,
222
+ :MH_ALLOW_STACK_EXECUTION => 0x20000,
223
+ :MH_ROOT_SAFE => 0x40000,
224
+ :MH_SETUID_SAFE => 0x80000,
225
+ :MH_NO_REEXPORTED_DYLIBS => 0x100000,
226
+ :MH_PIE => 0x200000,
227
+ :MH_DEAD_STRIPPABLE_DYLIB => 0x400000,
228
+ :MH_HAS_TLV_DESCRIPTORS => 0x800000,
229
+ :MH_NO_HEAP_EXECUTION => 0x1000000,
230
+ :MH_APP_EXTENSION_SAFE => 0x02000000
231
+ }
232
+
233
+ # Fat binary header structure
234
+ # @see MachO::FatArch
235
+ class FatHeader < MachOStructure
236
+ # @return [Fixnum] the magic number of the header (and file)
237
+ attr_reader :magic
238
+
239
+ # @return [Fixnum] the number of fat architecture structures following the header
240
+ attr_reader :nfat_arch
241
+
242
+ # always big-endian
243
+ FORMAT = "N2"
244
+ SIZEOF = 8
245
+
246
+ # @api private
247
+ def initialize(magic, nfat_arch)
248
+ @magic = magic
249
+ @nfat_arch = nfat_arch
250
+ end
251
+ end
252
+
253
+ # Fat binary header architecture structure. A Fat binary has one or more of
254
+ # these, representing one or more internal Mach-O blobs.
255
+ # @see MachO::FatHeader
256
+ class FatArch < MachOStructure
257
+ # @return [Fixnum] the CPU type of the Mach-O
258
+ attr_reader :cputype
259
+
260
+ # @return [Fixnum] the CPU subtype of the Mach-O
261
+ attr_reader :cpusubtype
262
+
263
+ # @return [Fixnum] the file offset to the beginning of the Mach-O data
264
+ attr_reader :offset
265
+
266
+ # @return [Fixnum] the size, in bytes, of the Mach-O data
267
+ attr_reader :size
268
+
269
+ # @return [Fixnum] the alignment, as a power of 2
270
+ attr_reader :align
271
+
272
+ # always big-endian
273
+ FORMAT = "N5"
274
+ SIZEOF = 20
275
+
276
+ # @api private
277
+ def initialize(cputype, cpusubtype, offset, size, align)
278
+ @cputype = cputype
279
+ @cpusubtype = cpusubtype
280
+ @offset = offset
281
+ @size = size
282
+ @align = align
283
+ end
284
+ end
285
+
286
+ # 32-bit Mach-O file header structure
287
+ class MachHeader < MachOStructure
288
+ # @return [Fixnum] the magic number
289
+ attr_reader :magic
290
+
291
+ # @return [Fixnum] the CPU type of the Mach-O
292
+ attr_reader :cputype
293
+
294
+ # @return [Fixnum] the CPU subtype of the Mach-O
295
+ attr_reader :cpusubtype
296
+
297
+ # @return [Fixnum] the file type of the Mach-O
298
+ attr_reader :filetype
299
+
300
+ # @return [Fixnum] the number of load commands in the Mach-O
301
+ attr_reader :ncmds
302
+
303
+ # @return [Fixnum] the size of all load commands, in bytes, in the Mach-O
304
+ attr_reader :sizeofcmds
305
+
306
+ # @return [Fixnum] the header flags associated with the Mach-O
307
+ attr_reader :flags
308
+
309
+ FORMAT = "L=7"
310
+ SIZEOF = 28
311
+
312
+ # @api private
313
+ def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
314
+ flags)
315
+ @magic = magic
316
+ @cputype = cputype
317
+ # For now we're not interested in additional capability bits also to be
318
+ # found in the `cpusubtype` field. We only care about the CPU sub-type.
319
+ @cpusubtype = cpusubtype & ~CPU_SUBTYPE_MASK
320
+ @filetype = filetype
321
+ @ncmds = ncmds
322
+ @sizeofcmds = sizeofcmds
323
+ @flags = flags
324
+ end
325
+
326
+ # @example
327
+ # puts "this mach-o has position-independent execution" if header.flag?(:MH_PIE)
328
+ # @param flag [Symbol] a mach header flag symbol
329
+ # @return [Boolean] true if `flag` is present in the header's flag section
330
+ def flag?(flag)
331
+ flag = MH_FLAGS[flag]
332
+ return false if flag.nil?
333
+ flags & flag == flag
334
+ end
335
+ end
336
+
337
+ # 64-bit Mach-O file header structure
338
+ class MachHeader64 < MachHeader
339
+ # @return [void]
340
+ attr_reader :reserved
341
+
342
+ FORMAT = "L=8"
343
+ SIZEOF = 32
344
+
345
+ # @api private
346
+ def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
347
+ flags, reserved)
348
+ super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
349
+ @reserved = reserved
350
+ end
351
+ end
275
352
  end