ruby-macho 1.3.0.pre.1 → 1.3.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: 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