ruby-macho 1.3.0.pre.1 → 1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 73711cb2c95bea44060fc6ab6ebd99a66b06ee1a6187b512ae68527e8dc4e8f7
4
- data.tar.gz: fefdf5b471bbf158af6d8a1bf766f5b327ad737e09badc60d8adae723ef3d3b9
3
+ metadata.gz: 644d3e65c34cd64ddcba05a186fa28caa4032adb7ca7c4022e485f5d2a5bb399
4
+ data.tar.gz: 6835b176571ab230e171080c418a4f2873be9af58b47ebd1a316e8e219119222
5
5
  SHA512:
6
- metadata.gz: ed466ba6c6c0c62f1cb7fa365401faef73a322c636f9a1e97f3e655457f1787b83ef134360168618849f0d3253f1d6b8ed41aa0f085a9a40b3ca966ef1d437e4
7
- data.tar.gz: 61781f5efc71e38eff94704c09de7338e53918030189abe0f0bb2e1b442e5685a58076c431f112d27518e921fe5177666ccea7e6015fea65a5d8460da7632d13
6
+ metadata.gz: d4e29aaa92deb1128369c0f5368b6832d9c1068a89c5d1e35951ca17dc068806fc7674064dcf603ba3b6ba66a1e7b57189cb9589bbd53f74b7df4602d7726926
7
+ data.tar.gz: '0838f24f7b496660ce71eb06b1167c65f8c8b551ae6b6f223ec1518664d43bb8c1bdc0803e605ff93319c07ca2c8088a80aad1d2f397c9019c7fc067bae6c3d6'
@@ -1,18 +1,18 @@
1
- require "#{File.dirname(__FILE__)}/macho/structure"
2
- require "#{File.dirname(__FILE__)}/macho/view"
3
- require "#{File.dirname(__FILE__)}/macho/headers"
4
- require "#{File.dirname(__FILE__)}/macho/load_commands"
5
- require "#{File.dirname(__FILE__)}/macho/sections"
6
- require "#{File.dirname(__FILE__)}/macho/macho_file"
7
- require "#{File.dirname(__FILE__)}/macho/fat_file"
8
- require "#{File.dirname(__FILE__)}/macho/exceptions"
9
- require "#{File.dirname(__FILE__)}/macho/utils"
10
- require "#{File.dirname(__FILE__)}/macho/tools"
1
+ require_relative "macho/structure"
2
+ require_relative "macho/view"
3
+ require_relative "macho/headers"
4
+ require_relative "macho/load_commands"
5
+ require_relative "macho/sections"
6
+ require_relative "macho/macho_file"
7
+ require_relative "macho/fat_file"
8
+ require_relative "macho/exceptions"
9
+ require_relative "macho/utils"
10
+ require_relative "macho/tools"
11
11
 
12
12
  # The primary namespace for ruby-macho.
13
13
  module MachO
14
14
  # release version
15
- VERSION = "1.3.0.pre.1".freeze
15
+ VERSION = "1.3.0".freeze
16
16
 
17
17
  # Opens the given filename as a MachOFile or FatFile, depending on its magic.
18
18
  # @param filename [String] the file being opened
@@ -194,4 +194,14 @@ module MachO
194
194
  super "Unimplemented: #{thing}"
195
195
  end
196
196
  end
197
+
198
+ # Raised when attempting to create a {FatFile} from one or more {MachOFile}s
199
+ # whose offsets will not fit within the resulting 32-bit {Headers::FatArch#offset} fields.
200
+ class FatArchOffsetOverflowError < MachOError
201
+ # @param offset [Integer] the offending offset
202
+ def initialize(offset)
203
+ super "Offset #{offset} exceeds the 32-bit width of a fat_arch offset." \
204
+ " Consider merging with `fat64: true`"
205
+ end
206
+ end
197
207
  end
@@ -14,7 +14,7 @@ module MachO
14
14
  # @return [Headers::FatHeader] the file's header
15
15
  attr_reader :header
16
16
 
17
- # @return [Array<Headers::FatArch>] an array of fat architectures
17
+ # @return [Array<Headers::FatArch>, Array<Headers::FatArch64] an array of fat architectures
18
18
  attr_reader :fat_archs
19
19
 
20
20
  # @return [Array<MachOFile>] an array of Mach-O binaries
@@ -22,22 +22,54 @@ module MachO
22
22
 
23
23
  # Creates a new FatFile from the given (single-arch) Mach-Os
24
24
  # @param machos [Array<MachOFile>] the machos to combine
