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