ruby-macho 4.0.0 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 669b2133517dc564c92df8ebdc0b2f6fdc91869939cd6a642cfbc2b1c6e20a09
4
- data.tar.gz: 0077afabc9c4be7d891e5c7e5a8b4ec173223b00f73d550fc96fb7cf4f103c1d
3
+ metadata.gz: cf1e87b27661d19099f8a7160c774dab716e37be7dec050f84c701e9fc6c1ea6
4
+ data.tar.gz: 18d7705d4204bd10bd593b7ab8759058d2cea94eadeed9d7edce06b96d303a9b
5
5
  SHA512:
6
- metadata.gz: 4e8bd64595d93d50c0046c5bd292010a51a9d4154cbcda3a0a0a962882475e61d631d55da106e4655ba31a32011f583222d5b147129230e08ad11d12a34ee8e6
7
- data.tar.gz: ccc53798eb56f378f5688ad7141636ecca274e552e8ad62f4fab5600b6a6fddcac0e5ffc75ed4924e62538a6b3ac7b291667870b6cd02bf0edf6286da1a4e62a
6
+ metadata.gz: 0c6007d3ef6a175bf58c6b900a42aacdfd557d1f283f3e144828c25a3207f4791ef031c3313ace7a4f807b62ecf05ffb7944ca39d746d6446d23d20c0c4a6166
7
+ data.tar.gz: d7345efc2941999717f803ae9740067ee4a53cec738fd44c0ea5cee610f1b7d28bac8bf572f5558ff02f63a590ce323f024b9e2fd6e55977fc521dcb39ca2c03
data/README.md CHANGED
@@ -2,7 +2,7 @@ ruby-macho
2
2
  ================
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/ruby-macho.svg)](http://badge.fury.io/rb/ruby-macho)
5
- [![Build Status](https://travis-ci.org/Homebrew/ruby-macho.svg?branch=master)](https://travis-ci.org/Homebrew/ruby-macho)
5
+ [![CI](https://github.com/Homebrew/ruby-macho/actions/workflows/tests.yml/badge.svg)](https://github.com/Homebrew/ruby-macho/actions/workflows/tests.yml)
6
6
  [![Coverage Status](https://codecov.io/gh/Homebrew/ruby-macho/branch/master/graph/badge.svg)](https://codecov.io/gh/Homebrew/ruby-macho)
7
7
 
8
8
  A Ruby library for examining and modifying Mach-O files.
@@ -65,6 +65,7 @@ module MachO
65
65
  (LC_REQ_DYLD | 0x33) => :LC_DYLD_EXPORTS_TRIE,
66
66
  (LC_REQ_DYLD | 0x34) => :LC_DYLD_CHAINED_FIXUPS,
67
67
  (LC_REQ_DYLD | 0x35) => :LC_FILESET_ENTRY,
68
+ 0x36 => :LC_ATOM_INFO,
68
69
  }.freeze
69
70
 
70
71
  # association of symbol representations to load command constants
@@ -110,7 +111,7 @@ module MachO
110
111
  # "reserved for internal use only", no public struct
111
112
  :LC_PREPAGE => "LoadCommand",
112
113
  :LC_DYSYMTAB => "DysymtabCommand",
113
- :LC_LOAD_DYLIB => "DylibCommand",
114
+ :LC_LOAD_DYLIB => "DylibUseCommand",
114
115
  :LC_ID_DYLIB => "DylibCommand",
115
116
  :LC_LOAD_DYLINKER => "DylinkerCommand",
116
117
  :LC_ID_DYLINKER => "DylinkerCommand",
@@ -122,7 +123,7 @@ module MachO
122
123
  :LC_SUB_LIBRARY => "SubLibraryCommand",
123
124
  :LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
124
125
  :LC_PREBIND_CKSUM => "PrebindCksumCommand",
125
- :LC_LOAD_WEAK_DYLIB => "DylibCommand",
126
+ :LC_LOAD_WEAK_DYLIB => "DylibUseCommand",
126
127
  :LC_SEGMENT_64 => "SegmentCommand64",
127
128
  :LC_ROUTINES_64 => "RoutinesCommand64",
128
129
  :LC_UUID => "UUIDCommand",
@@ -153,6 +154,7 @@ module MachO
153
154
  :LC_DYLD_EXPORTS_TRIE => "LinkeditDataCommand",
154
155
  :LC_DYLD_CHAINED_FIXUPS => "LinkeditDataCommand",
155
156
  :LC_FILESET_ENTRY => "FilesetEntryCommand",
157
+ :LC_ATOM_INFO => "LinkeditDataCommand",
156
158
  }.freeze
157
159
 
158
160
  # association of segment name symbols to names
@@ -193,6 +195,20 @@ module MachO
193
195
  :SG_READ_ONLY => 0x10,
194
196
  }.freeze
195
197
 
198
+ # association of dylib use flag symbols to values
199
+ # @api private
200
+ DYLIB_USE_FLAGS = {
201
+ :DYLIB_USE_WEAK_LINK => 0x1,
202
+ :DYLIB_USE_REEXPORT => 0x2,
203
+ :DYLIB_USE_UPWARD => 0x4,
204
+ :DYLIB_USE_DELAYED_INIT => 0x8,
205
+ }.freeze
206
+
207
+ # the marker used to denote a newer style dylib use command.
208
+ # the value is the timestamp 24 January 1984 18:12:16
209
+ # @api private
210
+ DYLIB_USE_MARKER = 0x1a741800
211
+
196
212
  # The top-level Mach-O load command structure.
197
213
  #
198
214
  # This is the most generic load command -- only the type ID and size are
@@ -231,6 +247,13 @@ module MachO
231
247
  # cmd will be filled in, view and cmdsize will be left unpopulated
232
248
  klass_arity = klass.min_args - 3
233
249
 
250
+ # macOS 15 introduces a new dylib load command that adds a flags field to the end.
251
+ # It uses the same commands with it dynamically being created if the dylib has a flags field
252
+ if klass == DylibUseCommand && (args[1] != DYLIB_USE_MARKER || args.size <= DylibCommand.min_args - 3)
253
+ klass = DylibCommand
254
+ klass_arity = klass.min_args - 3
255
+ end
256
+
234
257
  raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity > args.size
235
258
 
236
259
  klass.new(nil, cmd, nil, *args)
@@ -526,6 +549,23 @@ module MachO
526
549
  # @return [Integer] the library's compatibility version number
527
550
  field :compatibility_version, :uint32
528
551
 
552
+ # @example
553
+ # puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
554
+ # @param flag [Symbol] a dylib use command flag symbol
555
+ # @return [Boolean] true if `flag` applies to this dylib command
556
+ def flag?(flag)
557
+ case cmd
558
+ when LOAD_COMMAND_CONSTANTS[:LC_LOAD_WEAK_DYLIB]
559
+ flag == :DYLIB_USE_WEAK_LINK
560
+ when LOAD_COMMAND_CONSTANTS[:LC_REEXPORT_DYLIB]
561
+ flag == :DYLIB_USE_REEXPORT
562
+ when LOAD_COMMAND_CONSTANTS[:LC_LOAD_UPWARD_DYLIB]
563
+ flag == :DYLIB_USE_UPWARD
564
+ else
565
+ false
566
+ end
567
+ end
568
+
529
569
  # @param context [SerializationContext]
530
570
  # the context
531
571
  # @return [String] the serialized fields of the load command
@@ -551,6 +591,65 @@ module MachO
551
591
  end
552
592
  end
553
593
 
594
+ # The newer format of load command representing some aspect of shared libraries,
595
+ # depending on filetype. Corresponds to LC_LOAD_DYLIB or LC_LOAD_WEAK_DYLIB.
596
+ class DylibUseCommand < DylibCommand
597
+ # @return [Integer] any flags associated with this dylib use command
598
+ field :flags, :uint32
599
+
600
+ alias marker timestamp
601
+
602
+ # Instantiates a new DylibCommand or DylibUseCommand.
603
+ # macOS 15 and later use a new format for dylib commands (DylibUseCommand),
604
+ # which is determined based on a special timestamp and the name offset.
605
+ # @param view [MachO::MachOView] the load command's raw view
606
+ # @return [DylibCommand] the new dylib load command
607
+ # @api private
608
+ def self.new_from_bin(view)
609
+ dylib_command = DylibCommand.new_from_bin(view)
610
+
611
+ if dylib_command.timestamp == DYLIB_USE_MARKER &&
612
+ dylib_command.name.to_i == DylibUseCommand.bytesize
613
+ super(view)
614
+ else
615
+ dylib_command
616
+ end
617
+ end
618
+
619
+ # @example
620
+ # puts "this dylib is weakly loaded" if dylib_command.flag?(:DYLIB_USE_WEAK_LINK)
621
+ # @param flag [Symbol] a dylib use command flag symbol
622
+ # @return [Boolean] true if `flag` applies to this dylib command
623
+ def flag?(flag)
624
+ flag = DYLIB_USE_FLAGS[flag]
625
+
626
+ return false if flag.nil?
627
+
628
+ flags & flag == flag
629
+ end
630
+
631
+ # @param context [SerializationContext]
632
+ # the context
633
+ # @return [String] the serialized fields of the load command
634
+ # @api private
635
+ def serialize(context)
636
+ format = Utils.specialize_format(self.class.format, context.endianness)
637
+ string_payload, string_offsets = Utils.pack_strings(self.class.bytesize,
638
+ context.alignment,
639
+ :name => name.to_s)
640
+ cmdsize = self.class.bytesize + string_payload.bytesize
641
+ [cmd, cmdsize, string_offsets[:name], marker, current_version,
642
+ compatibility_version, flags].pack(format) + string_payload
643
+ end
644
+
645
+ # @return [Hash] a hash representation of this {DylibUseCommand}
646
+ def to_h
647
+ {
648
+ "flags" => flags,
649
+ }.merge super
650
+ end
651
+ end
652
+
554
653
  # A load command representing some aspect of the dynamic linker, depending
555
654
  # on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
556
655
  # LC_DYLD_ENVIRONMENT.
@@ -958,7 +1057,7 @@ module MachO
958
1057
  # the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE,
959
1058
  # LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
960
1059
  # LC_DYLIB_CODE_SIGN_DRS, LC_LINKER_OPTIMIZATION_HINT, LC_DYLD_EXPORTS_TRIE,
961
- # or LC_DYLD_CHAINED_FIXUPS.
1060
+ # LC_DYLD_CHAINED_FIXUPS, or LC_ATOM_INFO.
962
1061
  class LinkeditDataCommand < LoadCommand
963
1062
  # @return [Integer] offset to the data in the __LINKEDIT segment
964
1063
  field :dataoff, :uint32
@@ -411,9 +411,15 @@ module MachO
411
411
 
412
412
  # Delete the given runtime path from the Mach-O.
413
413
  # @example
414
- # file.rpaths # => ["/lib"]
415
- # file.delete_rpath("/lib")
416
- # file.rpaths # => []
414
+ # file1.rpaths # => ["/lib", "/usr/lib", "/lib"]
415
+ # file1.delete_rpath("/lib")
416
+ # file1.rpaths # => ["/usr/lib", "/lib"]
417
+ # file2.rpaths # => ["foo", "foo"]
418
+ # file2.delete_rpath("foo", :uniq => true)
419
+ # file2.rpaths # => []
420
+ # file3.rpaths # => ["foo", "bar", "foo"]
421
+ # file3.delete_rpath("foo", :last => true)
422
+ # file3.rpaths # => ["foo", "bar"]
417
423
  # @param path [String] the runtime path to delete
418
424
  # @param options [Hash]
419
425
  # @option options [Boolean] :uniq (false) if true, also delete
@@ -421,7 +427,7 @@ module MachO
421
427
  # instance (by offset) of the requested path, unless :last is true.
422
428
  # Incompatible with :last.
423
429
  # @option options [Boolean] :last (false) if true, delete the last
424
- # instance (by offset) of the requested path. Incompatible with :uniq.
430
+ # instance (by offset) of the requested path. Incompatible with :uniq.
425
431
  # @return void
426
432
  # @raise [RpathUnknownError] if no such runtime path exists
427
433
  # @raise [ArgumentError] if both :uniq and :last are true
@@ -131,7 +131,7 @@ module MachO
131
131
 
132
132
  # @param name [Symbol] name of internal field
133
133
  # @param type [Symbol] type of field in terms of binary size
134
- # @param options [Hash] set of additonal options
134
+ # @param options [Hash] set of additional options
135
135
  # Expected options
136
136
  # :size [Integer] size in bytes
137
137
  # :mask [Integer] bitmask
@@ -236,7 +236,7 @@ module MachO
236
236
  # Generates a reader method for fields that need further unpacking.
237
237
  # @param name [Symbol] name of internal field
238
238
  # @param idx [Integer] the index of the field value in the @values array
239
- # @param unpack [String] the format code used for futher binary unpacking
239
+ # @param unpack [String] the format code used for further binary unpacking
240
240
  # @api private
241
241
  def def_unpack_reader(name, idx, unpack)
242
242
  define_method(name) do
data/lib/macho.rb CHANGED
@@ -16,7 +16,7 @@ require_relative "macho/tools"
16
16
  # The primary namespace for ruby-macho.
17
17
  module MachO
18
18
  # release version
19
- VERSION = "4.0.0"
19
+ VERSION = "4.1.0"
20
20
 
21
21
  # Opens the given filename as a MachOFile or FatFile, depending on its magic.
22
22
  # @param filename [String] the file being opened
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-macho
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Woodruff
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-07-25 00:00:00.000000000 Z
11
+ date: 2024-06-11 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A library for viewing and manipulating Mach-O files in Ruby.
14
14
  email: william@yossarian.net
@@ -35,7 +35,7 @@ licenses:
35
35
  - MIT
36
36
  metadata:
37
37
  rubygems_mfa_required: 'true'
38
- post_install_message:
38
+ post_install_message:
39
39
  rdoc_options: []
40
40
  require_paths:
41
41
  - lib
@@ -51,7 +51,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
51
51
  version: '0'
52
52
  requirements: []
53
53
  rubygems_version: 3.4.10
54
- signing_key:
54
+ signing_key:
55
55
  specification_version: 4
56
56
  summary: ruby-macho - Mach-O file analyzer.
57
57
  test_files: []