25
+ # @param fat64 [Boolean] whether to use {Headers::FatArch64}s to represent each slice
25
26
  # @return [FatFile] a new FatFile containing the give machos
26
- def self.new_from_machos(*machos)
27
- header = Headers::FatHeader.new(Headers::FAT_MAGIC, machos.size)
28
- offset = Headers::FatHeader.bytesize + (machos.size * Headers::FatArch.bytesize)
29
- fat_archs = []
27
+ # @raise [ArgumentError] if less than one Mach-O is given
28
+ # @raise [FatArchOffsetOverflowError] if the Mach-Os are too big to be represented
29
+ # in a 32-bit {Headers::FatArch} and `fat64` is `false`.
30
+ def self.new_from_machos(*machos, fat64: false)
31
+ raise ArgumentError, "expected at least one Mach-O" if machos.empty?
32
+
33
+ fa_klass, magic = if fat64
34
+ [Headers::FatArch64, Headers::FAT_MAGIC_64]
35
+ else
36
+ [Headers::FatArch, Headers::FAT_MAGIC]
37
+ end
38
+
39
+ # put the smaller alignments further forwards in fat macho, so that we do less padding
40
+ machos = machos.sort_by(&:segment_alignment)
41
+
42
+ bin = if String.instance_methods.include? :+@
43
+ +""
44
+ else
45
+ ""
46
+ end
47
+
48
+ bin << Headers::FatHeader.new(magic, machos.size).serialize
49
+ offset = Headers::FatHeader.bytesize + (machos.size * fa_klass.bytesize)
50
+
51
+ macho_pads = {}
52
+
30
53
  machos.each do |macho|
31
- fat_archs << Headers::FatArch.new(macho.header.cputype,
32
- macho.header.cpusubtype,
33
- offset, macho.serialize.bytesize,
34
- macho.alignment)
35
- offset += macho.serialize.bytesize
54
+ macho_offset = Utils.round(offset, 2**macho.segment_alignment)
55
+
56
+ if !fat64 && macho_offset > (2**32 - 1)
57
+ raise FatArchOffsetOverflowError, macho_offset
58
+ end
59
+
60
+ macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment)
61
+
62
+ bin << fa_klass.new(macho.header.cputype, macho.header.cpusubtype,
63
+ macho_offset, macho.serialize.bytesize,
64
+ macho.segment_alignment).serialize
65
+
66
+ offset += (macho.serialize.bytesize + macho_pads[macho])
36
67
  end
37
68
 
38
- bin = header.serialize
39
- bin << fat_archs.map(&:serialize).join
40
- bin << machos.map(&:serialize).join
69
+ machos.each do |macho|
70
+ bin << Utils.nullpad(macho_pads[macho])
71
+ bin << macho.serialize
72
+ end
41
73
 
42
74
  new_from_bin(bin)
43
75
  end
@@ -262,6 +294,7 @@ module MachO
262
294
  # @note Overwrites all data in the file!
263
295
  def write!
264
296
  raise MachOError, "no initial file to write to" if filename.nil?
297
+
265
298
  File.open(@filename, "wb") { |f| f.write(@raw_data) }
266
299
  end
267
300
 
@@ -311,10 +344,12 @@ module MachO
311
344
  def populate_fat_archs
312
345
  archs = []
313
346
 
314
- fa_off = Headers::FatHeader.bytesize
315
- fa_len = Headers::FatArch.bytesize
347
+ fa_klass = Utils.fat_magic32?(header.magic) ? Headers::FatArch : Headers::FatArch64
348
+ fa_off = Headers::FatHeader.bytesize
349
+ fa_len = fa_klass.bytesize
350
+
316
351
  header.nfat_arch.times do |i|
317
- archs << Headers::FatArch.new_from_bin(:big, @raw_data[fa_off + (fa_len * i), fa_len])
352
+ archs << fa_klass.new_from_bin(:big, @raw_data[fa_off + (fa_len * i), fa_len])
318
353
  end
319
354
 
320
355
  archs
@@ -364,6 +399,7 @@ module MachO
364
399
 
365
400
  # Strict mode: Immediately re-raise. Otherwise: Retain, check later.
366
401
  raise error if strict
402
+
367
403
  errors << error
368
404
  end
369
405
  end
@@ -6,11 +6,19 @@ module MachO
6
6
  FAT_MAGIC = 0xcafebabe
7
7
 
8
8
  # little-endian fat magic
