vendor: Update ruby-macho to 1.1.0.
This commit is contained in:
parent
422afa0b49
commit
024264c381
4
Library/Homebrew/vendor/README.md
vendored
4
Library/Homebrew/vendor/README.md
vendored
@ -3,7 +3,7 @@ Vendored Dependencies
|
|||||||
|
|
||||||
* [plist](https://github.com/bleything/plist), version 3.1.0
|
* [plist](https://github.com/bleything/plist), version 3.1.0
|
||||||
|
|
||||||
* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 0.2.6
|
* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 1.1.0
|
||||||
|
|
||||||
## Licenses:
|
## Licenses:
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ Vendored Dependencies
|
|||||||
### ruby-macho
|
### ruby-macho
|
||||||
|
|
||||||
> The MIT License
|
> The MIT License
|
||||||
> Copyright (c) 2015, 2016 William Woodruff <william @ tuffbizz.com>
|
> Copyright (c) 2015, 2016, 2017 William Woodruff <william @ tuffbizz.com>
|
||||||
>
|
>
|
||||||
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
> Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
> of this software and associated documentation files (the "Software"), to deal
|
> of this software and associated documentation files (the "Software"), to deal
|
||||||
|
27
Library/Homebrew/vendor/macho/macho.rb
vendored
27
Library/Homebrew/vendor/macho/macho.rb
vendored
@ -5,7 +5,6 @@ require "#{File.dirname(__FILE__)}/macho/load_commands"
|
|||||||
require "#{File.dirname(__FILE__)}/macho/sections"
|
require "#{File.dirname(__FILE__)}/macho/sections"
|
||||||
require "#{File.dirname(__FILE__)}/macho/macho_file"
|
require "#{File.dirname(__FILE__)}/macho/macho_file"
|
||||||
require "#{File.dirname(__FILE__)}/macho/fat_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/exceptions"
|
||||||
require "#{File.dirname(__FILE__)}/macho/utils"
|
require "#{File.dirname(__FILE__)}/macho/utils"
|
||||||
require "#{File.dirname(__FILE__)}/macho/tools"
|
require "#{File.dirname(__FILE__)}/macho/tools"
|
||||||
@ -13,5 +12,29 @@ require "#{File.dirname(__FILE__)}/macho/tools"
|
|||||||
# The primary namespace for ruby-macho.
|
# The primary namespace for ruby-macho.
|
||||||
module MachO
|
module MachO
|
||||||
# release version
|
# release version
|
||||||
VERSION = "0.2.6".freeze
|
VERSION = "1.1.0".freeze
|
||||||
|
|
||||||
|
# Opens the given filename as a MachOFile or FatFile, depending on its magic.
|
||||||
|
# @param filename [String] the file being opened
|
||||||
|
# @return [MachOFile] if the file is a Mach-O
|
||||||
|
# @return [FatFile] if the file is a Fat file
|
||||||
|
# @raise [ArgumentError] if the given file does not exist
|
||||||
|
# @raise [TruncatedFileError] if the file is too small to have a valid header
|
||||||
|
# @raise [MagicError] if the file's magic is not valid Mach-O magic
|
||||||
|
def self.open(filename)
|
||||||
|
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
||||||
|
raise TruncatedFileError unless File.stat(filename).size >= 4
|
||||||
|
|
||||||
|
magic = File.open(filename, "rb") { |f| f.read(4) }.unpack("N").first
|
||||||
|
|
||||||
|
if Utils.fat_magic?(magic)
|
||||||
|
file = FatFile.new(filename)
|
||||||
|
elsif Utils.magic?(magic)
|
||||||
|
file = MachOFile.new(filename)
|
||||||
|
else
|
||||||
|
raise MagicError, magic
|
||||||
|
end
|
||||||
|
|
||||||
|
file
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -80,7 +80,8 @@ module MachO
|
|||||||
# @param cputype [Fixnum] the CPU type of the unknown pair
|
# @param cputype [Fixnum] the CPU type of the unknown pair
|
||||||
# @param cpusubtype [Fixnum] the CPU sub-type of the unknown pair
|
# @param cpusubtype [Fixnum] the CPU sub-type of the unknown pair
|
||||||
def initialize(cputype, cpusubtype)
|
def initialize(cputype, cpusubtype)
|
||||||
super "Unrecognized CPU sub-type: 0x#{"%08x" % cpusubtype} (for CPU type: 0x#{"%08x" % cputype})"
|
super "Unrecognized CPU sub-type: 0x#{"%08x" % cpusubtype}" \
|
||||||
|
" (for CPU type: 0x#{"%08x" % cputype})"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -108,13 +109,15 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Raised when the number of arguments used to create a load command manually is wrong.
|
# Raised when the number of arguments used to create a load command manually
|
||||||
|
# is wrong.
|
||||||
class LoadCommandCreationArityError < MachOError
|
class LoadCommandCreationArityError < MachOError
|
||||||
# @param cmd_sym [Symbol] the load command's symbol
|
# @param cmd_sym [Symbol] the load command's symbol
|
||||||
# @param expected_arity [Fixnum] the number of arguments expected
|
# @param expected_arity [Fixnum] the number of arguments expected
|
||||||
# @param actual_arity [Fixnum] the number of arguments received
|
# @param actual_arity [Fixnum] the number of arguments received
|
||||||
def initialize(cmd_sym, expected_arity, actual_arity)
|
def initialize(cmd_sym, expected_arity, actual_arity)
|
||||||
super "Expected #{expected_arity} arguments for #{cmd_sym} creation, got #{actual_arity}"
|
super "Expected #{expected_arity} arguments for #{cmd_sym} creation," \
|
||||||
|
" got #{actual_arity}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -130,7 +133,8 @@ module MachO
|
|||||||
class LCStrMalformedError < MachOError
|
class LCStrMalformedError < MachOError
|
||||||
# @param lc [MachO::LoadCommand] the load command containing the string
|
# @param lc [MachO::LoadCommand] the load command containing the string
|
||||||
def initialize(lc)
|
def initialize(lc)
|
||||||
super "Load command #{lc.type} at offset #{lc.view.offset} contains a malformed string"
|
super "Load command #{lc.type} at offset #{lc.view.offset} contains a" \
|
||||||
|
" malformed string"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
200
Library/Homebrew/vendor/macho/macho/fat_file.rb
vendored
200
Library/Homebrew/vendor/macho/macho/fat_file.rb
vendored
@ -1,24 +1,50 @@
|
|||||||
|
require "forwardable"
|
||||||
|
|
||||||
module MachO
|
module MachO
|
||||||
# Represents a "Fat" file, which contains a header, a listing of available
|
# Represents a "Fat" file, which contains a header, a listing of available
|
||||||
# architectures, and one or more Mach-O binaries.
|
# architectures, and one or more Mach-O binaries.
|
||||||
# @see https://en.wikipedia.org/wiki/Mach-O#Multi-architecture_binaries
|
# @see https://en.wikipedia.org/wiki/Mach-O#Multi-architecture_binaries
|
||||||
# @see MachO::MachOFile
|
# @see MachOFile
|
||||||
class FatFile
|
class FatFile
|
||||||
|
extend Forwardable
|
||||||
|
|
||||||
# @return [String] the filename loaded from, or nil if loaded from a binary string
|
# @return [String] the filename loaded from, or nil if loaded from a binary string
|
||||||
attr_accessor :filename
|
attr_accessor :filename
|
||||||
|
|
||||||
# @return [MachO::FatHeader] the file's header
|
# @return [Headers::FatHeader] the file's header
|
||||||
attr_reader :header
|
attr_reader :header
|
||||||
|
|
||||||
# @return [Array<MachO::FatArch>] an array of fat architectures
|
# @return [Array<Headers::FatArch>] an array of fat architectures
|
||||||
attr_reader :fat_archs
|
attr_reader :fat_archs
|
||||||
|
|
||||||
# @return [Array<MachO::MachOFile>] an array of Mach-O binaries
|
# @return [Array<MachOFile>] an array of Mach-O binaries
|
||||||
attr_reader :machos
|
attr_reader :machos
|
||||||
|
|
||||||
|
# Creates a new FatFile from the given (single-arch) Mach-Os
|
||||||
|
# @param machos [Array<MachOFile>] the machos to combine
|
||||||
|
# @return [FatFile] a new FatFile containing the give machos
|
||||||
|
def self.new_from_machos(*machos)
|
||||||
|
header = Headers::FatHeader.new(Headers::FAT_MAGIC, machos.size)
|
||||||
|
offset = Headers::FatHeader.bytesize + (machos.size * Headers::FatArch.bytesize)
|
||||||
|
fat_archs = []
|
||||||
|
machos.each do |macho|
|
||||||
|
fat_archs << Headers::FatArch.new(macho.header.cputype,
|
||||||
|
macho.header.cpusubtype,
|
||||||
|
offset, macho.serialize.bytesize,
|
||||||
|
macho.alignment)
|
||||||
|
offset += macho.serialize.bytesize
|
||||||
|
end
|
||||||
|
|
||||||
|
bin = header.serialize
|
||||||
|
bin << fat_archs.map(&:serialize).join
|
||||||
|
bin << machos.map(&:serialize).join
|
||||||
|
|
||||||
|
new_from_bin(bin)
|
||||||
|
end
|
||||||
|
|
||||||
# Creates a new FatFile instance from a binary string.
|
# Creates a new FatFile instance from a binary string.
|
||||||
# @param bin [String] a binary string containing raw Mach-O data
|
# @param bin [String] a binary string containing raw Mach-O data
|
||||||
# @return [MachO::FatFile] a new FatFile
|
# @return [FatFile] a new FatFile
|
||||||
def self.new_from_bin(bin)
|
def self.new_from_bin(bin)
|
||||||
instance = allocate
|
instance = allocate
|
||||||
instance.initialize_from_bin(bin)
|
instance.initialize_from_bin(bin)
|
||||||
@ -38,7 +64,7 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Initializes a new FatFile instance from a binary string.
|
# Initializes a new FatFile instance from a binary string.
|
||||||
# @see MachO::FatFile.new_from_bin
|
# @see new_from_bin
|
||||||
# @api private
|
# @api private
|
||||||
def initialize_from_bin(bin)
|
def initialize_from_bin(bin)
|
||||||
@filename = nil
|
@filename = nil
|
||||||
@ -52,70 +78,41 @@ module MachO
|
|||||||
@raw_data
|
@raw_data
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] true if the file is of type `MH_OBJECT`, false otherwise
|
# @!method object?
|
||||||
def object?
|
# @return (see MachO::MachOFile#object?)
|
||||||
machos.first.object?
|
# @!method executable?
|
||||||
end
|
# @return (see MachO::MachOFile#executable?)
|
||||||
|
# @!method fvmlib?
|
||||||
|
# @return (see MachO::MachOFile#fvmlib?)
|
||||||
|
# @!method core?
|
||||||
|
# @return (see MachO::MachOFile#core?)
|
||||||
|
# @!method preload?
|
||||||
|
# @return (see MachO::MachOFile#preload?)
|
||||||
|
# @!method dylib?
|
||||||
|
# @return (see MachO::MachOFile#dylib?)
|
||||||
|
# @!method dylinker?
|
||||||
|
# @return (see MachO::MachOFile#dylinker?)
|
||||||
|
# @!method bundle?
|
||||||
|
# @return (see MachO::MachOFile#bundle?)
|
||||||
|
# @!method dsym?
|
||||||
|
# @return (see MachO::MachOFile#dsym?)
|
||||||
|
# @!method kext?
|
||||||
|
# @return (see MachO::MachOFile#kext?)
|
||||||
|
# @!method filetype
|
||||||
|
# @return (see MachO::MachOFile#filetype)
|
||||||
|
# @!method dylib_id
|
||||||
|
# @return (see MachO::MachOFile#dylib_id)
|
||||||
|
def_delegators :canonical_macho, :object?, :executable?, :fvmlib?,
|
||||||
|
:core?, :preload?, :dylib?, :dylinker?, :bundle?,
|
||||||
|
:dsym?, :kext?, :filetype, :dylib_id
|
||||||
|
|
||||||
# @return [Boolean] true if the file is of type `MH_EXECUTE`, false otherwise
|
# @!method magic
|
||||||
def executable?
|
# @return (see MachO::Headers::FatHeader#magic)
|
||||||
machos.first.executable?
|
def_delegators :header, :magic
|
||||||
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
|
# @return [String] a string representation of the file's magic number
|
||||||
def magic_string
|
def magic_string
|
||||||
MH_MAGICS[magic]
|
Headers::MH_MAGICS[magic]
|
||||||
end
|
|
||||||
|
|
||||||
# The file's type. Assumed to be the same for every Mach-O within.
|
|
||||||
# @return [Symbol] the filetype
|
|
||||||
def filetype
|
|
||||||
machos.first.filetype
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Populate the instance's fields with the raw Fat Mach-O data.
|
# Populate the instance's fields with the raw Fat Mach-O data.
|
||||||
@ -128,21 +125,13 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# All load commands responsible for loading dylibs in the file's Mach-O's.
|
# All load commands responsible for loading dylibs in the file's Mach-O's.
|
||||||
# @return [Array<MachO::DylibCommand>] an array of DylibCommands
|
# @return [Array<LoadCommands::DylibCommand>] an array of DylibCommands
|
||||||
def dylib_load_commands
|
def dylib_load_commands
|
||||||
machos.map(&:dylib_load_commands).flatten
|
machos.map(&:dylib_load_commands).flatten
|
||||||
end
|
end
|
||||||
|
|
||||||
# The file's dylib ID. If the file is not a dylib, returns `nil`.
|
# Changes the file's dylib ID to `new_id`. If the file is not a dylib,
|
||||||
# @example
|
# does nothing.
|
||||||
# file.dylib_id # => 'libBar.dylib'
|
|
||||||
# @return [String, nil] the file's dylib ID
|
|
||||||
# @see MachO::MachOFile#linked_dylibs
|
|
||||||
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
|
# @example
|
||||||
# file.change_dylib_id('libFoo.dylib')
|
# file.change_dylib_id('libFoo.dylib')
|
||||||
# @param new_id [String] the new dylib ID
|
# @param new_id [String] the new dylib ID
|
||||||
@ -151,7 +140,7 @@ module MachO
|
|||||||
# if false, fail only if all slices fail.
|
# if false, fail only if all slices fail.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [ArgumentError] if `new_id` is not a String
|
# @raise [ArgumentError] if `new_id` is not a String
|
||||||
# @see MachO::MachOFile#linked_dylibs
|
# @see MachOFile#linked_dylibs
|
||||||
def change_dylib_id(new_id, options = {})
|
def change_dylib_id(new_id, options = {})
|
||||||
raise ArgumentError, "argument must be a String" unless new_id.is_a?(String)
|
raise ArgumentError, "argument must be a String" unless new_id.is_a?(String)
|
||||||
return unless machos.all?(&:dylib?)
|
return unless machos.all?(&:dylib?)
|
||||||
@ -167,7 +156,7 @@ module MachO
|
|||||||
|
|
||||||
# All shared libraries linked to the file's Mach-Os.
|
# All shared libraries linked to the file's Mach-Os.
|
||||||
# @return [Array<String>] an array of all shared libraries
|
# @return [Array<String>] an array of all shared libraries
|
||||||
# @see MachO::MachOFile#linked_dylibs
|
# @see MachOFile#linked_dylibs
|
||||||
def linked_dylibs
|
def linked_dylibs
|
||||||
# Individual architectures in a fat binary can link to different subsets
|
# 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.
|
# of libraries, but at this point we want to have the full picture, i.e.
|
||||||
@ -175,8 +164,9 @@ module MachO
|
|||||||
machos.map(&:linked_dylibs).flatten.uniq
|
machos.map(&:linked_dylibs).flatten.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
# Changes all dependent shared library install names from `old_name` to `new_name`.
|
# Changes all dependent shared library install names from `old_name` to
|
||||||
# In a fat file, this changes install names in all internal Mach-Os.
|
# `new_name`. In a fat file, this changes install names in all internal
|
||||||
|
# Mach-Os.
|
||||||
# @example
|
# @example
|
||||||
# file.change_install_name('/usr/lib/libFoo.dylib', '/usr/lib/libBar.dylib')
|
# file.change_install_name('/usr/lib/libFoo.dylib', '/usr/lib/libBar.dylib')
|
||||||
# @param old_name [String] the shared library name being changed
|
# @param old_name [String] the shared library name being changed
|
||||||
@ -185,7 +175,7 @@ module MachO
|
|||||||
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
||||||
# if false, fail only if all slices fail.
|
# if false, fail only if all slices fail.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @see MachO::MachOFile#change_install_name
|
# @see MachOFile#change_install_name
|
||||||
def change_install_name(old_name, new_name, options = {})
|
def change_install_name(old_name, new_name, options = {})
|
||||||
each_macho(options) do |macho|
|
each_macho(options) do |macho|
|
||||||
macho.change_install_name(old_name, new_name, options)
|
macho.change_install_name(old_name, new_name, options)
|
||||||
@ -198,7 +188,7 @@ module MachO
|
|||||||
|
|
||||||
# All runtime paths associated with the file's Mach-Os.
|
# All runtime paths associated with the file's Mach-Os.
|
||||||
# @return [Array<String>] an array of all runtime paths
|
# @return [Array<String>] an array of all runtime paths
|
||||||
# @see MachO::MachOFile#rpaths
|
# @see MachOFile#rpaths
|
||||||
def rpaths
|
def rpaths
|
||||||
# Can individual architectures have different runtime paths?
|
# Can individual architectures have different runtime paths?
|
||||||
machos.map(&:rpaths).flatten.uniq
|
machos.map(&:rpaths).flatten.uniq
|
||||||
@ -211,7 +201,7 @@ module MachO
|
|||||||
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
||||||
# if false, fail only if all slices fail.
|
# if false, fail only if all slices fail.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @see MachO::MachOFile#change_rpath
|
# @see MachOFile#change_rpath
|
||||||
def change_rpath(old_path, new_path, options = {})
|
def change_rpath(old_path, new_path, options = {})
|
||||||
each_macho(options) do |macho|
|
each_macho(options) do |macho|
|
||||||
macho.change_rpath(old_path, new_path, options)
|
macho.change_rpath(old_path, new_path, options)
|
||||||
@ -226,7 +216,7 @@ module MachO
|
|||||||
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
||||||
# if false, fail only if all slices fail.
|
# if false, fail only if all slices fail.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @see MachO::MachOFile#add_rpath
|
# @see MachOFile#add_rpath
|
||||||
def add_rpath(path, options = {})
|
def add_rpath(path, options = {})
|
||||||
each_macho(options) do |macho|
|
each_macho(options) do |macho|
|
||||||
macho.add_rpath(path, options)
|
macho.add_rpath(path, options)
|
||||||
@ -241,7 +231,7 @@ module MachO
|
|||||||
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
# @option options [Boolean] :strict (true) if true, fail if one slice fails.
|
||||||
# if false, fail only if all slices fail.
|
# if false, fail only if all slices fail.
|
||||||
# @return void
|
# @return void
|
||||||
# @see MachO::MachOFile#delete_rpath
|
# @see MachOFile#delete_rpath
|
||||||
def delete_rpath(path, options = {})
|
def delete_rpath(path, options = {})
|
||||||
each_macho(options) do |macho|
|
each_macho(options) do |macho|
|
||||||
macho.delete_rpath(path, options)
|
macho.delete_rpath(path, options)
|
||||||
@ -254,20 +244,21 @@ module MachO
|
|||||||
# @example
|
# @example
|
||||||
# file.extract(:i386) # => MachO::MachOFile
|
# file.extract(:i386) # => MachO::MachOFile
|
||||||
# @param cputype [Symbol] the CPU type of the Mach-O being extracted
|
# @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
|
# @return [MachOFile, nil] the extracted Mach-O or nil if no Mach-O has the given CPU type
|
||||||
def extract(cputype)
|
def extract(cputype)
|
||||||
machos.select { |macho| macho.cputype == cputype }.first
|
machos.select { |macho| macho.cputype == cputype }.first
|
||||||
end
|
end
|
||||||
|
|
||||||
# Write all (fat) data to the given filename.
|
# Write all (fat) data to the given filename.
|
||||||
# @param filename [String] the file to write to
|
# @param filename [String] the file to write to
|
||||||
|
# @return [void]
|
||||||
def write(filename)
|
def write(filename)
|
||||||
File.open(filename, "wb") { |f| f.write(@raw_data) }
|
File.open(filename, "wb") { |f| f.write(@raw_data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Write all (fat) data to the file used to initialize the instance.
|
# Write all (fat) data to the file used to initialize the instance.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::MachOError] if the instance was initialized without a file
|
# @raise [MachOError] if the instance was initialized without a file
|
||||||
# @note Overwrites all data in the file!
|
# @note Overwrites all data in the file!
|
||||||
def write!
|
def write!
|
||||||
if filename.nil?
|
if filename.nil?
|
||||||
@ -280,17 +271,18 @@ module MachO
|
|||||||
private
|
private
|
||||||
|
|
||||||
# Obtain the fat header from raw file data.
|
# Obtain the fat header from raw file data.
|
||||||
# @return [MachO::FatHeader] the fat header
|
# @return [Headers::FatHeader] the fat header
|
||||||
# @raise [MachO::TruncatedFileError] if the file is too small to have a valid header
|
# @raise [TruncatedFileError] if the file is too small to have a
|
||||||
# @raise [MachO::MagicError] if the magic is not valid Mach-O magic
|
# valid header
|
||||||
# @raise [MachO::MachOBinaryError] if the magic is for a non-fat Mach-O file
|
# @raise [MagicError] if the magic is not valid Mach-O magic
|
||||||
# @raise [MachO::JavaClassFileError] if the file is a Java classfile
|
# @raise [MachOBinaryError] if the magic is for a non-fat Mach-O file
|
||||||
|
# @raise [JavaClassFileError] if the file is a Java classfile
|
||||||
# @api private
|
# @api private
|
||||||
def populate_fat_header
|
def populate_fat_header
|
||||||
# the smallest fat Mach-O header is 8 bytes
|
# the smallest fat Mach-O header is 8 bytes
|
||||||
raise TruncatedFileError if @raw_data.size < 8
|
raise TruncatedFileError if @raw_data.size < 8
|
||||||
|
|
||||||
fh = FatHeader.new_from_bin(:big, @raw_data[0, FatHeader.bytesize])
|
fh = Headers::FatHeader.new_from_bin(:big, @raw_data[0, Headers::FatHeader.bytesize])
|
||||||
|
|
||||||
raise MagicError, fh.magic unless Utils.magic?(fh.magic)
|
raise MagicError, fh.magic unless Utils.magic?(fh.magic)
|
||||||
raise MachOBinaryError unless Utils.fat_magic?(fh.magic)
|
raise MachOBinaryError unless Utils.fat_magic?(fh.magic)
|
||||||
@ -308,22 +300,22 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Obtain an array of fat architectures from raw file data.
|
# Obtain an array of fat architectures from raw file data.
|
||||||
# @return [Array<MachO::FatArch>] an array of fat architectures
|
# @return [Array<Headers::FatArch>] an array of fat architectures
|
||||||
# @api private
|
# @api private
|
||||||
def populate_fat_archs
|
def populate_fat_archs
|
||||||
archs = []
|
archs = []
|
||||||
|
|
||||||
fa_off = FatHeader.bytesize
|
fa_off = Headers::FatHeader.bytesize
|
||||||
fa_len = FatArch.bytesize
|
fa_len = Headers::FatArch.bytesize
|
||||||
header.nfat_arch.times do |i|
|
header.nfat_arch.times do |i|
|
||||||
archs << FatArch.new_from_bin(:big, @raw_data[fa_off + (fa_len * i), fa_len])
|
archs << Headers::FatArch.new_from_bin(:big, @raw_data[fa_off + (fa_len * i), fa_len])
|
||||||
end
|
end
|
||||||
|
|
||||||
archs
|
archs
|
||||||
end
|
end
|
||||||
|
|
||||||
# Obtain an array of Mach-O blobs from raw file data.
|
# Obtain an array of Mach-O blobs from raw file data.
|
||||||
# @return [Array<MachO::MachOFile>] an array of Mach-Os
|
# @return [Array<MachOFile>] an array of Mach-Os
|
||||||
# @api private
|
# @api private
|
||||||
def populate_machos
|
def populate_machos
|
||||||
machos = []
|
machos = []
|
||||||
@ -351,7 +343,7 @@ module MachO
|
|||||||
# @option options [Boolean] :strict (true) whether or not to fail loudly
|
# @option options [Boolean] :strict (true) whether or not to fail loudly
|
||||||
# with an exception if at least one Mach-O raises an exception. If false,
|
# with an exception if at least one Mach-O raises an exception. If false,
|
||||||
# only raises an exception if *all* Mach-Os raise exceptions.
|
# only raises an exception if *all* Mach-Os raise exceptions.
|
||||||
# @raise [MachO::RecoverableModificationError] under the conditions of
|
# @raise [RecoverableModificationError] under the conditions of
|
||||||
# the `:strict` option above.
|
# the `:strict` option above.
|
||||||
# @api private
|
# @api private
|
||||||
def each_macho(options = {})
|
def each_macho(options = {})
|
||||||
@ -373,5 +365,13 @@ module MachO
|
|||||||
# Non-strict mode: Raise first error if *all* Mach-O slices failed.
|
# Non-strict mode: Raise first error if *all* Mach-O slices failed.
|
||||||
raise errors.first if errors.size == machos.size
|
raise errors.first if errors.size == machos.size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Return a single-arch Mach-O that represents this fat Mach-O for purposes
|
||||||
|
# of delegation.
|
||||||
|
# @return [MachOFile] the Mach-O file
|
||||||
|
# @api private
|
||||||
|
def canonical_macho
|
||||||
|
machos.first
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
80
Library/Homebrew/vendor/macho/macho/headers.rb
vendored
80
Library/Homebrew/vendor/macho/macho/headers.rb
vendored
@ -1,4 +1,6 @@
|
|||||||
module MachO
|
module MachO
|
||||||
|
# Classes and constants for parsing the headers of Mach-O binaries.
|
||||||
|
module Headers
|
||||||
# big-endian fat magic
|
# big-endian fat magic
|
||||||
# @api private
|
# @api private
|
||||||
FAT_MAGIC = 0xcafebabe
|
FAT_MAGIC = 0xcafebabe
|
||||||
@ -468,11 +470,16 @@ module MachO
|
|||||||
@magic = magic
|
@magic = magic
|
||||||
@nfat_arch = nfat_arch
|
@nfat_arch = nfat_arch
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [String] the serialized fields of the fat header
|
||||||
|
def serialize
|
||||||
|
[magic, nfat_arch].pack(FORMAT)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Fat binary header architecture structure. A Fat binary has one or more of
|
# Fat binary header architecture structure. A Fat binary has one or more of
|
||||||
# these, representing one or more internal Mach-O blobs.
|
# these, representing one or more internal Mach-O blobs.
|
||||||
# @see MachO::FatHeader
|
# @see MachO::Headers::FatHeader
|
||||||
class FatArch < MachOStructure
|
class FatArch < MachOStructure
|
||||||
# @return [Fixnum] the CPU type of the Mach-O
|
# @return [Fixnum] the CPU type of the Mach-O
|
||||||
attr_reader :cputype
|
attr_reader :cputype
|
||||||
@ -506,6 +513,11 @@ module MachO
|
|||||||
@size = size
|
@size = size
|
||||||
@align = align
|
@align = align
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [String] the serialized fields of the fat arch
|
||||||
|
def serialize
|
||||||
|
[cputype, cpusubtype, offset, size, align].pack(FORMAT)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 32-bit Mach-O file header structure
|
# 32-bit Mach-O file header structure
|
||||||
@ -562,6 +574,71 @@ module MachO
|
|||||||
return false if flag.nil?
|
return false if flag.nil?
|
||||||
flags & flag == flag
|
flags & flag == flag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_OBJECT`
|
||||||
|
def object?
|
||||||
|
filetype == Headers::MH_OBJECT
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_EXECUTE`
|
||||||
|
def executable?
|
||||||
|
filetype == Headers::MH_EXECUTE
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_FVMLIB`
|
||||||
|
def fvmlib?
|
||||||
|
filetype == Headers::MH_FVMLIB
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_CORE`
|
||||||
|
def core?
|
||||||
|
filetype == Headers::MH_CORE
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_PRELOAD`
|
||||||
|
def preload?
|
||||||
|
filetype == Headers::MH_PRELOAD
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_DYLIB`
|
||||||
|
def dylib?
|
||||||
|
filetype == Headers::MH_DYLIB
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_DYLINKER`
|
||||||
|
def dylinker?
|
||||||
|
filetype == Headers::MH_DYLINKER
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_BUNDLE`
|
||||||
|
def bundle?
|
||||||
|
filetype == Headers::MH_BUNDLE
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_DSYM`
|
||||||
|
def dsym?
|
||||||
|
filetype == Headers::MH_DSYM
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether or not the file is of type `MH_KEXT_BUNDLE`
|
||||||
|
def kext?
|
||||||
|
filetype == Headers::MH_KEXT_BUNDLE
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] true if the Mach-O has 32-bit magic, false otherwise
|
||||||
|
def magic32?
|
||||||
|
Utils.magic32?(magic)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] true if the Mach-O has 64-bit magic, false otherwise
|
||||||
|
def magic64?
|
||||||
|
Utils.magic64?(magic)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Fixnum] the file's internal alignment
|
||||||
|
def alignment
|
||||||
|
magic32? ? 4 : 8
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 64-bit Mach-O file header structure
|
# 64-bit Mach-O file header structure
|
||||||
@ -585,3 +662,4 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
156
Library/Homebrew/vendor/macho/macho/load_commands.rb
vendored
156
Library/Homebrew/vendor/macho/macho/load_commands.rb
vendored
@ -1,6 +1,8 @@
|
|||||||
module MachO
|
module MachO
|
||||||
|
# Classes and constants for parsing load commands in Mach-O binaries.
|
||||||
|
module LoadCommands
|
||||||
# load commands added after OS X 10.1 need to be bitwise ORed with
|
# 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 to be recognized by the dynamic linker (dyld)
|
||||||
# @api private
|
# @api private
|
||||||
LC_REQ_DYLD = 0x80000000
|
LC_REQ_DYLD = 0x80000000
|
||||||
|
|
||||||
@ -85,14 +87,21 @@ module MachO
|
|||||||
LC_STRUCTURES = {
|
LC_STRUCTURES = {
|
||||||
:LC_SEGMENT => "SegmentCommand",
|
:LC_SEGMENT => "SegmentCommand",
|
||||||
:LC_SYMTAB => "SymtabCommand",
|
:LC_SYMTAB => "SymtabCommand",
|
||||||
:LC_SYMSEG => "SymsegCommand", # obsolete
|
# "obsolete"
|
||||||
:LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such
|
:LC_SYMSEG => "SymsegCommand",
|
||||||
|
# seems obsolete, but not documented as such
|
||||||
|
:LC_THREAD => "ThreadCommand",
|
||||||
:LC_UNIXTHREAD => "ThreadCommand",
|
:LC_UNIXTHREAD => "ThreadCommand",
|
||||||
:LC_LOADFVMLIB => "FvmlibCommand", # obsolete
|
# "obsolete"
|
||||||
:LC_IDFVMLIB => "FvmlibCommand", # obsolete
|
:LC_LOADFVMLIB => "FvmlibCommand",
|
||||||
:LC_IDENT => "IdentCommand", # obsolete
|
# "obsolete"
|
||||||
:LC_FVMFILE => "FvmfileCommand", # reserved for internal use only
|
:LC_IDFVMLIB => "FvmlibCommand",
|
||||||
:LC_PREPAGE => "LoadCommand", # reserved for internal use only, no public struct
|
# "obsolete"
|
||||||
|
:LC_IDENT => "IdentCommand",
|
||||||
|
# "reserved for internal use only"
|
||||||
|
:LC_FVMFILE => "FvmfileCommand",
|
||||||
|
# "reserved for internal use only", no public struct
|
||||||
|
:LC_PREPAGE => "LoadCommand",
|
||||||
:LC_DYSYMTAB => "DysymtabCommand",
|
:LC_DYSYMTAB => "DysymtabCommand",
|
||||||
:LC_LOAD_DYLIB => "DylibCommand",
|
:LC_LOAD_DYLIB => "DylibCommand",
|
||||||
:LC_ID_DYLIB => "DylibCommand",
|
:LC_ID_DYLIB => "DylibCommand",
|
||||||
@ -180,7 +189,7 @@ module MachO
|
|||||||
|
|
||||||
# Instantiates a new LoadCommand given a view into its origin Mach-O
|
# Instantiates a new LoadCommand given a view into its origin Mach-O
|
||||||
# @param view [MachO::MachOView] the load command's raw view
|
# @param view [MachO::MachOView] the load command's raw view
|
||||||
# @return [MachO::LoadCommand] the new load command
|
# @return [LoadCommand] the new load command
|
||||||
# @api private
|
# @api private
|
||||||
def self.new_from_bin(view)
|
def self.new_from_bin(view)
|
||||||
bin = view.raw_data.slice(view.offset, bytesize)
|
bin = view.raw_data.slice(view.offset, bytesize)
|
||||||
@ -195,7 +204,7 @@ module MachO
|
|||||||
def self.create(cmd_sym, *args)
|
def self.create(cmd_sym, *args)
|
||||||
raise LoadCommandNotCreatableError, cmd_sym unless CREATABLE_LOAD_COMMANDS.include?(cmd_sym)
|
raise LoadCommandNotCreatableError, cmd_sym unless CREATABLE_LOAD_COMMANDS.include?(cmd_sym)
|
||||||
|
|
||||||
klass = MachO.const_get LC_STRUCTURES[cmd_sym]
|
klass = LoadCommands.const_get LC_STRUCTURES[cmd_sym]
|
||||||
cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
|
cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
|
||||||
|
|
||||||
# cmd will be filled in, view and cmdsize will be left unpopulated
|
# cmd will be filled in, view and cmdsize will be left unpopulated
|
||||||
@ -216,12 +225,12 @@ module MachO
|
|||||||
@cmdsize = cmdsize
|
@cmdsize = cmdsize
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] true if the load command can be serialized, false otherwise
|
# @return [Boolean] whether the load command can be serialized
|
||||||
def serializable?
|
def serializable?
|
||||||
CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
|
CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param context [MachO::LoadCommand::SerializationContext] the context
|
# @param context [SerializationContext] the context
|
||||||
# to serialize into
|
# to serialize into
|
||||||
# @return [String, nil] the serialized fields of the load command, or nil
|
# @return [String, nil] the serialized fields of the load command, or nil
|
||||||
# if the load command can't be serialized
|
# if the load command can't be serialized
|
||||||
@ -238,14 +247,16 @@ module MachO
|
|||||||
view.offset
|
view.offset
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Symbol] a symbol representation of the load command's identifying number
|
# @return [Symbol] a symbol representation of the load command's
|
||||||
|
# identifying number
|
||||||
def type
|
def type
|
||||||
LOAD_COMMANDS[cmd]
|
LOAD_COMMANDS[cmd]
|
||||||
end
|
end
|
||||||
|
|
||||||
alias to_sym type
|
alias to_sym type
|
||||||
|
|
||||||
# @return [String] a string representation of the load command's identifying number
|
# @return [String] a string representation of the load command's
|
||||||
|
# identifying number
|
||||||
def to_s
|
def to_s
|
||||||
type.to_s
|
type.to_s
|
||||||
end
|
end
|
||||||
@ -255,9 +266,9 @@ module MachO
|
|||||||
# pretend that strings stored in LCs are immediately available without
|
# pretend that strings stored in LCs are immediately available without
|
||||||
# explicit operations on the raw Mach-O data.
|
# explicit operations on the raw Mach-O data.
|
||||||
class LCStr
|
class LCStr
|
||||||
# @param lc [MachO::LoadCommand] the load command
|
# @param lc [LoadCommand] the load command
|
||||||
# @param lc_str [Fixnum, String] the offset to the beginning of the string,
|
# @param lc_str [Fixnum, String] the offset to the beginning of the
|
||||||
# or the string itself if not being initialized with a view.
|
# string, or the string itself if not being initialized with a view.
|
||||||
# @raise [MachO::LCStrMalformedError] if the string is malformed
|
# @raise [MachO::LCStrMalformedError] if the string is malformed
|
||||||
# @todo devise a solution such that the `lc_str` parameter is not
|
# @todo devise a solution such that the `lc_str` parameter is not
|
||||||
# interpreted differently depending on `lc.view`. The current behavior
|
# interpreted differently depending on `lc.view`. The current behavior
|
||||||
@ -284,7 +295,8 @@ module MachO
|
|||||||
@string
|
@string
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Fixnum] the offset to the beginning of the string in the load command
|
# @return [Fixnum] the offset to the beginning of the string in the
|
||||||
|
# load command
|
||||||
def to_i
|
def to_i
|
||||||
@string_offset
|
@string_offset
|
||||||
end
|
end
|
||||||
@ -296,11 +308,13 @@ module MachO
|
|||||||
# @return [Symbol] the endianness of the serialized load command
|
# @return [Symbol] the endianness of the serialized load command
|
||||||
attr_reader :endianness
|
attr_reader :endianness
|
||||||
|
|
||||||
# @return [Fixnum] the constant alignment value used to pad the serialized load command
|
# @return [Fixnum] the constant alignment value used to pad the
|
||||||
|
# serialized load command
|
||||||
attr_reader :alignment
|
attr_reader :alignment
|
||||||
|
|
||||||
# @param macho [MachO::MachOFile] the file to contextualize
|
# @param macho [MachO::MachOFile] the file to contextualize
|
||||||
# @return [MachO::LoadCommand::SerializationContext] the resulting context
|
# @return [SerializationContext] the
|
||||||
|
# resulting context
|
||||||
def self.context_for(macho)
|
def self.context_for(macho)
|
||||||
new(macho.endianness, macho.alignment)
|
new(macho.endianness, macho.alignment)
|
||||||
end
|
end
|
||||||
@ -315,8 +329,9 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing a single 128-bit unique random number identifying
|
# A load command containing a single 128-bit unique random number
|
||||||
# an object produced by static link editor. Corresponds to LC_UUID.
|
# identifying an object produced by static link editor. Corresponds to
|
||||||
|
# LC_UUID.
|
||||||
class UUIDCommand < LoadCommand
|
class UUIDCommand < LoadCommand
|
||||||
# @return [Array<Fixnum>] the UUID
|
# @return [Array<Fixnum>] the UUID
|
||||||
attr_reader :uuid
|
attr_reader :uuid
|
||||||
@ -401,17 +416,20 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# All sections referenced within this segment.
|
# All sections referenced within this segment.
|
||||||
# @return [Array<MachO::Section>] if the Mach-O is 32-bit
|
# @return [Array<MachO::Sections::Section>] if the Mach-O is 32-bit
|
||||||
# @return [Array<MachO::Section64>] if the Mach-O is 64-bit
|
# @return [Array<MachO::Sections::Section64>] if the Mach-O is 64-bit
|
||||||
def sections
|
def sections
|
||||||
klass = case self
|
klass = case self
|
||||||
when MachO::SegmentCommand64
|
when SegmentCommand64
|
||||||
MachO::Section64
|
MachO::Sections::Section64
|
||||||
when MachO::SegmentCommand
|
when SegmentCommand
|
||||||
MachO::Section
|
MachO::Sections::Section
|
||||||
end
|
end
|
||||||
|
|
||||||
bins = view.raw_data[view.offset + self.class.bytesize, nsects * klass.bytesize]
|
offset = view.offset + self.class.bytesize
|
||||||
|
length = nsects * klass.bytesize
|
||||||
|
|
||||||
|
bins = view.raw_data[offset, length]
|
||||||
bins.unpack("a#{klass.bytesize}" * nsects).map do |bin|
|
bins.unpack("a#{klass.bytesize}" * nsects).map do |bin|
|
||||||
klass.new_from_bin(view.endianness, bin)
|
klass.new_from_bin(view.endianness, bin)
|
||||||
end
|
end
|
||||||
@ -441,10 +459,11 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing some aspect of shared libraries, depending
|
# A load command representing some aspect of shared libraries, depending
|
||||||
# on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
|
# on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB,
|
||||||
# and LC_REEXPORT_DYLIB.
|
# LC_LOAD_WEAK_DYLIB, and LC_REEXPORT_DYLIB.
|
||||||
class DylibCommand < LoadCommand
|
class DylibCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
|
# @return [LCStr] the library's path
|
||||||
|
# name as an LCStr
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# @return [Fixnum] the library's build time stamp
|
# @return [Fixnum] the library's build time stamp
|
||||||
@ -465,7 +484,8 @@ module MachO
|
|||||||
SIZEOF = 24
|
SIZEOF = 24
|
||||||
|
|
||||||
# @api private
|
# @api private
|
||||||
def initialize(view, cmd, cmdsize, name, timestamp, current_version, compatibility_version)
|
def initialize(view, cmd, cmdsize, name, timestamp, current_version,
|
||||||
|
compatibility_version)
|
||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@name = LCStr.new(self, name)
|
@name = LCStr.new(self, name)
|
||||||
@timestamp = timestamp
|
@timestamp = timestamp
|
||||||
@ -473,12 +493,15 @@ module MachO
|
|||||||
@compatibility_version = compatibility_version
|
@compatibility_version = compatibility_version
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
# @param context [SerializationContext]
|
||||||
|
# the context
|
||||||
# @return [String] the serialized fields of the load command
|
# @return [String] the serialized fields of the load command
|
||||||
# @api private
|
# @api private
|
||||||
def serialize(context)
|
def serialize(context)
|
||||||
format = Utils.specialize_format(FORMAT, context.endianness)
|
format = Utils.specialize_format(FORMAT, context.endianness)
|
||||||
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
|
string_payload, string_offsets = Utils.pack_strings(SIZEOF,
|
||||||
|
context.alignment,
|
||||||
|
:name => name.to_s)
|
||||||
cmdsize = SIZEOF + string_payload.bytesize
|
cmdsize = SIZEOF + string_payload.bytesize
|
||||||
[cmd, cmdsize, string_offsets[:name], timestamp, current_version,
|
[cmd, cmdsize, string_offsets[:name], timestamp, current_version,
|
||||||
compatibility_version].pack(format) + string_payload
|
compatibility_version].pack(format) + string_payload
|
||||||
@ -489,7 +512,8 @@ module MachO
|
|||||||
# on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
|
# on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
|
||||||
# LC_DYLD_ENVIRONMENT.
|
# LC_DYLD_ENVIRONMENT.
|
||||||
class DylinkerCommand < LoadCommand
|
class DylinkerCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
|
# @return [LCStr] the dynamic linker's
|
||||||
|
# path name as an LCStr
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -506,12 +530,15 @@ module MachO
|
|||||||
@name = LCStr.new(self, name)
|
@name = LCStr.new(self, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
# @param context [SerializationContext]
|
||||||
|
# the context
|
||||||
# @return [String] the serialized fields of the load command
|
# @return [String] the serialized fields of the load command
|
||||||
# @api private
|
# @api private
|
||||||
def serialize(context)
|
def serialize(context)
|
||||||
format = Utils.specialize_format(FORMAT, context.endianness)
|
format = Utils.specialize_format(FORMAT, context.endianness)
|
||||||
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
|
string_payload, string_offsets = Utils.pack_strings(SIZEOF,
|
||||||
|
context.alignment,
|
||||||
|
:name => name.to_s)
|
||||||
cmdsize = SIZEOF + string_payload.bytesize
|
cmdsize = SIZEOF + string_payload.bytesize
|
||||||
[cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
|
[cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
|
||||||
end
|
end
|
||||||
@ -520,7 +547,8 @@ module MachO
|
|||||||
# A load command used to indicate dynamic libraries used in prebinding.
|
# A load command used to indicate dynamic libraries used in prebinding.
|
||||||
# Corresponds to LC_PREBOUND_DYLIB.
|
# Corresponds to LC_PREBOUND_DYLIB.
|
||||||
class PreboundDylibCommand < LoadCommand
|
class PreboundDylibCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
|
# @return [LCStr] the library's path
|
||||||
|
# name as an LCStr
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# @return [Fixnum] the number of modules in the library
|
# @return [Fixnum] the number of modules in the library
|
||||||
@ -547,7 +575,8 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# A load command used to represent threads.
|
# A load command used to represent threads.
|
||||||
# @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize)
|
# @note cctools-870 and onwards have all fields of thread_command commented
|
||||||
|
# out except the common ones (cmd, cmdsize)
|
||||||
class ThreadCommand < LoadCommand
|
class ThreadCommand < LoadCommand
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
# @api private
|
# @api private
|
||||||
@ -565,7 +594,8 @@ module MachO
|
|||||||
# @return [Fixnum] the address of the initialization routine
|
# @return [Fixnum] the address of the initialization routine
|
||||||
attr_reader :init_address
|
attr_reader :init_address
|
||||||
|
|
||||||
# @return [Fixnum] the index into the module table that the init routine is defined in
|
# @return [Fixnum] the index into the module table that the init routine
|
||||||
|
# is defined in
|
||||||
attr_reader :init_module
|
attr_reader :init_module
|
||||||
|
|
||||||
# @return [void]
|
# @return [void]
|
||||||
@ -625,7 +655,7 @@ module MachO
|
|||||||
# A load command signifying membership of a subframework containing the name
|
# A load command signifying membership of a subframework containing the name
|
||||||
# of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
|
# of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
|
||||||
class SubFrameworkCommand < LoadCommand
|
class SubFrameworkCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr
|
# @return [LCStr] the umbrella framework name as an LCStr
|
||||||
attr_reader :umbrella
|
attr_reader :umbrella
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -646,7 +676,7 @@ module MachO
|
|||||||
# A load command signifying membership of a subumbrella containing the name
|
# A load command signifying membership of a subumbrella containing the name
|
||||||
# of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
|
# of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
|
||||||
class SubUmbrellaCommand < LoadCommand
|
class SubUmbrellaCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr
|
# @return [LCStr] the subumbrella framework name as an LCStr
|
||||||
attr_reader :sub_umbrella
|
attr_reader :sub_umbrella
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -667,7 +697,7 @@ module MachO
|
|||||||
# A load command signifying a sublibrary of a shared library. Corresponds
|
# A load command signifying a sublibrary of a shared library. Corresponds
|
||||||
# to LC_SUB_LIBRARY.
|
# to LC_SUB_LIBRARY.
|
||||||
class SubLibraryCommand < LoadCommand
|
class SubLibraryCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr
|
# @return [LCStr] the sublibrary name as an LCStr
|
||||||
attr_reader :sub_library
|
attr_reader :sub_library
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -688,7 +718,7 @@ module MachO
|
|||||||
# A load command signifying a shared library that is a subframework of
|
# A load command signifying a shared library that is a subframework of
|
||||||
# an umbrella framework. Corresponds to LC_SUB_CLIENT.
|
# an umbrella framework. Corresponds to LC_SUB_CLIENT.
|
||||||
class SubClientCommand < LoadCommand
|
class SubClientCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr
|
# @return [LCStr] the subclient name as an LCStr
|
||||||
attr_reader :sub_client
|
attr_reader :sub_client
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -841,7 +871,8 @@ module MachO
|
|||||||
# @return [Fixnum] the number of hints in the hint table
|
# @return [Fixnum] the number of hints in the hint table
|
||||||
attr_reader :nhints
|
attr_reader :nhints
|
||||||
|
|
||||||
# @return [MachO::TwolevelHintsCommand::TwolevelHintTable] the hint table
|
# @return [TwolevelHintsTable]
|
||||||
|
# the hint table
|
||||||
attr_reader :table
|
attr_reader :table
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -863,7 +894,7 @@ module MachO
|
|||||||
# A representation of the two-level namespace lookup hints table exposed
|
# A representation of the two-level namespace lookup hints table exposed
|
||||||
# by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
|
# by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
|
||||||
class TwolevelHintsTable
|
class TwolevelHintsTable
|
||||||
# @return [Array<MachO::TwoLevelHintsTable::TwoLevelHint>] all hints in the table
|
# @return [Array<TwolevelHint>] all hints in the table
|
||||||
attr_reader :hints
|
attr_reader :hints
|
||||||
|
|
||||||
# @param view [MachO::MachOView] the view into the current Mach-O
|
# @param view [MachO::MachOView] the view into the current Mach-O
|
||||||
@ -921,7 +952,7 @@ module MachO
|
|||||||
# be added to the current run path used to find @rpath prefixed dylibs.
|
# be added to the current run path used to find @rpath prefixed dylibs.
|
||||||
# Corresponds to LC_RPATH.
|
# Corresponds to LC_RPATH.
|
||||||
class RpathCommand < LoadCommand
|
class RpathCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr
|
# @return [LCStr] the path to add to the run path as an LCStr
|
||||||
attr_reader :path
|
attr_reader :path
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -938,20 +969,23 @@ module MachO
|
|||||||
@path = LCStr.new(self, path)
|
@path = LCStr.new(self, path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# @param context [MachO::LoadCcommand::SerializationContext] the context
|
# @param context [SerializationContext] the context
|
||||||
# @return [String] the serialized fields of the load command
|
# @return [String] the serialized fields of the load command
|
||||||
# @api private
|
# @api private
|
||||||
def serialize(context)
|
def serialize(context)
|
||||||
format = Utils.specialize_format(FORMAT, context.endianness)
|
format = Utils.specialize_format(FORMAT, context.endianness)
|
||||||
string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :path => path.to_s)
|
string_payload, string_offsets = Utils.pack_strings(SIZEOF,
|
||||||
|
context.alignment,
|
||||||
|
:path => path.to_s)
|
||||||
cmdsize = SIZEOF + string_payload.bytesize
|
cmdsize = SIZEOF + string_payload.bytesize
|
||||||
[cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
|
[cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing the offsets and sizes of a blob of data in
|
# 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,
|
# the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE,
|
||||||
# LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
|
# LC_SEGMENT_SPLIT_INFO, LC_FUNCTION_STARTS, LC_DATA_IN_CODE,
|
||||||
|
# LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
|
||||||
class LinkeditDataCommand < LoadCommand
|
class LinkeditDataCommand < LoadCommand
|
||||||
# @return [Fixnum] offset to the data in the __LINKEDIT segment
|
# @return [Fixnum] offset to the data in the __LINKEDIT segment
|
||||||
attr_reader :dataoff
|
attr_reader :dataoff
|
||||||
@ -1038,7 +1072,8 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the minimum OS version on which the binary
|
# 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.
|
# was built to run. Corresponds to LC_VERSION_MIN_MACOSX and
|
||||||
|
# LC_VERSION_MIN_IPHONEOS.
|
||||||
class VersionMinCommand < LoadCommand
|
class VersionMinCommand < LoadCommand
|
||||||
# @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
|
# @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
|
||||||
attr_reader :version
|
attr_reader :version
|
||||||
@ -1247,9 +1282,9 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An obsolete load command containing a free format string table. Each string
|
# An obsolete load command containing a free format string table. Each
|
||||||
# is null-terminated and the command is zero-padded to a multiple of 4.
|
# string is null-terminated and the command is zero-padded to a multiple of
|
||||||
# Corresponds to LC_IDENT.
|
# 4. Corresponds to LC_IDENT.
|
||||||
class IdentCommand < LoadCommand
|
class IdentCommand < LoadCommand
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
# @api private
|
# @api private
|
||||||
@ -1263,7 +1298,7 @@ module MachO
|
|||||||
# An obsolete load command containing the path to a file to be loaded into
|
# An obsolete load command containing the path to a file to be loaded into
|
||||||
# memory. Corresponds to LC_FVMFILE.
|
# memory. Corresponds to LC_FVMFILE.
|
||||||
class FvmfileCommand < LoadCommand
|
class FvmfileCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the pathname of the file being loaded
|
# @return [LCStr] the pathname of the file being loaded
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# @return [Fixnum] the virtual address being loaded at
|
# @return [Fixnum] the virtual address being loaded at
|
||||||
@ -1284,10 +1319,10 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An obsolete load command containing the path to a library to be loaded into
|
# An obsolete load command containing the path to a library to be loaded
|
||||||
# memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
|
# into memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
|
||||||
class FvmlibCommand < LoadCommand
|
class FvmlibCommand < LoadCommand
|
||||||
# @return [MachO::LoadCommand::LCStr] the library's target pathname
|
# @return [LCStr] the library's target pathname
|
||||||
attr_reader :name
|
attr_reader :name
|
||||||
|
|
||||||
# @return [Fixnum] the library's minor version number
|
# @return [Fixnum] the library's minor version number
|
||||||
@ -1312,3 +1347,4 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
246
Library/Homebrew/vendor/macho/macho/macho_file.rb
vendored
246
Library/Homebrew/vendor/macho/macho/macho_file.rb
vendored
@ -1,27 +1,33 @@
|
|||||||
|
require "forwardable"
|
||||||
|
|
||||||
module MachO
|
module MachO
|
||||||
# Represents a Mach-O file, which contains a header and load commands
|
# Represents a Mach-O file, which contains a header and load commands
|
||||||
# as well as binary executable instructions. Mach-O binaries are
|
# as well as binary executable instructions. Mach-O binaries are
|
||||||
# architecture specific.
|
# architecture specific.
|
||||||
# @see https://en.wikipedia.org/wiki/Mach-O
|
# @see https://en.wikipedia.org/wiki/Mach-O
|
||||||
# @see MachO::FatFile
|
# @see FatFile
|
||||||
class MachOFile
|
class MachOFile
|
||||||
# @return [String] the filename loaded from, or nil if loaded from a binary string
|
extend Forwardable
|
||||||
|
|
||||||
|
# @return [String] the filename loaded from, or nil if loaded from a binary
|
||||||
|
# string
|
||||||
attr_accessor :filename
|
attr_accessor :filename
|
||||||
|
|
||||||
# @return [Symbol] the endianness of the file, :big or :little
|
# @return [Symbol] the endianness of the file, :big or :little
|
||||||
attr_reader :endianness
|
attr_reader :endianness
|
||||||
|
|
||||||
# @return [MachO::MachHeader] if the Mach-O is 32-bit
|
# @return [Headers::MachHeader] if the Mach-O is 32-bit
|
||||||
# @return [MachO::MachHeader64] if the Mach-O is 64-bit
|
# @return [Headers::MachHeader64] if the Mach-O is 64-bit
|
||||||
attr_reader :header
|
attr_reader :header
|
||||||
|
|
||||||
# @return [Array<MachO::LoadCommand>] an array of the file's load commands
|
# @return [Array<LoadCommands::LoadCommand>] an array of the file's load
|
||||||
|
# commands
|
||||||
# @note load commands are provided in order of ascending offset.
|
# @note load commands are provided in order of ascending offset.
|
||||||
attr_reader :load_commands
|
attr_reader :load_commands
|
||||||
|
|
||||||
# Creates a new MachOFile instance from a binary string.
|
# Creates a new MachOFile instance from a binary string.
|
||||||
# @param bin [String] a binary string containing raw Mach-O data
|
# @param bin [String] a binary string containing raw Mach-O data
|
||||||
# @return [MachO::MachOFile] a new MachOFile
|
# @return [MachOFile] a new MachOFile
|
||||||
def self.new_from_bin(bin)
|
def self.new_from_bin(bin)
|
||||||
instance = allocate
|
instance = allocate
|
||||||
instance.initialize_from_bin(bin)
|
instance.initialize_from_bin(bin)
|
||||||
@ -55,109 +61,63 @@ module MachO
|
|||||||
@raw_data
|
@raw_data
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] true if the Mach-O has 32-bit magic, false otherwise
|
# @!method magic
|
||||||
def magic32?
|
# @return (see MachO::Headers::MachHeader#magic)
|
||||||
Utils.magic32?(header.magic)
|
# @!method ncmds
|
||||||
end
|
# @return (see MachO::Headers::MachHeader#ncmds)
|
||||||
|
# @!method sizeofcmds
|
||||||
# @return [Boolean] true if the Mach-O has 64-bit magic, false otherwise
|
# @return (see MachO::Headers::MachHeader#sizeofcmds)
|
||||||
def magic64?
|
# @!method flags
|
||||||
Utils.magic64?(header.magic)
|
# @return (see MachO::Headers::MachHeader#flags)
|
||||||
end
|
# @!method object?
|
||||||
|
# @return (see MachO::Headers::MachHeader#object?)
|
||||||
# @return [Fixnum] the file's internal alignment
|
# @!method executable?
|
||||||
def alignment
|
# @return (see MachO::Headers::MachHeader#executable?)
|
||||||
magic32? ? 4 : 8
|
# @!method fvmlib?
|
||||||
end
|
# @return (see MachO::Headers::MachHeader#fvmlib?)
|
||||||
|
# @!method core?
|
||||||
# @return [Boolean] true if the file is of type `MH_OBJECT`, false otherwise
|
# @return (see MachO::Headers::MachHeader#core?)
|
||||||
def object?
|
# @!method preload?
|
||||||
header.filetype == MH_OBJECT
|
# @return (see MachO::Headers::MachHeader#preload?)
|
||||||
end
|
# @!method dylib?
|
||||||
|
# @return (see MachO::Headers::MachHeader#dylib?)
|
||||||
# @return [Boolean] true if the file is of type `MH_EXECUTE`, false otherwise
|
# @!method dylinker?
|
||||||
def executable?
|
# @return (see MachO::Headers::MachHeader#dylinker?)
|
||||||
header.filetype == MH_EXECUTE
|
# @!method bundle?
|
||||||
end
|
# @return (see MachO::Headers::MachHeader#bundle?)
|
||||||
|
# @!method dsym?
|
||||||
# @return [Boolean] true if the file is of type `MH_FVMLIB`, false otherwise
|
# @return (see MachO::Headers::MachHeader#dsym?)
|
||||||
def fvmlib?
|
# @!method kext?
|
||||||
header.filetype == MH_FVMLIB
|
# @return (see MachO::Headers::MachHeader#kext?)
|
||||||
end
|
# @!method magic32?
|
||||||
|
# @return (see MachO::Headers::MachHeader#magic32?)
|
||||||
# @return [Boolean] true if the file is of type `MH_CORE`, false otherwise
|
# @!method magic64?
|
||||||
def core?
|
# @return (see MachO::Headers::MachHeader#magic64?)
|
||||||
header.filetype == MH_CORE
|
# @!method alignment
|
||||||
end
|
# @return (see MachO::Headers::MachHeader#alignment)
|
||||||
|
def_delegators :header, :magic, :ncmds, :sizeofcmds, :flags, :object?,
|
||||||
# @return [Boolean] true if the file is of type `MH_PRELOAD`, false otherwise
|
:executable?, :fvmlib?, :core?, :preload?, :dylib?,
|
||||||
def preload?
|
:dylinker?, :bundle?, :dsym?, :kext?, :magic32?, :magic64?,
|
||||||
header.filetype == MH_PRELOAD
|
:alignment
|
||||||
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
|
# @return [String] a string representation of the file's magic number
|
||||||
def magic_string
|
def magic_string
|
||||||
MH_MAGICS[magic]
|
Headers::MH_MAGICS[magic]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Symbol] a string representation of the Mach-O's filetype
|
# @return [Symbol] a string representation of the Mach-O's filetype
|
||||||
def filetype
|
def filetype
|
||||||
MH_FILETYPES[header.filetype]
|
Headers::MH_FILETYPES[header.filetype]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Symbol] a symbol representation of the Mach-O's CPU type
|
# @return [Symbol] a symbol representation of the Mach-O's CPU type
|
||||||
def cputype
|
def cputype
|
||||||
CPU_TYPES[header.cputype]
|
Headers::CPU_TYPES[header.cputype]
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Symbol] a symbol representation of the Mach-O's CPU subtype
|
# @return [Symbol] a symbol representation of the Mach-O's CPU subtype
|
||||||
def cpusubtype
|
def cpusubtype
|
||||||
CPU_SUBTYPES[header.cputype][header.cpusubtype]
|
Headers::CPU_SUBTYPES[header.cputype][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
|
end
|
||||||
|
|
||||||
# All load commands of a given name.
|
# All load commands of a given name.
|
||||||
@ -165,7 +125,8 @@ module MachO
|
|||||||
# file.command("LC_LOAD_DYLIB")
|
# file.command("LC_LOAD_DYLIB")
|
||||||
# file[:LC_LOAD_DYLIB]
|
# file[:LC_LOAD_DYLIB]
|
||||||
# @param [String, Symbol] name the load command ID
|
# @param [String, Symbol] name the load command ID
|
||||||
# @return [Array<MachO::LoadCommand>] an array of LoadCommands corresponding to `name`
|
# @return [Array<LoadCommands::LoadCommand>] an array of load commands
|
||||||
|
# corresponding to `name`
|
||||||
def command(name)
|
def command(name)
|
||||||
load_commands.select { |lc| lc.type == name.to_sym }
|
load_commands.select { |lc| lc.type == name.to_sym }
|
||||||
end
|
end
|
||||||
@ -174,16 +135,16 @@ module MachO
|
|||||||
|
|
||||||
# Inserts a load command at the given offset.
|
# Inserts a load command at the given offset.
|
||||||
# @param offset [Fixnum] the offset to insert at
|
# @param offset [Fixnum] the offset to insert at
|
||||||
# @param lc [MachO::LoadCommand] the load command to insert
|
# @param lc [LoadCommands::LoadCommand] the load command to insert
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
||||||
# the instance fields
|
# the instance fields
|
||||||
# @raise [MachO::OffsetInsertionError] if the offset is not in the load command region
|
# @raise [OffsetInsertionError] if the offset is not in the load command region
|
||||||
# @raise [MachO::HeaderPadError] if the new command exceeds the header pad buffer
|
# @raise [HeaderPadError] if the new command exceeds the header pad buffer
|
||||||
# @note Calling this method with an arbitrary offset in the load command
|
# @note Calling this method with an arbitrary offset in the load command
|
||||||
# region **will leave the object in an inconsistent state**.
|
# region **will leave the object in an inconsistent state**.
|
||||||
def insert_command(offset, lc, options = {})
|
def insert_command(offset, lc, options = {})
|
||||||
context = LoadCommand::SerializationContext.context_for(self)
|
context = LoadCommands::LoadCommand::SerializationContext.context_for(self)
|
||||||
cmd_raw = lc.serialize(context)
|
cmd_raw = lc.serialize(context)
|
||||||
|
|
||||||
if offset < header.class.bytesize || offset + cmd_raw.bytesize > low_fileoff
|
if offset < header.class.bytesize || offset + cmd_raw.bytesize > low_fileoff
|
||||||
@ -207,14 +168,14 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Replace a load command with another command in the Mach-O, preserving location.
|
# Replace a load command with another command in the Mach-O, preserving location.
|
||||||
# @param old_lc [MachO::LoadCommand] the load command being replaced
|
# @param old_lc [LoadCommands::LoadCommand] the load command being replaced
|
||||||
# @param new_lc [MachO::LoadCommand] the load command being added
|
# @param new_lc [LoadCommands::LoadCommand] the load command being added
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::HeaderPadError] if the new command exceeds the header pad buffer
|
# @raise [HeaderPadError] if the new command exceeds the header pad buffer
|
||||||
# @see {#insert_command}
|
# @see #insert_command
|
||||||
# @note This is public, but methods like {#dylib_id=} should be preferred.
|
# @note This is public, but methods like {#dylib_id=} should be preferred.
|
||||||
def replace_command(old_lc, new_lc)
|
def replace_command(old_lc, new_lc)
|
||||||
context = LoadCommand::SerializationContext.context_for(self)
|
context = LoadCommands::LoadCommand::SerializationContext.context_for(self)
|
||||||
cmd_raw = new_lc.serialize(context)
|
cmd_raw = new_lc.serialize(context)
|
||||||
new_sizeofcmds = sizeofcmds + cmd_raw.bytesize - old_lc.cmdsize
|
new_sizeofcmds = sizeofcmds + cmd_raw.bytesize - old_lc.cmdsize
|
||||||
if header.class.bytesize + new_sizeofcmds > low_fileoff
|
if header.class.bytesize + new_sizeofcmds > low_fileoff
|
||||||
@ -226,12 +187,12 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Appends a new load command to the Mach-O.
|
# Appends a new load command to the Mach-O.
|
||||||
# @param lc [MachO::LoadCommand] the load command being added
|
# @param lc [LoadCommands::LoadCommand] the load command being added
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
||||||
# the instance fields
|
# the instance fields
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @see {#insert_command}
|
# @see #insert_command
|
||||||
# @note This is public, but methods like {#add_rpath} should be preferred.
|
# @note This is public, but methods like {#add_rpath} should be preferred.
|
||||||
# Setting `repopulate` to false **will leave the instance in an
|
# Setting `repopulate` to false **will leave the instance in an
|
||||||
# inconsistent state** unless {#populate_fields} is called **immediately**
|
# inconsistent state** unless {#populate_fields} is called **immediately**
|
||||||
@ -241,7 +202,7 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Delete a load command from the Mach-O.
|
# Delete a load command from the Mach-O.
|
||||||
# @param lc [MachO::LoadCommand] the load command being deleted
|
# @param lc [LoadCommands::LoadCommand] the load command being deleted
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
# @option options [Boolean] :repopulate (true) whether or not to repopulate
|
||||||
# the instance fields
|
# the instance fields
|
||||||
@ -275,14 +236,14 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# All load commands responsible for loading dylibs.
|
# All load commands responsible for loading dylibs.
|
||||||
# @return [Array<MachO::DylibCommand>] an array of DylibCommands
|
# @return [Array<LoadCommands::DylibCommand>] an array of DylibCommands
|
||||||
def dylib_load_commands
|
def dylib_load_commands
|
||||||
load_commands.select { |lc| DYLIB_LOAD_COMMANDS.include?(lc.type) }
|
load_commands.select { |lc| LoadCommands::DYLIB_LOAD_COMMANDS.include?(lc.type) }
|
||||||
end
|
end
|
||||||
|
|
||||||
# All segment load commands in the Mach-O.
|
# All segment load commands in the Mach-O.
|
||||||
# @return [Array<MachO::SegmentCommand>] if the Mach-O is 32-bit
|
# @return [Array<LoadCommands::SegmentCommand>] if the Mach-O is 32-bit
|
||||||
# @return [Array<MachO::SegmentCommand64>] if the Mach-O is 64-bit
|
# @return [Array<LoadCommands::SegmentCommand64>] if the Mach-O is 64-bit
|
||||||
def segments
|
def segments
|
||||||
if magic32?
|
if magic32?
|
||||||
command(:LC_SEGMENT)
|
command(:LC_SEGMENT)
|
||||||
@ -319,7 +280,7 @@ module MachO
|
|||||||
old_lc = command(:LC_ID_DYLIB).first
|
old_lc = command(:LC_ID_DYLIB).first
|
||||||
raise DylibIdMissingError unless old_lc
|
raise DylibIdMissingError unless old_lc
|
||||||
|
|
||||||
new_lc = LoadCommand.create(:LC_ID_DYLIB, new_id,
|
new_lc = LoadCommands::LoadCommand.create(:LC_ID_DYLIB, new_id,
|
||||||
old_lc.timestamp,
|
old_lc.timestamp,
|
||||||
old_lc.current_version,
|
old_lc.current_version,
|
||||||
old_lc.compatibility_version)
|
old_lc.compatibility_version)
|
||||||
@ -341,19 +302,19 @@ module MachO
|
|||||||
|
|
||||||
# Changes the shared library `old_name` to `new_name`
|
# Changes the shared library `old_name` to `new_name`
|
||||||
# @example
|
# @example
|
||||||
# file.change_install_name("/usr/lib/libWhatever.dylib", "/usr/local/lib/libWhatever2.dylib")
|
# file.change_install_name("abc.dylib", "def.dylib")
|
||||||
# @param old_name [String] the shared library's old name
|
# @param old_name [String] the shared library's old name
|
||||||
# @param new_name [String] the shared library's new name
|
# @param new_name [String] the shared library's new name
|
||||||
# @param _options [Hash]
|
# @param _options [Hash]
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::DylibUnknownError] if no shared library has the old name
|
# @raise [DylibUnknownError] if no shared library has the old name
|
||||||
# @note `_options` is currently unused and is provided for signature
|
# @note `_options` is currently unused and is provided for signature
|
||||||
# compatibility with {MachO::FatFile#change_install_name}
|
# compatibility with {MachO::FatFile#change_install_name}
|
||||||
def change_install_name(old_name, new_name, _options = {})
|
def change_install_name(old_name, new_name, _options = {})
|
||||||
old_lc = dylib_load_commands.find { |d| d.name.to_s == old_name }
|
old_lc = dylib_load_commands.find { |d| d.name.to_s == old_name }
|
||||||
raise DylibUnknownError, old_name if old_lc.nil?
|
raise DylibUnknownError, old_name if old_lc.nil?
|
||||||
|
|
||||||
new_lc = LoadCommand.create(old_lc.type, new_name,
|
new_lc = LoadCommands::LoadCommand.create(old_lc.type, new_name,
|
||||||
old_lc.timestamp,
|
old_lc.timestamp,
|
||||||
old_lc.current_version,
|
old_lc.current_version,
|
||||||
old_lc.compatibility_version)
|
old_lc.compatibility_version)
|
||||||
@ -376,8 +337,8 @@ module MachO
|
|||||||
# @param new_path [String] the new runtime path
|
# @param new_path [String] the new runtime path
|
||||||
# @param _options [Hash]
|
# @param _options [Hash]
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::RpathUnknownError] if no such old runtime path exists
|
# @raise [RpathUnknownError] if no such old runtime path exists
|
||||||
# @raise [MachO::RpathExistsError] if the new runtime path already exists
|
# @raise [RpathExistsError] if the new runtime path already exists
|
||||||
# @note `_options` is currently unused and is provided for signature
|
# @note `_options` is currently unused and is provided for signature
|
||||||
# compatibility with {MachO::FatFile#change_rpath}
|
# compatibility with {MachO::FatFile#change_rpath}
|
||||||
def change_rpath(old_path, new_path, _options = {})
|
def change_rpath(old_path, new_path, _options = {})
|
||||||
@ -385,7 +346,7 @@ module MachO
|
|||||||
raise RpathUnknownError, old_path if old_lc.nil?
|
raise RpathUnknownError, old_path if old_lc.nil?
|
||||||
raise RpathExistsError, new_path if rpaths.include?(new_path)
|
raise RpathExistsError, new_path if rpaths.include?(new_path)
|
||||||
|
|
||||||
new_lc = LoadCommand.create(:LC_RPATH, new_path)
|
new_lc = LoadCommands::LoadCommand.create(:LC_RPATH, new_path)
|
||||||
|
|
||||||
delete_rpath(old_path)
|
delete_rpath(old_path)
|
||||||
insert_command(old_lc.view.offset, new_lc)
|
insert_command(old_lc.view.offset, new_lc)
|
||||||
@ -399,13 +360,13 @@ module MachO
|
|||||||
# @param path [String] the new runtime path
|
# @param path [String] the new runtime path
|
||||||
# @param _options [Hash]
|
# @param _options [Hash]
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::RpathExistsError] if the runtime path already exists
|
# @raise [RpathExistsError] if the runtime path already exists
|
||||||
# @note `_options` is currently unused and is provided for signature
|
# @note `_options` is currently unused and is provided for signature
|
||||||
# compatibility with {MachO::FatFile#add_rpath}
|
# compatibility with {MachO::FatFile#add_rpath}
|
||||||
def add_rpath(path, _options = {})
|
def add_rpath(path, _options = {})
|
||||||
raise RpathExistsError, path if rpaths.include?(path)
|
raise RpathExistsError, path if rpaths.include?(path)
|
||||||
|
|
||||||
rpath_cmd = LoadCommand.create(:LC_RPATH, path)
|
rpath_cmd = LoadCommands::LoadCommand.create(:LC_RPATH, path)
|
||||||
add_command(rpath_cmd)
|
add_command(rpath_cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -417,7 +378,7 @@ module MachO
|
|||||||
# @param path [String] the runtime path to delete
|
# @param path [String] the runtime path to delete
|
||||||
# @param _options [Hash]
|
# @param _options [Hash]
|
||||||
# @return void
|
# @return void
|
||||||
# @raise [MachO::RpathUnknownError] if no such runtime path exists
|
# @raise [RpathUnknownError] if no such runtime path exists
|
||||||
# @note `_options` is currently unused and is provided for signature
|
# @note `_options` is currently unused and is provided for signature
|
||||||
# compatibility with {MachO::FatFile#delete_rpath}
|
# compatibility with {MachO::FatFile#delete_rpath}
|
||||||
def delete_rpath(path, _options = {})
|
def delete_rpath(path, _options = {})
|
||||||
@ -431,15 +392,6 @@ module MachO
|
|||||||
populate_fields
|
populate_fields
|
||||||
end
|
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
|
|
||||||
# @deprecated use {MachO::SegmentCommand#sections} instead
|
|
||||||
def sections(segment)
|
|
||||||
segment.sections
|
|
||||||
end
|
|
||||||
|
|
||||||
# Write all Mach-O data to the given filename.
|
# Write all Mach-O data to the given filename.
|
||||||
# @param filename [String] the file to write to
|
# @param filename [String] the file to write to
|
||||||
# @return [void]
|
# @return [void]
|
||||||
@ -449,7 +401,7 @@ module MachO
|
|||||||
|
|
||||||
# Write all Mach-O data to the file used to initialize the instance.
|
# Write all Mach-O data to the file used to initialize the instance.
|
||||||
# @return [void]
|
# @return [void]
|
||||||
# @raise [MachO::MachOError] if the instance was initialized without a file
|
# @raise [MachOError] if the instance was initialized without a file
|
||||||
# @note Overwrites all data in the file!
|
# @note Overwrites all data in the file!
|
||||||
def write!
|
def write!
|
||||||
if @filename.nil?
|
if @filename.nil?
|
||||||
@ -462,16 +414,16 @@ module MachO
|
|||||||
private
|
private
|
||||||
|
|
||||||
# The file's Mach-O header structure.
|
# The file's Mach-O header structure.
|
||||||
# @return [MachO::MachHeader] if the Mach-O is 32-bit
|
# @return [Headers::MachHeader] if the Mach-O is 32-bit
|
||||||
# @return [MachO::MachHeader64] if the Mach-O is 64-bit
|
# @return [Headers::MachHeader64] if the Mach-O is 64-bit
|
||||||
# @raise [MachO::TruncatedFileError] if the file is too small to have a valid header
|
# @raise [TruncatedFileError] if the file is too small to have a valid header
|
||||||
# @api private
|
# @api private
|
||||||
def populate_mach_header
|
def populate_mach_header
|
||||||
# the smallest Mach-O header is 28 bytes
|
# the smallest Mach-O header is 28 bytes
|
||||||
raise TruncatedFileError if @raw_data.size < 28
|
raise TruncatedFileError if @raw_data.size < 28
|
||||||
|
|
||||||
magic = populate_and_check_magic
|
magic = populate_and_check_magic
|
||||||
mh_klass = Utils.magic32?(magic) ? MachHeader : MachHeader64
|
mh_klass = Utils.magic32?(magic) ? Headers::MachHeader : Headers::MachHeader64
|
||||||
mh = mh_klass.new_from_bin(endianness, @raw_data[0, mh_klass.bytesize])
|
mh = mh_klass.new_from_bin(endianness, @raw_data[0, mh_klass.bytesize])
|
||||||
|
|
||||||
check_cputype(mh.cputype)
|
check_cputype(mh.cputype)
|
||||||
@ -483,8 +435,8 @@ module MachO
|
|||||||
|
|
||||||
# Read just the file's magic number and check its validity.
|
# Read just the file's magic number and check its validity.
|
||||||
# @return [Fixnum] the magic
|
# @return [Fixnum] the magic
|
||||||
# @raise [MachO::MagicError] if the magic is not valid Mach-O magic
|
# @raise [MagicError] if the magic is not valid Mach-O magic
|
||||||
# @raise [MachO::FatBinaryError] if the magic is for a Fat file
|
# @raise [FatBinaryError] if the magic is for a Fat file
|
||||||
# @api private
|
# @api private
|
||||||
def populate_and_check_magic
|
def populate_and_check_magic
|
||||||
magic = @raw_data[0..3].unpack("N").first
|
magic = @raw_data[0..3].unpack("N").first
|
||||||
@ -499,32 +451,32 @@ module MachO
|
|||||||
|
|
||||||
# Check the file's CPU type.
|
# Check the file's CPU type.
|
||||||
# @param cputype [Fixnum] the CPU type
|
# @param cputype [Fixnum] the CPU type
|
||||||
# @raise [MachO::CPUTypeError] if the CPU type is unknown
|
# @raise [CPUTypeError] if the CPU type is unknown
|
||||||
# @api private
|
# @api private
|
||||||
def check_cputype(cputype)
|
def check_cputype(cputype)
|
||||||
raise CPUTypeError, cputype unless CPU_TYPES.key?(cputype)
|
raise CPUTypeError, cputype unless Headers::CPU_TYPES.key?(cputype)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check the file's CPU type/subtype pair.
|
# Check the file's CPU type/subtype pair.
|
||||||
# @param cpusubtype [Fixnum] the CPU subtype
|
# @param cpusubtype [Fixnum] the CPU subtype
|
||||||
# @raise [MachO::CPUSubtypeError] if the CPU sub-type is unknown
|
# @raise [CPUSubtypeError] if the CPU sub-type is unknown
|
||||||
# @api private
|
# @api private
|
||||||
def check_cpusubtype(cputype, cpusubtype)
|
def check_cpusubtype(cputype, cpusubtype)
|
||||||
# Only check sub-type w/o capability bits (see `populate_mach_header`).
|
# Only check sub-type w/o capability bits (see `populate_mach_header`).
|
||||||
raise CPUSubtypeError.new(cputype, cpusubtype) unless CPU_SUBTYPES[cputype].key?(cpusubtype)
|
raise CPUSubtypeError.new(cputype, cpusubtype) unless Headers::CPU_SUBTYPES[cputype].key?(cpusubtype)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check the file's type.
|
# Check the file's type.
|
||||||
# @param filetype [Fixnum] the file type
|
# @param filetype [Fixnum] the file type
|
||||||
# @raise [MachO::FiletypeError] if the file type is unknown
|
# @raise [FiletypeError] if the file type is unknown
|
||||||
# @api private
|
# @api private
|
||||||
def check_filetype(filetype)
|
def check_filetype(filetype)
|
||||||
raise FiletypeError, filetype unless MH_FILETYPES.key?(filetype)
|
raise FiletypeError, filetype unless Headers::MH_FILETYPES.key?(filetype)
|
||||||
end
|
end
|
||||||
|
|
||||||
# All load commands in the file.
|
# All load commands in the file.
|
||||||
# @return [Array<MachO::LoadCommand>] an array of load commands
|
# @return [Array<LoadCommands::LoadCommand>] an array of load commands
|
||||||
# @raise [MachO::LoadCommandError] if an unknown load command is encountered
|
# @raise [LoadCommandError] if an unknown load command is encountered
|
||||||
# @api private
|
# @api private
|
||||||
def populate_load_commands
|
def populate_load_commands
|
||||||
offset = header.class.bytesize
|
offset = header.class.bytesize
|
||||||
@ -533,13 +485,13 @@ module MachO
|
|||||||
header.ncmds.times do
|
header.ncmds.times do
|
||||||
fmt = Utils.specialize_format("L=", endianness)
|
fmt = Utils.specialize_format("L=", endianness)
|
||||||
cmd = @raw_data.slice(offset, 4).unpack(fmt).first
|
cmd = @raw_data.slice(offset, 4).unpack(fmt).first
|
||||||
cmd_sym = LOAD_COMMANDS[cmd]
|
cmd_sym = LoadCommands::LOAD_COMMANDS[cmd]
|
||||||
|
|
||||||
raise LoadCommandError, cmd if cmd_sym.nil?
|
raise LoadCommandError, cmd if cmd_sym.nil?
|
||||||
|
|
||||||
# why do I do this? i don't like declaring constants below
|
# why do I do this? i don't like declaring constants below
|
||||||
# classes, and i need them to resolve...
|
# classes, and i need them to resolve...
|
||||||
klass = MachO.const_get LC_STRUCTURES[cmd_sym]
|
klass = LoadCommands.const_get LoadCommands::LC_STRUCTURES[cmd_sym]
|
||||||
view = MachOView.new(@raw_data, endianness, offset)
|
view = MachOView.new(@raw_data, endianness, offset)
|
||||||
command = klass.new_from_bin(view)
|
command = klass.new_from_bin(view)
|
||||||
|
|
||||||
|
25
Library/Homebrew/vendor/macho/macho/open.rb
vendored
25
Library/Homebrew/vendor/macho/macho/open.rb
vendored
@ -1,25 +0,0 @@
|
|||||||
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
|
|
||||||
# @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)
|
|
||||||
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
|
||||||
raise TruncatedFileError unless File.stat(filename).size >= 4
|
|
||||||
|
|
||||||
magic = File.open(filename, "rb") { |f| f.read(4) }.unpack("N").first
|
|
||||||
|
|
||||||
if Utils.fat_magic?(magic)
|
|
||||||
file = FatFile.new(filename)
|
|
||||||
elsif Utils.magic?(magic)
|
|
||||||
file = MachOFile.new(filename)
|
|
||||||
else
|
|
||||||
raise MagicError, magic
|
|
||||||
end
|
|
||||||
|
|
||||||
file
|
|
||||||
end
|
|
||||||
end
|
|
16
Library/Homebrew/vendor/macho/macho/sections.rb
vendored
16
Library/Homebrew/vendor/macho/macho/sections.rb
vendored
@ -1,4 +1,6 @@
|
|||||||
module MachO
|
module MachO
|
||||||
|
# Classes and constants for parsing sections in Mach-O binaries.
|
||||||
|
module Sections
|
||||||
# type mask
|
# type mask
|
||||||
SECTION_TYPE = 0x000000ff
|
SECTION_TYPE = 0x000000ff
|
||||||
|
|
||||||
@ -70,7 +72,8 @@ module MachO
|
|||||||
# @return [String] the name of the section, including null pad bytes
|
# @return [String] the name of the section, including null pad bytes
|
||||||
attr_reader :sectname
|
attr_reader :sectname
|
||||||
|
|
||||||
# @return [String] the name of the segment's section, including null pad bytes
|
# @return [String] the name of the segment's section, including null
|
||||||
|
# pad bytes
|
||||||
attr_reader :segname
|
attr_reader :segname
|
||||||
|
|
||||||
# @return [Fixnum] the memory address of the section
|
# @return [Fixnum] the memory address of the section
|
||||||
@ -122,17 +125,19 @@ module MachO
|
|||||||
@reserved2 = reserved2
|
@reserved2 = reserved2
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [String] the section's name, with any trailing NULL characters removed
|
# @return [String] the section's name, with any trailing NULL characters
|
||||||
|
# removed
|
||||||
def section_name
|
def section_name
|
||||||
sectname.delete("\x00")
|
sectname.delete("\x00")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [String] the parent segment's name, with any trailing NULL characters removed
|
# @return [String] the parent segment's name, with any trailing NULL
|
||||||
|
# characters removed
|
||||||
def segment_name
|
def segment_name
|
||||||
segname.delete("\x00")
|
segname.delete("\x00")
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] true if the section has no contents (i.e, `size` is 0)
|
# @return [Boolean] whether the section is empty (i.e, {size} is 0)
|
||||||
def empty?
|
def empty?
|
||||||
size.zero?
|
size.zero?
|
||||||
end
|
end
|
||||||
@ -140,7 +145,7 @@ module MachO
|
|||||||
# @example
|
# @example
|
||||||
# puts "this section is regular" if sect.flag?(:S_REGULAR)
|
# puts "this section is regular" if sect.flag?(:S_REGULAR)
|
||||||
# @param flag [Symbol] a section flag symbol
|
# @param flag [Symbol] a section flag symbol
|
||||||
# @return [Boolean] true if `flag` is present in the section's flag field
|
# @return [Boolean] whether the flag is present in the section's {flags}
|
||||||
def flag?(flag)
|
def flag?(flag)
|
||||||
flag = SECTION_FLAGS[flag]
|
flag = SECTION_FLAGS[flag]
|
||||||
return false if flag.nil?
|
return false if flag.nil?
|
||||||
@ -168,3 +173,4 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
@ -19,7 +19,7 @@ module MachO
|
|||||||
|
|
||||||
# @param endianness [Symbol] either `:big` or `:little`
|
# @param endianness [Symbol] either `:big` or `:little`
|
||||||
# @param bin [String] the string to be unpacked into the new structure
|
# @param bin [String] the string to be unpacked into the new structure
|
||||||
# @return [MachO::MachOStructure] a new MachOStructure initialized with `bin`
|
# @return [MachO::MachOStructure] the resulting structure
|
||||||
# @api private
|
# @api private
|
||||||
def self.new_from_bin(endianness, bin)
|
def self.new_from_bin(endianness, bin)
|
||||||
format = Utils.specialize_format(self::FORMAT, endianness)
|
format = Utils.specialize_format(self::FORMAT, endianness)
|
||||||
|
34
Library/Homebrew/vendor/macho/macho/tools.rb
vendored
34
Library/Homebrew/vendor/macho/macho/tools.rb
vendored
@ -1,5 +1,6 @@
|
|||||||
module MachO
|
module MachO
|
||||||
# A collection of convenient methods for common operations on Mach-O and Fat binaries.
|
# A collection of convenient methods for common operations on Mach-O and Fat
|
||||||
|
# binaries.
|
||||||
module Tools
|
module Tools
|
||||||
# @param filename [String] the Mach-O or Fat binary being read
|
# @param filename [String] the Mach-O or Fat binary being read
|
||||||
# @return [Array<String>] an array of all dylibs linked to the binary
|
# @return [Array<String>] an array of all dylibs linked to the binary
|
||||||
@ -9,7 +10,8 @@ module MachO
|
|||||||
file.linked_dylibs
|
file.linked_dylibs
|
||||||
end
|
end
|
||||||
|
|
||||||
# Changes the dylib ID of a Mach-O or Fat binary, overwriting the source file.
|
# 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 filename [String] the Mach-O or Fat binary being modified
|
||||||
# @param new_id [String] the new dylib ID for the binary
|
# @param new_id [String] the new dylib ID for the binary
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
@ -23,7 +25,8 @@ module MachO
|
|||||||
file.write!
|
file.write!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Changes a shared library install name in a Mach-O or Fat binary, overwriting the source file.
|
# 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 filename [String] the Mach-O or Fat binary being modified
|
||||||
# @param old_name [String] the old shared library name
|
# @param old_name [String] the old shared library name
|
||||||
# @param new_name [String] the new shared library name
|
# @param new_name [String] the new shared library name
|
||||||
@ -38,7 +41,8 @@ module MachO
|
|||||||
file.write!
|
file.write!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Changes a runtime path in a Mach-O or Fat binary, overwriting the source file.
|
# 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 filename [String] the Mach-O or Fat binary being modified
|
||||||
# @param old_path [String] the old runtime path
|
# @param old_path [String] the old runtime path
|
||||||
# @param new_path [String] the new runtime path
|
# @param new_path [String] the new runtime path
|
||||||
@ -67,7 +71,8 @@ module MachO
|
|||||||
file.write!
|
file.write!
|
||||||
end
|
end
|
||||||
|
|
||||||
# Delete a runtime path from a Mach-O or Fat binary, overwriting the source file.
|
# 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 filename [String] the Mach-O or Fat binary being modified
|
||||||
# @param old_path [String] the old runtime path
|
# @param old_path [String] the old runtime path
|
||||||
# @param options [Hash]
|
# @param options [Hash]
|
||||||
@ -80,5 +85,24 @@ module MachO
|
|||||||
file.delete_rpath(old_path, options)
|
file.delete_rpath(old_path, options)
|
||||||
file.write!
|
file.write!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Merge multiple Mach-Os into one universal (Fat) binary.
|
||||||
|
# @param filename [String] the fat binary to create
|
||||||
|
# @param files [Array<MachO::MachOFile, MachO::FatFile>] the files to merge
|
||||||
|
# @return [void]
|
||||||
|
def self.merge_machos(filename, *files)
|
||||||
|
machos = files.map do |file|
|
||||||
|
macho = MachO.open(file)
|
||||||
|
case macho
|
||||||
|
when MachO::MachOFile
|
||||||
|
macho
|
||||||
|
else
|
||||||
|
macho.machos
|
||||||
|
end
|
||||||
|
end.flatten
|
||||||
|
|
||||||
|
fat_macho = MachO::FatFile.new_from_machos(*machos)
|
||||||
|
fat_macho.write(filename)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
35
Library/Homebrew/vendor/macho/macho/utils.rb
vendored
35
Library/Homebrew/vendor/macho/macho/utils.rb
vendored
@ -5,7 +5,7 @@ module MachO
|
|||||||
# @param value [Fixnum] the number being rounded
|
# @param value [Fixnum] the number being rounded
|
||||||
# @param round [Fixnum] the number being rounded with
|
# @param round [Fixnum] the number being rounded with
|
||||||
# @return [Fixnum] the rounded value
|
# @return [Fixnum] the rounded value
|
||||||
# @see https://www.opensource.apple.com/source/cctools/cctools-870/libstuff/rnd.c
|
# @see http://www.opensource.apple.com/source/cctools/cctools-870/libstuff/rnd.c
|
||||||
def self.round(value, round)
|
def self.round(value, round)
|
||||||
round -= 1
|
round -= 1
|
||||||
value += round
|
value += round
|
||||||
@ -13,7 +13,8 @@ module MachO
|
|||||||
value
|
value
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the number of bytes needed to pad the given size to the given alignment.
|
# Returns the number of bytes needed to pad the given size to the given
|
||||||
|
# alignment.
|
||||||
# @param size [Fixnum] the unpadded size
|
# @param size [Fixnum] the unpadded size
|
||||||
# @param alignment [Fixnum] the number to alignment the size with
|
# @param alignment [Fixnum] the number to alignment the size with
|
||||||
# @return [Fixnum] the number of pad bytes required
|
# @return [Fixnum] the number of pad bytes required
|
||||||
@ -21,7 +22,8 @@ module MachO
|
|||||||
round(size, alignment) - size
|
round(size, alignment) - size
|
||||||
end
|
end
|
||||||
|
|
||||||
# Converts an abstract (native-endian) String#unpack format to big or little.
|
# Converts an abstract (native-endian) String#unpack format to big or
|
||||||
|
# little.
|
||||||
# @param format [String] the format string being converted
|
# @param format [String] the format string being converted
|
||||||
# @param endianness [Symbol] either `:big` or `:little`
|
# @param endianness [Symbol] either `:big` or `:little`
|
||||||
# @return [String] the converted string
|
# @return [String] the converted string
|
||||||
@ -31,7 +33,8 @@ module MachO
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Packs tagged strings into an aligned payload.
|
# Packs tagged strings into an aligned payload.
|
||||||
# @param fixed_offset [Fixnum] the baseline offset for the first packed string
|
# @param fixed_offset [Fixnum] the baseline offset for the first packed
|
||||||
|
# string
|
||||||
# @param alignment [Fixnum] the alignment value to use for packing
|
# @param alignment [Fixnum] the alignment value to use for packing
|
||||||
# @param strings [Hash] the labeled strings to pack
|
# @param strings [Hash] the labeled strings to pack
|
||||||
# @return [Array<String, Hash>] the packed string and labeled offsets
|
# @return [Array<String, Hash>] the packed string and labeled offsets
|
||||||
@ -53,44 +56,44 @@ module MachO
|
|||||||
|
|
||||||
# Compares the given number to valid Mach-O magic numbers.
|
# Compares the given number to valid Mach-O magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid Mach-O magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid Mach-O magic number
|
||||||
def self.magic?(num)
|
def self.magic?(num)
|
||||||
MH_MAGICS.key?(num)
|
Headers::MH_MAGICS.key?(num)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares the given number to valid Fat magic numbers.
|
# Compares the given number to valid Fat magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid Fat magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid Fat magic number
|
||||||
def self.fat_magic?(num)
|
def self.fat_magic?(num)
|
||||||
num == FAT_MAGIC
|
num == Headers::FAT_MAGIC
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares the given number to valid 32-bit Mach-O magic numbers.
|
# Compares the given number to valid 32-bit Mach-O magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid 32-bit magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid 32-bit magic number
|
||||||
def self.magic32?(num)
|
def self.magic32?(num)
|
||||||
num == MH_MAGIC || num == MH_CIGAM
|
num == Headers::MH_MAGIC || num == Headers::MH_CIGAM
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares the given number to valid 64-bit Mach-O magic numbers.
|
# Compares the given number to valid 64-bit Mach-O magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid 64-bit magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid 64-bit magic number
|
||||||
def self.magic64?(num)
|
def self.magic64?(num)
|
||||||
num == MH_MAGIC_64 || num == MH_CIGAM_64
|
num == Headers::MH_MAGIC_64 || num == Headers::MH_CIGAM_64
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares the given number to valid little-endian magic numbers.
|
# Compares the given number to valid little-endian magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid little-endian magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid little-endian magic number
|
||||||
def self.little_magic?(num)
|
def self.little_magic?(num)
|
||||||
num == MH_CIGAM || num == MH_CIGAM_64
|
num == Headers::MH_CIGAM || num == Headers::MH_CIGAM_64
|
||||||
end
|
end
|
||||||
|
|
||||||
# Compares the given number to valid big-endian magic numbers.
|
# Compares the given number to valid big-endian magic numbers.
|
||||||
# @param num [Fixnum] the number being checked
|
# @param num [Fixnum] the number being checked
|
||||||
# @return [Boolean] true if `num` is a valid big-endian magic number, false otherwise
|
# @return [Boolean] whether `num` is a valid big-endian magic number
|
||||||
def self.big_magic?(num)
|
def self.big_magic?(num)
|
||||||
num == MH_CIGAM || num == MH_CIGAM_64
|
num == Headers::MH_CIGAM || num == Headers::MH_CIGAM_64
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user