aboutsummaryrefslogtreecommitdiffstats
path: root/Library
diff options
context:
space:
mode:
authorWilliam Woodruff2015-10-15 16:00:12 -0400
committerMike McQuaid2016-02-03 21:25:20 +0000
commit1cb6a2ad186624b9013eb63fb0a5f14a1336a53c (patch)
tree4e66b1c2253aef9639b6945b8c6c0b2a011009e9 /Library
parent35e2209c10ffcf6a666ac4a8051a1f20801895ea (diff)
downloadbrew-1cb6a2ad186624b9013eb63fb0a5f14a1336a53c.tar.bz2
vendor: vendor ruby_macho library.
Diffstat (limited to 'Library')
-rw-r--r--Library/Homebrew/vendor/README.md53
-rw-r--r--Library/Homebrew/vendor/macho/macho.rb16
-rw-r--r--Library/Homebrew/vendor/macho/macho/exceptions.rb85
-rw-r--r--Library/Homebrew/vendor/macho/macho/fat_file.rb230
-rw-r--r--Library/Homebrew/vendor/macho/macho/headers.rb275
-rw-r--r--Library/Homebrew/vendor/macho/macho/load_commands.rb1001
-rw-r--r--Library/Homebrew/vendor/macho/macho/macho_file.rb531
-rw-r--r--Library/Homebrew/vendor/macho/macho/open.rb16
-rw-r--r--Library/Homebrew/vendor/macho/macho/sections.rb159
-rw-r--r--Library/Homebrew/vendor/macho/macho/structure.rb22
-rw-r--r--Library/Homebrew/vendor/macho/macho/tools.rb65
-rw-r--r--Library/Homebrew/vendor/macho/macho/utils.rb36
12 files changed, 2489 insertions, 0 deletions
diff --git a/Library/Homebrew/vendor/README.md b/Library/Homebrew/vendor/README.md
new file mode 100644
index 000000000..325bab28d
--- /dev/null
+++ b/Library/Homebrew/vendor/README.md
@@ -0,0 +1,53 @@
+Vendored Dependencies
+=====================
+
+* [okjson](https://github.com/kr/okjson), version 43.
+
+* [ruby-macho](https://github.com/woodruffw/ruby-macho), version 0.2.2.
+
+## Licenses:
+
+### okjson
+
+> Copyright 2011, 2012 Keith Rarick
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
+
+### ruby-macho
+
+> The MIT License
+> Copyright (c) 2015 William Woodruff <william @ tuffbizz.com>
+>
+> Permission is hereby granted, free of charge, to any person obtaining a copy
+> of this software and associated documentation files (the "Software"), to deal
+> in the Software without restriction, including without limitation the rights
+> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+> copies of the Software, and to permit persons to whom the Software is
+> furnished to do so, subject to the following conditions:
+>
+> The above copyright notice and this permission notice shall be included in
+> all copies or substantial portions of the Software.
+>
+> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+> THE SOFTWARE.
diff --git a/Library/Homebrew/vendor/macho/macho.rb b/Library/Homebrew/vendor/macho/macho.rb
new file mode 100644
index 000000000..8cfc5521c
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho.rb
@@ -0,0 +1,16 @@
+require "#{File.dirname(__FILE__)}/macho/structure"
+require "#{File.dirname(__FILE__)}/macho/headers"
+require "#{File.dirname(__FILE__)}/macho/load_commands"
+require "#{File.dirname(__FILE__)}/macho/sections"
+require "#{File.dirname(__FILE__)}/macho/macho_file"
+require "#{File.dirname(__FILE__)}/macho/fat_file"
+require "#{File.dirname(__FILE__)}/macho/open"
+require "#{File.dirname(__FILE__)}/macho/exceptions"
+require "#{File.dirname(__FILE__)}/macho/utils"
+require "#{File.dirname(__FILE__)}/macho/tools"
+
+# The primary namespace for ruby-macho.
+module MachO
+ # release version
+ VERSION = "0.2.2".freeze
+end
diff --git a/Library/Homebrew/vendor/macho/macho/exceptions.rb b/Library/Homebrew/vendor/macho/macho/exceptions.rb
new file mode 100644
index 000000000..1295176b2
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/exceptions.rb
@@ -0,0 +1,85 @@
+module MachO
+ # A generic Mach-O error in execution.
+ class MachOError < RuntimeError
+ end
+
+ # Raised when a file's magic bytes are not valid Mach-O magic.
+ class MagicError < MachOError
+ # @param num [Fixnum] the unknown number
+ def initialize(num)
+ super "Unrecognized Mach-O magic: 0x#{"%02x" % num}"
+ end
+ end
+
+ # Raised when a fat binary is loaded with MachOFile.
+ class FatBinaryError < MachOError
+ def initialize
+ super "Fat binaries must be loaded with MachO::FatFile"
+ end
+ end
+
+ # Raised when a Mach-O is loaded with FatFile.
+ class MachOBinaryError < MachOError
+ def initialize
+ super "Normal binaries must be loaded with MachO::MachOFile"
+ end
+ end
+
+ # 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}"
+ end
+ end
+
+ # Raised when the CPU subtype is unknown.
+ class CPUSubtypeError < MachOError
+ # @param num [Fixnum] the unknown number
+ def initialize(num)
+ super "Unrecognized CPU sub-type: 0x#{"%02x" % num}"
+ end
+ end
+
+ # Raised when a mach-o file's filetype field is unknown.
+ class FiletypeError < MachOError
+ # @param num [Fixnum] the unknown number
+ def initialize(num)
+ super "Unrecognized Mach-O filetype code: 0x#{"%02x" % num}"
+ end
+ end
+
+ # Raised when an unknown load command is encountered.
+ class LoadCommandError < MachOError
+ # @param num [Fixnum] the unknown number
+ def initialize(num)
+ super "Unrecognized Mach-O load command: 0x#{"%02x" % num}"
+ end
+ end
+
+ # Raised when load commands are too large to fit in the current file.
+ class HeaderPadError < MachOError
+ # @param filename [String] the filename
+ def initialize(filename)
+ super "Updated load commands do not fit in the header of " +
+ "#{filename}. #{filename} needs to be relinked, possibly with " +
+ "-headerpad or -headerpad_max_install_names"
+ end
+ end
+
+ # Raised when attempting to change a dylib name that doesn't exist.
+ class DylibUnknownError < MachOError
+ # @param dylib [String] the unknown shared library name
+ def initialize(dylib)
+ super "No such dylib name: #{dylib}"
+ end
+ end
+
+ # Raised when attempting to change an rpath that doesn't exist.
+ class RpathUnknownError < MachOError
+ # @param path [String] the unknown runtime path
+ def initialize(path)
+ super "No such runtime path: #{path}"
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/fat_file.rb b/Library/Homebrew/vendor/macho/macho/fat_file.rb
new file mode 100644
index 000000000..829ee83f0
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/fat_file.rb
@@ -0,0 +1,230 @@
+module MachO
+ # Represents a "Fat" file, which contains a header, a listing of available
+ # architectures, and one or more Mach-O binaries.
+ # @see https://en.wikipedia.org/wiki/Mach-O#Multi-architecture_binaries
+ # @see MachO::MachOFile
+ class FatFile
+ # @return [MachO::FatHeader] the file's header
+ attr_reader :header
+
+ # @return [Array<MachO::FatArch>] an array of fat architectures
+ attr_reader :fat_archs
+
+ # @return [Array<MachO::MachOFile>] an array of Mach-O binaries
+ attr_reader :machos
+
+ # 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
+ def initialize(filename)
+ raise ArgumentError.new("#{filetype}: no such file") unless File.exist?(filename)
+
+ @filename = filename
+ @raw_data = open(@filename, "rb") { |f| f.read }
+ @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
+ @raw_data
+ end
+
+ # @return [Boolean] true if the file is of type `MH_OBJECT`, false otherwise
+ def object?
+ machos.first.object?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_EXECUTE`, false otherwise
+ def executable?
+ machos.first.executable?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_FVMLIB`, false otherwise
+ def fvmlib?
+ machos.first.fvmlib?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_CORE`, false otherwise
+ def core?
+ machos.first.core?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_PRELOAD`, false otherwise
+ def preload?
+ machos.first.preload?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DYLIB`, false otherwise
+ def dylib?
+ machos.first.dylib?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DYLINKER`, false otherwise
+ def dylinker?
+ machos.first.dylinker?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_BUNDLE`, false otherwise
+ def bundle?
+ machos.first.bundle?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DSYM`, false otherwise
+ def dsym?
+ machos.first.dsym?
+ end
+
+ # @return [Boolean] true if the file is of type `MH_KEXT_BUNDLE`, false otherwise
+ def kext?
+ machos.first.kext?
+ end
+
+ # @return [Fixnum] the file's magic number
+ def magic
+ header.magic
+ end
+
+ # @return [String] a string representation of the file's magic number
+ def magic_string
+ MH_MAGICS[magic]
+ end
+
+ # The file's type. Assumed to be the same for every Mach-O within.
+ # @return [String] the filetype
+ def filetype
+ machos.first.filetype
+ end
+
+ # The file's dylib ID. If the file is not a dylib, returns `nil`.
+ # @example
+ # file.dylib_id # => 'libBar.dylib'
+ # @return [String, nil] the file's dylib ID
+ def dylib_id
+ machos.first.dylib_id
+ end
+
+ # Changes the file's dylib ID to `new_id`. If the file is not a dylib, does nothing.
+ # @example
+ # file.dylib_id = 'libFoo.dylib'
+ # @param new_id [String] the new dylib ID
+ # @return [void]
+ # @raise [ArgumentError] if `new_id` is not a String
+ def dylib_id=(new_id)
+ if !new_id.is_a?(String)
+ raise ArgumentError.new("argument must be a String")
+ end
+
+ if !machos.all?(&:dylib?)
+ return nil
+ end
+
+ machos.each do |macho|
+ macho.dylib_id = new_id
+ end
+
+ synchronize_raw_data
+ end
+
+ # 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
+ end
+
+ # Changes all dependent shared library install names from `old_name` to `new_name`.
+ # In a fat file, this changes install names in all internal Mach-Os.
+ # @example
+ # file.change_install_name('/usr/lib/libFoo.dylib', '/usr/lib/libBar.dylib')
+ # @param old_name [String] the shared library name being changed
+ # @param new_name [String] the new name
+ # @todo incomplete
+ def change_install_name(old_name, new_name)
+ machos.each do |macho|
+ macho.change_install_name(old_name, new_name)
+ end
+
+ synchronize_raw_data
+ end
+
+ alias :change_dylib :change_install_name
+
+ # 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
+ # @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
+ end
+
+ # Write all (fat) data to the given filename.
+ # @param filename [String] the file to write to
+ def write(filename)
+ File.open(filename, "wb") { |f| f.write(@raw_data) }
+ end
+
+ # Write all (fat) data to the file used to initialize the instance.
+ # @note Overwrites all data in the file!
+ def write!
+ File.open(@filename, "wb") { |f| f.write(@raw_data) }
+ end
+
+ private
+
+ # Obtain the fat header from raw file data.
+ # @return [MachO::FatHeader] the fat 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
+ # @private
+ def get_fat_header
+ magic, nfat_arch = @raw_data[0..7].unpack("N2")
+
+ raise MagicError.new(magic) unless MachO.magic?(magic)
+ raise MachOBinaryError.new unless MachO.fat_magic?(magic)
+
+ FatHeader.new(magic, nfat_arch)
+ end
+
+ # Obtain an array of fat architectures from raw file data.
+ # @return [Array<MachO::FatArch>] an array of fat architectures
+ # @private
+ def get_fat_archs
+ archs = []
+
+ header.nfat_arch.times do |i|
+ fields = @raw_data[8 + (FatArch.bytesize * i), FatArch.bytesize].unpack("N5")
+ archs << FatArch.new(*fields)
+ end
+
+ archs
+ end
+
+ # Obtain an array of Mach-O blobs from raw file data.
+ # @return [Array<MachO::MachOFile>] an array of Mach-Os
+ # @private
+ def get_machos
+ machos = []
+
+ fat_archs.each do |arch|
+ machos << MachOFile.new_from_bin(@raw_data[arch.offset, arch.size])
+ end
+
+ machos
+ end
+
+ # @todo this needs to be redesigned. arch[:offset] and arch[:size] are
+ # already out-of-date, and the header needs to be synchronized as well.
+ # @private
+ def synchronize_raw_data
+ machos.each_with_index do |macho, i|
+ arch = fat_archs[i]
+
+ @raw_data[arch.offset, arch.size] = macho.serialize
+ end
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/headers.rb b/Library/Homebrew/vendor/macho/macho/headers.rb
new file mode 100644
index 000000000..7e4d126a3
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/headers.rb
@@ -0,0 +1,275 @@
+module MachO
+ # big-endian fat magic
+ FAT_MAGIC = 0xcafebabe
+
+ # little-endian fat magic
+ FAT_CIGAM = 0xbebafeca
+
+ # 32-bit big-endian magic
+ MH_MAGIC = 0xfeedface
+
+ # 32-bit little-endian magic
+ MH_CIGAM = 0xcefaedfe
+
+ # 64-bit big-endian magic
+ MH_MAGIC_64 = 0xfeedfacf
+
+ # 64-bit little-endian magic
+ MH_CIGAM_64 = 0xcffaedfe
+
+ # 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",
+ MH_CIGAM_64 => "MH_CIGAM_64"
+ }
+
+ # mask for CPUs with 64-bit architectures (when running a 64-bit ABI?)
+ CPU_ARCH_ABI64 = 0x01000000
+
+ # 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
+
+ # x86_64 (AMD64) compatible CPUs
+ CPU_TYPE_X86_64 = (CPU_TYPE_X86 | CPU_ARCH_ABI64)
+
+ # PowerPC compatible CPUs (7400 series?)
+ CPU_TYPE_POWERPC = 0x12
+
+ # PowerPC64 compatible CPUs (970 series?)
+ CPU_TYPE_POWERPC64 = (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
+
+ # 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",
+ CPU_TYPE_POWERPC64 => "CPU_TYPE_POWERPC64"
+ }
+
+ # mask for CPU subtype capabilities
+ CPU_SUBTYPE_MASK = 0xff000000
+
+ # 64-bit libraries (undocumented!)
+ # @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
+
+ # all x86-type CPUs (what makes this different from CPU_SUBTYPE_X86_ALL?)
+ CPU_SUBTYPE_X86_ARCH1 = 4
+
+ # association of cpu subtypes to string representations
+ CPU_SUBTYPES = {
+ CPU_SUBTYPE_X86_ALL => "CPU_SUBTYPE_X86_ALL",
+ CPU_SUBTYPE_X86_ARCH1 => "CPU_SUBTYPE_X86_ARCH1"
+ }
+
+ # relocatable object file
+ MH_OBJECT = 0x1
+
+ # demand paged executable file
+ MH_EXECUTE = 0x2
+
+ # fixed VM shared library file
+ MH_FVMLIB = 0x3
+
+ # core dump file
+ MH_CORE = 0x4
+
+ # preloaded executable file
+ MH_PRELOAD = 0x5
+
+ # dynamically bound shared library
+ MH_DYLIB = 0x6
+
+ # dynamic link editor
+ MH_DYLINKER = 0x7
+
+ # dynamically bound bundle file
+ MH_BUNDLE = 0x8
+
+ # shared library stub for static linking only, no section contents
+ MH_DYLIB_STUB = 0x9
+
+ # companion file with only debug sections
+ MH_DSYM = 0xa
+
+ # x86_64 kexts
+ MH_KEXT_BUNDLE = 0xb
+
+ # association of filetypes to string representations
+ # @api private
+ MH_FILETYPES = {
+ MH_OBJECT => "MH_OBJECT",
+ MH_EXECUTE => "MH_EXECUTE",
+ MH_FVMLIB => "MH_FVMLIB",
+ MH_CORE => "MH_CORE",
+ MH_PRELOAD => "MH_PRELOAD",
+ MH_DYLIB => "MH_DYLIB",
+ MH_DYLINKER => "MH_DYLINKER",
+ MH_BUNDLE => "MH_BUNDLE",
+ MH_DYLIB_STUB => "MH_DYLIB_STUB",
+ MH_DSYM => "MH_DSYM",
+ MH_KEXT_BUNDLE => "MH_KEXT_BUNDLE"
+ }
+
+ # association of mach header flag symbols to values
+ # @api private
+ MH_FLAGS = {
+ :MH_NOUNDEFS => 0x1,
+ :MH_INCRLINK => 0x2,
+ :MH_DYLDLINK => 0x4,
+ :MH_BINDATLOAD => 0x8,
+ :MH_PREBOUND => 0x10,
+ :MH_SPLIT_SEGS => 0x20,
+ :MH_LAZY_INIT => 0x40,
+ :MH_TWOLEVEL => 0x80,
+ :MH_FORCE_FLAT => 0x100,
+ :MH_NOMULTIDEFS => 0x200,
+ :MH_NOPREFIXBINDING => 0x400,
+ :MH_PREBINDABLE => 0x800,
+ :MH_ALLMODSBOUND => 0x1000,
+ :MH_SUBSECTIONS_VIA_SYMBOLS => 0x2000,
+ :MH_CANONICAL => 0x4000,
+ :MH_WEAK_DEFINES => 0x8000,
+ :MH_BINDS_TO_WEAK => 0x10000,
+ :MH_ALLOW_STACK_EXECUTION => 0x20000,
+ :MH_ROOT_SAFE => 0x40000,
+ :MH_SETUID_SAFE => 0x80000,
+ :MH_NO_REEXPORTED_DYLIBS => 0x100000,
+ :MH_PIE => 0x200000,
+ :MH_DEAD_STRIPPABLE_DYLIB => 0x400000,
+ :MH_HAS_TLV_DESCRIPTORS => 0x800000,
+ :MH_NO_HEAP_EXECUTION => 0x1000000,
+ :MH_APP_EXTENSION_SAFE => 0x02000000
+ }
+
+ # Fat binary header structure
+ # @see MachO::FatArch
+ class FatHeader < MachOStructure
+ # @return [Fixnum] the magic number of the header (and file)
+ attr_reader :magic
+
+ # @return [Fixnum] the number of fat architecture structures following the header
+ attr_reader :nfat_arch
+
+ FORMAT = "VV"
+ SIZEOF = 8
+
+ # @api private
+ def initialize(magic, nfat_arch)
+ @magic = magic
+ @nfat_arch = nfat_arch
+ end
+ end
+
+ # Fat binary header architecture structure. A Fat binary has one or more of
+ # these, representing one or more internal Mach-O blobs.
+ # @see MachO::FatHeader
+ class FatArch < MachOStructure
+ # @return [Fixnum] the CPU type of the Mach-O
+ attr_reader :cputype
+
+ # @return [Fixnum] the CPU subtype of the Mach-O
+ attr_reader :cpusubtype
+
+ # @return [Fixnum] the file offset to the beginning of the Mach-O data
+ attr_reader :offset
+
+ # @return [Fixnum] the size, in bytes, of the Mach-O data
+ attr_reader :size
+
+ # @return [Fixnum] the alignment, as a power of 2
+ attr_reader :align
+
+ FORMAT = "VVVVV"
+ SIZEOF = 20
+
+ # @api private
+ def initialize(cputype, cpusubtype, offset, size, align)
+ @cputype = cputype
+ @cpusubtype = cpusubtype
+ @offset = offset
+ @size = size
+ @align = align
+ end
+ end
+
+ # 32-bit Mach-O file header structure
+ class MachHeader < MachOStructure
+ # @return [Fixnum] the magic number
+ attr_reader :magic
+
+ # @return [Fixnum] the CPU type of the Mach-O
+ attr_reader :cputype
+
+ # @return [Fixnum] the CPU subtype of the Mach-O
+ attr_reader :cpusubtype
+
+ # @return [Fixnum] the file type of the Mach-O
+ attr_reader :filetype
+
+ # @return [Fixnum] the number of load commands in the Mach-O
+ attr_reader :ncmds
+
+ # @return [Fixnum] the size of all load commands, in bytes, in the Mach-O
+ attr_reader :sizeofcmds
+
+ # @return [Fixnum] the header flags associated with the Mach-O
+ attr_reader :flags
+
+ FORMAT = "VVVVVVV"
+ SIZEOF = 28
+
+ # @api private
+ def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
+ flags)
+ @magic = magic
+ @cputype = cputype
+ @cpusubtype = cpusubtype
+ @filetype = filetype
+ @ncmds = ncmds
+ @sizeofcmds = sizeofcmds
+ @flags = flags
+ end
+
+ # @example
+ # puts "this mach-o has position-independent execution" if header.flag?(:MH_PIE)
+ # @param flag [Symbol] a mach header flag symbol
+ # @return [Boolean] true if `flag` is present in the header's flag section
+ def flag?(flag)
+ flag = MH_FLAGS[flag]
+ return false if flag.nil?
+ flags & flag == flag
+ end
+ end
+
+ # 64-bit Mach-O file header structure
+ class MachHeader64 < MachHeader
+ # @return [void]
+ attr_reader :reserved
+
+ FORMAT = "VVVVVVVV"
+ SIZEOF = 32
+
+ # @api private
+ def initialize(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds,
+ flags, reserved)
+ super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
+ @reserved = reserved
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/load_commands.rb b/Library/Homebrew/vendor/macho/macho/load_commands.rb
new file mode 100644
index 000000000..e5c71b160
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/load_commands.rb
@@ -0,0 +1,1001 @@
+module MachO
+ # load commands added after OS X 10.1 need to be bitwise ORed with
+ # LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
+ LC_REQ_DYLD = 0x80000000
+
+ # association of load commands to symbol representations
+ # @api private
+ LOAD_COMMANDS = {
+ 0x1 => :LC_SEGMENT,
+ 0x2 => :LC_SYMTAB,
+ 0x3 => :LC_SYMSEG,
+ 0x4 => :LC_THREAD,
+ 0x5 => :LC_UNIXTHREAD,
+ 0x6 => :LC_LOADFVMLIB,
+ 0x7 => :LC_IDFVMLIB,
+ 0x8 => :LC_IDENT,
+ 0x9 => :LC_FVMFILE,
+ 0xa => :LC_PREPAGE,
+ 0xb => :LC_DYSYMTAB,
+ 0xc => :LC_LOAD_DYLIB,
+ 0xd => :LC_ID_DYLIB,
+ 0xe => :LC_LOAD_DYLINKER,
+ 0xf => :LC_ID_DYLINKER,
+ 0x10 => :LC_PREBOUND_DYLIB,
+ 0x11 => :LC_ROUTINES,
+ 0x12 => :LC_SUB_FRAMEWORK,
+ 0x13 => :LC_SUB_UMBRELLA,
+ 0x14 => :LC_SUB_CLIENT,
+ 0x15 => :LC_SUB_LIBRARY,
+ 0x16 => :LC_TWOLEVEL_HINTS,
+ 0x17 => :LC_PREBIND_CKSUM,
+ (0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
+ 0x19 => :LC_SEGMENT_64,
+ 0x1a => :LC_ROUTINES_64,
+ 0x1b => :LC_UUID,
+ (0x1c | LC_REQ_DYLD) => :LC_RPATH,
+ 0x1d => :LC_CODE_SIGNATURE,
+ 0x1e => :LC_SEGMENT_SPLIT_INFO,
+ (0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
+ 0x20 => :LC_LAZY_LOAD_DYLIB,
+ 0x21 => :LC_ENCRYPTION_INFO,
+ 0x22 => :LC_DYLD_INFO,
+ (0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
+ (0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
+ 0x24 => :LC_VERSION_MIN_MACOSX,
+ 0x25 => :LC_VERSION_MIN_IPHONEOS,
+ 0x26 => :LC_FUNCTION_STARTS,
+ 0x27 => :LC_DYLD_ENVIRONMENT,
+ (0x28 | LC_REQ_DYLD) => :LC_MAIN,
+ 0x29 => :LC_DATA_IN_CODE,
+ 0x2a => :LC_SOURCE_VERSION,
+ 0x2b => :LC_DYLIB_CODE_SIGN_DRS,
+ 0x2c => :LC_ENCRYPTION_INFO_64,
+ 0x2d => :LC_LINKER_OPTION,
+ 0x2e => :LC_LINKER_OPTIMIZATION_HINT
+ }
+
+ # load commands responsible for loading dylibs
+ # @api private
+ DYLIB_LOAD_COMMANDS = [
+ :LC_LOAD_DYLIB,
+ :LC_LOAD_WEAK_DYLIB,
+ :LC_REEXPORT_DYLIB,
+ :LC_LAZY_LOAD_DYLIB,
+ :LC_LOAD_UPWARD_DYLIB,
+ ].freeze
+
+ # association of load command symbols to string representations of classes
+ # @api private
+ LC_STRUCTURES = {
+ :LC_SEGMENT => "SegmentCommand",
+ :LC_SYMTAB => "SymtabCommand",
+ :LC_SYMSEG => "LoadCommand", # obsolete
+ :LC_THREAD => "ThreadCommand",
+ :LC_UNIXTHREAD => "ThreadCommand",
+ :LC_LOADFVMLIB => "LoadCommand", # obsolete
+ :LC_IDFVMLIB => "LoadCommand", # obsolete
+ :LC_IDENT => "LoadCommand", # obsolete
+ :LC_FVMFILE => "LoadCommand", # reserved for internal use only
+ :LC_PREPAGE => "LoadCommand", # reserved for internal use only
+ :LC_DYSYMTAB => "DysymtabCommand",
+ :LC_LOAD_DYLIB => "DylibCommand",
+ :LC_ID_DYLIB => "DylibCommand",
+ :LC_LOAD_DYLINKER => "DylinkerCommand",
+ :LC_ID_DYLINKER => "DylinkerCommand",
+ :LC_PREBOUND_DYLIB => "PreboundDylibCommand",
+ :LC_ROUTINES => "RoutinesCommand",
+ :LC_SUB_FRAMEWORK => "SubFrameworkCommand",
+ :LC_SUB_UMBRELLA => "SubUmbrellaCommand",
+ :LC_SUB_CLIENT => "SubClientCommand",
+ :LC_SUB_LIBRARY => "SubLibraryCommand",
+ :LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
+ :LC_PREBIND_CKSUM => "PrebindCksumCommand",
+ :LC_LOAD_WEAK_DYLIB => "DylibCommand",
+ :LC_SEGMENT_64 => "SegmentCommand64",
+ :LC_ROUTINES_64 => "RoutinesCommand64",
+ :LC_UUID => "UUIDCommand",
+ :LC_RPATH => "RpathCommand",
+ :LC_CODE_SIGNATURE => "LinkeditDataCommand",
+ :LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
+ :LC_REEXPORT_DYLIB => "DylibCommand",
+ :LC_LAZY_LOAD_DYLIB => "DylibCommand",
+ :LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
+ :LC_DYLD_INFO => "DyldInfoCommand",
+ :LC_DYLD_INFO_ONLY => "DyldInfoCommand",
+ :LC_LOAD_UPWARD_DYLIB => "DylibCommand",
+ :LC_VERSION_MIN_MACOSX => "VersionMinCommand",
+ :LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
+ :LC_FUNCTION_STARTS => "LinkeditDataCommand",
+ :LC_DYLD_ENVIRONMENT => "DylinkerCommand",
+ :LC_MAIN => "EntryPointCommand",
+ :LC_DATA_IN_CODE => "LinkeditDataCommand",
+ :LC_SOURCE_VERSION => "SourceVersionCommand",
+ :LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
+ :LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
+ :LC_LINKER_OPTION => "LinkerOptionCommand",
+ :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand"
+ }
+
+ # association of segment name symbols to names
+ # @api private
+ SEGMENT_NAMES = {
+ :SEG_PAGEZERO => "__PAGEZERO",
+ :SEG_TEXT => "__TEXT",
+ :SEG_DATA => "__DATA",
+ :SEG_OBJC => "__OBJC",
+ :SEG_ICON => "__ICON",
+ :SEG_LINKEDIT => "__LINKEDIT",
+ :SEG_UNIXSTACK => "__UNIXSTACK",
+ :SEG_IMPORT => "__IMPORT"
+ }
+
+ # association of segment flag symbols to values
+ # @api private
+ SEGMENT_FLAGS = {
+ :SG_HIGHVM => 0x1,
+ :SG_FVMLIB => 0x2,
+ :SG_NORELOC => 0x4,
+ :SG_PROTECTED_VERSION_1 => 0x8
+ }
+
+ # Mach-O load command structure
+ # This is the most generic load command - only cmd ID and size are
+ # represented, and no actual data. Used when a more specific class
+ # isn't available/implemented.
+ class LoadCommand < MachOStructure
+ # @return [Fixnum] the offset in the file the command was created from
+ attr_reader :offset
+
+ # @return [Fixnum] the load command's identifying number
+ attr_reader :cmd
+
+ # @return [Fixnum] the size of the load command, in bytes
+ attr_reader :cmdsize
+
+ FORMAT = "VV"
+ SIZEOF = 8
+
+ # Creates a new LoadCommand given an offset and binary string
+ # @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))
+ end
+
+ # @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
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize)
+ @raw_data = raw_data
+ @offset = offset
+ @cmd = cmd
+ @cmdsize = cmdsize
+ end
+
+ # @return [Symbol] a symbol representation of the load command's identifying number
+ def type
+ LOAD_COMMANDS[cmd]
+ end
+
+ alias :to_sym :type
+
+ # @return [String] a string representation of the load command's identifying number
+ def to_s
+ type.to_s
+ end
+
+ # Represents a Load Command string. A rough analogue to the lc_str
+ # struct used internally by OS X. This class allows ruby-macho to
+ # pretend that strings stored in LCs are immediately available without
+ # explicit operations on the raw Mach-O data.
+ class LCStr
+ # @param raw_data [String] the raw Mach-O data.
+ # @param lc [MachO::LoadCommand] the load command
+ # @param lc_str [Fixnum] the offset to the beginning of the string
+ # @api private
+ def initialize(raw_data, lc, lc_str)
+ @raw_data = raw_data
+ @lc = lc
+ @lc_str = lc_str
+ @str = @raw_data.slice(@lc.offset + @lc_str...@lc.offset + @lc.cmdsize).delete("\x00")
+ end
+
+ # @return [String] a string representation of the LCStr
+ def to_s
+ @str
+ end
+
+ # @return [Fixnum] the offset to the beginning of the string in the load command
+ def to_i
+ @lc_str
+ end
+ end
+ end
+
+ # A load command containing a single 128-bit unique random number identifying
+ # an object produced by static link editor. Corresponds to LC_UUID.
+ class UUIDCommand < LoadCommand
+ # @return [Array<Fixnum>] the UUID
+ attr_reader :uuid
+
+ FORMAT = "VVa16"
+ SIZEOF = 24
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, uuid)
+ super(raw_data, offset, cmd, cmdsize)
+ @uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
+ end
+
+ # @return [String] a string representation of the UUID
+ def uuid_string
+ hexes = uuid.map { |e| "%02x" % e }
+ segs = [
+ hexes[0..3].join, hexes[4..5].join, hexes[6..7].join,
+ hexes[8..9].join, hexes[10..15].join
+ ]
+
+ segs.join("-")
+ end
+ end
+
+ # A load command indicating that part of this file is to be mapped into
+ # the task's address space. Corresponds to LC_SEGMENT.
+ class SegmentCommand < LoadCommand
+ # @return [String] the name of the segment
+ attr_reader :segname
+
+ # @return [Fixnum] the memory address of the segment
+ attr_reader :vmaddr
+
+ # @return [Fixnum] the memory size of the segment
+ attr_reader :vmsize
+
+ # @return [Fixnum] the file offset of the segment
+ attr_reader :fileoff
+
+ # @return [Fixnum] the amount to map from the file
+ attr_reader :filesize
+
+ # @return [Fixnum] the maximum VM protection
+ attr_reader :maxprot
+
+ # @return [Fixnum] the initial VM protection
+ attr_reader :initprot
+
+ # @return [Fixnum] the number of sections in the segment
+ attr_reader :nsects
+
+ # @return [Fixnum] any flags associated with the segment
+ attr_reader :flags
+
+ FORMAT = "VVa16VVVVVVVV"
+ SIZEOF = 56
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
+ filesize, maxprot, initprot, nsects, flags)
+ super(raw_data, offset, cmd, cmdsize)
+ @segname = segname.delete("\x00")
+ @vmaddr = vmaddr
+ @vmsize = vmsize
+ @fileoff = fileoff
+ @filesize = filesize
+ @maxprot = maxprot
+ @initprot = initprot
+ @nsects = nsects
+ @flags = flags
+ end
+
+ # @example
+ # puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
+ # @param flag [Symbol] a segment flag symbol
+ # @return [Boolean] true if `flag` is present in the segment's flag field
+ def flag?(flag)
+ flag = SEGMENT_FLAGS[flag]
+ return false if flag.nil?
+ flags & flag == flag
+ end
+ end
+
+ # A load command indicating that part of this file is to be mapped into
+ # the task's address space. Corresponds to LC_SEGMENT_64.
+ class SegmentCommand64 < LoadCommand
+ # @return [String] the name of the segment
+ attr_reader :segname
+
+ # @return [Fixnum] the memory address of the segment
+ attr_reader :vmaddr
+
+ # @return [Fixnum] the memory size of the segment
+ attr_reader :vmsize
+
+ # @return [Fixnum] the file offset of the segment
+ attr_reader :fileoff
+
+ # @return [Fixnum] the amount to map from the file
+ attr_reader :filesize
+
+ # @return [Fixnum] the maximum VM protection
+ attr_reader :maxprot
+
+ # @return [Fixnum] the initial VM protection
+ attr_reader :initprot
+
+ # @return [Fixnum] the number of sections in the segment
+ attr_reader :nsects
+
+ # @return [Fixnum] any flags associated with the segment
+ attr_reader :flags
+
+ FORMAT = "VVa16QQQQVVVV"
+ SIZEOF = 72
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
+ filesize, maxprot, initprot, nsects, flags)
+ super(raw_data, offset, cmd, cmdsize)
+ @segname = segname.delete("\x00")
+ @vmaddr = vmaddr
+ @vmsize = vmsize
+ @fileoff = fileoff
+ @filesize = filesize
+ @maxprot = maxprot
+ @initprot = initprot
+ @nsects = nsects
+ @flags = flags
+ end
+
+ # @example
+ # puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
+ # @param flag [Symbol] a segment flag symbol
+ # @return [Boolean] true if `flag` is present in the segment's flag field
+ def flag?(flag)
+ flag = SEGMENT_FLAGS[flag]
+ return false if flag.nil?
+ flags & flag == flag
+ end
+ end
+
+ # A load command representing some aspect of shared libraries, depending
+ # on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
+ # and LC_REEXPORT_DYLIB.
+ class DylibCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
+ attr_reader :name
+
+ # @return [Fixnum] the library's build time stamp
+ attr_reader :timestamp
+
+ # @return [Fixnum] the library's current version number
+ attr_reader :current_version
+
+ # @return [Fixnum] the library's compatibility version number
+ attr_reader :compatibility_version
+
+ FORMAT = "VVVVVV"
+ SIZEOF = 24
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, name, timestamp, current_version,
+ compatibility_version)
+ super(raw_data, offset, cmd, cmdsize)
+ @name = LCStr.new(raw_data, self, name)
+ @timestamp = timestamp
+ @current_version = current_version
+ @compatibility_version = compatibility_version
+ end
+ end
+
+ # A load command representing some aspect of the dynamic linker, depending
+ # on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
+ # LC_DYLD_ENVIRONMENT.
+ class DylinkerCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
+ attr_reader :name
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, name)
+ super(raw_data, offset, cmd, cmdsize)
+ @name = LCStr.new(raw_data, self, name)
+ end
+ end
+
+ # A load command used to indicate dynamic libraries used in prebinding.
+ # Corresponds to LC_PREBOUND_DYLIB.
+ class PreboundDylibCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
+ attr_reader :name
+
+ # @return [Fixnum] the number of modules in the library
+ attr_reader :nmodules
+
+ # @return [Fixnum] a bit vector of linked modules
+ attr_reader :linked_modules
+
+ FORMAT = "VVVVV"
+ SIZEOF = 20
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, name, nmodules, linked_modules)
+ super(raw_data, offset, cmd, cmdsize)
+ @name = LCStr.new(raw_data, self, name)
+ @nmodules = nmodules
+ @linked_modules = linked_modules
+ end
+ end
+
+ # 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
+
+ end
+
+ # A load command containing the address of the dynamic shared library
+ # initialization routine and an index into the module table for the module
+ # that defines the routine. Corresponds to LC_ROUTINES.
+ class RoutinesCommand < LoadCommand
+ # @return [Fixnum] the address of the initialization routine
+ attr_reader :init_address
+
+ # @return [Fixnum] the index into the module table that the init routine is defined in
+ attr_reader :init_module
+
+ # @return [void]
+ attr_reader :reserved1
+
+ # @return [void]
+ attr_reader :reserved2
+
+ # @return [void]
+ attr_reader :reserved3
+
+ # @return [void]
+ attr_reader :reserved4
+
+ # @return [void]
+ attr_reader :reserved5
+
+ # @return [void]
+ attr_reader :reserved6
+
+ FORMAT = "VVVVVVVVVV"
+ SIZEOF = 40
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, init_address, init_module,
+ reserved1, reserved2, reserved3, reserved4, reserved5,
+ reserved6)
+ super(raw_data, offset, cmd, cmdsize)
+ @init_address = init_address
+ @init_module = init_module
+ @reserved1 = reserved1
+ @reserved2 = reserved2
+ @reserved3 = reserved3
+ @reserved4 = reserved4
+ @reserved5 = reserved5
+ @reserved6 = reserved6
+ end
+ end
+
+ # A load command containing the address of the dynamic shared library
+ # initialization routine and an index into the module table for the module
+ # that defines the routine. Corresponds to LC_ROUTINES_64.
+ class RoutinesCommand64 < LoadCommand
+ # @return [Fixnum] the address of the initialization routine
+ attr_reader :init_address
+
+ # @return [Fixnum] the index into the module table that the init routine is defined in
+ attr_reader :init_module
+
+ # @return [void]
+ attr_reader :reserved1
+
+ # @return [void]
+ attr_reader :reserved2
+
+ # @return [void]
+ attr_reader :reserved3
+
+ # @return [void]
+ attr_reader :reserved4
+
+ # @return [void]
+ attr_reader :reserved5
+
+ # @return [void]
+ attr_reader :reserved6
+
+ FORMAT = "VVQQQQQQQQ"
+ SIZEOF = 72
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, init_address, init_module,
+ reserved1, reserved2, reserved3, reserved4, reserved5,
+ reserved6)
+ super(raw_data, offset, cmd, cmdsize)
+ @init_address = init_address
+ @init_module = init_module
+ @reserved1 = reserved1
+ @reserved2 = reserved2
+ @reserved3 = reserved3
+ @reserved4 = reserved4
+ @reserved5 = reserved5
+ @reserved6 = reserved6
+ end
+ end
+
+ # A load command signifying membership of a subframework containing the name
+ # of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
+ class SubFrameworkCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr
+ attr_reader :umbrella
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, umbrella)
+ super(raw_data, offset, cmd, cmdsize)
+ @umbrella = LCStr.new(raw_data, self, umbrella)
+ end
+ end
+
+ # A load command signifying membership of a subumbrella containing the name
+ # of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
+ class SubUmbrellaCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr
+ attr_reader :sub_umbrella
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, sub_umbrella)
+ super(raw_data, offset, cmd, cmdsize)
+ @sub_umbrella = LCStr.new(raw_data, self, sub_umbrella)
+ end
+ end
+
+ # A load command signifying a sublibrary of a shared library. Corresponds
+ # to LC_SUB_LIBRARY.
+ class SubLibraryCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr
+ attr_reader :sub_library
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, sub_library)
+ super(raw_data, offset, cmd, cmdsize)
+ @sub_library = LCStr.new(raw_data, self, sub_library)
+ end
+ end
+
+ # A load command signifying a shared library that is a subframework of
+ # an umbrella framework. Corresponds to LC_SUB_CLIENT.
+ class SubClientCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr
+ attr_reader :sub_client
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, sub_client)
+ super(raw_data, offset, cmd, cmdsize)
+ @sub_client = LCStr.new(raw_data, self, sub_client)
+ end
+ end
+
+ # A load command containing the offsets and sizes of the link-edit 4.3BSD
+ # "stab" style symbol table information. Corresponds to LC_SYMTAB.
+ class SymtabCommand < LoadCommand
+ # @return [Fixnum] the symbol table's offset
+ attr_reader :symoff
+
+ # @return [Fixnum] the number of symbol table entries
+ attr_reader :nsyms
+
+ # @return the string table's offset
+ attr_reader :stroff
+
+ # @return the string table size in bytes
+ attr_reader :strsize
+
+ FORMAT = "VVVVVV"
+ SIZEOF = 24
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, symoff, nsyms, stroff, strsize)
+ super(raw_data, offset, cmd, cmdsize)
+ @symoff = symoff
+ @nsyms = nsyms
+ @stroff = stroff
+ @strsize = strsize
+ end
+ end
+
+ # A load command containing symbolic information needed to support data
+ # structures used by the dynamic link editor. Corresponds to LC_DYSYMTAB.
+ class DysymtabCommand < LoadCommand
+ # @return [Fixnum] the index to local symbols
+ attr_reader :ilocalsym
+
+ # @return [Fixnum] the number of local symbols
+ attr_reader :nlocalsym
+
+ # @return [Fixnum] the index to externally defined symbols
+ attr_reader :iextdefsym
+
+ # @return [Fixnum] the number of externally defined symbols
+ attr_reader :nextdefsym
+
+ # @return [Fixnum] the index to undefined symbols
+ attr_reader :iundefsym
+
+ # @return [Fixnum] the number of undefined symbols
+ attr_reader :nundefsym
+
+ # @return [Fixnum] the file offset to the table of contents
+ attr_reader :tocoff
+
+ # @return [Fixnum] the number of entries in the table of contents
+ attr_reader :ntoc
+
+ # @return [Fixnum] the file offset to the module table
+ attr_reader :modtaboff
+
+ # @return [Fixnum] the number of entries in the module table
+ attr_reader :nmodtab
+
+ # @return [Fixnum] the file offset to the referenced symbol table
+ attr_reader :extrefsymoff
+
+ # @return [Fixnum] the number of entries in the referenced symbol table
+ attr_reader :nextrefsyms
+
+ # @return [Fixnum] the file offset to the indirect symbol table
+ attr_reader :indirectsymoff
+
+ # @return [Fixnum] the number of entries in the indirect symbol table
+ attr_reader :nindirectsyms
+
+ # @return [Fixnum] the file offset to the external relocation entries
+ attr_reader :extreloff
+
+ # @return [Fixnum] the number of external relocation entries
+ attr_reader :nextrel
+
+ # @return [Fixnum] the file offset to the local relocation entries
+ attr_reader :locreloff
+
+ # @return [Fixnum] the number of local relocation entries
+ attr_reader :nlocrel
+
+
+ FORMAT = "VVVVVVVVVVVVVVVVVVVV"
+ SIZEOF = 80
+
+ # ugh
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
+ nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
+ nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
+ nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
+ super(raw_data, offset, cmd, cmdsize)
+ @ilocalsym = ilocalsym
+ @nlocalsym = nlocalsym
+ @iextdefsym = iextdefsym
+ @nextdefsym = nextdefsym
+ @iundefsym = iundefsym
+ @nundefsym = nundefsym
+ @tocoff = tocoff
+ @ntoc = ntoc
+ @modtaboff = modtaboff
+ @nmodtab = nmodtab
+ @extrefsymoff = extrefsymoff
+ @nextrefsyms = nextrefsyms
+ @indirectsymoff = indirectsymoff
+ @nindirectsyms = nindirectsyms
+ @extreloff = extreloff
+ @nextrel = nextrel
+ @locreloff = locreloff
+ @nlocrel = nlocrel
+ end
+ end
+
+ # A load command containing the offset and number of hints in the two-level
+ # namespace lookup hints table. Corresponds to LC_TWOLEVEL_HINTS.
+ class TwolevelHintsCommand < LoadCommand
+ # @return [Fixnum] the offset to the hint table
+ attr_reader :htoffset
+
+ # @return [Fixnum] the number of hints in the hint table
+ attr_reader :nhints
+
+ FORMAT = "VVVV"
+ SIZEOF = 16
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, htoffset, nhints)
+ super(raw_data, offset, cmd, cmdsize)
+ @htoffset = htoffset
+ @nhints = nhints
+ end
+ end
+
+ # A load command containing the value of the original checksum for prebound
+ # files, or zero. Corresponds to LC_PREBIND_CKSUM.
+ class PrebindCksumCommand < LoadCommand
+ # @return [Fixnum] the checksum or 0
+ attr_reader :cksum
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, cksum)
+ super(raw_data, offset, cmd, cmdsize)
+ @cksum = cksum
+ end
+ end
+
+ # A load command representing an rpath, which specifies a path that should
+ # be added to the current run path used to find @rpath prefixed dylibs.
+ # Corresponds to LC_RPATH.
+ class RpathCommand < LoadCommand
+ # @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr
+ attr_reader :path
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, path)
+ super(raw_data, offset, cmd, cmdsize)
+ @path = LCStr.new(raw_data, self, path)
+ end
+ end
+
+ # A load command representing the offsets and sizes of a blob of data in
+ # the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
+ # LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
+ class LinkeditDataCommand < LoadCommand
+ # @return [Fixnum] offset to the data in the __LINKEDIT segment
+ attr_reader :dataoff
+
+ # @return [Fixnum] size of the data in the __LINKEDIT segment
+ attr_reader :datasize
+
+ FORMAT = "VVVV"
+ SIZEOF = 16
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, dataoff, datasize)
+ super(raw_data, offset, cmd, cmdsize)
+ @dataoff = dataoff
+ @datasize = datasize
+ end
+ end
+
+ # A load command representing the offset to and size of an encrypted
+ # segment. Corresponds to LC_ENCRYPTION_INFO.
+ class EncryptionInfoCommand < LoadCommand
+ # @return [Fixnum] the offset to the encrypted segment
+ attr_reader :cryptoff
+
+ # @return [Fixnum] the size of the encrypted segment
+ attr_reader :cryptsize
+
+ # @return [Fixnum] the encryption system, or 0 if not encrypted yet
+ attr_reader :cryptid
+
+ FORMAT = "VVVVV"
+ SIZEOF = 20
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid)
+ super(raw_data, offset, cmd, cmdsize)
+ @cryptoff = cryptoff
+ @cryptsize = cryptsize
+ @cryptid = cryptid
+ end
+ end
+
+ # A load command representing the offset to and size of an encrypted
+ # segment. Corresponds to LC_ENCRYPTION_INFO_64.
+ class EncryptionInfoCommand64 < LoadCommand
+ # @return [Fixnum] the offset to the encrypted segment
+ attr_reader :cryptoff
+
+ # @return [Fixnum] the size of the encrypted segment
+ attr_reader :cryptsize
+
+ # @return [Fixnum] the encryption system, or 0 if not encrypted yet
+ attr_reader :cryptid
+
+ # @return [Fixnum] 64-bit padding value
+ attr_reader :pad
+
+ FORMAT = "VVVVVV"
+ SIZEOF = 24
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, cryptoff, cryptsize, cryptid)
+ super(raw_data, offset, cmd, cmdsize)
+ @cryptoff = cryptoff
+ @cryptsize = cryptsize
+ @cryptid = cryptid
+ @pad = pad
+ end
+ end
+
+ # A load command containing the minimum OS version on which the binary
+ # was built to run. Corresponds to LC_VERSION_MIN_MACOSX and LC_VERSION_MIN_IPHONEOS.
+ class VersionMinCommand < LoadCommand
+ # @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
+ attr_reader :version
+
+ # @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8
+ attr_reader :sdk
+
+ FORMAT = "VVVV"
+ SIZEOF = 16
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, version, sdk)
+ super(raw_data, offset, cmd, cmdsize)
+ @version = version
+ @sdk = sdk
+ end
+
+ # A string representation of the binary's minimum OS version.
+ # @return [String] a string representing the minimum OS version.
+ def version_string
+ binary = "%032b" % version
+ segs = [
+ binary[0..15], binary[16..23], binary[24..31]
+ ].map { |s| s.to_i(2) }
+
+ segs.join(".")
+ end
+
+ # A string representation of the binary's SDK version.
+ # @return [String] a string representing the SDK version.
+ def sdk_string
+ binary = "%032b" % sdk
+ segs = [
+ binary[0..15], binary[16..23], binary[24..31]
+ ].map { |s| s.to_i(2) }
+
+ segs.join(".")
+ end
+ end
+
+ # A load command containing the file offsets and sizes of the new
+ # compressed form of the information dyld needs to load the image.
+ # Corresponds to LC_DYLD_INFO and LC_DYLD_INFO_ONLY.
+ class DyldInfoCommand < LoadCommand
+ # @return [Fixnum] the file offset to the rebase information
+ attr_reader :rebase_off
+
+ # @return [Fixnum] the size of the rebase information
+ attr_reader :rebase_size
+
+ # @return [Fixnum] the file offset to the binding information
+ attr_reader :bind_off
+
+ # @return [Fixnum] the size of the binding information
+ attr_reader :bind_size
+
+ # @return [Fixnum] the file offset to the weak binding information
+ attr_reader :weak_bind_off
+
+ # @return [Fixnum] the size of the weak binding information
+ attr_reader :weak_bind_size
+
+ # @return [Fixnum] the file offset to the lazy binding information
+ attr_reader :lazy_bind_off
+
+ # @return [Fixnum] the size of the lazy binding information
+ attr_reader :lazy_bind_size
+
+ # @return [Fixnum] the file offset to the export information
+ attr_reader :export_off
+
+ # @return [Fixnum] the size of the export information
+ attr_reader :export_size
+
+ FORMAT = "VVVVVVVVVVVV"
+ SIZEOF = 48
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, rebase_off, rebase_size, bind_off,
+ bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
+ lazy_bind_size, export_off, export_size)
+ super(raw_data, offset, cmd, cmdsize)
+ @rebase_off = rebase_off
+ @rebase_size = rebase_size
+ @bind_off = bind_off
+ @bind_size = bind_size
+ @weak_bind_off = weak_bind_off
+ @weak_bind_size = weak_bind_size
+ @lazy_bind_off = lazy_bind_off
+ @lazy_bind_size = lazy_bind_size
+ @export_off = export_off
+ @export_size = export_size
+ end
+ end
+
+ # A load command containing linker options embedded in object files.
+ # Corresponds to LC_LINKER_OPTION.
+ class LinkerOptionCommand < LoadCommand
+ # @return [Fixnum] the number of strings
+ attr_reader :count
+
+ FORMAT = "VVV"
+ SIZEOF = 12
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, count)
+ super(raw_data, offset, cmd, cmdsize)
+ @count = count
+ end
+ end
+
+ # A load command specifying the offset of main(). Corresponds to LC_MAIN.
+ class EntryPointCommand < LoadCommand
+ # @return [Fixnum] the file (__TEXT) offset of main()
+ attr_reader :entryoff
+
+ # @return [Fixnum] if not 0, the initial stack size.
+ attr_reader :stacksize
+
+ FORMAT = "VVQQ"
+ SIZEOF = 24
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, entryoff, stacksize)
+ super(raw_data, offset, cmd, cmdsize)
+ @entryoff = entryoff
+ @stacksize = stacksize
+ end
+ end
+
+ # A load command specifying the version of the sources used to build the
+ # binary. Corresponds to LC_SOURCE_VERSION.
+ class SourceVersionCommand < LoadCommand
+ # @return [Fixnum] the version packed as a24.b10.c10.d10.e10
+ attr_reader :version
+
+ FORMAT = "VVQ"
+ SIZEOF = 16
+
+ # @api private
+ def initialize(raw_data, offset, cmd, cmdsize, version)
+ super(raw_data, offset, cmd, cmdsize)
+ @version = version
+ end
+
+ # A string representation of the sources used to build the binary.
+ # @return [String] a string representation of the version
+ def version_string
+ binary = "%064b" % version
+ segs = [
+ binary[0..23], binary[24..33], binary[34..43], binary[44..53],
+ binary[54..63]
+ ].map { |s| s.to_i(2) }
+
+ segs.join(".")
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/macho_file.rb b/Library/Homebrew/vendor/macho/macho/macho_file.rb
new file mode 100644
index 000000000..39d584c8e
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/macho_file.rb
@@ -0,0 +1,531 @@
+module MachO
+ # Represents a Mach-O file, which contains a header and load commands
+ # as well as binary executable instructions. Mach-O binaries are
+ # architecture specific.
+ # @see https://en.wikipedia.org/wiki/Mach-O
+ # @see MachO::FatFile
+ class MachOFile
+ # @return [MachO::MachHeader] if the Mach-O is 32-bit
+ # @return [MachO::MachHeader64] if the Mach-O is 64-bit
+ attr_reader :header
+
+ # @return [Array<MachO::LoadCommand>] an array of the file's load commands
+ attr_reader :load_commands
+
+ # Creates a new MachOFile instance from a binary string.
+ # @param bin [String] a binary string containing raw Mach-O data
+ # @return [MachO::MachOFile] a new MachOFile
+ 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 Mach-O file to load from
+ # @raise [ArgumentError] if the given filename does not exist
+ def initialize(filename)
+ raise ArgumentError.new("#{filetype}: no such file") unless File.exist?(filename)
+
+ @filename = filename
+ @raw_data = open(@filename, "rb") { |f| f.read }
+ @header = get_mach_header
+ @load_commands = get_load_commands
+ end
+
+ # @api private
+ def initialize_from_bin(bin)
+ @filename = nil
+ @raw_data = bin
+ @header = get_mach_header
+ @load_commands = get_load_commands
+ end
+
+ # The file's raw Mach-O data.
+ # @return [String] the raw Mach-O data
+ def serialize
+ @raw_data
+ end
+
+ # @return [Boolean] true if the Mach-O has 32-bit magic, false otherwise
+ def magic32?
+ MachO.magic32?(header.magic)
+ end
+
+ # @return [Boolean] true if the Mach-O has 64-bit magic, false otherwise
+ def magic64?
+ MachO.magic64?(header.magic)
+ end
+
+ # @return [Boolean] true if the file is of type `MH_OBJECT`, false otherwise
+ def object?
+ header.filetype == MH_OBJECT
+ end
+
+ # @return [Boolean] true if the file is of type `MH_EXECUTE`, false otherwise
+ def executable?
+ header.filetype == MH_EXECUTE
+ end
+
+ # @return [Boolean] true if the file is of type `MH_FVMLIB`, false otherwise
+ def fvmlib?
+ header.filetype == MH_FVMLIB
+ end
+
+ # @return [Boolean] true if the file is of type `MH_CORE`, false otherwise
+ def core?
+ header.filetype == MH_CORE
+ end
+
+ # @return [Boolean] true if the file is of type `MH_PRELOAD`, false otherwise
+ def preload?
+ header.filetype == MH_PRELOAD
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DYLIB`, false otherwise
+ def dylib?
+ header.filetype == MH_DYLIB
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DYLINKER`, false otherwise
+ def dylinker?
+ header.filetype == MH_DYLINKER
+ end
+
+ # @return [Boolean] true if the file is of type `MH_BUNDLE`, false otherwise
+ def bundle?
+ header.filetype == MH_BUNDLE
+ end
+
+ # @return [Boolean] true if the file is of type `MH_DSYM`, false otherwise
+ def dsym?
+ header.filetype == MH_DSYM
+ end
+
+ # @return [Boolean] true if the file is of type `MH_KEXT_BUNDLE`, false otherwise
+ def kext?
+ header.filetype == MH_KEXT_BUNDLE
+ end
+
+ # @return [Fixnum] the file's magic number
+ def magic
+ header.magic
+ end
+
+ # @return [String] a string representation of the file's magic number
+ def magic_string
+ MH_MAGICS[magic]
+ end
+
+ # @return [String] a string representation of the Mach-O's filetype
+ def filetype
+ MH_FILETYPES[header.filetype]
+ end
+
+ # @return [String] a string 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
+ def cpusubtype
+ CPU_SUBTYPES[header.cpusubtype]
+ end
+
+ # @return [Fixnum] the number of load commands in the Mach-O's header
+ def ncmds
+ header.ncmds
+ end
+
+ # @return [Fixnum] the size of all load commands, in bytes
+ def sizeofcmds
+ header.sizeofcmds
+ end
+
+ # @return [Fixnum] execution flags set by the linker
+ def flags
+ header.flags
+ end
+
+ # All load commands of a given name.
+ # @example
+ # file.command("LC_LOAD_DYLIB")
+ # file[:LC_LOAD_DYLIB]
+ # @param [String, Symbol] name the load command ID
+ # @return [Array<MachO::LoadCommand>] an array of LoadCommands corresponding to `name`
+ def command(name)
+ load_commands.select { |lc| lc.type == name.to_sym }
+ end
+
+ alias :[] :command
+
+ # All load commands responsible for loading dylibs.
+ # @return [Array<MachO::DylibCommand>] an array of DylibCommands
+ def dylib_load_commands
+ load_commands.select { |lc| DYLIB_LOAD_COMMANDS.include?(lc.type) }
+ end
+
+ # All segment load commands in the Mach-O.
+ # @return [Array<MachO::SegmentCommand>] if the Mach-O is 32-bit
+ # @return [Array<MachO::SegmentCommand64>] if the Mach-O is 64-bit
+ def segments
+ if magic32?
+ command(:LC_SEGMENT)
+ else
+ command(:LC_SEGMENT_64)
+ end
+ end
+
+ # The Mach-O's dylib ID, or `nil` if not a dylib.
+ # @example
+ # file.dylib_id # => 'libBar.dylib'
+ # @return [String, nil] the Mach-O's dylib ID
+ def dylib_id
+ if !dylib?
+ return nil
+ end
+
+ dylib_id_cmd = command(:LC_ID_DYLIB).first
+
+ dylib_id_cmd.name.to_s
+ end
+
+ # Changes the Mach-O's dylib ID to `new_id`. Does nothing if not a dylib.
+ # @example
+ # file.dylib_id = "libFoo.dylib"
+ # @param new_id [String] the dylib's new ID
+ # @return [void]
+ # @raise [ArgumentError] if `new_id` is not a String
+ def dylib_id=(new_id)
+ if !new_id.is_a?(String)
+ raise ArgumentError.new("argument must be a String")
+ end
+
+ if !dylib?
+ return nil
+ end
+
+ dylib_cmd = command(:LC_ID_DYLIB).first
+ old_id = dylib_id
+
+ set_name_in_dylib(dylib_cmd, old_id, new_id)
+ end
+
+ # 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)
+ end
+
+ # Changes the shared library `old_name` to `new_name`
+ # @example
+ # file.change_install_name("/usr/lib/libWhatever.dylib", "/usr/local/lib/libWhatever2.dylib")
+ # @param old_name [String] the shared library's old name
+ # @param new_name [String] the shared library's new name
+ # @return [void]
+ # @raise [MachO::DylibUnknownError] if no shared library has the old name
+ def change_install_name(old_name, new_name)
+ dylib_cmd = dylib_load_commands.find { |d| d.name.to_s == old_name }
+ raise DylibUnknownError.new(old_name) if dylib_cmd.nil?
+
+ set_name_in_dylib(dylib_cmd, old_name, new_name)
+ end
+
+ alias :change_dylib :change_install_name
+
+ # All runtime paths searched by the dynamic linker for the Mach-O.
+ # @return [Array<String>] an array of all runtime paths
+ def rpaths
+ command(:LC_RPATH).map(&:path).map(&:to_s)
+ end
+
+ # Changes the runtime path `old_path` to `new_path`
+ # @example
+ # file.change_rpath("/usr/lib", "/usr/local/lib")
+ # @param old_path [String] the old runtime path
+ # @param new_path [String] the new runtime path
+ # @return [void]
+ # @raise [MachO::RpathUnknownError] if no such old runtime path exists
+ # @api private
+ def change_rpath(old_path, new_path)
+ rpath_cmd = command(:LC_RPATH).find { |r| r.path.to_s == old_path }
+ raise RpathUnknownError.new(old_path) if rpath_cmd.nil?
+
+ set_path_in_rpath(rpath_cmd, old_path, new_path)
+ end
+
+ # All sections of the segment `segment`.
+ # @param segment [MachO::SegmentCommand, MachO::SegmentCommand64] the segment being inspected
+ # @return [Array<MachO::Section>] if the Mach-O is 32-bit
+ # @return [Array<MachO::Section64>] if the Mach-O is 64-bit
+ def sections(segment)
+ sections = []
+
+ if !segment.is_a?(SegmentCommand) && !segment.is_a?(SegmentCommand64)
+ raise ArgumentError.new("not a valid segment")
+ end
+
+ if segment.nsects.zero?
+ return sections
+ end
+
+ offset = segment.offset + segment.class.bytesize
+
+ segment.nsects.times do
+ if segment.is_a? SegmentCommand
+ sections << Section.new_from_bin(@raw_data.slice(offset, Section.bytesize))
+ offset += Section.bytesize
+ else
+ sections << Section64.new_from_bin(@raw_data.slice(offset, Section64.bytesize))
+ offset += Section64.bytesize
+ end
+ end
+
+ sections
+ end
+
+ # Write all Mach-O data to the given filename.
+ # @param filename [String] the file to write to
+ # @return [void]
+ def write(filename)
+ File.open(filename, "wb") { |f| f.write(@raw_data) }
+ 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!
+ def write!
+ 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
+
+ # 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
+ # @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
+ end
+
+ # The file's magic number.
+ # @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
+ magic = @raw_data[0..3].unpack("N").first
+
+ raise MagicError.new(magic) unless MachO.magic?(magic)
+ raise FatBinaryError.new if MachO.fat_magic?(magic)
+
+ magic
+ end
+
+ # The file's CPU type.
+ # @return [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
+
+ 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
+ # @private
+ def get_cpusubtype
+ cpusubtype = @raw_data[8..11].unpack("V").first
+ cpusubtype &= ~CPU_SUBTYPE_LIB64 # this mask isn't documented!
+
+ raise CPUSubtypeError.new(cpusubtype) unless CPU_SUBTYPES.key?(cpusubtype)
+
+ cpusubtype
+ end
+
+ # The file's type.
+ # @return [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
+
+ 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.
+ # @return [Array<MachO::LoadCommand>] an array of load commands
+ # @raise [MachO::LoadCommandError] if an unknown load command is encountered
+ # @private
+ def get_load_commands
+ offset = header.class.bytesize
+ load_commands = []
+
+ header.ncmds.times do
+ cmd = @raw_data.slice(offset, 4).unpack("V").first
+ cmd_sym = LOAD_COMMANDS[cmd]
+
+ raise LoadCommandError.new(cmd) if cmd_sym.nil?
+
+ # 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))
+
+ load_commands << command
+ offset += command.cmdsize
+ end
+
+ load_commands
+ end
+
+ # Updates the size of all load commands in the raw data.
+ # @param size [Fixnum] the new size, in bytes
+ # @return [void]
+ # @private
+ def set_sizeofcmds(size)
+ new_size = [size].pack("V")
+ @raw_data[20..23] = new_size
+ end
+
+ # Updates the `name` field in a DylibCommand.
+ # @param dylib_cmd [MachO::DylibCommand] the dylib command
+ # @param old_name [String] the old dylib name
+ # @param new_name [String] the new dylib name
+ # @return [void]
+ # @private
+ def set_name_in_dylib(dylib_cmd, old_name, new_name)
+ set_lc_str_in_cmd(dylib_cmd, dylib_cmd.name, old_name, new_name)
+ end
+
+ # Updates the `path` field in an RpathCommand.
+ # @param rpath_cmd [MachO::RpathCommand] the rpath command
+ # @param old_path [String] the old runtime name
+ # @param new_path [String] the new runtime name
+ # @return [void]
+ # @private
+ def set_path_in_rpath(rpath_cmd, old_path, new_path)
+ set_lc_str_in_cmd(rpath_cmd, rpath_cmd.path, old_path, new_path)
+ end
+
+ # Updates a generic LCStr field in any LoadCommand.
+ # @param cmd [MachO::LoadCommand] the load command
+ # @param lc_str [MachO::LoadCommand::LCStr] the load command string
+ # @param old_str [String] the old string
+ # @param new_str [String] the new string
+ # @raise [MachO::HeaderPadError] if the new name exceeds the header pad buffer
+ # @private
+ def set_lc_str_in_cmd(cmd, lc_str, old_str, new_str)
+ if magic32?
+ cmd_round = 4
+ else
+ cmd_round = 8
+ end
+
+ new_sizeofcmds = header.sizeofcmds
+ old_str = old_str.dup
+ new_str = new_str.dup
+
+ old_pad = MachO.round(old_str.size + 1, cmd_round) - old_str.size
+ new_pad = MachO.round(new_str.size + 1, cmd_round) - new_str.size
+
+ # pad the old and new IDs with null bytes to meet command bounds
+ old_str << "\x00" * old_pad
+ new_str << "\x00" * new_pad
+
+ # calculate the new size of the cmd and sizeofcmds in MH
+ new_size = cmd.class.bytesize + new_str.size
+ new_sizeofcmds += new_size - cmd.cmdsize
+
+ low_fileoff = 2**64 # ULLONGMAX
+
+ # 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
+
+ low_fileoff = sect.offset
+ end
+ end
+ end
+
+ if new_sizeofcmds + header.class.bytesize > low_fileoff
+ raise HeaderPadError.new(@filename)
+ end
+
+ # update sizeofcmds in mach_header
+ set_sizeofcmds(new_sizeofcmds)
+
+ # update cmdsize in the cmd
+ @raw_data[cmd.offset + 4, 4] = [new_size].pack("V")
+
+ # delete the old str
+ @raw_data.slice!(cmd.offset + lc_str.to_i...cmd.offset + cmd.class.bytesize + old_str.size)
+
+ # insert the new str
+ @raw_data.insert(cmd.offset + lc_str.to_i, new_str)
+
+ # pad/unpad after new_sizeofcmds until offsets are corrected
+ null_pad = old_str.size - new_str.size
+
+ if null_pad < 0
+ @raw_data.slice!(new_sizeofcmds + header.class.bytesize, null_pad.abs)
+ else
+ @raw_data.insert(new_sizeofcmds + header.class.bytesize, "\x00" * null_pad)
+ end
+
+ # synchronize fields with the raw data
+ @header = get_mach_header
+ @load_commands = get_load_commands
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/open.rb b/Library/Homebrew/vendor/macho/macho/open.rb
new file mode 100644
index 000000000..2c5fc0469
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/open.rb
@@ -0,0 +1,16 @@
+module MachO
+ # Opens the given filename as a MachOFile or FatFile, depending on its magic.
+ # @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
+ def self.open(filename)
+ # open file and test magic instead of using exceptions for control?
+ begin
+ file = MachOFile.new(filename)
+ rescue FatBinaryError
+ file = FatFile.new(filename)
+ end
+
+ file
+ end
+end \ No newline at end of file
diff --git a/Library/Homebrew/vendor/macho/macho/sections.rb b/Library/Homebrew/vendor/macho/macho/sections.rb
new file mode 100644
index 000000000..8a3cbac02
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/sections.rb
@@ -0,0 +1,159 @@
+module MachO
+ # type mask
+ SECTION_TYPE = 0x000000ff
+
+ # attributes mask
+ SECTION_ATTRIBUTES = 0xffffff00
+
+ # user settable attributes mask
+ SECTION_ATTRIBUTES_USR = 0xff000000
+
+ # system settable attributes mask
+ SECTION_ATTRIBUTES_SYS = 0x00ffff00
+
+ # association of section flag symbols to values
+ # @api private
+ SECTION_FLAGS = {
+ :S_REGULAR => 0x0,
+ :S_ZEROFILL => 0x1,
+ :S_CSTRING_LITERALS => 0x2,
+ :S_4BYTE_LITERALS => 0x3,
+ :S_8BYTE_LITERALS => 0x4,
+ :S_LITERAL_POINTERS => 0x5,
+ :S_NON_LAZY_SYMBOL_POINTERS => 0x6,
+ :S_LAZY_SYMBOL_POINTERS => 0x7,
+ :S_SYMBOL_STUBS => 0x8,
+ :S_MOD_INIT_FUNC_POINTERS => 0x9,
+ :S_MOD_TERM_FUNC_POINTERS => 0xa,
+ :S_COALESCED => 0xb,
+ :S_GB_ZEROFILE => 0xc,
+ :S_INTERPOSING => 0xd,
+ :S_16BYTE_LITERALS => 0xe,
+ :S_DTRACE_DOF => 0xf,
+ :S_LAZY_DYLIB_SYMBOL_POINTERS => 0x10,
+ :S_THREAD_LOCAL_REGULAR => 0x11,
+ :S_THREAD_LOCAL_ZEROFILL => 0x12,
+ :S_THREAD_LOCAL_VARIABLES => 0x13,
+ :S_THREAD_LOCAL_VARIABLE_POINTERS => 0x14,
+ :S_THREAD_LOCAL_INIT_FUNCTION_POINTERS => 0x15,
+ :S_ATTR_PURE_INSTRUCTIONS => 0x80000000,
+ :S_ATTR_NO_TOC => 0x40000000,
+ :S_ATTR_STRIP_STATIC_SYMS => 0x20000000,
+ :S_ATTR_NO_DEAD_STRIP => 0x10000000,
+ :S_ATTR_LIVE_SUPPORT => 0x08000000,
+ :S_ATTR_SELF_MODIFYING_CODE => 0x04000000,
+ :S_ATTR_DEBUG => 0x02000000,
+ :S_ATTR_SOME_INSTRUCTIONS => 0x00000400,
+ :S_ATTR_EXT_RELOC => 0x00000200,
+ :S_ATTR_LOC_RELOC => 0x00000100
+ }
+
+ # association of section name symbols to names
+ # @api private
+ SECTION_NAMES = {
+ :SECT_TEXT => "__text",
+ :SECT_FVMLIB_INIT0 => "__fvmlib_init0",
+ :SECT_FVMLIB_INIT1 => "__fvmlib_init1",
+ :SECT_DATA => "__data",
+ :SECT_BSS => "__bss",
+ :SECT_COMMON => "__common",
+ :SECT_OBJC_SYMBOLS => "__symbol_table",
+ :SECT_OBJC_MODULES => "__module_info",
+ :SECT_OBJC_STRINGS => "__selector_strs",
+ :SECT_OBJC_REFS => "__selector_refs",
+ :SECT_ICON_HEADER => "__header",
+ :SECT_ICON_TIFF => "__tiff"
+ }
+
+ # Represents a section of a segment for 32-bit architectures.
+ class Section < MachOStructure
+ # @return [String] the name of the section, including null pad bytes
+ attr_reader :sectname
+
+ # @return [String] the name of the segment's section, including null pad bytes
+ attr_reader :segname
+
+ # @return [Fixnum] the memory address of the section
+ attr_reader :addr
+
+ # @return [Fixnum] the size, in bytes, of the section
+ attr_reader :size
+
+ # @return [Fixnum] the file offset of the section
+ attr_reader :offset
+
+ # @return [Fixnum] the section alignment (power of 2) of the section
+ attr_reader :align
+
+ # @return [Fixnum] the file offset of the section's relocation entries
+ attr_reader :reloff
+
+ # @return [Fixnum] the number of relocation entries
+ attr_reader :nreloc
+
+ # @return [Fixnum] flags for type and addrributes of the section
+ attr_reader :flags
+
+ # @return [void] reserved (for offset or index)
+ attr_reader :reserved1
+
+ # @return [void] reserved (for count or sizeof)
+ attr_reader :reserved2
+
+ FORMAT = "a16a16VVVVVVVVV"
+ SIZEOF = 68
+
+ # @api private
+ def initialize(sectname, segname, addr, size, offset, align, reloff,
+ nreloc, flags, reserved1, reserved2)
+ @sectname = sectname
+ @segname = segname
+ @addr = addr
+ @size = size
+ @offset = offset
+ @align = align
+ @reloff = reloff
+ @nreloc = nreloc
+ @flags = flags
+ @reserved1 = reserved1
+ @reserved2 = reserved2
+ end
+
+ # @return [String] the section's name, with any trailing NULL characters removed
+ def section_name
+ @sectname.delete("\x00")
+ end
+
+ # @return [String] the parent segment's name, with any trailing NULL characters removed
+ def segment_name
+ @segname.delete("\x00")
+ end
+
+ # @example
+ # puts "this section is regular" if sect.flag?(:S_REGULAR)
+ # @param flag [Symbol] a section flag symbol
+ # @return [Boolean] true if `flag` is present in the section's flag field
+ def flag?(flag)
+ flag = SECTION_FLAGS[flag]
+ return false if flag.nil?
+ flags & flag == flag
+ end
+ end
+
+ # Represents a section of a segment for 64-bit architectures.
+ class Section64 < Section
+ # @return [void] reserved
+ attr_reader :reserved3
+
+ FORMAT = "a16a16QQVVVVVVVV"
+ SIZEOF = 80
+
+ # @api private
+ def initialize(sectname, segname, addr, size, offset, align, reloff,
+ nreloc, flags, reserved1, reserved2, reserved3)
+ super(sectname, segname, addr, size, offset, align, reloff,
+ nreloc, flags, reserved1, reserved2)
+ @reserved3 = reserved3
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/structure.rb b/Library/Homebrew/vendor/macho/macho/structure.rb
new file mode 100644
index 000000000..77aa18852
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/structure.rb
@@ -0,0 +1,22 @@
+module MachO
+ # A general purpose pseudo-structure.
+ # @abstract
+ class MachOStructure
+ # The format of the data structure, in String#unpack format.
+ FORMAT = ""
+
+ # The size of the data structure, in bytes.
+ SIZEOF = 0
+
+ # @return [Fixnum] the size, in bytes, of the represented structure.
+ def self.bytesize
+ self::SIZEOF
+ end
+
+ # @return [MachO::MachOStructure] a new MachOStructure initialized with `bin`
+ # @api private
+ def self.new_from_bin(bin)
+ self.new(*bin.unpack(self::FORMAT))
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/tools.rb b/Library/Homebrew/vendor/macho/macho/tools.rb
new file mode 100644
index 000000000..18f20fb80
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/tools.rb
@@ -0,0 +1,65 @@
+module MachO
+ # A collection of convenient methods for common operations on Mach-O and Fat binaries.
+ module Tools
+ # @param filename [String] the Mach-O or Fat binary being read
+ # @return [Array<String>] an array of all dylibs linked to the binary
+ def self.dylibs(filename)
+ file = MachO.open(filename)
+
+ file.linked_dylibs
+ end
+
+ # Changes the dylib ID of a Mach-O or Fat binary, overwriting the source file.
+ # @param filename [String] the Mach-O or Fat binary being modified
+ # @param new_id [String] the new dylib ID for the binary
+ # @return [void]
+ # @todo unstub for fat files
+ def self.change_dylib_id(filename, new_id)
+ file = MachO.open(filename)
+
+ file.dylib_id = new_id
+ file.write!
+ end
+
+ # Changes a shared library install name in a Mach-O or Fat binary, overwriting the source file.
+ # @param filename [String] the Mach-O or Fat binary being modified
+ # @param old_name [String] the old shared library name
+ # @param new_name [String] the new shared library name
+ # @return [void]
+ # @todo unstub for fat files
+ def self.change_install_name(filename, old_name, new_name)
+ file = MachO.open(filename)
+
+ file.change_install_name(old_name, new_name)
+ file.write!
+ end
+
+ # Changes a runtime path in a Mach-O or Fat binary, overwriting the source file.
+ # @param filename [String] the Mach-O or Fat binary being modified
+ # @param old_path [String] the old runtime path
+ # @param new_path [String] the new runtime path
+ # @return [void]
+ # @todo unstub
+ def self.change_rpath(filename, old_path, new_path)
+ raise "stub"
+ end
+
+ # Add a runtime path to a Mach-O or Fat binary, overwriting the source file.
+ # @param filename [String] the Mach-O or Fat binary being modified
+ # @param new_path [String] the new runtime path
+ # @return [void]
+ # @todo unstub
+ def self.add_rpath(filename, new_path)
+ raise "stub"
+ end
+
+ # Delete a runtime path from a Mach-O or Fat binary, overwriting the source file.
+ # @param filename [String] the Mach-O or Fat binary being modified
+ # @param old_path [String] the old runtime path
+ # @return [void]
+ # @todo unstub
+ def self.delete_rpath(filename, old_path)
+ raise "stub"
+ end
+ end
+end
diff --git a/Library/Homebrew/vendor/macho/macho/utils.rb b/Library/Homebrew/vendor/macho/macho/utils.rb
new file mode 100644
index 000000000..3b06cc125
--- /dev/null
+++ b/Library/Homebrew/vendor/macho/macho/utils.rb
@@ -0,0 +1,36 @@
+module MachO
+ # @param value [Fixnum] the number being rounded
+ # @param round [Fixnum] the number being rounded with
+ # @return [Fixnum] the next number >= `value` such that `round` is its divisor
+ # @see http://www.opensource.apple.com/source/cctools/cctools-870/libstuff/rnd.c
+ def self.round(value, round)
+ round -= 1
+ value += round
+ value &= ~round
+ value
+ end
+
+ # @param num [Fixnum] the number being checked
+ # @return [Boolean] true if `num` is a valid Mach-O magic number, false otherwise
+ def self.magic?(num)
+ MH_MAGICS.has_key?(num)
+ end
+
+ # @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
+ end
+
+ # @param num [Fixnum] the number being checked
+ # @return [Boolean] true if `num` is a valid 32-bit magic number, false otherwise
+ def self.magic32?(num)
+ num == MH_MAGIC || num == MH_CIGAM
+ end
+
+ # @param num [Fixnum] the number being checked
+ # @return [Boolean] true if `num` is a valid 64-bit magic number, false otherwise
+ def self.magic64?(num)
+ num == MH_MAGIC_64 || num == MH_CIGAM_64
+ end
+end