9
- # this is defined, but should never appear in ruby-macho code because
10
- # fat headers are always big-endian and therefore always unpacked as such.
9
+ # @note This is defined for completeness, but should never appear in ruby-macho code,
10
+ # since fat headers are always big-endian.
11
11
  # @api private
12
12
  FAT_CIGAM = 0xbebafeca
13
13
 
14
+ # 64-bit big-endian fat magic
15
+ FAT_MAGIC_64 = 0xcafebabf
16
+
17
+ # 64-bit little-endian fat magic
18
+ # @note This is defined for completeness, but should never appear in ruby-macho code,
19
+ # since fat headers are always big-endian.
20
+ FAT_CIGAM_64 = 0xbfbafeca
21
+
14
22
  # 32-bit big-endian magic
15
23
  # @api private
16
24
  MH_MAGIC = 0xfeedface
@@ -31,6 +39,7 @@ module MachO
31
39
  # @api private
32
40
  MH_MAGICS = {
33
41
  FAT_MAGIC => "FAT_MAGIC",
42
+ FAT_MAGIC_64 => "FAT_MAGIC_64",
34
43
  MH_MAGIC => "MH_MAGIC",
35
44
  MH_CIGAM => "MH_CIGAM",
36
45
  MH_MAGIC_64 => "MH_MAGIC_64",
@@ -41,6 +50,11 @@ module MachO
41
50
  # @api private
42
51
  CPU_ARCH_ABI64 = 0x01000000
43
52
 
53
+ # mask for CPUs with 64-bit architectures (when running a 32-bit ABI?)
54
+ # @see https://github.com/Homebrew/ruby-macho/issues/113
55
+ # @api private
56
+ CPU_ARCH_ABI32 = 0x02000000
57
+
44
58
  # any CPU (unused?)
45
59
  # @api private
46
60
  CPU_TYPE_ANY = -1
@@ -69,6 +83,10 @@ module MachO
69
83
  # @api private
70
84
  CPU_TYPE_ARM64 = (CPU_TYPE_ARM | CPU_ARCH_ABI64)
71
85
 
86
+ # 64-bit ARM compatible CPUs (running in 32-bit mode?)
87
+ # @see https://github.com/Homebrew/ruby-macho/issues/113
88
+ CPU_TYPE_ARM64_32 = (CPU_TYPE_ARM | CPU_ARCH_ABI32)
89
+
72
90
  # PowerPC compatible CPUs
73
91
  # @api private
74
92
  CPU_TYPE_POWERPC = 0x12
@@ -85,6 +103,7 @@ module MachO
85
103
  CPU_TYPE_X86_64 => :x86_64,
86
104
  CPU_TYPE_ARM => :arm,
87
105
  CPU_TYPE_ARM64 => :arm64,
106
+ CPU_TYPE_ARM64_32 => :arm64_32,
88
107
  CPU_TYPE_POWERPC => :ppc,
89
108
  CPU_TYPE_POWERPC64 => :ppc64,
90
109
  }.freeze
@@ -218,6 +237,10 @@ module MachO
218
237
  # @api private
219
238
  CPU_SUBTYPE_ARM64_V8 = 1
220
239
 
240
+ # the v8 sub-type for `CPU_TYPE_ARM64_32`
241
+ # @api private
242
+ CPU_SUBTYPE_ARM64_32_V8 = 1
243
+
221
244
  # the lowest common sub-type for `CPU_TYPE_MC88000`
222
245
  # @api private
223
246
  CPU_SUBTYPE_MC88000_ALL = 0
@@ -328,6 +351,9 @@ module MachO
328
351
  CPU_SUBTYPE_ARM64_ALL => :arm64,
329
352
  CPU_SUBTYPE_ARM64_V8 => :arm64v8,
330
353
  }.freeze,
