aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorMartin Afanasjew2016-02-18 18:04:41 +0100
committerMartin Afanasjew2016-02-25 21:54:41 +0100
commit01d642f150c90ac8a6e7ec266f8c424a8f197bc4 (patch)
treea07b9067f43af11a80cfa53c27585ad7f03fb0e2 /Library
parent2496bdf280edf4cc3f4ac2aa98518161f7985048 (diff)
downloadbrew-01d642f150c90ac8a6e7ec266f8c424a8f197bc4.tar.bz2
vendor/macho: update to 0.2.2-39-ge2fbedc9
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/vendor/README.md2
-rw-r--r--Library/Homebrew/vendor/macho/macho/exceptions.rb32
-rw-r--r--Library/Homebrew/vendor/macho/macho/fat_file.rb60
-rw-r--r--Library/Homebrew/vendor/macho/macho/headers.rb16
-rw-r--r--Library/Homebrew/vendor/macho/macho/load_commands.rb2
-rw-r--r--Library/Homebrew/vendor/macho/macho/macho_file.rb105
-rw-r--r--Library/Homebrew/vendor/macho/macho/tools.rb6
7 files changed, 131 insertions, 92 deletions
diff --git a/Library/Homebrew/vendor/README.md b/Library/Homebrew/vendor/README.md
index 325bab28d..ce1178f16 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/woodruffw/ruby-macho), version 0.2.2.
+* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 0.2.2-39-ge2fbedc9.
## Licenses:
diff --git a/Library/Homebrew/vendor/macho/macho/exceptions.rb b/Library/Homebrew/vendor/macho/macho/exceptions.rb
index 1295176b2..07ae43edb 100644
--- a/Library/Homebrew/vendor/macho/macho/exceptions.rb
+++ b/Library/Homebrew/vendor/macho/macho/exceptions.rb
@@ -3,14 +3,36 @@ module MachO
class MachOError < RuntimeError
end
+ # Raised when a file is not a Mach-O.
+ class NotAMachOError < MachOError
+ # @param error [String] the error in question
+ def initialize(error)
+ super error
+ end
+ end
+
+ # Raised when a file is too short to be a valid Mach-O file.
+ class TruncatedFileError < NotAMachOError
+ def initialize
+ super "File is too short to be a valid Mach-O"
+ end
+ end
+
# Raised when a file's magic bytes are not valid Mach-O magic.
- class MagicError < MachOError
+ class MagicError < NotAMachOError
# @param num [Fixnum] the unknown number
def initialize(num)
super "Unrecognized Mach-O magic: 0x#{"%02x" % num}"
end
end
+ # Raised when a file is a Java classfile instead of a fat Mach-O.
+ class JavaClassFileError < NotAMachOError
+ def initialize
+ super "File is a Java class file"
+ end
+ end
+
# Raised when a fat binary is loaded with MachOFile.
class FatBinaryError < MachOError
def initialize
@@ -82,4 +104,12 @@ module MachO
super "No such runtime path: #{path}"
end
end
+
+ # Raised whenever unfinished code is called.
+ class UnimplementedError < MachOError
+ # @param thing [String] the thing that is unimplemented
+ def initialize(thing)
+ super "Unimplemented: #{thing}"
+ end
+ end
end
diff --git a/Library/Homebrew/vendor/macho/macho/fat_file.rb b/Library/Homebrew/vendor/macho/macho/fat_file.rb
index 829ee83f0..0b25483a9 100644
--- a/Library/Homebrew/vendor/macho/macho/fat_file.rb
+++ b/Library/Homebrew/vendor/macho/macho/fat_file.rb
@@ -13,6 +13,16 @@ module MachO
# @return [Array<MachO::MachOFile>] an array of Mach-O binaries
attr_reader :machos
+ # Creates a new FatFile instance from a binary string.
+ # @param bin [String] a binary string containing raw Mach-O data
+ # @return [MachO::FatFile] a new FatFile
+ def self.new_from_bin(bin)
+ instance = allocate
+ instance.initialize_from_bin(bin)
+
+ instance
+ end
+
# 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
@@ -26,6 +36,15 @@ module MachO
@machos = get_machos
end
+ # @api private
+ def initialize_from_bin(bin)
+ @filename = nil
+ @raw_data = bin
+ @header = get_fat_header
+ @fat_archs = get_fat_archs
+ @machos = get_machos
+ end
+
# The file's raw fat data.
# @return [String] the raw fat data
def serialize
@@ -131,8 +150,10 @@ module MachO
# All shared libraries linked to the file's Mach-Os.
# @return [Array<String>] an array of all shared libraries
def linked_dylibs
- # can machos inside fat binaries have different dylibs?
- machos.flat_map(&:linked_dylibs).uniq
+ # Individual architectures in a fat binary can link to different subsets
+ # of libraries, but at this point we want to have the full picture, i.e.
+ # the union of all libraries used by all architectures.
+ machos.map(&:linked_dylibs).flatten.uniq
end
# Changes all dependent shared library install names from `old_name` to `new_name`.
@@ -168,25 +189,45 @@ module MachO
end
# Write all (fat) data to the file used to initialize the instance.
+ # @return [void]
+ # @raise [MachO::MachOError] if the instance was initialized without a file
# @note Overwrites all data in the file!
def write!
- File.open(@filename, "wb") { |f| f.write(@raw_data) }
+ if filename.nil?
+ raise MachOError.new("cannot write to a default file when initialized from a binary string")
+ else
+ File.open(@filename, "wb") { |f| f.write(@raw_data) }
+ end
end
private
# Obtain the fat header from raw file data.
# @return [MachO::FatHeader] the fat header
+ # @raise [MachO::TruncatedFileError] if the file is too small to have a valid header
# @raise [MachO::MagicError] if the magic is not valid Mach-O magic
# @raise [MachO::MachOBinaryError] if the magic is for a non-fat Mach-O file
+ # @raise [MachO::JavaClassFileError] if the file is a Java classfile
# @private
def get_fat_header
- magic, nfat_arch = @raw_data[0..7].unpack("N2")
+ # 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])
+
+ raise MagicError.new(fh.magic) unless MachO.magic?(fh.magic)
+ raise MachOBinaryError.new unless MachO.fat_magic?(fh.magic)
- raise MagicError.new(magic) unless MachO.magic?(magic)
- raise MachOBinaryError.new unless MachO.fat_magic?(magic)
+ # Rationale: Java classfiles have the same magic as big-endian fat
+ # Mach-Os. Classfiles encode their version at the same offset as
+ # `nfat_arch` and the lowest version number is 43, so we error out
+ # if a file claims to have over 30 internal architectures. It's
+ # technically possible for a fat Mach-O to have over 30 architectures,
+ # but this is extremely unlikely and in practice distinguishes the two
+ # formats.
+ raise JavaClassFileError.new if fh.nfat_arch > 30
- FatHeader.new(magic, nfat_arch)
+ fh
end
# Obtain an array of fat architectures from raw file data.
@@ -195,9 +236,10 @@ module MachO
def get_fat_archs
archs = []
+ fa_off = FatHeader.bytesize
+ fa_len = FatArch.bytesize
header.nfat_arch.times do |i|
- fields = @raw_data[8 + (FatArch.bytesize * i), FatArch.bytesize].unpack("N5")
- archs << FatArch.new(*fields)
+ archs << FatArch.new_from_bin(@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 7e4d126a3..1f99fe549 100644
--- a/Library/Homebrew/vendor/macho/macho/headers.rb
+++ b/Library/Homebrew/vendor/macho/macho/headers.rb
@@ -33,14 +33,11 @@ module MachO
# any CPU (unused?)
CPU_TYPE_ANY = -1
- # x86 compatible CPUs
- CPU_TYPE_X86 = 0x07
-
# i386 and later compatible CPUs
- CPU_TYPE_I386 = CPU_TYPE_X86
+ CPU_TYPE_I386 = 0x07
# x86_64 (AMD64) compatible CPUs
- CPU_TYPE_X86_64 = (CPU_TYPE_X86 | CPU_ARCH_ABI64)
+ CPU_TYPE_X86_64 = (CPU_TYPE_I386 | CPU_ARCH_ABI64)
# PowerPC compatible CPUs (7400 series?)
CPU_TYPE_POWERPC = 0x12
@@ -51,7 +48,6 @@ module MachO
# association of cpu types to string representations
CPU_TYPES = {
CPU_TYPE_ANY => "CPU_TYPE_ANY",
- CPU_TYPE_X86 => "CPU_TYPE_X86",
CPU_TYPE_I386 => "CPU_TYPE_I386",
CPU_TYPE_X86_64 => "CPU_TYPE_X86_64",
CPU_TYPE_POWERPC => "CPU_TYPE_POWERPC",
@@ -166,7 +162,7 @@ module MachO
# @return [Fixnum] the number of fat architecture structures following the header
attr_reader :nfat_arch
- FORMAT = "VV"
+ FORMAT = "N2" # always big-endian
SIZEOF = 8
# @api private
@@ -195,7 +191,7 @@ module MachO
# @return [Fixnum] the alignment, as a power of 2
attr_reader :align
- FORMAT = "VVVVV"
+ FORMAT = "N5" # always big-endian
SIZEOF = 20
# @api private
@@ -239,7 +235,9 @@ module MachO
flags)
@magic = magic
@cputype = cputype
- @cpusubtype = cpusubtype
+ # For now we're not interested in additional capability bits also to be
+ # found in the `cpusubtype` field. We only care about the CPU sub-type.
+ @cpusubtype = cpusubtype & ~CPU_SUBTYPE_MASK
@filetype = filetype
@ncmds = ncmds
@sizeofcmds = sizeofcmds
diff --git a/Library/Homebrew/vendor/macho/macho/load_commands.rb b/Library/Homebrew/vendor/macho/macho/load_commands.rb
index e5c71b160..5d30d8dda 100644
--- a/Library/Homebrew/vendor/macho/macho/load_commands.rb
+++ b/Library/Homebrew/vendor/macho/macho/load_commands.rb
@@ -830,7 +830,7 @@ module MachO
SIZEOF = 24
# @api private
- def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid)
+ def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
super(raw_data, offset, cmd, cmdsize)
@cryptoff = cryptoff
@cryptsize = cryptsize
diff --git a/Library/Homebrew/vendor/macho/macho/macho_file.rb b/Library/Homebrew/vendor/macho/macho/macho_file.rb
index 39d584c8e..dfdf4ae2c 100644
--- a/Library/Homebrew/vendor/macho/macho/macho_file.rb
+++ b/Library/Homebrew/vendor/macho/macho/macho_file.rb
@@ -215,7 +215,11 @@ module MachO
# All shared libraries linked to the Mach-O.
# @return [Array<String>] an array of all shared libraries
def linked_dylibs
- dylib_load_commands.map(&:name).map(&:to_s)
+ # Some linkers produce multiple `LC_LOAD_DYLIB` load commands for the same
+ # library, but at this point we're really only interested in a list of
+ # unique libraries this Mach-O file links to, thus: `uniq`. (This is also
+ # for consistency with `FatFile` that merges this list across all archs.)
+ dylib_load_commands.map(&:name).map(&:to_s).uniq
end
# Changes the shared library `old_name` to `new_name`
@@ -293,7 +297,6 @@ module MachO
end
# Write all Mach-O data to the file used to initialize the instance.
- # @raise [MachOError] if the instance was created from a binary string
# @return [void]
# @raise [MachO::MachOError] if the instance was initialized without a file
# @note Overwrites all data in the file!
@@ -310,30 +313,29 @@ module MachO
# The file's Mach-O header structure.
# @return [MachO::MachHeader] if the Mach-O is 32-bit
# @return [MachO::MachHeader64] if the Mach-O is 64-bit
+ # @raise [MachO::TruncatedFileError] if the file is too small to have a valid header
# @private
def get_mach_header
- magic = get_magic
- cputype = get_cputype
- cpusubtype = get_cpusubtype
- filetype = get_filetype
- ncmds = get_ncmds
- sizeofcmds = get_sizeofcmds
- flags = get_flags
-
- if MachO.magic32?(magic)
- MachHeader.new(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
- else
- # the reserved field is...reserved, so just fill it with 0
- MachHeader64.new(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags, 0)
- end
+ # the smallest Mach-O header is 28 bytes
+ raise TruncatedFileError.new if @raw_data.size < 28
+
+ magic = get_and_check_magic
+ mh_klass = MachO.magic32?(magic) ? MachHeader : MachHeader64
+ mh = mh_klass.new_from_bin(@raw_data[0, mh_klass.bytesize])
+
+ check_cputype(mh.cputype)
+ check_cpusubtype(mh.cpusubtype)
+ check_filetype(mh.filetype)
+
+ mh
end
- # The file's magic number.
+ # Read just the file's magic number and check its validity.
# @return [Fixnum] the magic
# @raise [MachO::MagicError] if the magic is not valid Mach-O magic
# @raise [MachO::FatBinaryError] if the magic is for a Fat file
# @private
- def get_magic
+ def get_and_check_magic
magic = @raw_data[0..3].unpack("N").first
raise MagicError.new(magic) unless MachO.magic?(magic)
@@ -342,62 +344,29 @@ module MachO
magic
end
- # The file's CPU type.
- # @return [Fixnum] the CPU type
+ # Check the file's CPU type.
+ # @param cputype [Fixnum] the CPU type
# @raise [MachO::CPUTypeError] if the CPU type is unknown
# @private
- def get_cputype
- cputype = @raw_data[4..7].unpack("V").first
-
+ def check_cputype(cputype)
raise CPUTypeError.new(cputype) unless CPU_TYPES.key?(cputype)
-
- cputype
end
- # The file's CPU subtype.
- # @return [Fixnum] the CPU subtype
- # @raise [MachO::CPUSubtypeError] if the CPU subtype is unknown
+ # Check the file's CPU sub-type.
+ # @param cpusubtype [Fixnum] the CPU subtype
+ # @raise [MachO::CPUSubtypeError] if the CPU sub-type is unknown
# @private
- def get_cpusubtype
- cpusubtype = @raw_data[8..11].unpack("V").first
- cpusubtype &= ~CPU_SUBTYPE_LIB64 # this mask isn't documented!
-
+ def check_cpusubtype(cpusubtype)
+ # Only check sub-type w/o capability bits (see `get_mach_header`).
raise CPUSubtypeError.new(cpusubtype) unless CPU_SUBTYPES.key?(cpusubtype)
-
- cpusubtype
end
- # The file's type.
- # @return [Fixnum] the file type
+ # Check the file's type.
+ # @param filetype [Fixnum] the file type
# @raise [MachO::FiletypeError] if the file type is unknown
# @private
- def get_filetype
- filetype = @raw_data[12..15].unpack("V").first
-
+ def check_filetype(filetype)
raise FiletypeError.new(filetype) unless MH_FILETYPES.key?(filetype)
-
- filetype
- end
-
- # The number of load commands in the file.
- # @return [Fixnum] the number of load commands
- # @private
- def get_ncmds
- @raw_data[16..19].unpack("V").first
- end
-
- # The size of all load commands, in bytes.
- # return [Fixnum] the size of all load commands
- # @private
- def get_sizeofcmds
- @raw_data[20..23].unpack("V").first
- end
-
- # The Mach-O header's flags.
- # @return [Fixnum] the flags
- # @private
- def get_flags
- @raw_data[24..27].unpack("V").first
end
# All load commands in the file.
@@ -484,17 +453,17 @@ module MachO
new_size = cmd.class.bytesize + new_str.size
new_sizeofcmds += new_size - cmd.cmdsize
- low_fileoff = 2**64 # ULLONGMAX
+ low_fileoff = @raw_data.size
# calculate the low file offset (offset to first section data)
segments.each do |seg|
sections(seg).each do |sect|
- if sect.size != 0 && !sect.flag?(:S_ZEROFILL) &&
- !sect.flag?(:S_THREAD_LOCAL_ZEROFILL) &&
- sect.offset < low_fileoff
+ next if sect.size == 0
+ next if sect.flag?(:S_ZEROFILL)
+ next if sect.flag?(:S_THREAD_LOCAL_ZEROFILL)
+ next unless sect.offset < low_fileoff
- low_fileoff = sect.offset
- end
+ low_fileoff = sect.offset
end
end
diff --git a/Library/Homebrew/vendor/macho/macho/tools.rb b/Library/Homebrew/vendor/macho/macho/tools.rb
index 18f20fb80..fe3da455b 100644
--- a/Library/Homebrew/vendor/macho/macho/tools.rb
+++ b/Library/Homebrew/vendor/macho/macho/tools.rb
@@ -41,7 +41,7 @@ module MachO
# @return [void]
# @todo unstub
def self.change_rpath(filename, old_path, new_path)
- raise "stub"
+ raise UnimplementedError.new("changing rpaths in a Mach-O")
end
# Add a runtime path to a Mach-O or Fat binary, overwriting the source file.
@@ -50,7 +50,7 @@ module MachO
# @return [void]
# @todo unstub
def self.add_rpath(filename, new_path)
- raise "stub"
+ raise UnimplementedError.new("adding rpaths to a Mach-O")
end
# Delete a runtime path from a Mach-O or Fat binary, overwriting the source file.
@@ -59,7 +59,7 @@ module MachO
# @return [void]
# @todo unstub
def self.delete_rpath(filename, old_path)
- raise "stub"
+ raise UnimplementedError.new("removing rpaths from a Mach-O")
end
end
end