vendor: ruby-macho 2.0
This commit is contained in:
parent
343a5b45a9
commit
bace3ac526
22
Library/Homebrew/vendor/macho/macho.rb
vendored
22
Library/Homebrew/vendor/macho/macho.rb
vendored
@ -1,18 +1,18 @@
|
|||||||
require "#{File.dirname(__FILE__)}/macho/structure"
|
require_relative "macho/structure"
|
||||||
require "#{File.dirname(__FILE__)}/macho/view"
|
require_relative "macho/view"
|
||||||
require "#{File.dirname(__FILE__)}/macho/headers"
|
require_relative "macho/headers"
|
||||||
require "#{File.dirname(__FILE__)}/macho/load_commands"
|
require_relative "macho/load_commands"
|
||||||
require "#{File.dirname(__FILE__)}/macho/sections"
|
require_relative "macho/sections"
|
||||||
require "#{File.dirname(__FILE__)}/macho/macho_file"
|
require_relative "macho/macho_file"
|
||||||
require "#{File.dirname(__FILE__)}/macho/fat_file"
|
require_relative "macho/fat_file"
|
||||||
require "#{File.dirname(__FILE__)}/macho/exceptions"
|
require_relative "macho/exceptions"
|
||||||
require "#{File.dirname(__FILE__)}/macho/utils"
|
require_relative "macho/utils"
|
||||||
require "#{File.dirname(__FILE__)}/macho/tools"
|
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 = "1.2.0".freeze
|
VERSION = "2.0.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
|
||||||
|
|||||||
45
Library/Homebrew/vendor/macho/macho/fat_file.rb
vendored
45
Library/Homebrew/vendor/macho/macho/fat_file.rb
vendored
@ -23,21 +23,37 @@ module MachO
|
|||||||
# Creates a new FatFile from the given (single-arch) Mach-Os
|
# Creates a new FatFile from the given (single-arch) Mach-Os
|
||||||
# @param machos [Array<MachOFile>] the machos to combine
|
# @param machos [Array<MachOFile>] the machos to combine
|
||||||
# @return [FatFile] a new FatFile containing the give machos
|
# @return [FatFile] a new FatFile containing the give machos
|
||||||
|
# @raise [ArgumentError] if less than one Mach-O is given
|
||||||
def self.new_from_machos(*machos)
|
def self.new_from_machos(*machos)
|
||||||
header = Headers::FatHeader.new(Headers::FAT_MAGIC, machos.size)
|
raise ArgumentError, "expected at least one Mach-O" if machos.empty?
|
||||||
|
|
||||||
|
# put the smaller alignments further forwards in fat macho, so that we do less padding
|
||||||
|
machos = machos.sort_by(&:segment_alignment)
|
||||||
|
|
||||||
|
bin = +""
|
||||||
|
|
||||||
|
bin << Headers::FatHeader.new(Headers::FAT_MAGIC, machos.size).serialize
|
||||||
offset = Headers::FatHeader.bytesize + (machos.size * Headers::FatArch.bytesize)
|
offset = Headers::FatHeader.bytesize + (machos.size * Headers::FatArch.bytesize)
|
||||||
fat_archs = []
|
|
||||||
|
macho_pads = {}
|
||||||
|
macho_bins = {}
|
||||||
|
|
||||||
machos.each do |macho|
|
machos.each do |macho|
|
||||||
fat_archs << Headers::FatArch.new(macho.header.cputype,
|
macho_offset = Utils.round(offset, 2**macho.segment_alignment)
|
||||||
macho.header.cpusubtype,
|
macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment)
|
||||||
offset, macho.serialize.bytesize,
|
macho_bins[macho] = macho.serialize
|
||||||
macho.alignment)
|
|
||||||
offset += macho.serialize.bytesize
|
bin << Headers::FatArch.new(macho.header.cputype, macho.header.cpusubtype,
|
||||||
|
macho_offset, macho_bins[macho].bytesize,
|
||||||
|
macho.segment_alignment).serialize
|
||||||
|
|
||||||
|
offset += (macho_bins[macho].bytesize + macho_pads[macho])
|
||||||
end
|
end
|
||||||
|
|
||||||
bin = header.serialize
|
machos.each do |macho|
|
||||||
bin << fat_archs.map(&:serialize).join
|
bin << Utils.nullpad(macho_pads[macho])
|
||||||
bin << machos.map(&:serialize).join
|
bin << macho_bins[macho]
|
||||||
|
end
|
||||||
|
|
||||||
new_from_bin(bin)
|
new_from_bin(bin)
|
||||||
end
|
end
|
||||||
@ -265,6 +281,15 @@ module MachO
|
|||||||
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {FatFile}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"header" => header.to_h,
|
||||||
|
"fat_archs" => fat_archs.map(&:to_h),
|
||||||
|
"machos" => machos.map(&:to_h),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Obtain the fat header from raw file data.
|
# Obtain the fat header from raw file data.
|
||||||
|
|||||||
49
Library/Homebrew/vendor/macho/macho/headers.rb
vendored
49
Library/Homebrew/vendor/macho/macho/headers.rb
vendored
@ -475,6 +475,15 @@ module MachO
|
|||||||
def serialize
|
def serialize
|
||||||
[magic, nfat_arch].pack(FORMAT)
|
[magic, nfat_arch].pack(FORMAT)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {FatHeader}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"magic" => magic,
|
||||||
|
"magic_sym" => MH_MAGICS[magic],
|
||||||
|
"nfat_arch" => nfat_arch,
|
||||||
|
}.merge super
|
||||||
|
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
|
||||||
@ -508,7 +517,7 @@ module MachO
|
|||||||
# @api private
|
# @api private
|
||||||
def initialize(cputype, cpusubtype, offset, size, align)
|
def initialize(cputype, cpusubtype, offset, size, align)
|
||||||
@cputype = cputype
|
@cputype = cputype
|
||||||
@cpusubtype = cpusubtype
|
@cpusubtype = cpusubtype & ~CPU_SUBTYPE_MASK
|
||||||
@offset = offset
|
@offset = offset
|
||||||
@size = size
|
@size = size
|
||||||
@align = align
|
@align = align
|
||||||
@ -518,6 +527,19 @@ module MachO
|
|||||||
def serialize
|
def serialize
|
||||||
[cputype, cpusubtype, offset, size, align].pack(FORMAT)
|
[cputype, cpusubtype, offset, size, align].pack(FORMAT)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {FatArch}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"cputype" => cputype,
|
||||||
|
"cputype_sym" => CPU_TYPES[cputype],
|
||||||
|
"cpusubtype" => cpusubtype,
|
||||||
|
"cpusubtype_sym" => CPU_SUBTYPES[cputype][cpusubtype],
|
||||||
|
"offset" => offset,
|
||||||
|
"size" => size,
|
||||||
|
"align" => align,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 32-bit Mach-O file header structure
|
# 32-bit Mach-O file header structure
|
||||||
@ -639,6 +661,24 @@ module MachO
|
|||||||
def alignment
|
def alignment
|
||||||
magic32? ? 4 : 8
|
magic32? ? 4 : 8
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {MachHeader}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"magic" => magic,
|
||||||
|
"magic_sym" => MH_MAGICS[magic],
|
||||||
|
"cputype" => cputype,
|
||||||
|
"cputype_sym" => CPU_TYPES[cputype],
|
||||||
|
"cpusubtype" => cpusubtype,
|
||||||
|
"cpusubtype_sym" => CPU_SUBTYPES[cputype][cpusubtype],
|
||||||
|
"filetype" => filetype,
|
||||||
|
"filetype_sym" => MH_FILETYPES[filetype],
|
||||||
|
"ncmds" => ncmds,
|
||||||
|
"sizeofcmds" => sizeofcmds,
|
||||||
|
"flags" => flags,
|
||||||
|
"alignment" => alignment,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# 64-bit Mach-O file header structure
|
# 64-bit Mach-O file header structure
|
||||||
@ -660,6 +700,13 @@ module MachO
|
|||||||
super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
|
super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
|
||||||
@reserved = reserved
|
@reserved = reserved
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {MachHeader64}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"reserved" => reserved,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
444
Library/Homebrew/vendor/macho/macho/load_commands.rb
vendored
444
Library/Homebrew/vendor/macho/macho/load_commands.rb
vendored
@ -143,7 +143,7 @@ module MachO
|
|||||||
:LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand",
|
:LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand",
|
||||||
:LC_VERSION_MIN_TVOS => "VersionMinCommand",
|
:LC_VERSION_MIN_TVOS => "VersionMinCommand",
|
||||||
:LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
|
:LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
|
||||||
:LC_NOTE => "LoadCommand",
|
:LC_NOTE => "NoteCommand",
|
||||||
:LC_BUILD_VERSION => "BuildVersionCommand",
|
:LC_BUILD_VERSION => "BuildVersionCommand",
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
@ -169,15 +169,16 @@ module MachO
|
|||||||
:SG_PROTECTED_VERSION_1 => 0x8,
|
:SG_PROTECTED_VERSION_1 => 0x8,
|
||||||
}.freeze
|
}.freeze
|
||||||
|
|
||||||
# Mach-O load command structure
|
# The top-level Mach-O load command structure.
|
||||||
# This is the most generic load command - only cmd ID and size are
|
#
|
||||||
# represented, and no actual data. Used when a more specific class
|
# This is the most generic load command -- only the type ID and size are
|
||||||
# isn't available/implemented.
|
# represented. Used when a more specific class isn't available or isn't implemented.
|
||||||
class LoadCommand < MachOStructure
|
class LoadCommand < MachOStructure
|
||||||
# @return [MachO::MachOView] the raw view associated with the load command
|
# @return [MachO::MachOView, nil] the raw view associated with the load command,
|
||||||
|
# or nil if the load command was created via {create}.
|
||||||
attr_reader :view
|
attr_reader :view
|
||||||
|
|
||||||
# @return [Integer] the load command's identifying number
|
# @return [Integer] the load command's type ID
|
||||||
attr_reader :cmd
|
attr_reader :cmd
|
||||||
|
|
||||||
# @return [Integer] the size of the load command, in bytes
|
# @return [Integer] the size of the load command, in bytes
|
||||||
@ -251,8 +252,8 @@ module MachO
|
|||||||
view.offset
|
view.offset
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Symbol] a symbol representation of the load command's
|
# @return [Symbol, nil] a symbol representation of the load command's
|
||||||
# identifying number
|
# type ID, or nil if the ID doesn't correspond to a known load command class
|
||||||
def type
|
def type
|
||||||
LOAD_COMMANDS[cmd]
|
LOAD_COMMANDS[cmd]
|
||||||
end
|
end
|
||||||
@ -265,6 +266,17 @@ module MachO
|
|||||||
type.to_s
|
type.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this load command
|
||||||
|
# @note Children should override this to include additional information.
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"view" => view.to_h,
|
||||||
|
"cmd" => cmd,
|
||||||
|
"cmdsize" => cmdsize,
|
||||||
|
"type" => type,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
|
|
||||||
# Represents a Load Command string. A rough analogue to the lc_str
|
# Represents a Load Command string. A rough analogue to the lc_str
|
||||||
# struct used internally by OS X. This class allows ruby-macho to
|
# struct used internally by OS X. This class allows ruby-macho to
|
||||||
# pretend that strings stored in LCs are immediately available without
|
# pretend that strings stored in LCs are immediately available without
|
||||||
@ -304,6 +316,14 @@ module MachO
|
|||||||
def to_i
|
def to_i
|
||||||
@string_offset
|
@string_offset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {LCStr}.
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"string" => to_s,
|
||||||
|
"offset" => to_i,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Represents the contextual information needed by a load command to
|
# Represents the contextual information needed by a load command to
|
||||||
@ -364,6 +384,14 @@ module MachO
|
|||||||
|
|
||||||
segs.join("-")
|
segs.join("-")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] returns a hash representation of this {UUIDCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"uuid" => uuid,
|
||||||
|
"uuid_string" => uuid_string,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command indicating that part of this file is to be mapped into
|
# A load command indicating that part of this file is to be mapped into
|
||||||
@ -398,7 +426,7 @@ module MachO
|
|||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
# @api private
|
# @api private
|
||||||
FORMAT = "L=2a16L=4l=2L=2".freeze
|
FORMAT = "L=2Z16L=4l=2L=2".freeze
|
||||||
|
|
||||||
# @see MachOStructure::SIZEOF
|
# @see MachOStructure::SIZEOF
|
||||||
# @api private
|
# @api private
|
||||||
@ -408,7 +436,7 @@ module MachO
|
|||||||
def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
||||||
filesize, maxprot, initprot, nsects, flags)
|
filesize, maxprot, initprot, nsects, flags)
|
||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@segname = segname.delete("\x00")
|
@segname = segname
|
||||||
@vmaddr = vmaddr
|
@vmaddr = vmaddr
|
||||||
@vmsize = vmsize
|
@vmsize = vmsize
|
||||||
@fileoff = fileoff
|
@fileoff = fileoff
|
||||||
@ -448,6 +476,42 @@ module MachO
|
|||||||
return false if flag.nil?
|
return false if flag.nil?
|
||||||
flags & flag == flag
|
flags & flag == flag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Guesses the alignment of the segment.
|
||||||
|
# @return [Integer] the guessed alignment, as a power of 2
|
||||||
|
# @note See `guess_align` in `cctools/misc/lipo.c`
|
||||||
|
def guess_align
|
||||||
|
return Sections::MAX_SECT_ALIGN if vmaddr.zero?
|
||||||
|
|
||||||
|
align = 0
|
||||||
|
segalign = 1
|
||||||
|
|
||||||
|
while (segalign & vmaddr).zero?
|
||||||
|
segalign <<= 1
|
||||||
|
align += 1
|
||||||
|
end
|
||||||
|
|
||||||
|
return 2 if align < 2
|
||||||
|
return Sections::MAX_SECT_ALIGN if align > Sections::MAX_SECT_ALIGN
|
||||||
|
|
||||||
|
align
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SegmentCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"segname" => segname,
|
||||||
|
"vmaddr" => vmaddr,
|
||||||
|
"vmsize" => vmsize,
|
||||||
|
"fileoff" => fileoff,
|
||||||
|
"filesize" => filesize,
|
||||||
|
"maxprot" => maxprot,
|
||||||
|
"initprot" => initprot,
|
||||||
|
"nsects" => nsects,
|
||||||
|
"flags" => flags,
|
||||||
|
"sections" => sections.map(&:to_h),
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command indicating that part of this file is to be mapped into
|
# A load command indicating that part of this file is to be mapped into
|
||||||
@ -455,7 +519,7 @@ module MachO
|
|||||||
class SegmentCommand64 < SegmentCommand
|
class SegmentCommand64 < SegmentCommand
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
# @api private
|
# @api private
|
||||||
FORMAT = "L=2a16Q=4l=2L=2".freeze
|
FORMAT = "L=2Z16Q=4l=2L=2".freeze
|
||||||
|
|
||||||
# @see MachOStructure::SIZEOF
|
# @see MachOStructure::SIZEOF
|
||||||
# @api private
|
# @api private
|
||||||
@ -510,6 +574,16 @@ module MachO
|
|||||||
[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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {DylibCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"name" => name.to_h,
|
||||||
|
"timestamp" => timestamp,
|
||||||
|
"current_version" => current_version,
|
||||||
|
"compatibility_version" => compatibility_version,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing some aspect of the dynamic linker, depending
|
# A load command representing some aspect of the dynamic linker, depending
|
||||||
@ -546,6 +620,13 @@ module MachO
|
|||||||
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
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {DylinkerCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"name" => name.to_h,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command used to indicate dynamic libraries used in prebinding.
|
# A load command used to indicate dynamic libraries used in prebinding.
|
||||||
@ -576,6 +657,15 @@ module MachO
|
|||||||
@nmodules = nmodules
|
@nmodules = nmodules
|
||||||
@linked_modules = linked_modules
|
@linked_modules = linked_modules
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {PreboundDylibCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"name" => name.to_h,
|
||||||
|
"nmodules" => nmodules,
|
||||||
|
"linked_modules" => linked_modules,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command used to represent threads.
|
# A load command used to represent threads.
|
||||||
@ -641,6 +731,20 @@ module MachO
|
|||||||
@reserved5 = reserved5
|
@reserved5 = reserved5
|
||||||
@reserved6 = reserved6
|
@reserved6 = reserved6
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {RoutinesCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"init_address" => init_address,
|
||||||
|
"init_module" => init_module,
|
||||||
|
"reserved1" => reserved1,
|
||||||
|
"reserved2" => reserved2,
|
||||||
|
"reserved3" => reserved3,
|
||||||
|
"reserved4" => reserved4,
|
||||||
|
"reserved5" => reserved5,
|
||||||
|
"reserved6" => reserved6,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the address of the dynamic shared library
|
# A load command containing the address of the dynamic shared library
|
||||||
@ -675,6 +779,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@umbrella = LCStr.new(self, umbrella)
|
@umbrella = LCStr.new(self, umbrella)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SubFrameworkCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"umbrella" => umbrella.to_h,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command signifying membership of a subumbrella containing the name
|
# A load command signifying membership of a subumbrella containing the name
|
||||||
@ -696,6 +807,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@sub_umbrella = LCStr.new(self, sub_umbrella)
|
@sub_umbrella = LCStr.new(self, sub_umbrella)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SubUmbrellaCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"sub_umbrella" => sub_umbrella.to_h,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command signifying a sublibrary of a shared library. Corresponds
|
# A load command signifying a sublibrary of a shared library. Corresponds
|
||||||
@ -717,6 +835,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@sub_library = LCStr.new(self, sub_library)
|
@sub_library = LCStr.new(self, sub_library)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SubLibraryCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"sub_library" => sub_library.to_h,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command signifying a shared library that is a subframework of
|
# A load command signifying a shared library that is a subframework of
|
||||||
@ -738,6 +863,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@sub_client = LCStr.new(self, sub_client)
|
@sub_client = LCStr.new(self, sub_client)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SubClientCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"sub_client" => sub_client.to_h,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the offsets and sizes of the link-edit 4.3BSD
|
# A load command containing the offsets and sizes of the link-edit 4.3BSD
|
||||||
@ -749,10 +881,10 @@ module MachO
|
|||||||
# @return [Integer] the number of symbol table entries
|
# @return [Integer] the number of symbol table entries
|
||||||
attr_reader :nsyms
|
attr_reader :nsyms
|
||||||
|
|
||||||
# @return the string table's offset
|
# @return [Integer] the string table's offset
|
||||||
attr_reader :stroff
|
attr_reader :stroff
|
||||||
|
|
||||||
# @return the string table size in bytes
|
# @return [Integer] the string table size in bytes
|
||||||
attr_reader :strsize
|
attr_reader :strsize
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
@ -771,6 +903,16 @@ module MachO
|
|||||||
@stroff = stroff
|
@stroff = stroff
|
||||||
@strsize = strsize
|
@strsize = strsize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SymtabCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"symoff" => symoff,
|
||||||
|
"nsyms" => nsyms,
|
||||||
|
"stroff" => stroff,
|
||||||
|
"strsize" => strsize,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing symbolic information needed to support data
|
# A load command containing symbolic information needed to support data
|
||||||
@ -864,6 +1006,30 @@ module MachO
|
|||||||
@locreloff = locreloff
|
@locreloff = locreloff
|
||||||
@nlocrel = nlocrel
|
@nlocrel = nlocrel
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {DysymtabCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"ilocalsym" => ilocalsym,
|
||||||
|
"nlocalsym" => nlocalsym,
|
||||||
|
"iextdefsym" => iextdefsym,
|
||||||
|
"nextdefsym" => nextdefsym,
|
||||||
|
"iundefsym" => iundefsym,
|
||||||
|
"nundefsym" => nundefsym,
|
||||||
|
"tocoff" => tocoff,
|
||||||
|
"ntoc" => ntoc,
|
||||||
|
"modtaboff" => modtaboff,
|
||||||
|
"nmodtab" => nmodtab,
|
||||||
|
"extrefsymoff" => extrefsymoff,
|
||||||
|
"nextrefsyms" => nextrefsyms,
|
||||||
|
"indirectsymoff" => indirectsymoff,
|
||||||
|
"nindirectsyms" => nindirectsyms,
|
||||||
|
"extreloff" => extreloff,
|
||||||
|
"nextrel" => nextrel,
|
||||||
|
"locreloff" => locreloff,
|
||||||
|
"nlocrel" => nlocrel,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the offset and number of hints in the two-level
|
# A load command containing the offset and number of hints in the two-level
|
||||||
@ -895,6 +1061,15 @@ module MachO
|
|||||||
@table = TwolevelHintsTable.new(view, htoffset, nhints)
|
@table = TwolevelHintsTable.new(view, htoffset, nhints)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {TwolevelHintsCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"htoffset" => htoffset,
|
||||||
|
"nhints" => nhints,
|
||||||
|
"table" => table.hints.map(&:to_h),
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
|
|
||||||
# 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
|
||||||
@ -927,6 +1102,14 @@ module MachO
|
|||||||
@isub_image = blob >> 24
|
@isub_image = blob >> 24
|
||||||
@itoc = blob & 0x00FFFFFF
|
@itoc = blob & 0x00FFFFFF
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {TwolevelHint}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"isub_image" => isub_image,
|
||||||
|
"itoc" => itoc,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -950,6 +1133,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@cksum = cksum
|
@cksum = cksum
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {PrebindCksumCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"cksum" => cksum,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing an rpath, which specifies a path that should
|
# A load command representing an rpath, which specifies a path that should
|
||||||
@ -984,6 +1174,13 @@ module MachO
|
|||||||
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
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {RpathCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"path" => path.to_h,
|
||||||
|
}.merge super
|
||||||
|
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
|
||||||
@ -1011,6 +1208,14 @@ module MachO
|
|||||||
@dataoff = dataoff
|
@dataoff = dataoff
|
||||||
@datasize = datasize
|
@datasize = datasize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {LinkeditDataCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"dataoff" => dataoff,
|
||||||
|
"datasize" => datasize,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing the offset to and size of an encrypted
|
# A load command representing the offset to and size of an encrypted
|
||||||
@ -1040,20 +1245,20 @@ module MachO
|
|||||||
@cryptsize = cryptsize
|
@cryptsize = cryptsize
|
||||||
@cryptid = cryptid
|
@cryptid = cryptid
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {EncryptionInfoCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"cryptoff" => cryptoff,
|
||||||
|
"cryptsize" => cryptsize,
|
||||||
|
"cryptid" => cryptid,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command representing the offset to and size of an encrypted
|
# A load command representing the offset to and size of an encrypted
|
||||||
# segment. Corresponds to LC_ENCRYPTION_INFO_64.
|
# segment. Corresponds to LC_ENCRYPTION_INFO_64.
|
||||||
class EncryptionInfoCommand64 < LoadCommand
|
class EncryptionInfoCommand64 < EncryptionInfoCommand
|
||||||
# @return [Integer] the offset to the encrypted segment
|
|
||||||
attr_reader :cryptoff
|
|
||||||
|
|
||||||
# @return [Integer] the size of the encrypted segment
|
|
||||||
attr_reader :cryptsize
|
|
||||||
|
|
||||||
# @return [Integer] the encryption system, or 0 if not encrypted yet
|
|
||||||
attr_reader :cryptid
|
|
||||||
|
|
||||||
# @return [Integer] 64-bit padding value
|
# @return [Integer] 64-bit padding value
|
||||||
attr_reader :pad
|
attr_reader :pad
|
||||||
|
|
||||||
@ -1067,12 +1272,16 @@ module MachO
|
|||||||
|
|
||||||
# @api private
|
# @api private
|
||||||
def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
|
def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
|
||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
|
||||||
@cryptoff = cryptoff
|
|
||||||
@cryptsize = cryptsize
|
|
||||||
@cryptid = cryptid
|
|
||||||
@pad = pad
|
@pad = pad
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {EncryptionInfoCommand64}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"pad" => pad,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
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
|
||||||
@ -1121,6 +1330,16 @@ module MachO
|
|||||||
|
|
||||||
segs.join(".")
|
segs.join(".")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {VersionMinCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"version" => version,
|
||||||
|
"version_string" => version_string,
|
||||||
|
"sdk" => sdk,
|
||||||
|
"sdk_string" => sdk_string,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the minimum OS version on which
|
# A load command containing the minimum OS version on which
|
||||||
@ -1156,6 +1375,40 @@ module MachO
|
|||||||
@tool_entries = ToolEntries.new(view, ntools)
|
@tool_entries = ToolEntries.new(view, ntools)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# A string representation of the binary's minimum OS version.
|
||||||
|
# @return [String] a string representing the minimum OS version.
|
||||||
|
def minos_string
|
||||||
|
binary = "%032b" % minos
|
||||||
|
segs = [
|
||||||
|
binary[0..15], binary[16..23], binary[24..31]
|
||||||
|
].map { |s| s.to_i(2) }
|
||||||
|
|
||||||
|
segs.join(".")
|
||||||
|
end
|
||||||
|
|
||||||
|
# A string representation of the binary's SDK version.
|
||||||
|
# @return [String] a string representing the SDK version.
|
||||||
|
def sdk_string
|
||||||
|
binary = "%032b" % sdk
|
||||||
|
segs = [
|
||||||
|
binary[0..15], binary[16..23], binary[24..31]
|
||||||
|
].map { |s| s.to_i(2) }
|
||||||
|
|
||||||
|
segs.join(".")
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {BuildVersionCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"platform" => platform,
|
||||||
|
"minos" => minos,
|
||||||
|
"minos_string" => minos_string,
|
||||||
|
"sdk" => sdk,
|
||||||
|
"sdk_string" => sdk_string,
|
||||||
|
"tool_entries" => tool_entries.tools.map(&:to_h),
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
|
|
||||||
# A representation of the tool versions exposed
|
# A representation of the tool versions exposed
|
||||||
# by a {BuildVersionCommand} (`LC_BUILD_VERSION`).
|
# by a {BuildVersionCommand} (`LC_BUILD_VERSION`).
|
||||||
class ToolEntries
|
class ToolEntries
|
||||||
@ -1181,37 +1434,23 @@ module MachO
|
|||||||
# @return [Integer] the tool's version number
|
# @return [Integer] the tool's version number
|
||||||
attr_reader :version
|
attr_reader :version
|
||||||
|
|
||||||
# @param tool 32-bit integer
|
# @param tool [Integer] 32-bit integer
|
||||||
# # @param version 32-bit integer
|
# @param version [Integer] 32-bit integer
|
||||||
# @api private
|
# @api private
|
||||||
def initialize(tool, version)
|
def initialize(tool, version)
|
||||||
@tool = tool
|
@tool = tool
|
||||||
@version = version
|
@version = version
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {Tool}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"tool" => tool,
|
||||||
|
"version" => version,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A string representation of the binary's minimum OS version.
|
|
||||||
# @return [String] a string representing the minimum OS version.
|
|
||||||
def minos_string
|
|
||||||
binary = "%032b" % minos
|
|
||||||
segs = [
|
|
||||||
binary[0..15], binary[16..23], binary[24..31]
|
|
||||||
].map { |s| s.to_i(2) }
|
|
||||||
|
|
||||||
segs.join(".")
|
|
||||||
end
|
|
||||||
|
|
||||||
# A string representation of the binary's SDK version.
|
|
||||||
# @return [String] a string representing the SDK version.
|
|
||||||
def sdk_string
|
|
||||||
binary = "%032b" % sdk
|
|
||||||
segs = [
|
|
||||||
binary[0..15], binary[16..23], binary[24..31]
|
|
||||||
].map { |s| s.to_i(2) }
|
|
||||||
|
|
||||||
segs.join(".")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing the file offsets and sizes of the new
|
# A load command containing the file offsets and sizes of the new
|
||||||
@ -1272,6 +1511,22 @@ module MachO
|
|||||||
@export_off = export_off
|
@export_off = export_off
|
||||||
@export_size = export_size
|
@export_size = export_size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {DyldInfoCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"rebase_off" => rebase_off,
|
||||||
|
"rebase_size" => rebase_size,
|
||||||
|
"bind_off" => bind_off,
|
||||||
|
"bind_size" => bind_size,
|
||||||
|
"weak_bind_off" => weak_bind_off,
|
||||||
|
"weak_bind_size" => weak_bind_size,
|
||||||
|
"lazy_bind_off" => lazy_bind_off,
|
||||||
|
"lazy_bind_size" => lazy_bind_size,
|
||||||
|
"export_off" => export_off,
|
||||||
|
"export_size" => export_size,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command containing linker options embedded in object files.
|
# A load command containing linker options embedded in object files.
|
||||||
@ -1293,6 +1548,13 @@ module MachO
|
|||||||
super(view, cmd, cmdsize)
|
super(view, cmd, cmdsize)
|
||||||
@count = count
|
@count = count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {LinkerOptionCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"count" => count,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command specifying the offset of main(). Corresponds to LC_MAIN.
|
# A load command specifying the offset of main(). Corresponds to LC_MAIN.
|
||||||
@ -1317,6 +1579,14 @@ module MachO
|
|||||||
@entryoff = entryoff
|
@entryoff = entryoff
|
||||||
@stacksize = stacksize
|
@stacksize = stacksize
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {EntryPointCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"entryoff" => entryoff,
|
||||||
|
"stacksize" => stacksize,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# A load command specifying the version of the sources used to build the
|
# A load command specifying the version of the sources used to build the
|
||||||
@ -1350,6 +1620,14 @@ module MachO
|
|||||||
|
|
||||||
segs.join(".")
|
segs.join(".")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SourceVersionCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"version" => version,
|
||||||
|
"version_string" => version_string,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An obsolete load command containing the offset and size of the (GNU style)
|
# An obsolete load command containing the offset and size of the (GNU style)
|
||||||
@ -1375,6 +1653,14 @@ module MachO
|
|||||||
@offset = offset
|
@offset = offset
|
||||||
@size = size
|
@size = size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {SymsegCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"offset" => offset,
|
||||||
|
"size" => size,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An obsolete load command containing a free format string table. Each
|
# An obsolete load command containing a free format string table. Each
|
||||||
@ -1412,6 +1698,14 @@ module MachO
|
|||||||
@name = LCStr.new(self, name)
|
@name = LCStr.new(self, name)
|
||||||
@header_addr = header_addr
|
@header_addr = header_addr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {FvmfileCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"name" => name.to_h,
|
||||||
|
"header_addr" => header_addr,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# An obsolete load command containing the path to a library to be loaded
|
# An obsolete load command containing the path to a library to be loaded
|
||||||
@ -1440,6 +1734,52 @@ module MachO
|
|||||||
@minor_version = minor_version
|
@minor_version = minor_version
|
||||||
@header_addr = header_addr
|
@header_addr = header_addr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {FvmlibCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"name" => name.to_h,
|
||||||
|
"minor_version" => minor_version,
|
||||||
|
"header_addr" => header_addr,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# A load command containing an owner name and offset/size for an arbitrary data region.
|
||||||
|
# Corresponds to LC_NOTE.
|
||||||
|
class NoteCommand < LoadCommand
|
||||||
|
# @return [String] the name of the owner for this note
|
||||||
|
attr_reader :data_owner
|
||||||
|
|
||||||
|
# @return [Integer] the offset, within the file, of the note
|
||||||
|
attr_reader :offset
|
||||||
|
|
||||||
|
# @return [Integer] the size, in bytes, of the note
|
||||||
|
attr_reader :size
|
||||||
|
|
||||||
|
# @see MachOStructure::FORMAT
|
||||||
|
# @api private
|
||||||
|
FORMAT = "L=2Z16Q=2".freeze
|
||||||
|
|
||||||
|
# @see MachOStructure::SIZEOF
|
||||||
|
# @api private
|
||||||
|
SIZEOF = 48
|
||||||
|
|
||||||
|
def initialize(view, cmd, cmdsize, data_owner, offset, size)
|
||||||
|
super(view, cmd, cmdsize)
|
||||||
|
@data_owner = data_owner
|
||||||
|
@offset = offset
|
||||||
|
@size = size
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {NoteCommand}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"data_owner" => data_owner,
|
||||||
|
"offset" => offset,
|
||||||
|
"size" => size,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@ -25,7 +25,7 @@ module MachO
|
|||||||
# @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 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 [MachOFile] a new MachOFile
|
# @return [MachOFile] a new MachOFile
|
||||||
def self.new_from_bin(bin)
|
def self.new_from_bin(bin)
|
||||||
@ -35,7 +35,7 @@ module MachO
|
|||||||
instance
|
instance
|
||||||
end
|
end
|
||||||
|
|
||||||
# Creates a new FatFile 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
|
||||||
# @raise [ArgumentError] if the given file does not exist
|
# @raise [ArgumentError] if the given file does not exist
|
||||||
def initialize(filename)
|
def initialize(filename)
|
||||||
@ -219,8 +219,7 @@ module MachO
|
|||||||
update_sizeofcmds(sizeofcmds - lc.cmdsize)
|
update_sizeofcmds(sizeofcmds - lc.cmdsize)
|
||||||
|
|
||||||
# pad the space after the load commands to preserve offsets
|
# pad the space after the load commands to preserve offsets
|
||||||
null_pad = "\x00" * lc.cmdsize
|
@raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, Utils.nullpad(lc.cmdsize))
|
||||||
@raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, null_pad)
|
|
||||||
|
|
||||||
populate_fields if options.fetch(:repopulate, true)
|
populate_fields if options.fetch(:repopulate, true)
|
||||||
end
|
end
|
||||||
@ -252,6 +251,33 @@ module MachO
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# The segment alignment for the Mach-O. Guesses conservatively.
|
||||||
|
# @return [Integer] the alignment, as a power of 2
|
||||||
|
# @note This is **not** the same as {#alignment}!
|
||||||
|
# @note See `get_align` and `get_align_64` in `cctools/misc/lipo.c`
|
||||||
|
def segment_alignment
|
||||||
|
# special cases: 12 for x86/64/PPC/PP64, 14 for ARM/ARM64
|
||||||
|
return 12 if %i[i386 x86_64 ppc ppc64].include?(cputype)
|
||||||
|
return 14 if %i[arm arm64].include?(cputype)
|
||||||
|
|
||||||
|
cur_align = Sections::MAX_SECT_ALIGN
|
||||||
|
|
||||||
|
segments.each do |segment|
|
||||||
|
if filetype == :object
|
||||||
|
# start with the smallest alignment, and work our way up
|
||||||
|
align = magic32? ? 2 : 3
|
||||||
|
segment.sections.each do |section|
|
||||||
|
align = section.align unless section.align <= align
|
||||||
|
end
|
||||||
|
else
|
||||||
|
align = segment.guess_align
|
||||||
|
end
|
||||||
|
cur_align = align if align < cur_align
|
||||||
|
end
|
||||||
|
|
||||||
|
cur_align
|
||||||
|
end
|
||||||
|
|
||||||
# The Mach-O's dylib ID, or `nil` if not a dylib.
|
# The Mach-O's dylib ID, or `nil` if not a dylib.
|
||||||
# @example
|
# @example
|
||||||
# file.dylib_id # => 'libBar.dylib'
|
# file.dylib_id # => 'libBar.dylib'
|
||||||
@ -408,6 +434,14 @@ module MachO
|
|||||||
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {MachOFile}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"header" => header.to_h,
|
||||||
|
"load_commands" => load_commands.map(&:to_h),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# The file's Mach-O header structure.
|
# The file's Mach-O header structure.
|
||||||
|
|||||||
42
Library/Homebrew/vendor/macho/macho/sections.rb
vendored
42
Library/Homebrew/vendor/macho/macho/sections.rb
vendored
@ -13,6 +13,10 @@ module MachO
|
|||||||
# system settable attributes mask
|
# system settable attributes mask
|
||||||
SECTION_ATTRIBUTES_SYS = 0x00ffff00
|
SECTION_ATTRIBUTES_SYS = 0x00ffff00
|
||||||
|
|
||||||
|
# maximum specifiable section alignment, as a power of 2
|
||||||
|
# @note see `MAXSECTALIGN` macro in `cctools/misc/lipo.c`
|
||||||
|
MAX_SECT_ALIGN = 15
|
||||||
|
|
||||||
# association of section flag symbols to values
|
# association of section flag symbols to values
|
||||||
# @api private
|
# @api private
|
||||||
SECTION_FLAGS = {
|
SECTION_FLAGS = {
|
||||||
@ -104,7 +108,7 @@ module MachO
|
|||||||
attr_reader :reserved2
|
attr_reader :reserved2
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
FORMAT = "a16a16L=9".freeze
|
FORMAT = "Z16Z16L=9".freeze
|
||||||
|
|
||||||
# @see MachOStructure::SIZEOF
|
# @see MachOStructure::SIZEOF
|
||||||
SIZEOF = 68
|
SIZEOF = 68
|
||||||
@ -125,16 +129,14 @@ module MachO
|
|||||||
@reserved2 = reserved2
|
@reserved2 = reserved2
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [String] the section's name, with any trailing NULL characters
|
# @return [String] the section's name
|
||||||
# removed
|
|
||||||
def section_name
|
def section_name
|
||||||
sectname.delete("\x00")
|
sectname
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [String] the parent segment's name, with any trailing NULL
|
# @return [String] the parent segment's name
|
||||||
# characters removed
|
|
||||||
def segment_name
|
def segment_name
|
||||||
segname.delete("\x00")
|
segname
|
||||||
end
|
end
|
||||||
|
|
||||||
# @return [Boolean] whether the section is empty (i.e, {size} is 0)
|
# @return [Boolean] whether the section is empty (i.e, {size} is 0)
|
||||||
@ -151,6 +153,23 @@ module MachO
|
|||||||
return false if flag.nil?
|
return false if flag.nil?
|
||||||
flags & flag == flag
|
flags & flag == flag
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {Section}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"sectname" => sectname,
|
||||||
|
"segname" => segname,
|
||||||
|
"addr" => addr,
|
||||||
|
"size" => size,
|
||||||
|
"offset" => offset,
|
||||||
|
"align" => align,
|
||||||
|
"reloff" => reloff,
|
||||||
|
"nreloc" => nreloc,
|
||||||
|
"flags" => flags,
|
||||||
|
"reserved1" => reserved1,
|
||||||
|
"reserved2" => reserved2,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Represents a section of a segment for 64-bit architectures.
|
# Represents a section of a segment for 64-bit architectures.
|
||||||
@ -159,7 +178,7 @@ module MachO
|
|||||||
attr_reader :reserved3
|
attr_reader :reserved3
|
||||||
|
|
||||||
# @see MachOStructure::FORMAT
|
# @see MachOStructure::FORMAT
|
||||||
FORMAT = "a16a16Q=2L=8".freeze
|
FORMAT = "Z16Z16Q=2L=8".freeze
|
||||||
|
|
||||||
# @see MachOStructure::SIZEOF
|
# @see MachOStructure::SIZEOF
|
||||||
SIZEOF = 80
|
SIZEOF = 80
|
||||||
@ -171,6 +190,13 @@ module MachO
|
|||||||
nreloc, flags, reserved1, reserved2)
|
nreloc, flags, reserved1, reserved2)
|
||||||
@reserved3 = reserved3
|
@reserved3 = reserved3
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {Section64}
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"reserved3" => reserved3,
|
||||||
|
}.merge super
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
10
Library/Homebrew/vendor/macho/macho/structure.rb
vendored
10
Library/Homebrew/vendor/macho/macho/structure.rb
vendored
@ -26,5 +26,15 @@ module MachO
|
|||||||
|
|
||||||
new(*bin.unpack(format))
|
new(*bin.unpack(format))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {MachOStructure}.
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"structure" => {
|
||||||
|
"format" => self.class::FORMAT,
|
||||||
|
"bytesize" => self.class.bytesize,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
14
Library/Homebrew/vendor/macho/macho/utils.rb
vendored
14
Library/Homebrew/vendor/macho/macho/utils.rb
vendored
@ -22,6 +22,16 @@ module MachO
|
|||||||
round(size, alignment) - size
|
round(size, alignment) - size
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a string of null bytes of the requested (non-negative) size
|
||||||
|
# @param size [Integer] the size of the nullpad
|
||||||
|
# @return [String] the null string (or empty string, for `size = 0`)
|
||||||
|
# @raise [ArgumentError] if a non-positive nullpad is requested
|
||||||
|
def self.nullpad(size)
|
||||||
|
raise ArgumentError, "size < 0: #{size}" if size.negative?
|
||||||
|
|
||||||
|
"\x00" * size
|
||||||
|
end
|
||||||
|
|
||||||
# Converts an abstract (native-endian) String#unpack format to big or
|
# Converts an abstract (native-endian) String#unpack format to big or
|
||||||
# little.
|
# little.
|
||||||
# @param format [String] the format string being converted
|
# @param format [String] the format string being converted
|
||||||
@ -46,11 +56,11 @@ module MachO
|
|||||||
strings.each do |key, string|
|
strings.each do |key, string|
|
||||||
offsets[key] = next_offset
|
offsets[key] = next_offset
|
||||||
payload << string
|
payload << string
|
||||||
payload << "\x00"
|
payload << Utils.nullpad(1)
|
||||||
next_offset += string.bytesize + 1
|
next_offset += string.bytesize + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
payload << "\x00" * padding_for(fixed_offset + payload.bytesize, alignment)
|
payload << Utils.nullpad(padding_for(fixed_offset + payload.bytesize, alignment))
|
||||||
[payload, offsets]
|
[payload, offsets]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
8
Library/Homebrew/vendor/macho/macho/view.rb
vendored
8
Library/Homebrew/vendor/macho/macho/view.rb
vendored
@ -19,5 +19,13 @@ module MachO
|
|||||||
@endianness = endianness
|
@endianness = endianness
|
||||||
@offset = offset
|
@offset = offset
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return [Hash] a hash representation of this {MachOView}.
|
||||||
|
def to_h
|
||||||
|
{
|
||||||
|
"endianness" => endianness,
|
||||||
|
"offset" => offset,
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user