354
+ CPU_TYPE_ARM64_32 => {
355
+ CPU_SUBTYPE_ARM64_32_V8 => :arm64_32v8,
356
+ }.freeze,
331
357
  CPU_TYPE_POWERPC => {
332
358
  CPU_SUBTYPE_POWERPC_ALL => :ppc,
333
359
  CPU_SUBTYPE_POWERPC_601 => :ppc601,
@@ -486,8 +512,10 @@ module MachO
486
512
  end
487
513
  end
488
514
 
489
- # Fat binary header architecture structure. A Fat binary has one or more of
490
- # these, representing one or more internal Mach-O blobs.
515
+ # 32-bit fat binary header architecture structure. A 32-bit fat Mach-O has one or more of
516
+ # these, indicating one or more internal Mach-O blobs.
517
+ # @note "32-bit" indicates the fact that this structure stores 32-bit offsets, not that the
518
+ # Mach-Os that it points to necessarily *are* 32-bit.
491
519
  # @see MachO::Headers::FatHeader
492
520
  class FatArch < MachOStructure
493
521
  # @return [Integer] the CPU type of the Mach-O
@@ -505,10 +533,10 @@ module MachO
505
533
  # @return [Integer] the alignment, as a power of 2
506
534
  attr_reader :align
507
535
 
508
- # always big-endian
536
+ # @note Always big endian.
509
537
  # @see MachOStructure::FORMAT
510
538
  # @api private
511
- FORMAT = "N5".freeze
539
+ FORMAT = "L>5".freeze
512
540
 
513
541
  # @see MachOStructure::SIZEOF
514
542
  # @api private
@@ -542,6 +570,43 @@ module MachO
542
570
  end
543
571
  end
544
572
 
573
+ # 64-bit fat binary header architecture structure. A 64-bit fat Mach-O has one or more of
574
+ # these, indicating one or more internal Mach-O blobs.
575
+ # @note "64-bit" indicates the fact that this structure stores 64-bit offsets, not that the
576
+ # Mach-Os that it points to necessarily *are* 64-bit.
577
+ # @see MachO::Headers::FatHeader
578
+ class FatArch64 < FatArch
579
+ # @return [void]
580
+ attr_reader :reserved
581
+
582
+ # @note Always big endian.
583
+ # @see MachOStructure::FORMAT
584
+ # @api private
585
+ FORMAT = "L>2Q>2L>2".freeze
586
+
587
+ # @see MachOStructure::SIZEOF
588
+ # @api private
589
+ SIZEOF = 32
590
+
591
+ # @api private
592
+ def initialize(cputype, cpusubtype, offset, size, align, reserved = 0)
593
+ super(cputype, cpusubtype, offset, size, align)
594
+ @reserved = reserved
595
+ end
596
+
597
+ # @return [String] the serialized fields of the fat arch
598
+ def serialize
599
+ [cputype, cpusubtype, offset, size, align, reserved].pack(FORMAT)
600
+ end
601
+
602
+ # @return [Hash] a hash representation of this {FatArch64}
603
+ def to_h
604
+ {
605
+ "reserved" => reserved,
606
+ }.merge super
607
+ end
608
+ end
609
+
545
610
  # 32-bit Mach-O file header structure
546
611
  class MachHeader < MachOStructure
547
612
  # @return [Integer] the magic number
@@ -593,7 +658,9 @@ module MachO
593
658
  # @return [Boolean] true if `flag` is present in the header's flag section
594
659
  def flag?(flag)
595
660
  flag = MH_FLAGS[flag]
661
+
596
662
  return false if flag.nil?
663
+
597
664
  flags & flag == flag
598
665
  end
599
666
 
@@ -242,6 +242,7 @@ module MachO
242
242
  # @api private
243
243
  def serialize(context)
244
244
  raise LoadCommandNotSerializableError, LOAD_COMMANDS[cmd] unless serializable?
245
+
245
246
  format = Utils.specialize_format(FORMAT, context.endianness)
246
247
  [cmd, SIZEOF].pack(format)
247
248
  end
@@ -298,7 +299,9 @@ module MachO
298
299
  lc_end = view.offset + lc.cmdsize - 1
299
300
  raw_string = view.raw_data.slice(lc_str_abs..lc_end)
300
301
  @string, null_byte, _padding = raw_string.partition("\x00")
302
+
301
303
  raise LCStrMalformedError, lc if null_byte.empty?
304
+
302
305
  @string_offset = lc_str
303
306
  else
304
307
  @string = lc_str
@@ -473,10 +476,32 @@ module MachO
473
476
  # @return [Boolean] true if `flag` is present in the segment's flag field
474
477
  def flag?(flag)
475
478
  flag = SEGMENT_FLAGS[flag]
479
+
476
480
  return false if flag.nil?
481
+
477
482
  flags & flag == flag
478
483
  end
479
484
 
485
+ # Guesses the alignment of the segment.
486
+ # @return [Integer] the guessed alignment, as a power of 2
487
+ # @note See `guess_align` in `cctools/misc/lipo.c`
488
+ def guess_align
489
+ return Sections::MAX_SECT_ALIGN if vmaddr.zero?
490
+
491
+ align = 0
492
+ segalign = 1
493
+
494
+ while (segalign & vmaddr).zero?
495
+ segalign <<= 1
496
+ align += 1
497
+ end
498
+
499
+ return 2 if align < 2
500
+ return Sections::MAX_SECT_ALIGN if align > Sections::MAX_SECT_ALIGN
501
+
502
+ align
503
+ end
504
+
480
505
  # @return [Hash] a hash representation of this {SegmentCommand}
481
506
  def to_h
482
507
  {
@@ -219,8 +219,7 @@ module MachO
219
219
  update_sizeofcmds(sizeofcmds - lc.cmdsize)
220
220
 
221
221
  # pad the space after the load commands to preserve offsets
222
- null_pad = "\x00" * lc.cmdsize
223
- @raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, null_pad)
222
+ @raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, Utils.nullpad(lc.cmdsize))
224
223
 
