ruby-macho 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -9
- data/lib/macho.rb +2 -1
- data/lib/macho/exceptions.rb +83 -6
- data/lib/macho/fat_file.rb +130 -39
- data/lib/macho/headers.rb +131 -25
- data/lib/macho/load_commands.rb +518 -177
- data/lib/macho/macho_file.rb +254 -172
- data/lib/macho/open.rb +5 -5
- data/lib/macho/sections.rb +20 -9
- data/lib/macho/structure.rb +8 -16
- data/lib/macho/tools.rb +34 -15
- data/lib/macho/utils.rb +87 -39
- data/lib/macho/view.rb +23 -0
- metadata +4 -2
data/lib/macho/load_commands.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module MachO
|
2
2
|
# load commands added after OS X 10.1 need to be bitwise ORed with
|
3
3
|
# LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
|
4
|
+
# @api private
|
4
5
|
LC_REQ_DYLD = 0x80000000
|
5
6
|
|
6
7
|
# association of load commands to symbol representations
|
@@ -57,6 +58,10 @@ module MachO
|
|
57
58
|
0x30 => :LC_VERSION_MIN_WATCHOS,
|
58
59
|
}.freeze
|
59
60
|
|
61
|
+
# association of symbol representations to load command constants
|
62
|
+
# @api private
|
63
|
+
LOAD_COMMAND_CONSTANTS = LOAD_COMMANDS.invert.freeze
|
64
|
+
|
60
65
|
# load commands responsible for loading dylibs
|
61
66
|
# @api private
|
62
67
|
DYLIB_LOAD_COMMANDS = [
|
@@ -67,19 +72,27 @@ module MachO
|
|
67
72
|
:LC_LOAD_UPWARD_DYLIB,
|
68
73
|
].freeze
|
69
74
|
|
75
|
+
# load commands that can be created manually via {LoadCommand.create}
|
76
|
+
# @api private
|
77
|
+
CREATABLE_LOAD_COMMANDS = DYLIB_LOAD_COMMANDS + [
|
78
|
+
:LC_ID_DYLIB,
|
79
|
+
:LC_RPATH,
|
80
|
+
:LC_LOAD_DYLINKER,
|
81
|
+
].freeze
|
82
|
+
|
70
83
|
# association of load command symbols to string representations of classes
|
71
84
|
# @api private
|
72
85
|
LC_STRUCTURES = {
|
73
86
|
:LC_SEGMENT => "SegmentCommand",
|
74
87
|
:LC_SYMTAB => "SymtabCommand",
|
75
|
-
:LC_SYMSEG => "
|
88
|
+
:LC_SYMSEG => "SymsegCommand", # obsolete
|
76
89
|
:LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such
|
77
90
|
:LC_UNIXTHREAD => "ThreadCommand",
|
78
|
-
:LC_LOADFVMLIB => "
|
79
|
-
:LC_IDFVMLIB => "
|
80
|
-
:LC_IDENT => "
|
81
|
-
:LC_FVMFILE => "
|
82
|
-
:LC_PREPAGE => "LoadCommand", # reserved for internal use only
|
91
|
+
:LC_LOADFVMLIB => "FvmlibCommand", # obsolete
|
92
|
+
:LC_IDFVMLIB => "FvmlibCommand", # obsolete
|
93
|
+
:LC_IDENT => "IdentCommand", # obsolete
|
94
|
+
:LC_FVMFILE => "FvmfileCommand", # reserved for internal use only
|
95
|
+
:LC_PREPAGE => "LoadCommand", # reserved for internal use only, no public struct
|
83
96
|
:LC_DYSYMTAB => "DysymtabCommand",
|
84
97
|
:LC_LOAD_DYLIB => "DylibCommand",
|
85
98
|
:LC_ID_DYLIB => "DylibCommand",
|
@@ -148,8 +161,8 @@ module MachO
|
|
148
161
|
# represented, and no actual data. Used when a more specific class
|
149
162
|
# isn't available/implemented.
|
150
163
|
class LoadCommand < MachOStructure
|
151
|
-
# @return [
|
152
|
-
attr_reader :
|
164
|
+
# @return [MachO::MachOView] the raw view associated with the load command
|
165
|
+
attr_reader :view
|
153
166
|
|
154
167
|
# @return [Fixnum] the load command's identifying number
|
155
168
|
attr_reader :cmd
|
@@ -157,40 +170,80 @@ module MachO
|
|
157
170
|
# @return [Fixnum] the size of the load command, in bytes
|
158
171
|
attr_reader :cmdsize
|
159
172
|
|
160
|
-
|
173
|
+
# @see MachOStructure::FORMAT
|
174
|
+
# @api private
|
175
|
+
FORMAT = "L=2".freeze
|
176
|
+
|
177
|
+
# @see MachOStructure::SIZEOF
|
178
|
+
# @api private
|
161
179
|
SIZEOF = 8
|
162
180
|
|
163
|
-
#
|
164
|
-
# @param
|
165
|
-
# @param endianness [Symbol] the endianness of the command (:big or :little)
|
166
|
-
# @param offset [Fixnum] the offset to initialize with
|
167
|
-
# @param bin [String] the binary string to initialize with
|
181
|
+
# Instantiates a new LoadCommand given a view into its origin Mach-O
|
182
|
+
# @param view [MachO::MachOView] the load command's raw view
|
168
183
|
# @return [MachO::LoadCommand] the new load command
|
169
184
|
# @api private
|
170
|
-
def self.new_from_bin(
|
171
|
-
|
185
|
+
def self.new_from_bin(view)
|
186
|
+
bin = view.raw_data.slice(view.offset, bytesize)
|
187
|
+
format = Utils.specialize_format(self::FORMAT, view.endianness)
|
188
|
+
|
189
|
+
new(view, *bin.unpack(format))
|
190
|
+
end
|
191
|
+
|
192
|
+
# Creates a new (viewless) command corresponding to the symbol provided
|
193
|
+
# @param cmd_sym [Symbol] the symbol of the load command being created
|
194
|
+
# @param args [Array] the arguments for the load command being created
|
195
|
+
def self.create(cmd_sym, *args)
|
196
|
+
raise LoadCommandNotCreatableError, cmd_sym unless CREATABLE_LOAD_COMMANDS.include?(cmd_sym)
|
197
|
+
|
198
|
+
klass = MachO.const_get LC_STRUCTURES[cmd_sym]
|
199
|
+
cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
|
172
200
|
|
173
|
-
|
201
|
+
# cmd will be filled in, view and cmdsize will be left unpopulated
|
202
|
+
klass_arity = klass.instance_method(:initialize).arity - 3
|
203
|
+
|
204
|
+
raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity != args.size
|
205
|
+
|
206
|
+
klass.new(nil, cmd, nil, *args)
|
174
207
|
end
|
175
208
|
|
176
|
-
# @param
|
177
|
-
# @param offset [Fixnum] the offset to initialize with
|
209
|
+
# @param view [MachO::MachOView] the load command's raw view
|
178
210
|
# @param cmd [Fixnum] the load command's identifying number
|
179
211
|
# @param cmdsize [Fixnum] the size of the load command in bytes
|
180
212
|
# @api private
|
181
|
-
def initialize(
|
182
|
-
@
|
183
|
-
@offset = offset
|
213
|
+
def initialize(view, cmd, cmdsize)
|
214
|
+
@view = view
|
184
215
|
@cmd = cmd
|
185
216
|
@cmdsize = cmdsize
|
186
217
|
end
|
187
218
|
|
219
|
+
# @return [Boolean] true if the load command can be serialized, false otherwise
|
220
|
+
def serializable?
|
221
|
+
CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
|
222
|
+
end
|
223
|
+
|
224
|
+
# @param context [MachO::LoadCommand::SerializationContext] the context
|
225
|
+
# to serialize into
|
226
|
+
# @return [String, nil] the serialized fields of the load command, or nil
|
227
|
+
# if the load command can't be serialized
|
228
|
+
# @api private
|
229
|
+
def serialize(context)
|
230
|
+
raise LoadCommandNotSerializableError, LOAD_COMMANDS[cmd] unless serializable?
|
231
|
+
format = Utils.specialize_format(FORMAT, context.endianness)
|
232
|
+
[cmd, SIZEOF].pack(format)
|
233
|
+
end
|
234
|
+
|
235
|
+
# @return [Fixnum] the load command's offset in the source file
|
236
|
+
# @deprecated use {#view} instead
|
237
|
+
def offset
|
238
|
+
view.offset
|
239
|
+
end
|
240
|
+
|
188
241
|
# @return [Symbol] a symbol representation of the load command's identifying number
|
189
242
|
def type
|
190
243
|
LOAD_COMMANDS[cmd]
|
191
244
|
end
|
192
245
|
|
193
|
-
alias
|
246
|
+
alias to_sym type
|
194
247
|
|
195
248
|
# @return [String] a string representation of the load command's identifying number
|
196
249
|
def to_s
|
@@ -202,25 +255,62 @@ module MachO
|
|
202
255
|
# pretend that strings stored in LCs are immediately available without
|
203
256
|
# explicit operations on the raw Mach-O data.
|
204
257
|
class LCStr
|
205
|
-
# @param raw_data [String] the raw Mach-O data.
|
206
258
|
# @param lc [MachO::LoadCommand] the load command
|
207
|
-
# @param lc_str [Fixnum] the offset to the beginning of the string
|
259
|
+
# @param lc_str [Fixnum, String] the offset to the beginning of the string,
|
260
|
+
# or the string itself if not being initialized with a view.
|
261
|
+
# @raise [MachO::LCStrMalformedError] if the string is malformed
|
262
|
+
# @todo devise a solution such that the `lc_str` parameter is not
|
263
|
+
# interpreted differently depending on `lc.view`. The current behavior
|
264
|
+
# is a hack to allow viewless load command creation.
|
208
265
|
# @api private
|
209
|
-
def initialize(
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
266
|
+
def initialize(lc, lc_str)
|
267
|
+
view = lc.view
|
268
|
+
|
269
|
+
if view
|
270
|
+
lc_str_abs = view.offset + lc_str
|
271
|
+
lc_end = view.offset + lc.cmdsize - 1
|
272
|
+
raw_string = view.raw_data.slice(lc_str_abs..lc_end)
|
273
|
+
@string, null_byte, _padding = raw_string.partition("\x00")
|
274
|
+
raise LCStrMalformedError, lc if null_byte.empty?
|
275
|
+
@string_offset = lc_str
|
276
|
+
else
|
277
|
+
@string = lc_str
|
278
|
+
@string_offset = 0
|
279
|
+
end
|
214
280
|
end
|
215
281
|
|
216
282
|
# @return [String] a string representation of the LCStr
|
217
283
|
def to_s
|
218
|
-
@
|
284
|
+
@string
|
219
285
|
end
|
220
286
|
|
221
287
|
# @return [Fixnum] the offset to the beginning of the string in the load command
|
222
288
|
def to_i
|
223
|
-
@
|
289
|
+
@string_offset
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# Represents the contextual information needed by a load command to
|
294
|
+
# serialize itself correctly into a binary string.
|
295
|
+
class SerializationContext
|
296
|
+
# @return [Symbol] the endianness of the serialized load command
|
297
|
+
attr_reader :endianness
|
298
|
+
|
299
|
+
# @return [Fixnum] the constant alignment value used to pad the serialized load command
|
300
|
+
attr_reader :alignment
|
301
|
+
|
302
|
+
# @param macho [MachO::MachOFile] the file to contextualize
|
303
|
+
# @return [MachO::LoadCommand::SerializationContext] the resulting context
|
304
|
+
def self.context_for(macho)
|
305
|
+
new(macho.endianness, macho.alignment)
|
306
|
+
end
|
307
|
+
|
308
|
+
# @param endianness [Symbol] the endianness of the context
|
309
|
+
# @param alignment [Fixnum] the alignment of the context
|
310
|
+
# @api private
|
311
|
+
def initialize(endianness, alignment)
|
312
|
+
@endianness = endianness
|
313
|
+
@alignment = alignment
|
224
314
|
end
|
225
315
|
end
|
226
316
|
end
|
@@ -231,12 +321,17 @@ module MachO
|
|
231
321
|
# @return [Array<Fixnum>] the UUID
|
232
322
|
attr_reader :uuid
|
233
323
|
|
234
|
-
|
324
|
+
# @see MachOStructure::FORMAT
|
325
|
+
# @api private
|
326
|
+
FORMAT = "L=2a16".freeze
|
327
|
+
|
328
|
+
# @see MachOStructure::SIZEOF
|
329
|
+
# @api private
|
235
330
|
SIZEOF = 24
|
236
331
|
|
237
332
|
# @api private
|
238
|
-
def initialize(
|
239
|
-
super(
|
333
|
+
def initialize(view, cmd, cmdsize, uuid)
|
334
|
+
super(view, cmd, cmdsize)
|
240
335
|
@uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
|
241
336
|
end
|
242
337
|
|
@@ -282,13 +377,18 @@ module MachO
|
|
282
377
|
# @return [Fixnum] any flags associated with the segment
|
283
378
|
attr_reader :flags
|
284
379
|
|
285
|
-
|
380
|
+
# @see MachOStructure::FORMAT
|
381
|
+
# @api private
|
382
|
+
FORMAT = "L=2a16L=4l=2L=2".freeze
|
383
|
+
|
384
|
+
# @see MachOStructure::SIZEOF
|
385
|
+
# @api private
|
286
386
|
SIZEOF = 56
|
287
387
|
|
288
388
|
# @api private
|
289
|
-
def initialize(
|
290
|
-
|
291
|
-
super(
|
389
|
+
def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
390
|
+
filesize, maxprot, initprot, nsects, flags)
|
391
|
+
super(view, cmd, cmdsize)
|
292
392
|
@segname = segname.delete("\x00")
|
293
393
|
@vmaddr = vmaddr
|
294
394
|
@vmsize = vmsize
|
@@ -300,6 +400,23 @@ module MachO
|
|
300
400
|
@flags = flags
|
301
401
|
end
|
302
402
|
|
403
|
+
# All sections referenced within this segment.
|
404
|
+
# @return [Array<MachO::Section>] if the Mach-O is 32-bit
|
405
|
+
# @return [Array<MachO::Section64>] if the Mach-O is 64-bit
|
406
|
+
def sections
|
407
|
+
klass = case self
|
408
|
+
when MachO::SegmentCommand64
|
409
|
+
MachO::Section64
|
410
|
+
when MachO::SegmentCommand
|
411
|
+
MachO::Section
|
412
|
+
end
|
413
|
+
|
414
|
+
bins = view.raw_data[view.offset + self.class.bytesize, nsects * klass.bytesize]
|
415
|
+
bins.unpack("a#{klass.bytesize}" * nsects).map do |bin|
|
416
|
+
klass.new_from_bin(view.endianness, bin)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
303
420
|
# @example
|
304
421
|
# puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
|
305
422
|
# @param flag [Symbol] a segment flag symbol
|
@@ -313,61 +430,14 @@ module MachO
|
|
313
430
|
|
314
431
|
# A load command indicating that part of this file is to be mapped into
|
315
432
|
# the task's address space. Corresponds to LC_SEGMENT_64.
|
316
|
-
class SegmentCommand64 <
|
317
|
-
# @
|
318
|
-
attr_reader :segname
|
319
|
-
|
320
|
-
# @return [Fixnum] the memory address of the segment
|
321
|
-
attr_reader :vmaddr
|
322
|
-
|
323
|
-
# @return [Fixnum] the memory size of the segment
|
324
|
-
attr_reader :vmsize
|
325
|
-
|
326
|
-
# @return [Fixnum] the file offset of the segment
|
327
|
-
attr_reader :fileoff
|
328
|
-
|
329
|
-
# @return [Fixnum] the amount to map from the file
|
330
|
-
attr_reader :filesize
|
331
|
-
|
332
|
-
# @return [Fixnum] the maximum VM protection
|
333
|
-
attr_reader :maxprot
|
334
|
-
|
335
|
-
# @return [Fixnum] the initial VM protection
|
336
|
-
attr_reader :initprot
|
337
|
-
|
338
|
-
# @return [Fixnum] the number of sections in the segment
|
339
|
-
attr_reader :nsects
|
340
|
-
|
341
|
-
# @return [Fixnum] any flags associated with the segment
|
342
|
-
attr_reader :flags
|
343
|
-
|
344
|
-
FORMAT = "L=2a16Q=4l=2L=2"
|
345
|
-
SIZEOF = 72
|
346
|
-
|
433
|
+
class SegmentCommand64 < SegmentCommand
|
434
|
+
# @see MachOStructure::FORMAT
|
347
435
|
# @api private
|
348
|
-
|
349
|
-
filesize, maxprot, initprot, nsects, flags)
|
350
|
-
super(raw_data, offset, cmd, cmdsize)
|
351
|
-
@segname = segname.delete("\x00")
|
352
|
-
@vmaddr = vmaddr
|
353
|
-
@vmsize = vmsize
|
354
|
-
@fileoff = fileoff
|
355
|
-
@filesize = filesize
|
356
|
-
@maxprot = maxprot
|
357
|
-
@initprot = initprot
|
358
|
-
@nsects = nsects
|
359
|
-
@flags = flags
|
360
|
-
end
|
436
|
+
FORMAT = "L=2a16Q=4l=2L=2".freeze
|
361
437
|
|
362
|
-
# @
|
363
|
-
#
|
364
|
-
|
365
|
-
# @return [Boolean] true if `flag` is present in the segment's flag field
|
366
|
-
def flag?(flag)
|
367
|
-
flag = SEGMENT_FLAGS[flag]
|
368
|
-
return false if flag.nil?
|
369
|
-
flags & flag == flag
|
370
|
-
end
|
438
|
+
# @see MachOStructure::SIZEOF
|
439
|
+
# @api private
|
440
|
+
SIZEOF = 72
|
371
441
|
end
|
372
442
|
|
373
443
|
# A load command representing some aspect of shared libraries, depending
|
@@ -386,18 +456,33 @@ module MachO
|
|
386
456
|
# @return [Fixnum] the library's compatibility version number
|
387
457
|
attr_reader :compatibility_version
|
388
458
|
|
389
|
-
|
459
|
+
# @see MachOStructure::FORMAT
|
460
|
+
# @api private
|
461
|
+
FORMAT = "L=6".freeze
|
462
|
+
|
463
|
+
# @see MachOStructure::SIZEOF
|
464
|
+
# @api private
|
390
465
|
SIZEOF = 24
|
391
466
|
|
392
467
|
# @api private
|
393
|
-
def initialize(
|
394
|
-
|
395
|
-
|
396
|
-
@name = LCStr.new(raw_data, self, name)
|
468
|
+
def initialize(view, cmd, cmdsize, name, timestamp, current_version, compatibility_version)
|
469
|
+
super(view, cmd, cmdsize)
|
470
|
+
@name = LCStr.new(self, name)
|
397
471
|
@timestamp = timestamp
|
398
472
|
@current_version = current_version
|
399
473
|
@compatibility_version = compatibility_version
|
400
474
|
end
|
475
|
+
|
476
|
+
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
477
|
+
# @return [String] the serialized fields of the load command
|
478
|
+
# @api private
|
479
|
+
def serialize(context)
|
480
|
+
format = Utils.specialize_format(FORMAT, context.endianness)
|
481
|
+
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
|
482
|
+
cmdsize = SIZEOF + string_payload.bytesize
|
483
|
+
[cmd, cmdsize, string_offsets[:name], timestamp, current_version,
|
484
|
+
compatibility_version].pack(format) + string_payload
|
485
|
+
end
|
401
486
|
end
|
402
487
|
|
403
488
|
# A load command representing some aspect of the dynamic linker, depending
|
@@ -407,13 +492,28 @@ module MachO
|
|
407
492
|
# @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
|
408
493
|
attr_reader :name
|
409
494
|
|
410
|
-
|
495
|
+
# @see MachOStructure::FORMAT
|
496
|
+
# @api private
|
497
|
+
FORMAT = "L=3".freeze
|
498
|
+
|
499
|
+
# @see MachOStructure::SIZEOF
|
500
|
+
# @api private
|
411
501
|
SIZEOF = 12
|
412
502
|
|
413
503
|
# @api private
|
414
|
-
def initialize(
|
415
|
-
super(
|
416
|
-
@name = LCStr.new(
|
504
|
+
def initialize(view, cmd, cmdsize, name)
|
505
|
+
super(view, cmd, cmdsize)
|
506
|
+
@name = LCStr.new(self, name)
|
507
|
+
end
|
508
|
+
|
509
|
+
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
510
|
+
# @return [String] the serialized fields of the load command
|
511
|
+
# @api private
|
512
|
+
def serialize(context)
|
513
|
+
format = Utils.specialize_format(FORMAT, context.endianness)
|
514
|
+
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
|
515
|
+
cmdsize = SIZEOF + string_payload.bytesize
|
516
|
+
[cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
|
417
517
|
end
|
418
518
|
end
|
419
519
|
|
@@ -429,13 +529,18 @@ module MachO
|
|
429
529
|
# @return [Fixnum] a bit vector of linked modules
|
430
530
|
attr_reader :linked_modules
|
431
531
|
|
432
|
-
|
532
|
+
# @see MachOStructure::FORMAT
|
533
|
+
# @api private
|
534
|
+
FORMAT = "L=5".freeze
|
535
|
+
|
536
|
+
# @see MachOStructure::SIZEOF
|
537
|
+
# @api private
|
433
538
|
SIZEOF = 20
|
434
539
|
|
435
540
|
# @api private
|
436
|
-
def initialize(
|
437
|
-
super(
|
438
|
-
@name = LCStr.new(
|
541
|
+
def initialize(view, cmd, cmdsize, name, nmodules, linked_modules)
|
542
|
+
super(view, cmd, cmdsize)
|
543
|
+
@name = LCStr.new(self, name)
|
439
544
|
@nmodules = nmodules
|
440
545
|
@linked_modules = linked_modules
|
441
546
|
end
|
@@ -444,7 +549,12 @@ module MachO
|
|
444
549
|
# A load command used to represent threads.
|
445
550
|
# @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize)
|
446
551
|
class ThreadCommand < LoadCommand
|
447
|
-
|
552
|
+
# @see MachOStructure::FORMAT
|
553
|
+
# @api private
|
554
|
+
FORMAT = "L=2".freeze
|
555
|
+
|
556
|
+
# @see MachOStructure::SIZEOF
|
557
|
+
# @api private
|
448
558
|
SIZEOF = 8
|
449
559
|
end
|
450
560
|
|
@@ -476,14 +586,18 @@ module MachO
|
|
476
586
|
# @return [void]
|
477
587
|
attr_reader :reserved6
|
478
588
|
|
479
|
-
|
589
|
+
# @see MachOStructure::FORMAT
|
590
|
+
# @api private
|
591
|
+
FORMAT = "L=10".freeze
|
592
|
+
|
593
|
+
# @see MachOStructure::SIZEOF
|
594
|
+
# @api private
|
480
595
|
SIZEOF = 40
|
481
596
|
|
482
597
|
# @api private
|
483
|
-
def initialize(
|
484
|
-
|
485
|
-
|
486
|
-
super(raw_data, offset, cmd, cmdsize)
|
598
|
+
def initialize(view, cmd, cmdsize, init_address, init_module, reserved1,
|
599
|
+
reserved2, reserved3, reserved4, reserved5, reserved6)
|
600
|
+
super(view, cmd, cmdsize)
|
487
601
|
@init_address = init_address
|
488
602
|
@init_module = init_module
|
489
603
|
@reserved1 = reserved1
|
@@ -523,14 +637,18 @@ module MachO
|
|
523
637
|
# @return [void]
|
524
638
|
attr_reader :reserved6
|
525
639
|
|
526
|
-
|
640
|
+
# @see MachOStructure::FORMAT
|
641
|
+
# @api private
|
642
|
+
FORMAT = "L=2Q=8".freeze
|
643
|
+
|
644
|
+
# @see MachOStructure::SIZEOF
|
645
|
+
# @api private
|
527
646
|
SIZEOF = 72
|
528
647
|
|
529
648
|
# @api private
|
530
|
-
def initialize(
|
531
|
-
|
532
|
-
|
533
|
-
super(raw_data, offset, cmd, cmdsize)
|
649
|
+
def initialize(view, cmd, cmdsize, init_address, init_module, reserved1,
|
650
|
+
reserved2, reserved3, reserved4, reserved5, reserved6)
|
651
|
+
super(view, cmd, cmdsize)
|
534
652
|
@init_address = init_address
|
535
653
|
@init_module = init_module
|
536
654
|
@reserved1 = reserved1
|
@@ -548,13 +666,18 @@ module MachO
|
|
548
666
|
# @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr
|
549
667
|
attr_reader :umbrella
|
550
668
|
|
551
|
-
|
669
|
+
# @see MachOStructure::FORMAT
|
670
|
+
# @api private
|
671
|
+
FORMAT = "L=3".freeze
|
672
|
+
|
673
|
+
# @see MachOStructure::SIZEOF
|
674
|
+
# @api private
|
552
675
|
SIZEOF = 12
|
553
676
|
|
554
677
|
# @api private
|
555
|
-
def initialize(
|
556
|
-
super(
|
557
|
-
@umbrella = LCStr.new(
|
678
|
+
def initialize(view, cmd, cmdsize, umbrella)
|
679
|
+
super(view, cmd, cmdsize)
|
680
|
+
@umbrella = LCStr.new(self, umbrella)
|
558
681
|
end
|
559
682
|
end
|
560
683
|
|
@@ -564,13 +687,18 @@ module MachO
|
|
564
687
|
# @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr
|
565
688
|
attr_reader :sub_umbrella
|
566
689
|
|
567
|
-
|
690
|
+
# @see MachOStructure::FORMAT
|
691
|
+
# @api private
|
692
|
+
FORMAT = "L=3".freeze
|
693
|
+
|
694
|
+
# @see MachOStructure::SIZEOF
|
695
|
+
# @api private
|
568
696
|
SIZEOF = 12
|
569
697
|
|
570
698
|
# @api private
|
571
|
-
def initialize(
|
572
|
-
super(
|
573
|
-
@sub_umbrella = LCStr.new(
|
699
|
+
def initialize(view, cmd, cmdsize, sub_umbrella)
|
700
|
+
super(view, cmd, cmdsize)
|
701
|
+
@sub_umbrella = LCStr.new(self, sub_umbrella)
|
574
702
|
end
|
575
703
|
end
|
576
704
|
|
@@ -580,13 +708,18 @@ module MachO
|
|
580
708
|
# @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr
|
581
709
|
attr_reader :sub_library
|
582
710
|
|
583
|
-
|
711
|
+
# @see MachOStructure::FORMAT
|
712
|
+
# @api private
|
713
|
+
FORMAT = "L=3".freeze
|
714
|
+
|
715
|
+
# @see MachOStructure::SIZEOF
|
716
|
+
# @api private
|
584
717
|
SIZEOF = 12
|
585
718
|
|
586
719
|
# @api private
|
587
|
-
def initialize(
|
588
|
-
super(
|
589
|
-
@sub_library = LCStr.new(
|
720
|
+
def initialize(view, cmd, cmdsize, sub_library)
|
721
|
+
super(view, cmd, cmdsize)
|
722
|
+
@sub_library = LCStr.new(self, sub_library)
|
590
723
|
end
|
591
724
|
end
|
592
725
|
|
@@ -596,13 +729,18 @@ module MachO
|
|
596
729
|
# @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr
|
597
730
|
attr_reader :sub_client
|
598
731
|
|
599
|
-
|
732
|
+
# @see MachOStructure::FORMAT
|
733
|
+
# @api private
|
734
|
+
FORMAT = "L=3".freeze
|
735
|
+
|
736
|
+
# @see MachOStructure::SIZEOF
|
737
|
+
# @api private
|
600
738
|
SIZEOF = 12
|
601
739
|
|
602
740
|
# @api private
|
603
|
-
def initialize(
|
604
|
-
super(
|
605
|
-
@sub_client = LCStr.new(
|
741
|
+
def initialize(view, cmd, cmdsize, sub_client)
|
742
|
+
super(view, cmd, cmdsize)
|
743
|
+
@sub_client = LCStr.new(self, sub_client)
|
606
744
|
end
|
607
745
|
end
|
608
746
|
|
@@ -621,12 +759,17 @@ module MachO
|
|
621
759
|
# @return the string table size in bytes
|
622
760
|
attr_reader :strsize
|
623
761
|
|
624
|
-
|
762
|
+
# @see MachOStructure::FORMAT
|
763
|
+
# @api private
|
764
|
+
FORMAT = "L=6".freeze
|
765
|
+
|
766
|
+
# @see MachOStructure::SIZEOF
|
767
|
+
# @api private
|
625
768
|
SIZEOF = 24
|
626
769
|
|
627
770
|
# @api private
|
628
|
-
def initialize(
|
629
|
-
super(
|
771
|
+
def initialize(view, cmd, cmdsize, symoff, nsyms, stroff, strsize)
|
772
|
+
super(view, cmd, cmdsize)
|
630
773
|
@symoff = symoff
|
631
774
|
@nsyms = nsyms
|
632
775
|
@stroff = stroff
|
@@ -691,17 +834,21 @@ module MachO
|
|
691
834
|
# @return [Fixnum] the number of local relocation entries
|
692
835
|
attr_reader :nlocrel
|
693
836
|
|
837
|
+
# @see MachOStructure::FORMAT
|
838
|
+
# @api private
|
839
|
+
FORMAT = "L=20".freeze
|
694
840
|
|
695
|
-
|
841
|
+
# @see MachOStructure::SIZEOF
|
842
|
+
# @api private
|
696
843
|
SIZEOF = 80
|
697
844
|
|
698
845
|
# ugh
|
699
846
|
# @api private
|
700
|
-
def initialize(
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
super(
|
847
|
+
def initialize(view, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
|
848
|
+
nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
|
849
|
+
nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
|
850
|
+
nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
|
851
|
+
super(view, cmd, cmdsize)
|
705
852
|
@ilocalsym = ilocalsym
|
706
853
|
@nlocalsym = nlocalsym
|
707
854
|
@iextdefsym = iextdefsym
|
@@ -732,14 +879,58 @@ module MachO
|
|
732
879
|
# @return [Fixnum] the number of hints in the hint table
|
733
880
|
attr_reader :nhints
|
734
881
|
|
735
|
-
|
882
|
+
# @return [MachO::TwolevelHintsCommand::TwolevelHintTable] the hint table
|
883
|
+
attr_reader :table
|
884
|
+
|
885
|
+
# @see MachOStructure::FORMAT
|
886
|
+
# @api private
|
887
|
+
FORMAT = "L=4".freeze
|
888
|
+
|
889
|
+
# @see MachOStructure::SIZEOF
|
890
|
+
# @api private
|
736
891
|
SIZEOF = 16
|
737
892
|
|
738
893
|
# @api private
|
739
|
-
def initialize(
|
740
|
-
super(
|
894
|
+
def initialize(view, cmd, cmdsize, htoffset, nhints)
|
895
|
+
super(view, cmd, cmdsize)
|
741
896
|
@htoffset = htoffset
|
742
897
|
@nhints = nhints
|
898
|
+
@table = TwolevelHintsTable.new(view, htoffset, nhints)
|
899
|
+
end
|
900
|
+
|
901
|
+
# A representation of the two-level namespace lookup hints table exposed
|
902
|
+
# by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
|
903
|
+
class TwolevelHintsTable
|
904
|
+
# @return [Array<MachO::TwoLevelHintsTable::TwoLevelHint>] all hints in the table
|
905
|
+
attr_reader :hints
|
906
|
+
|
907
|
+
# @param view [MachO::MachOView] the view into the current Mach-O
|
908
|
+
# @param htoffset [Fixnum] the offset of the hints table
|
909
|
+
# @param nhints [Fixnum] the number of two-level hints in the table
|
910
|
+
# @api private
|
911
|
+
def initialize(view, htoffset, nhints)
|
912
|
+
format = Utils.specialize_format("L=#{nhints}", view.endianness)
|
913
|
+
raw_table = view.raw_data[htoffset, nhints * 4]
|
914
|
+
blobs = raw_table.unpack(format)
|
915
|
+
|
916
|
+
@hints = blobs.map { |b| TwolevelHint.new(b) }
|
917
|
+
end
|
918
|
+
|
919
|
+
# An individual two-level namespace lookup hint.
|
920
|
+
class TwolevelHint
|
921
|
+
# @return [Fixnum] the index into the sub-images
|
922
|
+
attr_reader :isub_image
|
923
|
+
|
924
|
+
# @return [Fixnum] the index into the table of contents
|
925
|
+
attr_reader :itoc
|
926
|
+
|
927
|
+
# @param blob [Fixnum] the 32-bit number containing the lookup hint
|
928
|
+
# @api private
|
929
|
+
def initialize(blob)
|
930
|
+
@isub_image = blob >> 24
|
931
|
+
@itoc = blob & 0x00FFFFFF
|
932
|
+
end
|
933
|
+
end
|
743
934
|
end
|
744
935
|
end
|
745
936
|
|
@@ -749,12 +940,17 @@ module MachO
|
|
749
940
|
# @return [Fixnum] the checksum or 0
|
750
941
|
attr_reader :cksum
|
751
942
|
|
752
|
-
|
943
|
+
# @see MachOStructure::FORMAT
|
944
|
+
# @api private
|
945
|
+
FORMAT = "L=3".freeze
|
946
|
+
|
947
|
+
# @see MachOStructure::SIZEOF
|
948
|
+
# @api private
|
753
949
|
SIZEOF = 12
|
754
950
|
|
755
951
|
# @api private
|
756
|
-
def initialize(
|
757
|
-
super(
|
952
|
+
def initialize(view, cmd, cmdsize, cksum)
|
953
|
+
super(view, cmd, cmdsize)
|
758
954
|
@cksum = cksum
|
759
955
|
end
|
760
956
|
end
|
@@ -766,13 +962,28 @@ module MachO
|
|
766
962
|
# @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr
|
767
963
|
attr_reader :path
|
768
964
|
|
769
|
-
|
965
|
+
# @see MachOStructure::FORMAT
|
966
|
+
# @api private
|
967
|
+
FORMAT = "L=3".freeze
|
968
|
+
|
969
|
+
# @see MachOStructure::SIZEOF
|
970
|
+
# @api private
|
770
971
|
SIZEOF = 12
|
771
972
|
|
772
973
|
# @api private
|
773
|
-
def initialize(
|
774
|
-
super(
|
775
|
-
@path = LCStr.new(
|
974
|
+
def initialize(view, cmd, cmdsize, path)
|
975
|
+
super(view, cmd, cmdsize)
|
976
|
+
@path = LCStr.new(self, path)
|
977
|
+
end
|
978
|
+
|
979
|
+
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
980
|
+
# @return [String] the serialized fields of the load command
|
981
|
+
# @api private
|
982
|
+
def serialize(context)
|
983
|
+
format = Utils.specialize_format(FORMAT, context.endianness)
|
984
|
+
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :path => path.to_s)
|
985
|
+
cmdsize = SIZEOF + string_payload.bytesize
|
986
|
+
[cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
|
776
987
|
end
|
777
988
|
end
|
778
989
|
|
@@ -786,12 +997,17 @@ module MachO
|
|
786
997
|
# @return [Fixnum] size of the data in the __LINKEDIT segment
|
787
998
|
attr_reader :datasize
|
788
999
|
|
789
|
-
|
1000
|
+
# @see MachOStructure::FORMAT
|
1001
|
+
# @api private
|
1002
|
+
FORMAT = "L=4".freeze
|
1003
|
+
|
1004
|
+
# @see MachOStructure::SIZEOF
|
1005
|
+
# @api private
|
790
1006
|
SIZEOF = 16
|
791
1007
|
|
792
1008
|
# @api private
|
793
|
-
def initialize(
|
794
|
-
super(
|
1009
|
+
def initialize(view, cmd, cmdsize, dataoff, datasize)
|
1010
|
+
super(view, cmd, cmdsize)
|
795
1011
|
@dataoff = dataoff
|
796
1012
|
@datasize = datasize
|
797
1013
|
end
|
@@ -809,12 +1025,17 @@ module MachO
|
|
809
1025
|
# @return [Fixnum] the encryption system, or 0 if not encrypted yet
|
810
1026
|
attr_reader :cryptid
|
811
1027
|
|
812
|
-
|
1028
|
+
# @see MachOStructure::FORMAT
|
1029
|
+
# @api private
|
1030
|
+
FORMAT = "L=5".freeze
|
1031
|
+
|
1032
|
+
# @see MachOStructure::SIZEOF
|
1033
|
+
# @api private
|
813
1034
|
SIZEOF = 20
|
814
1035
|
|
815
1036
|
# @api private
|
816
|
-
def initialize(
|
817
|
-
super(
|
1037
|
+
def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
|
1038
|
+
super(view, cmd, cmdsize)
|
818
1039
|
@cryptoff = cryptoff
|
819
1040
|
@cryptsize = cryptsize
|
820
1041
|
@cryptid = cryptid
|
@@ -836,12 +1057,17 @@ module MachO
|
|
836
1057
|
# @return [Fixnum] 64-bit padding value
|
837
1058
|
attr_reader :pad
|
838
1059
|
|
839
|
-
|
1060
|
+
# @see MachOStructure::FORMAT
|
1061
|
+
# @api private
|
1062
|
+
FORMAT = "L=6".freeze
|
1063
|
+
|
1064
|
+
# @see MachOStructure::SIZEOF
|
1065
|
+
# @api private
|
840
1066
|
SIZEOF = 24
|
841
1067
|
|
842
1068
|
# @api private
|
843
|
-
def initialize(
|
844
|
-
super(
|
1069
|
+
def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
|
1070
|
+
super(view, cmd, cmdsize)
|
845
1071
|
@cryptoff = cryptoff
|
846
1072
|
@cryptsize = cryptsize
|
847
1073
|
@cryptid = cryptid
|
@@ -858,12 +1084,17 @@ module MachO
|
|
858
1084
|
# @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8
|
859
1085
|
attr_reader :sdk
|
860
1086
|
|
861
|
-
|
1087
|
+
# @see MachOStructure::FORMAT
|
1088
|
+
# @api private
|
1089
|
+
FORMAT = "L=4".freeze
|
1090
|
+
|
1091
|
+
# @see MachOStructure::SIZEOF
|
1092
|
+
# @api private
|
862
1093
|
SIZEOF = 16
|
863
1094
|
|
864
1095
|
# @api private
|
865
|
-
def initialize(
|
866
|
-
super(
|
1096
|
+
def initialize(view, cmd, cmdsize, version, sdk)
|
1097
|
+
super(view, cmd, cmdsize)
|
867
1098
|
@version = version
|
868
1099
|
@sdk = sdk
|
869
1100
|
end
|
@@ -925,14 +1156,19 @@ module MachO
|
|
925
1156
|
# @return [Fixnum] the size of the export information
|
926
1157
|
attr_reader :export_size
|
927
1158
|
|
928
|
-
|
1159
|
+
# @see MachOStructure::FORMAT
|
1160
|
+
# @api private
|
1161
|
+
FORMAT = "L=12".freeze
|
1162
|
+
|
1163
|
+
# @see MachOStructure::SIZEOF
|
1164
|
+
# @api private
|
929
1165
|
SIZEOF = 48
|
930
1166
|
|
931
1167
|
# @api private
|
932
|
-
def initialize(
|
933
|
-
|
934
|
-
|
935
|
-
super(
|
1168
|
+
def initialize(view, cmd, cmdsize, rebase_off, rebase_size, bind_off,
|
1169
|
+
bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
|
1170
|
+
lazy_bind_size, export_off, export_size)
|
1171
|
+
super(view, cmd, cmdsize)
|
936
1172
|
@rebase_off = rebase_off
|
937
1173
|
@rebase_size = rebase_size
|
938
1174
|
@bind_off = bind_off
|
@@ -952,12 +1188,17 @@ module MachO
|
|
952
1188
|
# @return [Fixnum] the number of strings
|
953
1189
|
attr_reader :count
|
954
1190
|
|
955
|
-
|
1191
|
+
# @see MachOStructure::FORMAT
|
1192
|
+
# @api private
|
1193
|
+
FORMAT = "L=3".freeze
|
1194
|
+
|
1195
|
+
# @see MachOStructure::SIZEOF
|
1196
|
+
# @api private
|
956
1197
|
SIZEOF = 12
|
957
1198
|
|
958
1199
|
# @api private
|
959
|
-
def initialize(
|
960
|
-
super(
|
1200
|
+
def initialize(view, cmd, cmdsize, count)
|
1201
|
+
super(view, cmd, cmdsize)
|
961
1202
|
@count = count
|
962
1203
|
end
|
963
1204
|
end
|
@@ -970,12 +1211,17 @@ module MachO
|
|
970
1211
|
# @return [Fixnum] if not 0, the initial stack size.
|
971
1212
|
attr_reader :stacksize
|
972
1213
|
|
973
|
-
|
1214
|
+
# @see MachOStructure::FORMAT
|
1215
|
+
# @api private
|
1216
|
+
FORMAT = "L=2Q=2".freeze
|
1217
|
+
|
1218
|
+
# @see MachOStructure::SIZEOF
|
1219
|
+
# @api private
|
974
1220
|
SIZEOF = 24
|
975
1221
|
|
976
1222
|
# @api private
|
977
|
-
def initialize(
|
978
|
-
super(
|
1223
|
+
def initialize(view, cmd, cmdsize, entryoff, stacksize)
|
1224
|
+
super(view, cmd, cmdsize)
|
979
1225
|
@entryoff = entryoff
|
980
1226
|
@stacksize = stacksize
|
981
1227
|
end
|
@@ -987,12 +1233,17 @@ module MachO
|
|
987
1233
|
# @return [Fixnum] the version packed as a24.b10.c10.d10.e10
|
988
1234
|
attr_reader :version
|
989
1235
|
|
990
|
-
|
1236
|
+
# @see MachOStructure::FORMAT
|
1237
|
+
# @api private
|
1238
|
+
FORMAT = "L=2Q=1".freeze
|
1239
|
+
|
1240
|
+
# @see MachOStructure::SIZEOF
|
1241
|
+
# @api private
|
991
1242
|
SIZEOF = 16
|
992
1243
|
|
993
1244
|
# @api private
|
994
|
-
def initialize(
|
995
|
-
super(
|
1245
|
+
def initialize(view, cmd, cmdsize, version)
|
1246
|
+
super(view, cmd, cmdsize)
|
996
1247
|
@version = version
|
997
1248
|
end
|
998
1249
|
|
@@ -1008,4 +1259,94 @@ module MachO
|
|
1008
1259
|
segs.join(".")
|
1009
1260
|
end
|
1010
1261
|
end
|
1262
|
+
|
1263
|
+
# An obsolete load command containing the offset and size of the (GNU style)
|
1264
|
+
# symbol table information. Corresponds to LC_SYMSEG.
|
1265
|
+
class SymsegCommand < LoadCommand
|
1266
|
+
# @return [Fixnum] the offset to the symbol segment
|
1267
|
+
attr_reader :offset
|
1268
|
+
|
1269
|
+
# @return [Fixnum] the size of the symbol segment in bytes
|
1270
|
+
attr_reader :size
|
1271
|
+
|
1272
|
+
# @see MachOStructure::FORMAT
|
1273
|
+
# @api private
|
1274
|
+
FORMAT = "L=4".freeze
|
1275
|
+
|
1276
|
+
# @see MachOStructure::SIZEOF
|
1277
|
+
# @api private
|
1278
|
+
SIZEOF = 16
|
1279
|
+
|
1280
|
+
# @api private
|
1281
|
+
def initialize(view, cmd, cmdsize, offset, size)
|
1282
|
+
super(view, cmd, cmdsize)
|
1283
|
+
@offset = offset
|
1284
|
+
@size = size
|
1285
|
+
end
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
# An obsolete load command containing a free format string table. Each string
|
1289
|
+
# is null-terminated and the command is zero-padded to a multiple of 4.
|
1290
|
+
# Corresponds to LC_IDENT.
|
1291
|
+
class IdentCommand < LoadCommand
|
1292
|
+
# @see MachOStructure::FORMAT
|
1293
|
+
# @api private
|
1294
|
+
FORMAT = "L=2".freeze
|
1295
|
+
|
1296
|
+
# @see MachOStructure::SIZEOF
|
1297
|
+
# @api private
|
1298
|
+
SIZEOF = 8
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
# An obsolete load command containing the path to a file to be loaded into
|
1302
|
+
# memory. Corresponds to LC_FVMFILE.
|
1303
|
+
class FvmfileCommand < LoadCommand
|
1304
|
+
# @return [MachO::LoadCommand::LCStr] the pathname of the file being loaded
|
1305
|
+
attr_reader :name
|
1306
|
+
|
1307
|
+
# @return [Fixnum] the virtual address being loaded at
|
1308
|
+
attr_reader :header_addr
|
1309
|
+
|
1310
|
+
# @see MachOStructure::FORMAT
|
1311
|
+
# @api private
|
1312
|
+
FORMAT = "L=4".freeze
|
1313
|
+
|
1314
|
+
# @see MachOStructure::SIZEOF
|
1315
|
+
# @api private
|
1316
|
+
SIZEOF = 16
|
1317
|
+
|
1318
|
+
def initialize(view, cmd, cmdsize, name, header_addr)
|
1319
|
+
super(view, cmd, cmdsize)
|
1320
|
+
@name = LCStr.new(self, name)
|
1321
|
+
@header_addr = header_addr
|
1322
|
+
end
|
1323
|
+
end
|
1324
|
+
|
1325
|
+
# An obsolete load command containing the path to a library to be loaded into
|
1326
|
+
# memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
|
1327
|
+
class FvmlibCommand < LoadCommand
|
1328
|
+
# @return [MachO::LoadCommand::LCStr] the library's target pathname
|
1329
|
+
attr_reader :name
|
1330
|
+
|
1331
|
+
# @return [Fixnum] the library's minor version number
|
1332
|
+
attr_reader :minor_version
|
1333
|
+
|
1334
|
+
# @return [Fixnum] the library's header address
|
1335
|
+
attr_reader :header_addr
|
1336
|
+
|
1337
|
+
# @see MachOStructure::FORMAT
|
1338
|
+
# @api private
|
1339
|
+
FORMAT = "L=5".freeze
|
1340
|
+
|
1341
|
+
# @see MachOStructure::SIZEOF
|
1342
|
+
# @api private
|
1343
|
+
SIZEOF = 20
|
1344
|
+
|
1345
|
+
def initialize(view, cmd, cmdsize, name, minor_version, header_addr)
|
1346
|
+
super(view, cmd, cmdsize)
|
1347
|
+
@name = LCStr.new(self, name)
|
1348
|
+
@minor_version = minor_version
|
1349
|
+
@header_addr = header_addr
|
1350
|
+
end
|
1351
|
+
end
|
1011
1352
|
end
|