brew vendor-gems: commit updates.
This commit is contained in:
parent
fdddc3eb4b
commit
72cc196197
@ -41,4 +41,4 @@ $:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-progressbar-1.10
|
|||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.4.1/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/unicode-display_width-1.4.1/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.65.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-0.65.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.32.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/rubocop-rspec-1.32.0/lib"
|
||||||
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.1.0/lib"
|
$:.unshift "#{path}/../#{ruby_engine}/#{ruby_version}/gems/ruby-macho-2.2.0/lib"
|
||||||
|
|||||||
@ -12,7 +12,7 @@ require_relative "macho/tools"
|
|||||||
# The primary namespace for ruby-macho.
|
# The primary namespace for ruby-macho.
|
||||||
module MachO
|
module MachO
|
||||||
# release version
|
# release version
|
||||||
VERSION = "2.1.0".freeze
|
VERSION = "2.2.0".freeze
|
||||||
|
|
||||||
# Opens the given filename as a MachOFile or FatFile, depending on its magic.
|
# Opens the given filename as a MachOFile or FatFile, depending on its magic.
|
||||||
# @param filename [String] the file being opened
|
# @param filename [String] the file being opened
|
||||||
@ -11,6 +11,10 @@ module MachO
|
|||||||
# @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 [Hash] any parser options that the instance was created with
|
||||||
|
# @note Options specified in a {FatFile} trickle down into the internal {MachOFile}s.
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
# @return [Headers::FatHeader] the file's header
|
# @return [Headers::FatHeader] the file's header
|
||||||
attr_reader :header
|
attr_reader :header
|
||||||
|
|
||||||
@ -49,9 +53,7 @@ module MachO
|
|||||||
machos.each do |macho|
|
machos.each do |macho|
|
||||||
macho_offset = Utils.round(offset, 2**macho.segment_alignment)
|
macho_offset = Utils.round(offset, 2**macho.segment_alignment)
|
||||||
|
|
||||||
if !fat64 && macho_offset > (2**32 - 1)
|
raise FatArchOffsetOverflowError, macho_offset if !fat64 && macho_offset > (2**32 - 1)
|
||||||
raise FatArchOffsetOverflowError, macho_offset
|
|
||||||
end
|
|
||||||
|
|
||||||
macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment)
|
macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment)
|
||||||
|
|
||||||
@ -72,30 +74,36 @@ module MachO
|
|||||||
|
|
||||||
# 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
|
||||||
|
# @param opts [Hash] options to control the parser with
|
||||||
|
# @note see {MachOFile#initialize} for currently valid options
|
||||||
# @return [FatFile] a new FatFile
|
# @return [FatFile] a new FatFile
|
||||||
def self.new_from_bin(bin)
|
def self.new_from_bin(bin, **opts)
|
||||||
instance = allocate
|
instance = allocate
|
||||||
instance.initialize_from_bin(bin)
|
instance.initialize_from_bin(bin, opts)
|
||||||
|
|
||||||
instance
|
instance
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a new FatFile from the given filename.
|
# Creates a new FatFile from the given filename.
|
||||||
# @param filename [String] the fat file to load from
|
# @param filename [String] the fat file to load from
|
||||||
|
# @param opts [Hash] options to control the parser with
|
||||||
|
# @note see {MachOFile#initialize} for currently valid options
|
||||||
# @raise [ArgumentError] if the given file does not exist
|
# @raise [ArgumentError] if the given file does not exist
|
||||||
def initialize(filename)
|
def initialize(filename, **opts)
|
||||||
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
||||||
|
|
||||||
@filename = filename
|
@filename = filename
|
||||||
|
@options = opts
|
||||||
@raw_data = File.open(@filename, "rb", &:read)
|
@raw_data = File.open(@filename, "rb", &:read)
|
||||||
populate_fields
|
populate_fields
|
||||||
end
|
end
|
||||||
|
|
||||||
# Initializes a new FatFile instance from a binary string.
|
# Initializes a new FatFile instance from a binary string with the given options.
|
||||||
# @see new_from_bin
|
# @see new_from_bin
|
||||||
# @api private
|
# @api private
|
||||||
def initialize_from_bin(bin)
|
def initialize_from_bin(bin, opts)
|
||||||
@filename = nil
|
@filename = nil
|
||||||
|
@options = opts
|
||||||
@raw_data = bin
|
@raw_data = bin
|
||||||
populate_fields
|
populate_fields
|
||||||
end
|
end
|
||||||
@ -358,7 +366,7 @@ module MachO
|
|||||||
machos = []
|
machos = []
|
||||||
|
|
||||||
fat_archs.each do |arch|
|
fat_archs.each do |arch|
|
||||||
machos << MachOFile.new_from_bin(@raw_data[arch.offset, arch.size])
|
machos << MachOFile.new_from_bin(@raw_data[arch.offset, arch.size], **options)
|
||||||
end
|
end
|
||||||
|
|
||||||
machos
|
machos
|
||||||
@ -241,6 +241,10 @@ module MachO
|
|||||||
# @api private
|
# @api private
|
||||||
CPU_SUBTYPE_ARM64_32_V8 = 1
|
CPU_SUBTYPE_ARM64_32_V8 = 1
|
||||||
|
|
||||||
|
# the e (A12) sub-type for `CPU_TYPE_ARM64`
|
||||||
|
# @api private
|
||||||
|
CPU_SUBTYPE_ARM64E = 2
|
||||||
|
|
||||||
# the lowest common sub-type for `CPU_TYPE_MC88000`
|
# the lowest common sub-type for `CPU_TYPE_MC88000`
|
||||||
# @api private
|
# @api private
|
||||||
CPU_SUBTYPE_MC88000_ALL = 0
|
CPU_SUBTYPE_MC88000_ALL = 0
|
||||||
@ -350,6 +354,7 @@ module MachO
|
|||||||
CPU_TYPE_ARM64 => {
|
CPU_TYPE_ARM64 => {
|
||||||
CPU_SUBTYPE_ARM64_ALL => :arm64,
|
CPU_SUBTYPE_ARM64_ALL => :arm64,
|
||||||
CPU_SUBTYPE_ARM64_V8 => :arm64v8,
|
CPU_SUBTYPE_ARM64_V8 => :arm64v8,
|
||||||
|
CPU_SUBTYPE_ARM64E => :arm64e,
|
||||||
}.freeze,
|
}.freeze,
|
||||||
CPU_TYPE_ARM64_32 => {
|
CPU_TYPE_ARM64_32 => {
|
||||||
CPU_SUBTYPE_ARM64_32_V8 => :arm64_32v8,
|
CPU_SUBTYPE_ARM64_32_V8 => :arm64_32v8,
|
||||||
@ -9,10 +9,13 @@ module MachO
|
|||||||
class MachOFile
|
class MachOFile
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
|
|
||||||
# @return [String] the filename loaded from, or nil if loaded from a binary
|
# @return [String, nil] the filename loaded from, or nil if loaded from a binary
|
||||||
# string
|
# string
|
||||||
attr_accessor :filename
|
attr_accessor :filename
|
||||||
|
|
||||||
|
# @return [Hash] any parser options that the instance was created with
|
||||||
|
attr_reader :options
|
||||||
|
|
||||||
# @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
|
||||||
|
|
||||||
@ -27,30 +30,36 @@ module MachO
|
|||||||
|
|
||||||
# Creates a new instance from a binary string.
|
# Creates a new 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
|
||||||
|
# @param opts [Hash] options to control the parser with
|
||||||
|
# @option opts [Boolean] :permissive whether to ignore unknown load commands
|
||||||
# @return [MachOFile] a new MachOFile
|
# @return [MachOFile] a new MachOFile
|
||||||
def self.new_from_bin(bin)
|
def self.new_from_bin(bin, **opts)
|
||||||
instance = allocate
|
instance = allocate
|
||||||
instance.initialize_from_bin(bin)
|
instance.initialize_from_bin(bin, opts)
|
||||||
|
|
||||||
instance
|
instance
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a new instance from data read from the given filename.
|
# Creates a new instance from data read from the given filename.
|
||||||
# @param filename [String] the Mach-O file to load from
|
# @param filename [String] the Mach-O file to load from
|
||||||
|
# @param opts [Hash] options to control the parser with
|
||||||
|
# @option opts [Boolean] :permissive whether to ignore unknown load commands
|
||||||
# @raise [ArgumentError] if the given file does not exist
|
# @raise [ArgumentError] if the given file does not exist
|
||||||
def initialize(filename)
|
def initialize(filename, **opts)
|
||||||
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
raise ArgumentError, "#{filename}: no such file" unless File.file?(filename)
|
||||||
|
|
||||||
@filename = filename
|
@filename = filename
|
||||||
|
@options = opts
|
||||||
@raw_data = File.open(@filename, "rb", &:read)
|
@raw_data = File.open(@filename, "rb", &:read)
|
||||||
populate_fields
|
populate_fields
|
||||||
end
|
end
|
||||||
|
|
||||||
# Initializes a new MachOFile instance from a binary string.
|
# Initializes a new MachOFile instance from a binary string with the given options.
|
||||||
# @see MachO::MachOFile.new_from_bin
|
# @see MachO::MachOFile.new_from_bin
|
||||||
# @api private
|
# @api private
|
||||||
def initialize_from_bin(bin)
|
def initialize_from_bin(bin, opts)
|
||||||
@filename = nil
|
@filename = nil
|
||||||
|
@options = opts
|
||||||
@raw_data = bin
|
@raw_data = bin
|
||||||
populate_fields
|
populate_fields
|
||||||
end
|
end
|
||||||
@ -146,16 +155,13 @@ module MachO
|
|||||||
def insert_command(offset, lc, options = {})
|
def insert_command(offset, lc, options = {})
|
||||||
context = LoadCommands::LoadCommand::SerializationContext.context_for(self)
|
context = LoadCommands::LoadCommand::SerializationContext.context_for(self)
|
||||||
cmd_raw = lc.serialize(context)
|
cmd_raw = lc.serialize(context)
|
||||||
|
fileoff = offset + cmd_raw.bytesize
|
||||||
|
|
||||||
if offset < header.class.bytesize || offset + cmd_raw.bytesize > low_fileoff
|
raise OffsetInsertionError, offset if offset < header.class.bytesize || fileoff > low_fileoff
|
||||||
raise OffsetInsertionError, offset
|
|
||||||
end
|
|
||||||
|
|
||||||
new_sizeofcmds = sizeofcmds + cmd_raw.bytesize
|
new_sizeofcmds = sizeofcmds + cmd_raw.bytesize
|
||||||
|
|
||||||
if header.class.bytesize + new_sizeofcmds > low_fileoff
|
raise HeaderPadError, @filename if header.class.bytesize + new_sizeofcmds > low_fileoff
|
||||||
raise HeaderPadError, @filename
|
|
||||||
end
|
|
||||||
|
|
||||||
# update Mach-O header fields to account for inserted load command
|
# update Mach-O header fields to account for inserted load command
|
||||||
update_ncmds(ncmds + 1)
|
update_ncmds(ncmds + 1)
|
||||||
@ -178,9 +184,8 @@ module MachO
|
|||||||
context = LoadCommands::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
|
|
||||||
raise HeaderPadError, @filename
|
raise HeaderPadError, @filename if header.class.bytesize + new_sizeofcmds > low_fileoff
|
||||||
end
|
|
||||||
|
|
||||||
delete_command(old_lc)
|
delete_command(old_lc)
|
||||||
insert_command(old_lc.view.offset, new_lc)
|
insert_command(old_lc.view.offset, new_lc)
|
||||||
@ -511,6 +516,7 @@ module MachO
|
|||||||
# @raise [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
|
||||||
|
permissive = options.fetch(:permissive, false)
|
||||||
offset = header.class.bytesize
|
offset = header.class.bytesize
|
||||||
load_commands = []
|
load_commands = []
|
||||||
|
|
||||||
@ -519,11 +525,16 @@ module MachO
|
|||||||
cmd = @raw_data.slice(offset, 4).unpack(fmt).first
|
cmd = @raw_data.slice(offset, 4).unpack(fmt).first
|
||||||
cmd_sym = LoadCommands::LOAD_COMMANDS[cmd]
|
cmd_sym = LoadCommands::LOAD_COMMANDS[cmd]
|
||||||
|
|
||||||
raise LoadCommandError, cmd if cmd_sym.nil?
|
raise LoadCommandError, cmd unless cmd_sym || permissive
|
||||||
|
|
||||||
|
# If we're here, then either cmd_sym represents a valid load
|
||||||
|
# command *or* we're in permissive mode.
|
||||||
|
klass = if (klass_str = LoadCommands::LC_STRUCTURES[cmd_sym])
|
||||||
|
LoadCommands.const_get klass_str
|
||||||
|
else
|
||||||
|
LoadCommands::LoadCommand
|
||||||
|
end
|
||||||
|
|
||||||
# why do I do this? i don't like declaring constants below
|
|
||||||
# classes, and i need them to resolve...
|
|
||||||
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)
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user