225
224
  populate_fields if options.fetch(:repopulate, true)
226
225
  end
@@ -252,6 +251,33 @@ module MachO
252
251
  end
253
252
  end
254
253
 
254
+ # The segment alignment for the Mach-O. Guesses conservatively.
255
+ # @return [Integer] the alignment, as a power of 2
256
+ # @note This is **not** the same as {#alignment}!
257
+ # @note See `get_align` and `get_align_64` in `cctools/misc/lipo.c`
258
+ def segment_alignment
259
+ # special cases: 12 for x86/64/PPC/PP64, 14 for ARM/ARM64
260
+ return 12 if %i[i386 x86_64 ppc ppc64].include?(cputype)
261
+ return 14 if %i[arm arm64].include?(cputype)
262
+
263
+ cur_align = Sections::MAX_SECT_ALIGN
264
+
265
+ segments.each do |segment|
266
+ if filetype == :object
267
+ # start with the smallest alignment, and work our way up
268
+ align = magic32? ? 2 : 3
269
+ segment.sections.each do |section|
270
+ align = section.align unless section.align <= align
271
+ end
272
+ else
273
+ align = segment.guess_align
274
+ end
275
+ cur_align = align if align < cur_align
276
+ end
277
+
278
+ cur_align
279
+ end
280
+
255
281
  # The Mach-O's dylib ID, or `nil` if not a dylib.
256
282
  # @example
257
283
  # file.dylib_id # => 'libBar.dylib'
@@ -405,6 +431,7 @@ module MachO
405
431
  # @note Overwrites all data in the file!
406
432
  def write!
407
433
  raise MachOError, "no initial file to write to" if @filename.nil?
434
+
408
435
  File.open(@filename, "wb") { |f| f.write(@raw_data) }
409
436
  end
410
437
 
@@ -13,6 +13,10 @@ module MachO
13
13
  # system settable attributes mask
14
14
  SECTION_ATTRIBUTES_SYS = 0x00ffff00
15
15
 
16
+ # maximum specifiable section alignment, as a power of 2
17
+ # @note see `MAXSECTALIGN` macro in `cctools/misc/lipo.c`
18
+ MAX_SECT_ALIGN = 15
19
+
16
20
  # association of section flag symbols to values
17
21
  # @api private
