ruby-macho 3.0.0 → 4.0.0

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.
@@ -34,24 +34,24 @@ module MachO
34
34
  0x15 => :LC_SUB_LIBRARY,
35
35
  0x16 => :LC_TWOLEVEL_HINTS,
36
36
  0x17 => :LC_PREBIND_CKSUM,
37
- (0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
37
+ (LC_REQ_DYLD | 0x18) => :LC_LOAD_WEAK_DYLIB,
38
38
  0x19 => :LC_SEGMENT_64,
39
39
  0x1a => :LC_ROUTINES_64,
40
40
  0x1b => :LC_UUID,
41
- (0x1c | LC_REQ_DYLD) => :LC_RPATH,
41
+ (LC_REQ_DYLD | 0x1c) => :LC_RPATH,
42
42
  0x1d => :LC_CODE_SIGNATURE,
43
43
  0x1e => :LC_SEGMENT_SPLIT_INFO,
44
- (0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
44
+ (LC_REQ_DYLD | 0x1f) => :LC_REEXPORT_DYLIB,
45
45
  0x20 => :LC_LAZY_LOAD_DYLIB,
46
46
  0x21 => :LC_ENCRYPTION_INFO,
47
47
  0x22 => :LC_DYLD_INFO,
48
- (0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
49
- (0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
48
+ (LC_REQ_DYLD | 0x22) => :LC_DYLD_INFO_ONLY,
49
+ (LC_REQ_DYLD | 0x23) => :LC_LOAD_UPWARD_DYLIB,
50
50
  0x24 => :LC_VERSION_MIN_MACOSX,
51
51
  0x25 => :LC_VERSION_MIN_IPHONEOS,
52
52
  0x26 => :LC_FUNCTION_STARTS,
53
53
  0x27 => :LC_DYLD_ENVIRONMENT,
54
- (0x28 | LC_REQ_DYLD) => :LC_MAIN,
54
+ (LC_REQ_DYLD | 0x28) => :LC_MAIN,
55
55
  0x29 => :LC_DATA_IN_CODE,
56
56
  0x2a => :LC_SOURCE_VERSION,
57
57
  0x2b => :LC_DYLIB_CODE_SIGN_DRS,
@@ -62,9 +62,9 @@ module MachO
62
62
  0x30 => :LC_VERSION_MIN_WATCHOS,
63
63
  0x31 => :LC_NOTE,
64
64
  0x32 => :LC_BUILD_VERSION,
65
- (0x33 | LC_REQ_DYLD) => :LC_DYLD_EXPORTS_TRIE,
66
- (0x34 | LC_REQ_DYLD) => :LC_DYLD_CHAINED_FIXUPS,
67
- (0x35 | LC_REQ_DYLD) => :LC_FILESET_ENTRY,
65
+ (LC_REQ_DYLD | 0x33) => :LC_DYLD_EXPORTS_TRIE,
66
+ (LC_REQ_DYLD | 0x34) => :LC_DYLD_CHAINED_FIXUPS,
67
+ (LC_REQ_DYLD | 0x35) => :LC_FILESET_ENTRY,
68
68
  }.freeze
69
69
 
70
70
  # association of symbol representations to load command constants
@@ -160,12 +160,27 @@ module MachO
160
160
  SEGMENT_NAMES = {
161
161
  :SEG_PAGEZERO => "__PAGEZERO",
162
162
  :SEG_TEXT => "__TEXT",
163
+ :SEG_TEXT_EXEC => "__TEXT_EXEC",
163
164
  :SEG_DATA => "__DATA",
165
+ :SEG_DATA_CONST => "__DATA_CONST",
164
166
  :SEG_OBJC => "__OBJC",
167
+ :SEG_OBJC_CONST => "__OBJC_CONST",
165
168
  :SEG_ICON => "__ICON",
166
169
  :SEG_LINKEDIT => "__LINKEDIT",
170
+ :SEG_LINKINFO => "__LINKINFO",
167
171
  :SEG_UNIXSTACK => "__UNIXSTACK",
168
172
  :SEG_IMPORT => "__IMPORT",
173
+ :SEG_KLD => "__KLD",
174
+ :SEG_KLDDATA => "__KLDDATA",
175
+ :SEG_HIB => "__HIB",
176
+ :SEG_VECTORS => "__VECTORS",
177
+ :SEG_LAST => "__LAST",
178
+ :SEG_LASTDATA_CONST => "__LASTDATA_CONST",
179
+ :SEG_PRELINK_TEXT => "__PRELINK_TEXT",
180
+ :SEG_PRELINK_INFO => "__PRELINK_INFO",
181
+ :SEG_CTF => "__CTF",
182
+ :SEG_AUTH => "__AUTH",
183
+ :SEG_AUTH_CONST => "__AUTH_CONST",
169
184
  }.freeze
170
185
 
171
186
  # association of segment flag symbols to values
@@ -185,21 +200,13 @@ module MachO
185
200
  class LoadCommand < MachOStructure
186
201
  # @return [MachO::MachOView, nil] the raw view associated with the load command,
187
202
  # or nil if the load command was created via {create}.
188
- attr_reader :view
203
+ field :view, :view
189
204
 
190
205
  # @return [Integer] the load command's type ID
191
- attr_reader :cmd
206
+ field :cmd, :uint32
192
207
 
193
208
  # @return [Integer] the size of the load command, in bytes
194
- attr_reader :cmdsize
195
-
196
- # @see MachOStructure::FORMAT
197
- # @api private
198
- FORMAT = "L=2"
199
-
200
- # @see MachOStructure::SIZEOF
201
- # @api private
202
- SIZEOF = 8
209
+ field :cmdsize, :uint32
203
210
 
204
211
  # Instantiates a new LoadCommand given a view into its origin Mach-O
205
212
  # @param view [MachO::MachOView] the load command's raw view
@@ -207,7 +214,7 @@ module MachO
207
214
  # @api private
208
215
  def self.new_from_bin(view)
209
216
  bin = view.raw_data.slice(view.offset, bytesize)
210
- format = Utils.specialize_format(self::FORMAT, view.endianness)
217
+ format = Utils.specialize_format(self.format, view.endianness)
211
218
 
212
219
  new(view, *bin.unpack(format))
213
220
  end
@@ -222,24 +229,13 @@ module MachO
222
229
  cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
223
230
 
224
231
  # cmd will be filled in, view and cmdsize will be left unpopulated
225
- klass_arity = klass.instance_method(:initialize).arity - 3
232
+ klass_arity = klass.min_args - 3
226
233
 
227
- raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity != args.size
234
+ raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity > args.size
228
235
 
229
236
  klass.new(nil, cmd, nil, *args)
230
237
  end
231
238
 
232
- # @param view [MachO::MachOView] the load command's raw view
233
- # @param cmd [Integer] the load command's identifying number
234
- # @param cmdsize [Integer] the size of the load command in bytes
235
- # @api private
236
- def initialize(view, cmd, cmdsize)
237
- super()
238
- @view = view
239
- @cmd = cmd
240
- @cmdsize = cmdsize
241
- end
242
-
243
239
  # @return [Boolean] whether the load command can be serialized
244
240
  def serializable?
245
241
  CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
@@ -253,8 +249,8 @@ module MachO
253
249
  def serialize(context)
254
250
  raise LoadCommandNotSerializableError, LOAD_COMMANDS[cmd] unless serializable?
255
251
 
256
- format = Utils.specialize_format(FORMAT, context.endianness)
257
- [cmd, SIZEOF].pack(format)
252
+ format = Utils.specialize_format(self.class.format, context.endianness)
253
+ [cmd, self.class.bytesize].pack(format)
258
254
  end
259
255
 
260
256
  # @return [Integer] the load command's offset in the source file
@@ -371,21 +367,7 @@ module MachO
371
367
  # LC_UUID.
372
368
  class UUIDCommand < LoadCommand
373
369
  # @return [Array<Integer>] the UUID
374
- attr_reader :uuid
375
-
376
- # @see MachOStructure::FORMAT
377
- # @api private
378
- FORMAT = "L=2a16"
379
-
380
- # @see MachOStructure::SIZEOF
381
- # @api private
382
- SIZEOF = 24
383
-
384
- # @api private
385
- def initialize(view, cmd, cmdsize, uuid)
386
- super(view, cmd, cmdsize)
387
- @uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
388
- end
370
+ field :uuid, :string, :size => 16, :unpack => "C16"
389
371
 
390
372
  # @return [String] a string representation of the UUID
391
373
  def uuid_string
@@ -398,6 +380,11 @@ module MachO
398
380
  segs.join("-")
399
381
  end
400
382
 
383
+ # @return [String] an alias for uuid_string
384
+ def to_s
385
+ uuid_string
386
+ end
387
+
401
388
  # @return [Hash] returns a hash representation of this {UUIDCommand}
402
389
  def to_h
403
390
  {
@@ -411,54 +398,31 @@ module MachO
411
398
  # the task's address space. Corresponds to LC_SEGMENT.
412
399
  class SegmentCommand < LoadCommand
413
400
  # @return [String] the name of the segment
414
- attr_reader :segname
401
+ field :segname, :string, :padding => :null, :size => 16, :to_s => true
415
402
 
416
403
  # @return [Integer] the memory address of the segment
417
- attr_reader :vmaddr
404
+ field :vmaddr, :uint32
418
405
 
419
406
  # @return [Integer] the memory size of the segment
420
- attr_reader :vmsize
407
+ field :vmsize, :uint32
421
408
 
422
409
  # @return [Integer] the file offset of the segment
423
- attr_reader :fileoff
410
+ field :fileoff, :uint32
424
411
 
425
412
  # @return [Integer] the amount to map from the file
426
- attr_reader :filesize
413
+ field :filesize, :uint32
427
414
 
428
415
  # @return [Integer] the maximum VM protection
429
- attr_reader :maxprot
416
+ field :maxprot, :int32
430
417
 
431
418
  # @return [Integer] the initial VM protection
432
- attr_reader :initprot
419
+ field :initprot, :int32
433
420
 
434
421
  # @return [Integer] the number of sections in the segment
435
- attr_reader :nsects
422
+ field :nsects, :uint32
436
423
 
437
424
  # @return [Integer] any flags associated with the segment
438
- attr_reader :flags
439
-
440
- # @see MachOStructure::FORMAT
441
- # @api private
442
- FORMAT = "L=2Z16L=4l=2L=2"
443
-
444
- # @see MachOStructure::SIZEOF
445
- # @api private
446
- SIZEOF = 56
447
-
448
- # @api private
449
- def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
450
- filesize, maxprot, initprot, nsects, flags)
451
- super(view, cmd, cmdsize)
452
- @segname = segname
453
- @vmaddr = vmaddr
454
- @vmsize = vmsize
455
- @fileoff = fileoff
456
- @filesize = filesize
457
- @maxprot = maxprot
458
- @initprot = initprot
459
- @nsects = nsects
460
- @flags = flags
461
- end
425
+ field :flags, :uint32
462
426
 
463
427
  # All sections referenced within this segment.
464
428
  # @return [Array<MachO::Sections::Section>] if the Mach-O is 32-bit
@@ -532,13 +496,17 @@ module MachO
532
496
  # A load command indicating that part of this file is to be mapped into
533
497
  # the task's address space. Corresponds to LC_SEGMENT_64.
534
498
  class SegmentCommand64 < SegmentCommand
535
- # @see MachOStructure::FORMAT
536
- # @api private
537
- FORMAT = "L=2Z16Q=4l=2L=2"
499
+ # @return [Integer] the memory address of the segment
500
+ field :vmaddr, :uint64
538
501
 
539
- # @see MachOStructure::SIZEOF
540
- # @api private
541
- SIZEOF = 72
502
+ # @return [Integer] the memory size of the segment
503
+ field :vmsize, :uint64
504
+
505
+ # @return [Integer] the file offset of the segment
506
+ field :fileoff, :uint64
507
+
508
+ # @return [Integer] the amount to map from the file
509
+ field :filesize, :uint64
542
510
  end
543
511
 
544
512
  # A load command representing some aspect of shared libraries, depending
@@ -547,45 +515,27 @@ module MachO
547
515
  class DylibCommand < LoadCommand
548
516
  # @return [LCStr] the library's path
549
517
  # name as an LCStr
550
- attr_reader :name
518
+ field :name, :lcstr, :to_s => true
551
519
 
552
520
  # @return [Integer] the library's build time stamp
553
- attr_reader :timestamp
521
+ field :timestamp, :uint32
554
522
 
555
523
  # @return [Integer] the library's current version number
556
- attr_reader :current_version
524
+ field :current_version, :uint32
557
525
 
558
526
  # @return [Integer] the library's compatibility version number
559
- attr_reader :compatibility_version
560
-
561
- # @see MachOStructure::FORMAT
562
- # @api private
563
- FORMAT = "L=6"
564
-
565
- # @see MachOStructure::SIZEOF
566
- # @api private
567
- SIZEOF = 24
568
-
569
- # @api private
570
- def initialize(view, cmd, cmdsize, name, timestamp, current_version,
571
- compatibility_version)
572
- super(view, cmd, cmdsize)
573
- @name = LCStr.new(self, name)
574
- @timestamp = timestamp
575
- @current_version = current_version
576
- @compatibility_version = compatibility_version
577
- end
527
+ field :compatibility_version, :uint32
578
528
 
579
529
  # @param context [SerializationContext]
580
530
  # the context
581
531
  # @return [String] the serialized fields of the load command
582
532
  # @api private
583
533
  def serialize(context)
584
- format = Utils.specialize_format(FORMAT, context.endianness)
585
- string_payload, string_offsets = Utils.pack_strings(SIZEOF,
534
+ format = Utils.specialize_format(self.class.format, context.endianness)
535
+ string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
586
536
  context.alignment,
587
537
  :name => name.to_s)
588
- cmdsize = SIZEOF + string_payload.bytesize
538
+ cmdsize = self.class.bytesize + string_payload.bytesize
589
539
  [cmd, cmdsize, string_offsets[:name], timestamp, current_version,
590
540
  compatibility_version].pack(format) + string_payload
591
541
  end
@@ -607,32 +557,18 @@ module MachO
607
557
  class DylinkerCommand < LoadCommand
608
558
  # @return [LCStr] the dynamic linker's
609
559
  # path name as an LCStr
610
- attr_reader :name
611
-
612
- # @see MachOStructure::FORMAT
613
- # @api private
614
- FORMAT = "L=3"
615
-
616
- # @see MachOStructure::SIZEOF
617
- # @api private
618
- SIZEOF = 12
619
-
620
- # @api private
621
- def initialize(view, cmd, cmdsize, name)
622
- super(view, cmd, cmdsize)
623
- @name = LCStr.new(self, name)
624
- end
560
+ field :name, :lcstr, :to_s => true
625
561
 
626
562
  # @param context [SerializationContext]
627
563
  # the context
628
564
  # @return [String] the serialized fields of the load command
629
565
  # @api private
630
566
  def serialize(context)
631
- format = Utils.specialize_format(FORMAT, context.endianness)
632
- string_payload, string_offsets = Utils.pack_strings(SIZEOF,
567
+ format = Utils.specialize_format(self.class.format, context.endianness)
568
+ string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
633
569
  context.alignment,
634
570
  :name => name.to_s)
635
- cmdsize = SIZEOF + string_payload.bytesize
571
+ cmdsize = self.class.bytesize + string_payload.bytesize
636
572
  [cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
637
573
  end
638
574
 
@@ -649,29 +585,13 @@ module MachO
649
585
  class PreboundDylibCommand < LoadCommand
650
586
  # @return [LCStr] the library's path
651
587
  # name as an LCStr
652
- attr_reader :name
588
+ field :name, :lcstr, :to_s => true
653
589
 
654
590
  # @return [Integer] the number of modules in the library
655
- attr_reader :nmodules
591
+ field :nmodules, :uint32
656
592
 
657
593
  # @return [Integer] a bit vector of linked modules
658
- attr_reader :linked_modules
659
-
660
- # @see MachOStructure::FORMAT
661
- # @api private
662
- FORMAT = "L=5"
663
-
664
- # @see MachOStructure::SIZEOF
665
- # @api private
666
- SIZEOF = 20
667
-
668
- # @api private
669
- def initialize(view, cmd, cmdsize, name, nmodules, linked_modules)
670
- super(view, cmd, cmdsize)
671
- @name = LCStr.new(self, name)
672
- @nmodules = nmodules
673
- @linked_modules = linked_modules
674
- end
594
+ field :linked_modules, :uint32
675
595
 
676
596
  # @return [Hash] a hash representation of this {PreboundDylibCommand}
677
597
  def to_h
@@ -687,13 +607,6 @@ module MachO
687
607
  # @note cctools-870 and onwards have all fields of thread_command commented
688
608
  # out except the common ones (cmd, cmdsize)
689
609
  class ThreadCommand < LoadCommand
690
- # @see MachOStructure::FORMAT
691
- # @api private
692
- FORMAT = "L=2"
693
-
694
- # @see MachOStructure::SIZEOF
695
- # @api private
696
- SIZEOF = 8
697
610
  end
698
611
 
699
612
  # A load command containing the address of the dynamic shared library
@@ -701,51 +614,29 @@ module MachO
701
614
  # that defines the routine. Corresponds to LC_ROUTINES.
702
615
  class RoutinesCommand < LoadCommand
703
616
  # @return [Integer] the address of the initialization routine
704
- attr_reader :init_address
617
+ field :init_address, :uint32
705
618
 
706
619
  # @return [Integer] the index into the module table that the init routine
707
620
  # is defined in
708
- attr_reader :init_module
621
+ field :init_module, :uint32
709
622
 
710
623
  # @return [void]
711
- attr_reader :reserved1
624
+ field :reserved1, :uint32
712
625
 
713
626
  # @return [void]
714
- attr_reader :reserved2
627
+ field :reserved2, :uint32
715
628
 
716
629
  # @return [void]
717
- attr_reader :reserved3
630
+ field :reserved3, :uint32
718
631
 
719
632
  # @return [void]
720
- attr_reader :reserved4
633
+ field :reserved4, :uint32
721
634
 
722
635
  # @return [void]
723
- attr_reader :reserved5
636
+ field :reserved5, :uint32
724
637
 
725
638
  # @return [void]
726
- attr_reader :reserved6
727
-
728
- # @see MachOStructure::FORMAT
729
- # @api private
730
- FORMAT = "L=10"
731
-
732
- # @see MachOStructure::SIZEOF
733
- # @api private
734
- SIZEOF = 40
735
-
736
- # @api private
737
- def initialize(view, cmd, cmdsize, init_address, init_module, reserved1,
738
- reserved2, reserved3, reserved4, reserved5, reserved6)
739
- super(view, cmd, cmdsize)
740
- @init_address = init_address
741
- @init_module = init_module
742
- @reserved1 = reserved1
743
- @reserved2 = reserved2
744
- @reserved3 = reserved3
745
- @reserved4 = reserved4
746
- @reserved5 = reserved5
747
- @reserved6 = reserved6
748
- end
639
+ field :reserved6, :uint32
749
640
 
750
641
  # @return [Hash] a hash representation of this {RoutinesCommand}
751
642
  def to_h
@@ -766,34 +657,37 @@ module MachO
766
657
  # initialization routine and an index into the module table for the module
767
658
  # that defines the routine. Corresponds to LC_ROUTINES_64.
768
659
  class RoutinesCommand64 < RoutinesCommand
769
- # @see MachOStructure::FORMAT
770
- # @api private
771
- FORMAT = "L=2Q=8"
660
+ # @return [Integer] the address of the initialization routine
661
+ field :init_address, :uint64
772
662
 
773
- # @see MachOStructure::SIZEOF
774
- # @api private
775
- SIZEOF = 72
663
+ # @return [Integer] the index into the module table that the init routine
664
+ # is defined in
665
+ field :init_module, :uint64
666
+
667
+ # @return [void]
668
+ field :reserved1, :uint64
669
+
670
+ # @return [void]
671
+ field :reserved2, :uint64
672
+
673
+ # @return [void]
674
+ field :reserved3, :uint64
675
+
676
+ # @return [void]
677
+ field :reserved4, :uint64
678
+
679
+ # @return [void]
680
+ field :reserved5, :uint64
681
+
682
+ # @return [void]
683
+ field :reserved6, :uint64
776
684
  end
777
685
 
778
686
  # A load command signifying membership of a subframework containing the name
779
687
  # of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
780
688
  class SubFrameworkCommand < LoadCommand
781
689
  # @return [LCStr] the umbrella framework name as an LCStr
782
- attr_reader :umbrella
783
-
784
- # @see MachOStructure::FORMAT
785
- # @api private
786
- FORMAT = "L=3"
787
-
788
- # @see MachOStructure::SIZEOF
789
- # @api private
790
- SIZEOF = 12
791
-
792
- # @api private
793
- def initialize(view, cmd, cmdsize, umbrella)
794
- super(view, cmd, cmdsize)
795
- @umbrella = LCStr.new(self, umbrella)
796
- end
690
+ field :umbrella, :lcstr, :to_s => true
797
691
 
798
692
  # @return [Hash] a hash representation of this {SubFrameworkCommand}
799
693
  def to_h
@@ -807,21 +701,7 @@ module MachO
807
701
  # of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
808
702
  class SubUmbrellaCommand < LoadCommand
809
703
  # @return [LCStr] the subumbrella framework name as an LCStr
810
- attr_reader :sub_umbrella
811
-
812
- # @see MachOStructure::FORMAT
813
- # @api private
814
- FORMAT = "L=3"
815
-
816
- # @see MachOStructure::SIZEOF
817
- # @api private
818
- SIZEOF = 12
819
-
820
- # @api private
821
- def initialize(view, cmd, cmdsize, sub_umbrella)
822
- super(view, cmd, cmdsize)
823
- @sub_umbrella = LCStr.new(self, sub_umbrella)
824
- end
704
+ field :sub_umbrella, :lcstr, :to_s => true
825
705
 
826
706
  # @return [Hash] a hash representation of this {SubUmbrellaCommand}
827
707
  def to_h
@@ -835,21 +715,7 @@ module MachO
835
715
  # to LC_SUB_LIBRARY.
836
716
  class SubLibraryCommand < LoadCommand
837
717
  # @return [LCStr] the sublibrary name as an LCStr
838
- attr_reader :sub_library
839
-
840
- # @see MachOStructure::FORMAT
841
- # @api private
842
- FORMAT = "L=3"
843
-
844
- # @see MachOStructure::SIZEOF
845
- # @api private
846
- SIZEOF = 12
847
-
848
- # @api private
849
- def initialize(view, cmd, cmdsize, sub_library)
850
- super(view, cmd, cmdsize)
851
- @sub_library = LCStr.new(self, sub_library)
852
- end
718
+ field :sub_library, :lcstr, :to_s => true
853
719
 
854
720
  # @return [Hash] a hash representation of this {SubLibraryCommand}
855
721
  def to_h
@@ -863,21 +729,7 @@ module MachO
863
729
  # an umbrella framework. Corresponds to LC_SUB_CLIENT.
864
730
  class SubClientCommand < LoadCommand
865
731
  # @return [LCStr] the subclient name as an LCStr
866
- attr_reader :sub_client
867
-
868
- # @see MachOStructure::FORMAT
869
- # @api private
870
- FORMAT = "L=3"
871
-
872
- # @see MachOStructure::SIZEOF
873
- # @api private
874
- SIZEOF = 12
875
-
876
- # @api private
877
- def initialize(view, cmd, cmdsize, sub_client)
878
- super(view, cmd, cmdsize)
879
- @sub_client = LCStr.new(self, sub_client)
880
- end
732
+ field :sub_client, :lcstr, :to_s => true
881
733
 
882
734
  # @return [Hash] a hash representation of this {SubClientCommand}
883
735
  def to_h
@@ -891,33 +743,16 @@ module MachO
891
743
  # "stab" style symbol table information. Corresponds to LC_SYMTAB.
892
744
  class SymtabCommand < LoadCommand
893
745
  # @return [Integer] the symbol table's offset
894
- attr_reader :symoff
746
+ field :symoff, :uint32
895
747
 
896
748
  # @return [Integer] the number of symbol table entries
897
- attr_reader :nsyms
749
+ field :nsyms, :uint32
898
750
 
899
751
  # @return [Integer] the string table's offset
900
- attr_reader :stroff
752
+ field :stroff, :uint32
901
753
 
902
754
  # @return [Integer] the string table size in bytes
903
- attr_reader :strsize
904
-
905
- # @see MachOStructure::FORMAT
906
- # @api private
907
- FORMAT = "L=6"
908
-
909
- # @see MachOStructure::SIZEOF
910
- # @api private
911
- SIZEOF = 24
912
-
913
- # @api private
914
- def initialize(view, cmd, cmdsize, symoff, nsyms, stroff, strsize)
915
- super(view, cmd, cmdsize)
916
- @symoff = symoff
917
- @nsyms = nsyms
918
- @stroff = stroff
919
- @strsize = strsize
920
- end
755
+ field :strsize, :uint32
921
756
 
922
757
  # @return [Hash] a hash representation of this {SymtabCommand}
923
758
  def to_h
@@ -934,93 +769,58 @@ module MachO
934
769
  # structures used by the dynamic link editor. Corresponds to LC_DYSYMTAB.
935
770
  class DysymtabCommand < LoadCommand
936
771
  # @return [Integer] the index to local symbols
937
- attr_reader :ilocalsym
772
+ field :ilocalsym, :uint32
938
773
 
939
774
  # @return [Integer] the number of local symbols
940
- attr_reader :nlocalsym
775
+ field :nlocalsym, :uint32
941
776
 
942
777
  # @return [Integer] the index to externally defined symbols
943
- attr_reader :iextdefsym
778
+ field :iextdefsym, :uint32
944
779
 
945
780
  # @return [Integer] the number of externally defined symbols
946
- attr_reader :nextdefsym
781
+ field :nextdefsym, :uint32
947
782
 
948
783
  # @return [Integer] the index to undefined symbols
949
- attr_reader :iundefsym
784
+ field :iundefsym, :uint32
950
785
 
951
786
  # @return [Integer] the number of undefined symbols
952
- attr_reader :nundefsym
787
+ field :nundefsym, :uint32
953
788
 
954
789
  # @return [Integer] the file offset to the table of contents
955
- attr_reader :tocoff
790
+ field :tocoff, :uint32
956
791
 
957
792
  # @return [Integer] the number of entries in the table of contents
958
- attr_reader :ntoc
793
+ field :ntoc, :uint32
959
794
 
960
795
  # @return [Integer] the file offset to the module table
961
- attr_reader :modtaboff
796
+ field :modtaboff, :uint32
962
797
 
963
798
  # @return [Integer] the number of entries in the module table
964
- attr_reader :nmodtab
799
+ field :nmodtab, :uint32
965
800
 
966
801
  # @return [Integer] the file offset to the referenced symbol table
967
- attr_reader :extrefsymoff
802
+ field :extrefsymoff, :uint32
968
803
 
969
804
  # @return [Integer] the number of entries in the referenced symbol table
970
- attr_reader :nextrefsyms
805
+ field :nextrefsyms, :uint32
971
806
 
972
807
  # @return [Integer] the file offset to the indirect symbol table
973
- attr_reader :indirectsymoff
808
+ field :indirectsymoff, :uint32
974
809
 
975
810
  # @return [Integer] the number of entries in the indirect symbol table
976
- attr_reader :nindirectsyms
811
+ field :nindirectsyms, :uint32
977
812
 
978
813
  # @return [Integer] the file offset to the external relocation entries
979
- attr_reader :extreloff
814
+ field :extreloff, :uint32
980
815
 
981
816
  # @return [Integer] the number of external relocation entries
982
- attr_reader :nextrel
817
+ field :nextrel, :uint32
983
818
 
984
819
  # @return [Integer] the file offset to the local relocation entries
985
- attr_reader :locreloff
820
+ field :locreloff, :uint32
986
821
 
987
822
  # @return [Integer] the number of local relocation entries
988
- attr_reader :nlocrel
989
-
990
- # @see MachOStructure::FORMAT
991
- # @api private
992
- FORMAT = "L=20"
993
-
994
- # @see MachOStructure::SIZEOF
995
- # @api private
996
- SIZEOF = 80
997
-
998
- # ugh
999
- # @api private
1000
- def initialize(view, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
1001
- nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
1002
- nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
1003
- nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
1004
- super(view, cmd, cmdsize)
1005
- @ilocalsym = ilocalsym
1006
- @nlocalsym = nlocalsym
1007
- @iextdefsym = iextdefsym
1008
- @nextdefsym = nextdefsym
1009
- @iundefsym = iundefsym
1010
- @nundefsym = nundefsym
1011
- @tocoff = tocoff
1012
- @ntoc = ntoc
1013
- @modtaboff = modtaboff
1014
- @nmodtab = nmodtab
1015
- @extrefsymoff = extrefsymoff
1016
- @nextrefsyms = nextrefsyms
1017
- @indirectsymoff = indirectsymoff
1018
- @nindirectsyms = nindirectsyms
1019
- @extreloff = extreloff
1020
- @nextrel = nextrel
1021
- @locreloff = locreloff
1022
- @nlocrel = nlocrel
1023
- end
823
+ field :nlocrel, :uint32
1024
824
 
1025
825
  # @return [Hash] a hash representation of this {DysymtabCommand}
1026
826
  def to_h
@@ -1051,30 +851,14 @@ module MachO
1051
851
  # namespace lookup hints table. Corresponds to LC_TWOLEVEL_HINTS.
1052
852
  class TwolevelHintsCommand < LoadCommand
1053
853
  # @return [Integer] the offset to the hint table
1054
- attr_reader :htoffset
854
+ field :htoffset, :uint32
1055
855
 
1056
856
  # @return [Integer] the number of hints in the hint table
1057
- attr_reader :nhints
857
+ field :nhints, :uint32
1058
858
 
1059
859
  # @return [TwolevelHintsTable]
1060
860
  # the hint table
1061
- attr_reader :table
1062
-
1063
- # @see MachOStructure::FORMAT
1064
- # @api private
1065
- FORMAT = "L=4"
1066
-
1067
- # @see MachOStructure::SIZEOF
1068
- # @api private
1069
- SIZEOF = 16
1070
-
1071
- # @api private
1072
- def initialize(view, cmd, cmdsize, htoffset, nhints)
1073
- super(view, cmd, cmdsize)
1074
- @htoffset = htoffset
1075
- @nhints = nhints
1076
- @table = TwolevelHintsTable.new(view, htoffset, nhints)
1077
- end
861
+ field :table, :two_level_hints_table
1078
862
 
1079
863
  # @return [Hash] a hash representation of this {TwolevelHintsCommand}
1080
864
  def to_h
@@ -1133,21 +917,7 @@ module MachO
1133
917
  # files, or zero. Corresponds to LC_PREBIND_CKSUM.
1134
918
  class PrebindCksumCommand < LoadCommand
1135
919
  # @return [Integer] the checksum or 0
1136
- attr_reader :cksum
1137
-
1138
- # @see MachOStructure::FORMAT
1139
- # @api private
1140
- FORMAT = "L=3"
1141
-
1142
- # @see MachOStructure::SIZEOF
1143
- # @api private
1144
- SIZEOF = 12
1145
-
1146
- # @api private
1147
- def initialize(view, cmd, cmdsize, cksum)
1148
- super(view, cmd, cmdsize)
1149
- @cksum = cksum
1150
- end
920
+ field :cksum, :uint32
1151
921
 
1152
922
  # @return [Hash] a hash representation of this {PrebindCksumCommand}
1153
923
  def to_h
@@ -1162,31 +932,17 @@ module MachO
1162
932
  # Corresponds to LC_RPATH.
1163
933
  class RpathCommand < LoadCommand
1164
934
  # @return [LCStr] the path to add to the run path as an LCStr
1165
- attr_reader :path
1166
-
1167
- # @see MachOStructure::FORMAT
1168
- # @api private
1169
- FORMAT = "L=3"
1170
-
1171
- # @see MachOStructure::SIZEOF
1172
- # @api private
1173
- SIZEOF = 12
1174
-
1175
- # @api private
1176
- def initialize(view, cmd, cmdsize, path)
1177
- super(view, cmd, cmdsize)
1178
- @path = LCStr.new(self, path)
1179
- end
935
+ field :path, :lcstr, :to_s => true
1180
936
 
1181
937
  # @param context [SerializationContext] the context
1182
938
  # @return [String] the serialized fields of the load command
1183
939
  # @api private
1184
940
  def serialize(context)
1185
- format = Utils.specialize_format(FORMAT, context.endianness)
1186
- string_payload, string_offsets = Utils.pack_strings(SIZEOF,
941
+ format = Utils.specialize_format(self.class.format, context.endianness)
942
+ string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
1187
943
  context.alignment,
1188
944
  :path => path.to_s)
1189
- cmdsize = SIZEOF + string_payload.bytesize
945
+ cmdsize = self.class.bytesize + string_payload.bytesize
1190
946
  [cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
1191
947
  end
1192
948
 
@@ -1205,25 +961,10 @@ module MachO
1205
961
  # or LC_DYLD_CHAINED_FIXUPS.
1206
962
  class LinkeditDataCommand < LoadCommand
1207
963
  # @return [Integer] offset to the data in the __LINKEDIT segment
1208
- attr_reader :dataoff
964
+ field :dataoff, :uint32
1209
965
 
1210
966
  # @return [Integer] size of the data in the __LINKEDIT segment
1211
- attr_reader :datasize
1212
-
1213
- # @see MachOStructure::FORMAT
1214
- # @api private
1215
- FORMAT = "L=4"
1216
-
1217
- # @see MachOStructure::SIZEOF
1218
- # @api private
1219
- SIZEOF = 16
1220
-
1221
- # @api private
1222
- def initialize(view, cmd, cmdsize, dataoff, datasize)
1223
- super(view, cmd, cmdsize)
1224
- @dataoff = dataoff
1225
- @datasize = datasize
1226
- end
967
+ field :datasize, :uint32
1227
968
 
1228
969
  # @return [Hash] a hash representation of this {LinkeditDataCommand}
1229
970
  def to_h
@@ -1238,29 +979,13 @@ module MachO
1238
979
  # segment. Corresponds to LC_ENCRYPTION_INFO.
1239
980
  class EncryptionInfoCommand < LoadCommand
1240
981
  # @return [Integer] the offset to the encrypted segment
1241
- attr_reader :cryptoff
982
+ field :cryptoff, :uint32
1242
983
 
1243
984
  # @return [Integer] the size of the encrypted segment
1244
- attr_reader :cryptsize
985
+ field :cryptsize, :uint32
1245
986
 
1246
987
  # @return [Integer] the encryption system, or 0 if not encrypted yet
1247
- attr_reader :cryptid
1248
-
1249
- # @see MachOStructure::FORMAT
1250
- # @api private
1251
- FORMAT = "L=5"
1252
-
1253
- # @see MachOStructure::SIZEOF
1254
- # @api private
1255
- SIZEOF = 20
1256
-
1257
- # @api private
1258
- def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
1259
- super(view, cmd, cmdsize)
1260
- @cryptoff = cryptoff
1261
- @cryptsize = cryptsize
1262
- @cryptid = cryptid
1263
- end
988
+ field :cryptid, :uint32
1264
989
 
1265
990
  # @return [Hash] a hash representation of this {EncryptionInfoCommand}
1266
991
  def to_h
@@ -1276,21 +1001,7 @@ module MachO
1276
1001
  # segment. Corresponds to LC_ENCRYPTION_INFO_64.
1277
1002
  class EncryptionInfoCommand64 < EncryptionInfoCommand
1278
1003
  # @return [Integer] 64-bit padding value
1279
- attr_reader :pad
1280
-
1281
- # @see MachOStructure::FORMAT
1282
- # @api private
1283
- FORMAT = "L=6"
1284
-
1285
- # @see MachOStructure::SIZEOF
1286
- # @api private
1287
- SIZEOF = 24
1288
-
1289
- # @api private
1290
- def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
1291
- super(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
1292
- @pad = pad
1293
- end
1004
+ field :pad, :uint32
1294
1005
 
1295
1006
  # @return [Hash] a hash representation of this {EncryptionInfoCommand64}
1296
1007
  def to_h
@@ -1305,25 +1016,10 @@ module MachO
1305
1016
  # LC_VERSION_MIN_IPHONEOS.
1306
1017
  class VersionMinCommand < LoadCommand
1307
1018
  # @return [Integer] the version X.Y.Z packed as x16.y8.z8
1308
- attr_reader :version
1019
+ field :version, :uint32
1309
1020
 
1310
1021
  # @return [Integer] the SDK version X.Y.Z packed as x16.y8.z8
1311
- attr_reader :sdk
1312
-
1313
- # @see MachOStructure::FORMAT
1314
- # @api private
1315
- FORMAT = "L=4"
1316
-
1317
- # @see MachOStructure::SIZEOF
1318
- # @api private
1319
- SIZEOF = 16
1320
-
1321
- # @api private
1322
- def initialize(view, cmd, cmdsize, version, sdk)
1323
- super(view, cmd, cmdsize)
1324
- @version = version
1325
- @sdk = sdk
1326
- end
1022
+ field :sdk, :uint32
1327
1023
 
1328
1024
  # A string representation of the binary's minimum OS version.
1329
1025
  # @return [String] a string representing the minimum OS version.
@@ -1363,33 +1059,16 @@ module MachO
1363
1059
  # Corresponds to LC_BUILD_VERSION.
1364
1060
  class BuildVersionCommand < LoadCommand
1365
1061
  # @return [Integer]
1366
- attr_reader :platform
1062
+ field :platform, :uint32
1367
1063
 
1368
1064
  # @return [Integer] the minimum OS version X.Y.Z packed as x16.y8.z8
1369
- attr_reader :minos
1065
+ field :minos, :uint32
1370
1066
 
1371
1067
  # @return [Integer] the SDK version X.Y.Z packed as x16.y8.z8
1372
- attr_reader :sdk
1068
+ field :sdk, :uint32
1373
1069
 
1374
1070
  # @return [ToolEntries] tool entries
1375
- attr_reader :tool_entries
1376
-
1377
- # @see MachOStructure::FORMAT
1378
- # @api private
1379
- FORMAT = "L=6"
1380
-
1381
- # @see MachOStructure::SIZEOF
1382
- # @api private
1383
- SIZEOF = 24
1384
-
1385
- # @api private
1386
- def initialize(view, cmd, cmdsize, platform, minos, sdk, ntools)
1387
- super(view, cmd, cmdsize)
1388
- @platform = platform
1389
- @minos = minos
1390
- @sdk = sdk
1391
- @tool_entries = ToolEntries.new(view, ntools)
1392
- end
1071
+ field :tool_entries, :tool_entries
1393
1072
 
1394
1073
  # A string representation of the binary's minimum OS version.
1395
1074
  # @return [String] a string representing the minimum OS version.
@@ -1474,59 +1153,34 @@ module MachO
1474
1153
  # Corresponds to LC_DYLD_INFO and LC_DYLD_INFO_ONLY.
1475
1154
  class DyldInfoCommand < LoadCommand
1476
1155
  # @return [Integer] the file offset to the rebase information
1477
- attr_reader :rebase_off
1156
+ field :rebase_off, :uint32
1478
1157
 
1479
1158
  # @return [Integer] the size of the rebase information
1480
- attr_reader :rebase_size
1159
+ field :rebase_size, :uint32
1481
1160
 
1482
1161
  # @return [Integer] the file offset to the binding information
1483
- attr_reader :bind_off
1162
+ field :bind_off, :uint32
1484
1163
 
1485
1164
  # @return [Integer] the size of the binding information
1486
- attr_reader :bind_size
1165
+ field :bind_size, :uint32
1487
1166
 
1488
1167
  # @return [Integer] the file offset to the weak binding information
1489
- attr_reader :weak_bind_off
1168
+ field :weak_bind_off, :uint32
1490
1169
 
1491
1170
  # @return [Integer] the size of the weak binding information
1492
- attr_reader :weak_bind_size
1171
+ field :weak_bind_size, :uint32
1493
1172
 
1494
1173
  # @return [Integer] the file offset to the lazy binding information
1495
- attr_reader :lazy_bind_off
1174
+ field :lazy_bind_off, :uint32
1496
1175
 
1497
1176
  # @return [Integer] the size of the lazy binding information
1498
- attr_reader :lazy_bind_size
1177
+ field :lazy_bind_size, :uint32
1499
1178
 
1500
1179
  # @return [Integer] the file offset to the export information
1501
- attr_reader :export_off
1180
+ field :export_off, :uint32
1502
1181
 
1503
1182
  # @return [Integer] the size of the export information
1504
- attr_reader :export_size
1505
-
1506
- # @see MachOStructure::FORMAT
1507
- # @api private
1508
- FORMAT = "L=12"
1509
-
1510
- # @see MachOStructure::SIZEOF
1511
- # @api private
1512
- SIZEOF = 48
1513
-
1514
- # @api private
1515
- def initialize(view, cmd, cmdsize, rebase_off, rebase_size, bind_off,
1516
- bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
1517
- lazy_bind_size, export_off, export_size)
1518
- super(view, cmd, cmdsize)
1519
- @rebase_off = rebase_off
1520
- @rebase_size = rebase_size
1521
- @bind_off = bind_off
1522
- @bind_size = bind_size
1523
- @weak_bind_off = weak_bind_off
1524
- @weak_bind_size = weak_bind_size
1525
- @lazy_bind_off = lazy_bind_off
1526
- @lazy_bind_size = lazy_bind_size
1527
- @export_off = export_off
1528
- @export_size = export_size
1529
- end
1183
+ field :export_size, :uint32
1530
1184
 
1531
1185
  # @return [Hash] a hash representation of this {DyldInfoCommand}
1532
1186
  def to_h
@@ -1549,21 +1203,7 @@ module MachO
1549
1203
  # Corresponds to LC_LINKER_OPTION.
1550
1204
  class LinkerOptionCommand < LoadCommand
1551
1205
  # @return [Integer] the number of strings
1552
- attr_reader :count
1553
-
1554
- # @see MachOStructure::FORMAT
1555
- # @api private
1556
- FORMAT = "L=3"
1557
-
1558
- # @see MachOStructure::SIZEOF
1559
- # @api private
1560
- SIZEOF = 12
1561
-
1562
- # @api private
1563
- def initialize(view, cmd, cmdsize, count)
1564
- super(view, cmd, cmdsize)
1565
- @count = count
1566
- end
1206
+ field :count, :uint32
1567
1207
 
1568
1208
  # @return [Hash] a hash representation of this {LinkerOptionCommand}
1569
1209
  def to_h
@@ -1576,25 +1216,10 @@ module MachO
1576
1216
  # A load command specifying the offset of main(). Corresponds to LC_MAIN.
1577
1217
  class EntryPointCommand < LoadCommand
1578
1218
  # @return [Integer] the file (__TEXT) offset of main()
1579
- attr_reader :entryoff
1219
+ field :entryoff, :uint64
1580
1220
 
1581
1221
  # @return [Integer] if not 0, the initial stack size.
1582
- attr_reader :stacksize
1583
-
1584
- # @see MachOStructure::FORMAT
1585
- # @api private
1586
- FORMAT = "L=2Q=2"
1587
-
1588
- # @see MachOStructure::SIZEOF
1589
- # @api private
1590
- SIZEOF = 24
1591
-
1592
- # @api private
1593
- def initialize(view, cmd, cmdsize, entryoff, stacksize)
1594
- super(view, cmd, cmdsize)
1595
- @entryoff = entryoff
1596
- @stacksize = stacksize
1597
- end
1222
+ field :stacksize, :uint64
1598
1223
 
1599
1224
  # @return [Hash] a hash representation of this {EntryPointCommand}
1600
1225
  def to_h
@@ -1609,21 +1234,7 @@ module MachO
1609
1234
  # binary. Corresponds to LC_SOURCE_VERSION.
1610
1235
  class SourceVersionCommand < LoadCommand
1611
1236
  # @return [Integer] the version packed as a24.b10.c10.d10.e10
1612
- attr_reader :version
1613
-
1614
- # @see MachOStructure::FORMAT
1615
- # @api private
1616
- FORMAT = "L=2Q=1"
1617
-
1618
- # @see MachOStructure::SIZEOF
1619
- # @api private
1620
- SIZEOF = 16
1621
-
1622
- # @api private
1623
- def initialize(view, cmd, cmdsize, version)
1624
- super(view, cmd, cmdsize)
1625
- @version = version
1626
- end
1237
+ field :version, :uint64
1627
1238
 
1628
1239
  # A string representation of the sources used to build the binary.
1629
1240
  # @return [String] a string representation of the version
@@ -1650,25 +1261,10 @@ module MachO
1650
1261
  # symbol table information. Corresponds to LC_SYMSEG.
1651
1262
  class SymsegCommand < LoadCommand
1652
1263
  # @return [Integer] the offset to the symbol segment
1653
- attr_reader :offset
1264
+ field :offset, :uint32
1654
1265
 
1655
1266
  # @return [Integer] the size of the symbol segment in bytes
1656
- attr_reader :size
1657
-
1658
- # @see MachOStructure::FORMAT
1659
- # @api private
1660
- FORMAT = "L=4"
1661
-
1662
- # @see MachOStructure::SIZEOF
1663
- # @api private
1664
- SIZEOF = 16
1665
-
1666
- # @api private
1667
- def initialize(view, cmd, cmdsize, offset, size)
1668
- super(view, cmd, cmdsize)
1669
- @offset = offset
1670
- @size = size
1671
- end
1267
+ field :size, :uint32
1672
1268
 
1673
1269
  # @return [Hash] a hash representation of this {SymsegCommand}
1674
1270
  def to_h
@@ -1683,37 +1279,16 @@ module MachO
1683
1279
  # string is null-terminated and the command is zero-padded to a multiple of
1684
1280
  # 4. Corresponds to LC_IDENT.
1685
1281
  class IdentCommand < LoadCommand
1686
- # @see MachOStructure::FORMAT
1687
- # @api private
1688
- FORMAT = "L=2"
1689
-
1690
- # @see MachOStructure::SIZEOF
1691
- # @api private
1692
- SIZEOF = 8
1693
1282
  end
1694
1283
 
1695
1284
  # An obsolete load command containing the path to a file to be loaded into
1696
1285
  # memory. Corresponds to LC_FVMFILE.
1697
1286
  class FvmfileCommand < LoadCommand
1698
1287
  # @return [LCStr] the pathname of the file being loaded
1699
- attr_reader :name
1288
+ field :name, :lcstr, :to_s => true
1700
1289
 
1701
1290
  # @return [Integer] the virtual address being loaded at
1702
- attr_reader :header_addr
1703
-
1704
- # @see MachOStructure::FORMAT
1705
- # @api private
1706
- FORMAT = "L=4"
1707
-
1708
- # @see MachOStructure::SIZEOF
1709
- # @api private
1710
- SIZEOF = 16
1711
-
1712
- def initialize(view, cmd, cmdsize, name, header_addr)
1713
- super(view, cmd, cmdsize)
1714
- @name = LCStr.new(self, name)
1715
- @header_addr = header_addr
1716
- end
1291
+ field :header_addr, :uint32
1717
1292
 
1718
1293
  # @return [Hash] a hash representation of this {FvmfileCommand}
1719
1294
  def to_h
@@ -1728,28 +1303,13 @@ module MachO
1728
1303
  # into memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
1729
1304
  class FvmlibCommand < LoadCommand
1730
1305
  # @return [LCStr] the library's target pathname
1731
- attr_reader :name
1306
+ field :name, :lcstr, :to_s => true
1732
1307
 
1733
1308
  # @return [Integer] the library's minor version number
1734
- attr_reader :minor_version
1309
+ field :minor_version, :uint32
1735
1310
 
1736
1311
  # @return [Integer] the library's header address
1737
- attr_reader :header_addr
1738
-
1739
- # @see MachOStructure::FORMAT
1740
- # @api private
1741
- FORMAT = "L=5"
1742
-
1743
- # @see MachOStructure::SIZEOF
1744
- # @api private
1745
- SIZEOF = 20
1746
-
1747
- def initialize(view, cmd, cmdsize, name, minor_version, header_addr)
1748
- super(view, cmd, cmdsize)
1749
- @name = LCStr.new(self, name)
1750
- @minor_version = minor_version
1751
- @header_addr = header_addr
1752
- end
1312
+ field :header_addr, :uint32
1753
1313
 
1754
1314
  # @return [Hash] a hash representation of this {FvmlibCommand}
1755
1315
  def to_h
@@ -1765,28 +1325,13 @@ module MachO
1765
1325
  # Corresponds to LC_NOTE.
1766
1326
  class NoteCommand < LoadCommand
1767
1327
  # @return [String] the name of the owner for this note
1768
- attr_reader :data_owner
1328
+ field :data_owner, :string, :padding => :null, :size => 16, :to_s => true
1769
1329
 
1770
1330
  # @return [Integer] the offset, within the file, of the note
1771
- attr_reader :offset
1331
+ field :offset, :uint64
1772
1332
 
1773
1333
  # @return [Integer] the size, in bytes, of the note
1774
- attr_reader :size
1775
-
1776
- # @see MachOStructure::FORMAT
1777
- # @api private
1778
- FORMAT = "L=2Z16Q=2"
1779
-
1780
- # @see MachOStructure::SIZEOF
1781
- # @api private
1782
- SIZEOF = 48
1783
-
1784
- def initialize(view, cmd, cmdsize, data_owner, offset, size)
1785
- super(view, cmd, cmdsize)
1786
- @data_owner = data_owner
1787
- @offset = offset
1788
- @size = size
1789
- end
1334
+ field :size, :uint64
1790
1335
 
1791
1336
  # @return [Hash] a hash representation of this {NoteCommand}
1792
1337
  def to_h
@@ -1803,32 +1348,16 @@ module MachO
1803
1348
  # Corresponds to LC_FILESET_ENTRY.
1804
1349
  class FilesetEntryCommand < LoadCommand
1805
1350
  # @return [Integer] the virtual memory address of the entry
1806
- attr_reader :vmaddr
1351
+ field :vmaddr, :uint64
1807
1352
 
1808
1353
  # @return [Integer] the file offset of the entry
1809
- attr_reader :fileoff
1354
+ field :fileoff, :uint64
1810
1355
 
1811
1356
  # @return [LCStr] the entry's ID
1812
- attr_reader :entry_id
1357
+ field :entry_id, :lcstr, :to_s => true
1813
1358
 
1814
1359
  # @return [void]
1815
- attr_reader :reserved
1816
-
1817
- # @see MachOStructure::FORMAT
1818
- # @api private
1819
- FORMAT = "L=2Q=2L=2"
1820
-
1821
- # @see MachOStructure::SIZEOF
1822
- # @api private
1823
- SIZEOF = 28
1824
-
1825
- def initialize(view, cmd, cmdsize, vmaddr, fileoff, entry_id, reserved)
1826
- super(view, cmd, cmdsize)
1827
- @vmaddr = vmaddr
1828
- @fileoff = fileoff
1829
- @entry_id = LCStr.new(self, entry_id)
1830
- @reserved = reserved
1831
- end
1360
+ field :reserved, :uint32
1832
1361
 
1833
1362
  # @return [Hash] a hash representation of this {FilesetEntryCommand}
1834
1363
  def to_h
@@ -1839,6 +1368,11 @@ module MachO
1839
1368
  "reserved" => reserved,
1840
1369
  }.merge super
1841
1370
  end
1371
+
1372
+ # @return [SegmentCommand64, nil] the matching segment command or nil if nothing matches
1373
+ def segment
1374
+ view.macho_file.command(:LC_SEGMENT_64).select { |cmd| cmd.fileoff == fileoff }.first
1375
+ end
1842
1376
  end
1843
1377
  end
1844
1378
  end