ruby-macho 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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