18
22
  SECTION_FLAGS = {
@@ -146,7 +150,9 @@ module MachO
146
150
  # @return [Boolean] whether the flag is present in the section's {flags}
147
151
  def flag?(flag)
148
152
  flag = SECTION_FLAGS[flag]
153
+
149
154
  return false if flag.nil?
155
+
150
156
  flags & flag == flag
151
157
  end
152
158
 
@@ -89,8 +89,9 @@ module MachO
89
89
  # Merge multiple Mach-Os into one universal (Fat) binary.
90
90
  # @param filename [String] the fat binary to create
91
91
  # @param files [Array<String>] the files to merge
92
+ # @param fat64 [Boolean] whether to use {Headers::FatArch64}s to represent each slice
92
93
  # @return [void]
93
- def self.merge_machos(filename, *files)
94
+ def self.merge_machos(filename, *files, fat64: false)
94
95
  machos = files.map do |file|
95
96
  macho = MachO.open(file)
96
97
  case macho
@@ -101,7 +102,7 @@ module MachO
101
102
  end
102
103
  end.flatten
103
104
 
104
- fat_macho = MachO::FatFile.new_from_machos(*machos)
105
+ fat_macho = MachO::FatFile.new_from_machos(*machos, :fat64 => fat64)
105
106
  fat_macho.write(filename)
106
107
  end
107
108
  end
@@ -22,6 +22,16 @@ module MachO
22
22
  round(size, alignment) - size
23
23
  end
24
24
 
25
+ # Returns a string of null bytes of the requested (non-negative) size
26
+ # @param size [Integer] the size of the nullpad
27
+ # @return [String] the null string (or empty string, for `size = 0`)
28
+ # @raise [ArgumentError] if a non-positive nullpad is requested
29
+ def self.nullpad(size)
30
+ raise ArgumentError, "size < 0: #{size}" if size < 0
31
+
32
+ "\x00" * size
33
+ end
34
+
25
35
  # Converts an abstract (native-endian) String#unpack format to big or
26
36
  # little.
27
37
  # @param format [String] the format string being converted
@@ -46,11 +56,11 @@ module MachO
46
56
  strings.each do |key, string|
47
57
  offsets[key] = next_offset
48
58
  payload << string
49
- payload << "\x00"
59
+ payload << Utils.nullpad(1)
50
60
  next_offset += string.bytesize + 1
51
61
  end
52
62
 
53
- payload << "\x00" * padding_for(fixed_offset + payload.bytesize, alignment)
63
+ payload << Utils.nullpad(padding_for(fixed_offset + payload.bytesize, alignment))
54
64
  [payload, offsets]
55
65
  end
56
66
 
@@ -65,35 +75,49 @@ module MachO
65
75
  # @param num [Integer] the number being checked
66
76
  # @return [Boolean] whether `num` is a valid Fat magic number
67
77
  def self.fat_magic?(num)
78
+ [Headers::FAT_MAGIC, Headers::FAT_MAGIC_64].include? num
79
+ end
80
+
81
+ # Compares the given number to valid 32-bit Fat magic numbers.
82
+ # @param num [Integer] the number being checked
83
+ # @return [Boolean] whether `num` is a valid 32-bit fat magic number
84
+ def self.fat_magic32?(num)
68
85
  num == Headers::FAT_MAGIC
69
86
  end
70
87
 
88
+ # Compares the given number to valid 64-bit Fat magic numbers.
89
+ # @param num [Integer] the number being checked
90
+ # @return [Boolean] whether `num` is a valid 64-bit fat magic number
91
+ def self.fat_magic64?(num)
92
+ num == Headers::FAT_MAGIC_64
93
+ end
94
+
71
95
  # Compares the given number to valid 32-bit Mach-O magic numbers.
72
96
  # @param num [Integer] the number being checked
73
97
  # @return [Boolean] whether `num` is a valid 32-bit magic number
74
98
  def self.magic32?(num)
75
- num == Headers::MH_MAGIC || num == Headers::MH_CIGAM
99
+ [Headers::MH_MAGIC, Headers::MH_CIGAM].include? num
76
100
  end
77
101
 
78
102
  # Compares the given number to valid 64-bit Mach-O magic numbers.
79
103
  # @param num [Integer] the number being checked
80
104
  # @return [Boolean] whether `num` is a valid 64-bit magic number
81
105
  def self.magic64?(num)
82
- num == Headers::MH_MAGIC_64 || num == Headers::MH_CIGAM_64
106
+ [Headers::MH_MAGIC_64, Headers::MH_CIGAM_64].include? num
83
107
  end
84
108
 
85
109
  # Compares the given number to valid little-endian magic numbers.
86
110
  # @param num [Integer] the number being checked
87
111
  # @return [Boolean] whether `num` is a valid little-endian magic number
88
112
  def self.little_magic?(num)
89
- num == Headers::MH_CIGAM || num == Headers::MH_CIGAM_64
113
+ [Headers::MH_CIGAM, Headers::MH_CIGAM_64].include? num
90
114
  end
91
115
 
92
116
  # Compares the given number to valid big-endian magic numbers.
93
117
  # @param num [Integer] the number being checked
94
118
  # @return [Boolean] whether `num` is a valid big-endian magic number
95
119
  def self.big_magic?(num)
96
- num == Headers::MH_CIGAM || num == Headers::MH_CIGAM_64
120
+ [Headers::MH_MAGIC, Headers::MH_MAGIC_64].include? num
97
121
  end
98
122
  end
99
123
  end
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: 1.3.0.pre.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - William Woodruff
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-21 00:00:00.000000000 Z
11
+ date: 2018-09-30 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
@@ -42,12 +42,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: '2.1'
45
+ version: '2.3'
46
46
  required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  requirements:
48
- - - ">"
48
+ - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: 1.3.1
50
+ version: '0'
51
51
  requirements: []
52
52
  rubyforge_project:
53
53
  rubygems_version: 2.7.6