diff --git a/Library/Homebrew/vendor/README.md b/Library/Homebrew/vendor/README.md index ce1178f168..c485718959 100644 --- a/Library/Homebrew/vendor/README.md +++ b/Library/Homebrew/vendor/README.md @@ -3,7 +3,7 @@ Vendored Dependencies * [okjson](https://github.com/kr/okjson), version 43. -* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 0.2.2-39-ge2fbedc9. +* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 0.2.4 ## Licenses: @@ -32,7 +32,7 @@ Vendored Dependencies ### ruby-macho > The MIT License -> Copyright (c) 2015 William Woodruff +> Copyright (c) 2015, 2016 William Woodruff > > Permission is hereby granted, free of charge, to any person obtaining a copy > of this software and associated documentation files (the "Software"), to deal diff --git a/Library/Homebrew/vendor/macho/macho.rb b/Library/Homebrew/vendor/macho/macho.rb index 8cfc5521cb..c94eec77b7 100644 --- a/Library/Homebrew/vendor/macho/macho.rb +++ b/Library/Homebrew/vendor/macho/macho.rb @@ -12,5 +12,5 @@ require "#{File.dirname(__FILE__)}/macho/tools" # The primary namespace for ruby-macho. module MachO # release version - VERSION = "0.2.2".freeze + VERSION = "0.2.4".freeze end diff --git a/Library/Homebrew/vendor/macho/macho/exceptions.rb b/Library/Homebrew/vendor/macho/macho/exceptions.rb index 07ae43edb7..6840060e88 100644 --- a/Library/Homebrew/vendor/macho/macho/exceptions.rb +++ b/Library/Homebrew/vendor/macho/macho/exceptions.rb @@ -49,17 +49,18 @@ module MachO # Raised when the CPU type is unknown. class CPUTypeError < MachOError - # @param num [Fixnum] the unknown number - def initialize(num) - super "Unrecognized CPU type: 0x#{"%02x" % num}" + # @param cputype [Fixnum] the unknown CPU type + def initialize(cputype) + super "Unrecognized CPU type: 0x#{"%08x" % cputype}" end end - # Raised when the CPU subtype is unknown. + # Raised when the CPU type/sub-type pair is unknown. class CPUSubtypeError < MachOError - # @param num [Fixnum] the unknown number - def initialize(num) - super "Unrecognized CPU sub-type: 0x#{"%02x" % num}" + # @param cputype [Fixnum] the CPU type of the unknown pair + # @param cpusubtype [Fixnum] the CPU sub-type of the unknown pair + def initialize(cputype, cpusubtype) + super "Unrecognized CPU sub-type: 0x#{"%08x" % cpusubtype} (for CPU type: 0x#{"%08x" % cputype})" end end diff --git a/Library/Homebrew/vendor/macho/macho/fat_file.rb b/Library/Homebrew/vendor/macho/macho/fat_file.rb index 0b25483a9f..dd24fa10fb 100644 --- a/Library/Homebrew/vendor/macho/macho/fat_file.rb +++ b/Library/Homebrew/vendor/macho/macho/fat_file.rb @@ -4,6 +4,9 @@ module MachO # @see https://en.wikipedia.org/wiki/Mach-O#Multi-architecture_binaries # @see MachO::MachOFile class FatFile + # @return [String] the filename loaded from, or nil if loaded from a binary string + attr_accessor :filename + # @return [MachO::FatHeader] the file's header attr_reader :header @@ -25,12 +28,12 @@ module MachO # Creates a new FatFile from the given filename. # @param filename [String] the fat file to load from - # @raise [ArgumentError] if the given filename does not exist + # @raise [ArgumentError] if the given file does not exist def initialize(filename) - raise ArgumentError.new("#{filetype}: no such file") unless File.exist?(filename) + raise ArgumentError.new("#{filename}: no such file") unless File.file?(filename) @filename = filename - @raw_data = open(@filename, "rb") { |f| f.read } + @raw_data = File.open(@filename, "rb") { |f| f.read } @header = get_fat_header @fat_archs = get_fat_archs @machos = get_machos @@ -175,8 +178,8 @@ module MachO # Extract a Mach-O with the given CPU type from the file. # @example - # file.extract("CPU_TYPE_I386") # => MachO::MachOFile - # @param cputype [String] the CPU type of the Mach-O being extracted + # file.extract(:i386) # => MachO::MachOFile + # @param cputype [Symbol] the CPU type of the Mach-O being extracted # @return [MachO::MachOFile, nil] the extracted Mach-O or nil if no Mach-O has the given CPU type def extract(cputype) machos.select { |macho| macho.cputype == cputype }.first @@ -213,7 +216,7 @@ module MachO # the smallest fat Mach-O header is 8 bytes raise TruncatedFileError.new if @raw_data.size < 8 - fh = FatHeader.new_from_bin(@raw_data[0, FatHeader.bytesize]) + fh = FatHeader.new_from_bin(:big, @raw_data[0, FatHeader.bytesize]) raise MagicError.new(fh.magic) unless MachO.magic?(fh.magic) raise MachOBinaryError.new unless MachO.fat_magic?(fh.magic) @@ -239,7 +242,7 @@ module MachO fa_off = FatHeader.bytesize fa_len = FatArch.bytesize header.nfat_arch.times do |i| - archs << FatArch.new_from_bin(@raw_data[fa_off + (fa_len * i), fa_len]) + archs << FatArch.new_from_bin(:big, @raw_data[fa_off + (fa_len * i), fa_len]) end archs diff --git a/Library/Homebrew/vendor/macho/macho/headers.rb b/Library/Homebrew/vendor/macho/macho/headers.rb index 1f99fe549f..79b5a1802f 100644 --- a/Library/Homebrew/vendor/macho/macho/headers.rb +++ b/Library/Homebrew/vendor/macho/macho/headers.rb @@ -3,6 +3,8 @@ module MachO FAT_MAGIC = 0xcafebabe # little-endian fat magic + # this is defined, but should never appear in ruby-macho code because + # fat headers are always big-endian and therefore always unpacked as such. FAT_CIGAM = 0xbebafeca # 32-bit big-endian magic @@ -20,7 +22,6 @@ module MachO # association of magic numbers to string representations MH_MAGICS = { FAT_MAGIC => "FAT_MAGIC", - FAT_CIGAM => "FAT_CIGAM", MH_MAGIC => "MH_MAGIC", MH_CIGAM => "MH_CIGAM", MH_MAGIC_64 => "MH_MAGIC_64", @@ -33,25 +34,39 @@ module MachO # any CPU (unused?) CPU_TYPE_ANY = -1 + # m68k compatible CPUs + CPU_TYPE_MC680X0 = 0x06 + # i386 and later compatible CPUs CPU_TYPE_I386 = 0x07 # x86_64 (AMD64) compatible CPUs CPU_TYPE_X86_64 = (CPU_TYPE_I386 | CPU_ARCH_ABI64) - # PowerPC compatible CPUs (7400 series?) + # 32-bit ARM compatible CPUs + CPU_TYPE_ARM = 0x0c + + # m88k compatible CPUs + CPU_TYPE_MC88000 = 0xd + + # 64-bit ARM compatible CPUs + CPU_TYPE_ARM64 = (CPU_TYPE_ARM | CPU_ARCH_ABI64) + + # PowerPC compatible CPUs CPU_TYPE_POWERPC = 0x12 - # PowerPC64 compatible CPUs (970 series?) + # PowerPC64 compatible CPUs CPU_TYPE_POWERPC64 = (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) - # association of cpu types to string representations + # association of cpu types to symbol representations CPU_TYPES = { - CPU_TYPE_ANY => "CPU_TYPE_ANY", - CPU_TYPE_I386 => "CPU_TYPE_I386", - CPU_TYPE_X86_64 => "CPU_TYPE_X86_64", - CPU_TYPE_POWERPC => "CPU_TYPE_POWERPC", - CPU_TYPE_POWERPC64 => "CPU_TYPE_POWERPC64" + CPU_TYPE_ANY => :any, + CPU_TYPE_I386 => :i386, + CPU_TYPE_X86_64 => :x86_64, + CPU_TYPE_ARM => :arm, + CPU_TYPE_ARM64 => :arm64, + CPU_TYPE_POWERPC => :ppc, + CPU_TYPE_POWERPC64 => :ppc64, } # mask for CPU subtype capabilities @@ -61,17 +76,208 @@ module MachO # @see http://llvm.org/docs/doxygen/html/Support_2MachO_8h_source.html CPU_SUBTYPE_LIB64 = 0x80000000 - # all x86-type CPUs - CPU_SUBTYPE_X86_ALL = 3 + # the lowest common sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_I386 = 3 - # all x86-type CPUs (what makes this different from CPU_SUBTYPE_X86_ALL?) - CPU_SUBTYPE_X86_ARCH1 = 4 + # the i486 sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_486 = 4 - # association of cpu subtypes to string representations + # the i486SX sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_486SX = 132 + + # the i586 (P5, Pentium) sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_586 = 5 + CPU_SUBTYPE_PENT = CPU_SUBTYPE_586 + + # the Pentium Pro (P6) sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_PENTPRO = 22 + + # the Pentium II (P6, M3?) sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_PENTII_M3 = 54 + + # the Pentium II (P6, M5?) sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_PENTII_M5 = 86 + + # the Pentium 4 (Netburst) sub-type for `CPU_TYPE_I386` + CPU_SUBTYPE_PENTIUM_4 = 10 + + # the lowest common sub-type for `CPU_TYPE_MC680X0` + CPU_SUBTYPE_MC680X0_ALL = 1 + CPU_SUBTYPE_MC68030 = CPU_SUBTYPE_MC680X0_ALL + + # the 040 subtype for `CPU_TYPE_MC680X0` + CPU_SUBTYPE_MC68040 = 2 + + # the 030 subtype for `CPU_TYPE_MC680X0` + CPU_SUBTYPE_MC68030_ONLY = 3 + + # the lowest common sub-type for `CPU_TYPE_X86_64` + CPU_SUBTYPE_X86_64_ALL = CPU_SUBTYPE_I386 + + # the Haskell sub-type for `CPU_TYPE_X86_64` + CPU_SUBTYPE_X86_64_H = 8 + + # the lowest common sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_ALL = 0 + + # the v4t sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V4T = 5 + + # the v6 sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V6 = 6 + + # the v5 sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V5TEJ = 7 + + # the xscale (v5 family) sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_XSCALE = 8 + + # the v7 sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7 = 9 + + # the v7f (Cortex A9) sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7F = 10 + + # the v7s ("Swift") sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7S = 11 + + # the v7k ("Kirkwood40") sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7K = 12 + + # the v6m sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V6M = 14 + + # the v7m sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7M = 15 + + # the v7em sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V7EM = 16 + + # the v8 sub-type for `CPU_TYPE_ARM` + CPU_SUBTYPE_ARM_V8 = 13 + + # the lowest common sub-type for `CPU_TYPE_ARM64` + CPU_SUBTYPE_ARM64_ALL = 0 + + # the v8 sub-type for `CPU_TYPE_ARM64` + CPU_SUBTYPE_ARM64_V8 = 1 + + # the lowest common sub-type for `CPU_TYPE_MC88000` + CPU_SUBTYPE_MC88000_ALL = 0 + CPU_SUBTYPE_MMAX_JPC = CPU_SUBTYPE_MC88000_ALL + + # the 100 sub-type for `CPU_TYPE_MC88000` + CPU_SUBTYPE_MC88100 = 1 + + # the 110 sub-type for `CPU_TYPE_MC88000` + CPU_SUBTYPE_MC88110 = 2 + + # the lowest common sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_ALL = 0 + + # the 601 sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_601 = 1 + + # the 602 sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_602 = 2 + + # the 603 sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_603 = 3 + + # the 603e (G2) sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_603E = 4 + + # the 603ev sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_603EV = 5 + + # the 604 sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_604 = 6 + + # the 604e sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_604E = 7 + + # the 620 sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_620 = 8 + + # the 750 (G3) sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_750 = 9 + + # the 7400 (G4) sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_7400 = 10 + + # the 7450 (G4 "Voyager") sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_7450 = 11 + + # the 970 (G5) sub-type for `CPU_TYPE_POWERPC` + CPU_SUBTYPE_POWERPC_970 = 100 + + # any CPU sub-type for CPU type `CPU_TYPE_POWERPC64` + CPU_SUBTYPE_POWERPC64_ALL = CPU_SUBTYPE_POWERPC_ALL + + # association of CPU types/subtype pairs to symbol representations in + # (very) roughly descending order of commonness + # @see https://opensource.apple.com/source/cctools/cctools-877.8/libstuff/arch.c CPU_SUBTYPES = { - CPU_SUBTYPE_X86_ALL => "CPU_SUBTYPE_X86_ALL", - CPU_SUBTYPE_X86_ARCH1 => "CPU_SUBTYPE_X86_ARCH1" - } + CPU_TYPE_I386 => { + CPU_SUBTYPE_I386 => :i386, + CPU_SUBTYPE_486 => :i486, + CPU_SUBTYPE_486SX => :i486SX, + CPU_SUBTYPE_586 => :i586, # also "pentium" in arch(3) + CPU_SUBTYPE_PENTPRO => :i686, # also "pentpro" in arch(3) + CPU_SUBTYPE_PENTII_M3 => :pentIIm3, + CPU_SUBTYPE_PENTII_M5 => :pentIIm5, + CPU_SUBTYPE_PENTIUM_4 => :pentium4, + }.freeze, + CPU_TYPE_X86_64 => { + CPU_SUBTYPE_X86_64_ALL => :x86_64, + CPU_SUBTYPE_X86_64_H => :x86_64h, + }.freeze, + CPU_TYPE_ARM => { + CPU_SUBTYPE_ARM_ALL => :arm, + CPU_SUBTYPE_ARM_V4T => :armv4t, + CPU_SUBTYPE_ARM_V6 => :armv6, + CPU_SUBTYPE_ARM_V5TEJ => :armv5, + CPU_SUBTYPE_ARM_XSCALE => :xscale, + CPU_SUBTYPE_ARM_V7 => :armv7, + CPU_SUBTYPE_ARM_V7F => :armv7f, + CPU_SUBTYPE_ARM_V7S => :armv7s, + CPU_SUBTYPE_ARM_V7K => :armv7k, + CPU_SUBTYPE_ARM_V6M => :armv6m, + CPU_SUBTYPE_ARM_V7M => :armv7m, + CPU_SUBTYPE_ARM_V7EM => :armv7em, + CPU_SUBTYPE_ARM_V8 => :armv8, + }.freeze, + CPU_TYPE_ARM64 => { + CPU_SUBTYPE_ARM64_ALL => :arm64, + CPU_SUBTYPE_ARM64_V8 => :arm64v8, + }.freeze, + CPU_TYPE_POWERPC => { + CPU_SUBTYPE_POWERPC_ALL => :ppc, + CPU_SUBTYPE_POWERPC_601 => :ppc601, + CPU_SUBTYPE_POWERPC_603 => :ppc603, + CPU_SUBTYPE_POWERPC_603E => :ppc603e, + CPU_SUBTYPE_POWERPC_603EV => :ppc603ev, + CPU_SUBTYPE_POWERPC_604 => :ppc604, + CPU_SUBTYPE_POWERPC_604E => :ppc604e, + CPU_SUBTYPE_POWERPC_750 => :ppc750, + CPU_SUBTYPE_POWERPC_7400 => :ppc7400, + CPU_SUBTYPE_POWERPC_7450 => :ppc7450, + CPU_SUBTYPE_POWERPC_970 => :ppc970, + }.freeze, + CPU_TYPE_POWERPC64 => { + CPU_SUBTYPE_POWERPC64_ALL => :ppc64, + # apparently the only exception to the naming scheme + CPU_SUBTYPE_POWERPC_970 => :ppc970_64, + }.freeze, + CPU_TYPE_MC680X0 => { + CPU_SUBTYPE_MC680X0_ALL => :m68k, + CPU_SUBTYPE_MC68030 => :mc68030, + CPU_SUBTYPE_MC68040 => :mc68040, + }, + CPU_TYPE_MC88000 => { + CPU_SUBTYPE_MC88000_ALL => :m88k, + }, + }.freeze # relocatable object file MH_OBJECT = 0x1 @@ -162,7 +368,8 @@ module MachO # @return [Fixnum] the number of fat architecture structures following the header attr_reader :nfat_arch - FORMAT = "N2" # always big-endian + # always big-endian + FORMAT = "N2" SIZEOF = 8 # @api private @@ -191,7 +398,8 @@ module MachO # @return [Fixnum] the alignment, as a power of 2 attr_reader :align - FORMAT = "N5" # always big-endian + # always big-endian + FORMAT = "N5" SIZEOF = 20 # @api private @@ -227,7 +435,7 @@ module MachO # @return [Fixnum] the header flags associated with the Mach-O attr_reader :flags - FORMAT = "VVVVVVV" + FORMAT = "L=7" SIZEOF = 28 # @api private @@ -260,7 +468,7 @@ module MachO # @return [void] attr_reader :reserved - FORMAT = "VVVVVVVV" + FORMAT = "L=8" SIZEOF = 32 # @api private diff --git a/Library/Homebrew/vendor/macho/macho/load_commands.rb b/Library/Homebrew/vendor/macho/macho/load_commands.rb index 5d30d8ddae..0e7695ee9a 100644 --- a/Library/Homebrew/vendor/macho/macho/load_commands.rb +++ b/Library/Homebrew/vendor/macho/macho/load_commands.rb @@ -52,8 +52,10 @@ module MachO 0x2b => :LC_DYLIB_CODE_SIGN_DRS, 0x2c => :LC_ENCRYPTION_INFO_64, 0x2d => :LC_LINKER_OPTION, - 0x2e => :LC_LINKER_OPTIMIZATION_HINT - } + 0x2e => :LC_LINKER_OPTIMIZATION_HINT, + 0x2f => :LC_VERSION_MIN_TVOS, + 0x30 => :LC_VERSION_MIN_WATCHOS, + }.freeze # load commands responsible for loading dylibs # @api private @@ -71,7 +73,7 @@ module MachO :LC_SEGMENT => "SegmentCommand", :LC_SYMTAB => "SymtabCommand", :LC_SYMSEG => "LoadCommand", # obsolete - :LC_THREAD => "ThreadCommand", + :LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such :LC_UNIXTHREAD => "ThreadCommand", :LC_LOADFVMLIB => "LoadCommand", # obsolete :LC_IDFVMLIB => "LoadCommand", # obsolete @@ -114,8 +116,10 @@ module MachO :LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand", :LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64", :LC_LINKER_OPTION => "LinkerOptionCommand", - :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand" - } + :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand", + :LC_VERSION_MIN_TVOS => "VersionMinCommand", + :LC_VERSION_MIN_WATCHOS => "VersionMinCommand", + }.freeze # association of segment name symbols to names # @api private @@ -127,8 +131,8 @@ module MachO :SEG_ICON => "__ICON", :SEG_LINKEDIT => "__LINKEDIT", :SEG_UNIXSTACK => "__UNIXSTACK", - :SEG_IMPORT => "__IMPORT" - } + :SEG_IMPORT => "__IMPORT", + }.freeze # association of segment flag symbols to values # @api private @@ -136,8 +140,8 @@ module MachO :SG_HIGHVM => 0x1, :SG_FVMLIB => 0x2, :SG_NORELOC => 0x4, - :SG_PROTECTED_VERSION_1 => 0x8 - } + :SG_PROTECTED_VERSION_1 => 0x8, + }.freeze # Mach-O load command structure # This is the most generic load command - only cmd ID and size are @@ -153,18 +157,23 @@ module MachO # @return [Fixnum] the size of the load command, in bytes attr_reader :cmdsize - FORMAT = "VV" + FORMAT = "L=2" SIZEOF = 8 # Creates a new LoadCommand given an offset and binary string + # @param raw_data [String] the raw Mach-O data + # @param endianness [Symbol] the endianness of the command (:big or :little) # @param offset [Fixnum] the offset to initialize with # @param bin [String] the binary string to initialize with # @return [MachO::LoadCommand] the new load command # @api private - def self.new_from_bin(raw_data, offset, bin) - self.new(raw_data, offset, *bin.unpack(self::FORMAT)) + def self.new_from_bin(raw_data, endianness, offset, bin) + format = specialize_format(self::FORMAT, endianness) + + self.new(raw_data, offset, *bin.unpack(format)) end + # @param raw_data [String] the raw Mach-O data # @param offset [Fixnum] the offset to initialize with # @param cmd [Fixnum] the load command's identifying number # @param cmdsize [Fixnum] the size of the load command in bytes @@ -222,7 +231,7 @@ module MachO # @return [Array] the UUID attr_reader :uuid - FORMAT = "VVa16" + FORMAT = "L=2a16" SIZEOF = 24 # @api private @@ -273,7 +282,7 @@ module MachO # @return [Fixnum] any flags associated with the segment attr_reader :flags - FORMAT = "VVa16VVVVVVVV" + FORMAT = "L=2a16L=4l=2L=2" SIZEOF = 56 # @api private @@ -332,7 +341,7 @@ module MachO # @return [Fixnum] any flags associated with the segment attr_reader :flags - FORMAT = "VVa16QQQQVVVV" + FORMAT = "L=2a16Q=4l=2L=2" SIZEOF = 72 # @api private @@ -377,7 +386,7 @@ module MachO # @return [Fixnum] the library's compatibility version number attr_reader :compatibility_version - FORMAT = "VVVVVV" + FORMAT = "L=6" SIZEOF = 24 # @api private @@ -398,7 +407,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr attr_reader :name - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -420,7 +429,7 @@ module MachO # @return [Fixnum] a bit vector of linked modules attr_reader :linked_modules - FORMAT = "VVVVV" + FORMAT = "L=5" SIZEOF = 20 # @api private @@ -435,7 +444,8 @@ module MachO # A load command used to represent threads. # @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize) class ThreadCommand < LoadCommand - + FORMAT = "L=2" + SIZEOF = 8 end # A load command containing the address of the dynamic shared library @@ -466,7 +476,7 @@ module MachO # @return [void] attr_reader :reserved6 - FORMAT = "VVVVVVVVVV" + FORMAT = "L=10" SIZEOF = 40 # @api private @@ -513,7 +523,7 @@ module MachO # @return [void] attr_reader :reserved6 - FORMAT = "VVQQQQQQQQ" + FORMAT = "L=2Q=8" SIZEOF = 72 # @api private @@ -538,7 +548,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr attr_reader :umbrella - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -554,7 +564,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr attr_reader :sub_umbrella - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -570,7 +580,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr attr_reader :sub_library - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -586,7 +596,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr attr_reader :sub_client - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -611,7 +621,7 @@ module MachO # @return the string table size in bytes attr_reader :strsize - FORMAT = "VVVVVV" + FORMAT = "L=6" SIZEOF = 24 # @api private @@ -682,7 +692,7 @@ module MachO attr_reader :nlocrel - FORMAT = "VVVVVVVVVVVVVVVVVVVV" + FORMAT = "L=20" SIZEOF = 80 # ugh @@ -722,7 +732,7 @@ module MachO # @return [Fixnum] the number of hints in the hint table attr_reader :nhints - FORMAT = "VVVV" + FORMAT = "L=4" SIZEOF = 16 # @api private @@ -739,7 +749,7 @@ module MachO # @return [Fixnum] the checksum or 0 attr_reader :cksum - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -756,7 +766,7 @@ module MachO # @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr attr_reader :path - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -776,7 +786,7 @@ module MachO # @return [Fixnum] size of the data in the __LINKEDIT segment attr_reader :datasize - FORMAT = "VVVV" + FORMAT = "L=4" SIZEOF = 16 # @api private @@ -799,7 +809,7 @@ module MachO # @return [Fixnum] the encryption system, or 0 if not encrypted yet attr_reader :cryptid - FORMAT = "VVVVV" + FORMAT = "L=5" SIZEOF = 20 # @api private @@ -826,7 +836,7 @@ module MachO # @return [Fixnum] 64-bit padding value attr_reader :pad - FORMAT = "VVVVVV" + FORMAT = "L=6" SIZEOF = 24 # @api private @@ -848,7 +858,7 @@ module MachO # @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8 attr_reader :sdk - FORMAT = "VVVV" + FORMAT = "L=4" SIZEOF = 16 # @api private @@ -915,7 +925,7 @@ module MachO # @return [Fixnum] the size of the export information attr_reader :export_size - FORMAT = "VVVVVVVVVVVV" + FORMAT = "L=12" SIZEOF = 48 # @api private @@ -942,7 +952,7 @@ module MachO # @return [Fixnum] the number of strings attr_reader :count - FORMAT = "VVV" + FORMAT = "L=3" SIZEOF = 12 # @api private @@ -960,7 +970,7 @@ module MachO # @return [Fixnum] if not 0, the initial stack size. attr_reader :stacksize - FORMAT = "VVQQ" + FORMAT = "L=2Q=2" SIZEOF = 24 # @api private @@ -977,7 +987,7 @@ module MachO # @return [Fixnum] the version packed as a24.b10.c10.d10.e10 attr_reader :version - FORMAT = "VVQ" + FORMAT = "L=2Q=1" SIZEOF = 16 # @api private diff --git a/Library/Homebrew/vendor/macho/macho/macho_file.rb b/Library/Homebrew/vendor/macho/macho/macho_file.rb index dfdf4ae2cb..dc8d6fc250 100644 --- a/Library/Homebrew/vendor/macho/macho/macho_file.rb +++ b/Library/Homebrew/vendor/macho/macho/macho_file.rb @@ -5,6 +5,12 @@ module MachO # @see https://en.wikipedia.org/wiki/Mach-O # @see MachO::FatFile class MachOFile + # @return [String] the filename loaded from, or nil if loaded from a binary string + attr_accessor :filename + + # @return [Symbol] the endianness of the file, :big or :little + attr_reader :endianness + # @return [MachO::MachHeader] if the Mach-O is 32-bit # @return [MachO::MachHeader64] if the Mach-O is 64-bit attr_reader :header @@ -24,12 +30,12 @@ module MachO # Creates a new FatFile from the given filename. # @param filename [String] the Mach-O file to load from - # @raise [ArgumentError] if the given filename does not exist + # @raise [ArgumentError] if the given file does not exist def initialize(filename) - raise ArgumentError.new("#{filetype}: no such file") unless File.exist?(filename) + raise ArgumentError.new("#{filename}: no such file") unless File.file?(filename) @filename = filename - @raw_data = open(@filename, "rb") { |f| f.read } + @raw_data = File.open(@filename, "rb") { |f| f.read } @header = get_mach_header @load_commands = get_load_commands end @@ -123,14 +129,14 @@ module MachO MH_FILETYPES[header.filetype] end - # @return [String] a string representation of the Mach-O's CPU type + # @return [Symbol] a symbol representation of the Mach-O's CPU type def cputype CPU_TYPES[header.cputype] end - # @return [String] a string representation of the Mach-O's CPU subtype + # @return [Symbol] a symbol representation of the Mach-O's CPU subtype def cpusubtype - CPU_SUBTYPES[header.cpusubtype] + CPU_SUBTYPES[header.cputype][header.cpusubtype] end # @return [Fixnum] the number of load commands in the Mach-O's header @@ -278,10 +284,10 @@ module MachO segment.nsects.times do if segment.is_a? SegmentCommand - sections << Section.new_from_bin(@raw_data.slice(offset, Section.bytesize)) + sections << Section.new_from_bin(endianness, @raw_data.slice(offset, Section.bytesize)) offset += Section.bytesize else - sections << Section64.new_from_bin(@raw_data.slice(offset, Section64.bytesize)) + sections << Section64.new_from_bin(endianness, @raw_data.slice(offset, Section64.bytesize)) offset += Section64.bytesize end end @@ -321,10 +327,10 @@ module MachO magic = get_and_check_magic mh_klass = MachO.magic32?(magic) ? MachHeader : MachHeader64 - mh = mh_klass.new_from_bin(@raw_data[0, mh_klass.bytesize]) + mh = mh_klass.new_from_bin(endianness, @raw_data[0, mh_klass.bytesize]) check_cputype(mh.cputype) - check_cpusubtype(mh.cpusubtype) + check_cpusubtype(mh.cputype, mh.cpusubtype) check_filetype(mh.filetype) mh @@ -341,6 +347,8 @@ module MachO raise MagicError.new(magic) unless MachO.magic?(magic) raise FatBinaryError.new if MachO.fat_magic?(magic) + @endianness = MachO.little_magic?(magic) ? :little : :big + magic end @@ -352,13 +360,13 @@ module MachO raise CPUTypeError.new(cputype) unless CPU_TYPES.key?(cputype) end - # Check the file's CPU sub-type. + # Check the file's CPU type/subtype pair. # @param cpusubtype [Fixnum] the CPU subtype # @raise [MachO::CPUSubtypeError] if the CPU sub-type is unknown # @private - def check_cpusubtype(cpusubtype) + def check_cpusubtype(cputype, cpusubtype) # Only check sub-type w/o capability bits (see `get_mach_header`). - raise CPUSubtypeError.new(cpusubtype) unless CPU_SUBTYPES.key?(cpusubtype) + raise CPUSubtypeError.new(cputype, cpusubtype) unless CPU_SUBTYPES[cputype].key?(cpusubtype) end # Check the file's type. @@ -378,7 +386,8 @@ module MachO load_commands = [] header.ncmds.times do - cmd = @raw_data.slice(offset, 4).unpack("V").first + fmt = (endianness == :little) ? "L<" : "L>" + cmd = @raw_data.slice(offset, 4).unpack(fmt).first cmd_sym = LOAD_COMMANDS[cmd] raise LoadCommandError.new(cmd) if cmd_sym.nil? @@ -386,7 +395,7 @@ module MachO # why do I do this? i don't like declaring constants below # classes, and i need them to resolve... klass = MachO.const_get "#{LC_STRUCTURES[cmd_sym]}" - command = klass.new_from_bin(@raw_data, offset, @raw_data.slice(offset, klass.bytesize)) + command = klass.new_from_bin(@raw_data, endianness, offset, @raw_data.slice(offset, klass.bytesize)) load_commands << command offset += command.cmdsize @@ -400,7 +409,8 @@ module MachO # @return [void] # @private def set_sizeofcmds(size) - new_size = [size].pack("V") + fmt = (endianness == :little) ? "L<" : "L>" + new_size = [size].pack(fmt) @raw_data[20..23] = new_size end @@ -475,7 +485,8 @@ module MachO set_sizeofcmds(new_sizeofcmds) # update cmdsize in the cmd - @raw_data[cmd.offset + 4, 4] = [new_size].pack("V") + fmt = (endianness == :little) ? "L<" : "L>" + @raw_data[cmd.offset + 4, 4] = [new_size].pack(fmt) # delete the old str @raw_data.slice!(cmd.offset + lc_str.to_i...cmd.offset + cmd.class.bytesize + old_str.size) diff --git a/Library/Homebrew/vendor/macho/macho/open.rb b/Library/Homebrew/vendor/macho/macho/open.rb index 2c5fc04692..ad1b02bb21 100644 --- a/Library/Homebrew/vendor/macho/macho/open.rb +++ b/Library/Homebrew/vendor/macho/macho/open.rb @@ -3,14 +3,23 @@ module MachO # @param filename [String] the file being opened # @return [MachO::MachOFile] if the file is a Mach-O # @return [MachO::FatFile] if the file is a Fat file + # @raise [ArgumentError] if the given file does not exist + # @raise [MachO::TruncatedFileError] if the file is too small to have a valid header + # @raise [MachO::MagicError] if the file's magic is not valid Mach-O magic def self.open(filename) - # open file and test magic instead of using exceptions for control? - begin - file = MachOFile.new(filename) - rescue FatBinaryError + raise ArgumentError.new("#{filename}: no such file") unless File.file?(filename) + raise TruncatedFileError.new unless File.stat(filename).size >= 4 + + magic = File.open(filename, "rb") { |f| f.read(4) }.unpack("N").first + + if MachO.fat_magic?(magic) file = FatFile.new(filename) + elsif MachO.magic?(magic) + file = MachOFile.new(filename) + else + raise MagicError.new(magic) end file end -end \ No newline at end of file +end diff --git a/Library/Homebrew/vendor/macho/macho/sections.rb b/Library/Homebrew/vendor/macho/macho/sections.rb index 8a3cbac024..3ea1e3fa4b 100644 --- a/Library/Homebrew/vendor/macho/macho/sections.rb +++ b/Library/Homebrew/vendor/macho/macho/sections.rb @@ -46,7 +46,7 @@ module MachO :S_ATTR_SOME_INSTRUCTIONS => 0x00000400, :S_ATTR_EXT_RELOC => 0x00000200, :S_ATTR_LOC_RELOC => 0x00000100 - } + }.freeze # association of section name symbols to names # @api private @@ -63,7 +63,7 @@ module MachO :SECT_OBJC_REFS => "__selector_refs", :SECT_ICON_HEADER => "__header", :SECT_ICON_TIFF => "__tiff" - } + }.freeze # Represents a section of a segment for 32-bit architectures. class Section < MachOStructure @@ -100,7 +100,7 @@ module MachO # @return [void] reserved (for count or sizeof) attr_reader :reserved2 - FORMAT = "a16a16VVVVVVVVV" + FORMAT = "a16a16L=9" SIZEOF = 68 # @api private @@ -145,7 +145,7 @@ module MachO # @return [void] reserved attr_reader :reserved3 - FORMAT = "a16a16QQVVVVVVVV" + FORMAT = "a16a16Q=2L=8" SIZEOF = 80 # @api private diff --git a/Library/Homebrew/vendor/macho/macho/structure.rb b/Library/Homebrew/vendor/macho/macho/structure.rb index 77aa18852d..aaa2ada275 100644 --- a/Library/Homebrew/vendor/macho/macho/structure.rb +++ b/Library/Homebrew/vendor/macho/macho/structure.rb @@ -2,7 +2,7 @@ module MachO # A general purpose pseudo-structure. # @abstract class MachOStructure - # The format of the data structure, in String#unpack format. + # The String#unpack format of the data structure. FORMAT = "" # The size of the data structure, in bytes. @@ -13,10 +13,26 @@ module MachO self::SIZEOF end + # @param endianness [Symbol] either :big or :little + # @param bin [String] the string to be unpacked into the new structure # @return [MachO::MachOStructure] a new MachOStructure initialized with `bin` # @api private - def self.new_from_bin(bin) - self.new(*bin.unpack(self::FORMAT)) + def self.new_from_bin(endianness, bin) + format = specialize_format(self::FORMAT, endianness) + + self.new(*bin.unpack(format)) + end + + private + + # Convert an abstract (native-endian) String#unpack format to big or little. + # @param format [String] the format string being converted + # @param endianness [Symbol] either :big or :little + # @return [String] the converted string + # @api private + def self.specialize_format(format, endianness) + modifier = (endianness == :big) ? ">" : "<" + format.tr("=", modifier) end end end diff --git a/Library/Homebrew/vendor/macho/macho/utils.rb b/Library/Homebrew/vendor/macho/macho/utils.rb index 3b06cc125e..102f1e57d4 100644 --- a/Library/Homebrew/vendor/macho/macho/utils.rb +++ b/Library/Homebrew/vendor/macho/macho/utils.rb @@ -19,7 +19,7 @@ module MachO # @param num [Fixnum] the number being checked # @return [Boolean] true if `num` is a valid Fat magic number, false otherwise def self.fat_magic?(num) - num == FAT_MAGIC || num == FAT_CIGAM + num == FAT_MAGIC end # @param num [Fixnum] the number being checked @@ -33,4 +33,16 @@ module MachO def self.magic64?(num) num == MH_MAGIC_64 || num == MH_CIGAM_64 end + + # @param num [Fixnum] the number being checked + # @return [Boolean] true if `num` is a valid little-endian magic number, false otherwise + def self.little_magic?(num) + num == MH_CIGAM || num == MH_CIGAM_64 + end + + # @param num [Fixnum] the number being checked + # @return [Boolean] true if `num` is a valid big-endian magic number, false otherwise + def self.big_magic?(num) + num == MH_CIGAM || num == MH_CIGAM_64 + end end