ruby-macho 0.2.2 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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