Merge pull request #4417 from woodruffw/ruby-macho-2.0
vendor: ruby-macho 2.0
This commit is contained in:
commit
77b429291a
2
Library/Homebrew/vendor/README.md
vendored
2
Library/Homebrew/vendor/README.md
vendored
@ -3,7 +3,7 @@ Vendored Dependencies
|
||||
|
||||
* [plist](https://github.com/patsplat/plist), version 3.3.0
|
||||
|
||||
* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 1.2.0
|
||||
* [ruby-macho](https://github.com/Homebrew/ruby-macho), version 2.0.0
|
||||
|
||||
* [backports](https://github.com/marcandre/backports), version 3.8.0
|
||||
|
||||
|
||||
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 "#{File.dirname(__FILE__)}/macho/view"
|
||||
require "#{File.dirname(__FILE__)}/macho/headers"
|
||||
require "#{File.dirname(__FILE__)}/macho/load_commands"
|
||||
require "#{File.dirname(__FILE__)}/macho/sections"
|
||||
require "#{File.dirname(__FILE__)}/macho/macho_file"
|
||||
require "#{File.dirname(__FILE__)}/macho/fat_file"
|
||||
require "#{File.dirname(__FILE__)}/macho/exceptions"
|
||||
require "#{File.dirname(__FILE__)}/macho/utils"
|
||||
require "#{File.dirname(__FILE__)}/macho/tools"
|
||||
require_relative "macho/structure"
|
||||
require_relative "macho/view"
|
||||
require_relative "macho/headers"
|
||||
require_relative "macho/load_commands"
|
||||
require_relative "macho/sections"
|
||||
require_relative "macho/macho_file"
|
||||
require_relative "macho/fat_file"
|
||||
require_relative "macho/exceptions"
|
||||
require_relative "macho/utils"
|
||||
require_relative "macho/tools"
|
||||
|
||||
# The primary namespace for ruby-macho.
|
||||
module MachO
|
||||
# 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.
|
||||
# @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
|
||||
# @param machos [Array<MachOFile>] the machos to combine
|
||||
# @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)
|
||||
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)
|
||||
fat_archs = []
|
||||
|
||||
macho_pads = {}
|
||||
macho_bins = {}
|
||||
|
||||
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
|
||||
macho_offset = Utils.round(offset, 2**macho.segment_alignment)
|
||||
macho_pads[macho] = Utils.padding_for(offset, 2**macho.segment_alignment)
|
||||
macho_bins[macho] = macho.serialize
|
||||
|
||||
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
|
||||
|
||||
bin = header.serialize
|
||||
bin << fat_archs.map(&:serialize).join
|
||||
bin << machos.map(&:serialize).join
|
||||
machos.each do |macho|
|
||||
bin << Utils.nullpad(macho_pads[macho])
|
||||
bin << macho_bins[macho]
|
||||
end
|
||||
|
||||
new_from_bin(bin)
|
||||
end
|
||||
@ -265,6 +281,15 @@ module MachO
|
||||
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
||||
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
|
||||
|
||||
# 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
|
||||
[magic, nfat_arch].pack(FORMAT)
|
||||
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
|
||||
|
||||
# Fat binary header architecture structure. A Fat binary has one or more of
|
||||
@ -508,7 +517,7 @@ module MachO
|
||||
# @api private
|
||||
def initialize(cputype, cpusubtype, offset, size, align)
|
||||
@cputype = cputype
|
||||
@cpusubtype = cpusubtype
|
||||
@cpusubtype = cpusubtype & ~CPU_SUBTYPE_MASK
|
||||
@offset = offset
|
||||
@size = size
|
||||
@align = align
|
||||
@ -518,6 +527,19 @@ module MachO
|
||||
def serialize
|
||||
[cputype, cpusubtype, offset, size, align].pack(FORMAT)
|
||||
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
|
||||
|
||||
# 32-bit Mach-O file header structure
|
||||
@ -639,6 +661,24 @@ module MachO
|
||||
def alignment
|
||||
magic32? ? 4 : 8
|
||||
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
|
||||
|
||||
# 64-bit Mach-O file header structure
|
||||
@ -660,6 +700,13 @@ module MachO
|
||||
super(magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags)
|
||||
@reserved = reserved
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {MachHeader64}
|
||||
def to_h
|
||||
{
|
||||
"reserved" => reserved,
|
||||
}.merge super
|
||||
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_VERSION_MIN_TVOS => "VersionMinCommand",
|
||||
:LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
|
||||
:LC_NOTE => "LoadCommand",
|
||||
:LC_NOTE => "NoteCommand",
|
||||
:LC_BUILD_VERSION => "BuildVersionCommand",
|
||||
}.freeze
|
||||
|
||||
@ -169,15 +169,16 @@ module MachO
|
||||
:SG_PROTECTED_VERSION_1 => 0x8,
|
||||
}.freeze
|
||||
|
||||
# Mach-O load command structure
|
||||
# This is the most generic load command - only cmd ID and size are
|
||||
# represented, and no actual data. Used when a more specific class
|
||||
# isn't available/implemented.
|
||||
# The top-level Mach-O load command structure.
|
||||
#
|
||||
# This is the most generic load command -- only the type ID and size are
|
||||
# represented. Used when a more specific class isn't available or isn't implemented.
|
||||
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
|
||||
|
||||
# @return [Integer] the load command's identifying number
|
||||
# @return [Integer] the load command's type ID
|
||||
attr_reader :cmd
|
||||
|
||||
# @return [Integer] the size of the load command, in bytes
|
||||
@ -251,8 +252,8 @@ module MachO
|
||||
view.offset
|
||||
end
|
||||
|
||||
# @return [Symbol] a symbol representation of the load command's
|
||||
# identifying number
|
||||
# @return [Symbol, nil] a symbol representation of the load command's
|
||||
# type ID, or nil if the ID doesn't correspond to a known load command class
|
||||
def type
|
||||
LOAD_COMMANDS[cmd]
|
||||
end
|
||||
@ -265,6 +266,17 @@ module MachO
|
||||
type.to_s
|
||||
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
|
||||
# struct used internally by OS X. This class allows ruby-macho to
|
||||
# pretend that strings stored in LCs are immediately available without
|
||||
@ -304,6 +316,14 @@ module MachO
|
||||
def to_i
|
||||
@string_offset
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {LCStr}.
|
||||
def to_h
|
||||
{
|
||||
"string" => to_s,
|
||||
"offset" => to_i,
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# Represents the contextual information needed by a load command to
|
||||
@ -364,6 +384,14 @@ module MachO
|
||||
|
||||
segs.join("-")
|
||||
end
|
||||
|
||||
# @return [Hash] returns a hash representation of this {UUIDCommand}
|
||||
def to_h
|
||||
{
|
||||
"uuid" => uuid,
|
||||
"uuid_string" => uuid_string,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command indicating that part of this file is to be mapped into
|
||||
@ -398,7 +426,7 @@ module MachO
|
||||
|
||||
# @see MachOStructure::FORMAT
|
||||
# @api private
|
||||
FORMAT = "L=2a16L=4l=2L=2".freeze
|
||||
FORMAT = "L=2Z16L=4l=2L=2".freeze
|
||||
|
||||
# @see MachOStructure::SIZEOF
|
||||
# @api private
|
||||
@ -408,7 +436,7 @@ module MachO
|
||||
def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
|
||||
filesize, maxprot, initprot, nsects, flags)
|
||||
super(view, cmd, cmdsize)
|
||||
@segname = segname.delete("\x00")
|
||||
@segname = segname
|
||||
@vmaddr = vmaddr
|
||||
@vmsize = vmsize
|
||||
@fileoff = fileoff
|
||||
@ -448,6 +476,42 @@ module MachO
|
||||
return false if flag.nil?
|
||||
flags & flag == flag
|
||||
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
|
||||
|
||||
# A load command indicating that part of this file is to be mapped into
|
||||
@ -455,7 +519,7 @@ module MachO
|
||||
class SegmentCommand64 < SegmentCommand
|
||||
# @see MachOStructure::FORMAT
|
||||
# @api private
|
||||
FORMAT = "L=2a16Q=4l=2L=2".freeze
|
||||
FORMAT = "L=2Z16Q=4l=2L=2".freeze
|
||||
|
||||
# @see MachOStructure::SIZEOF
|
||||
# @api private
|
||||
@ -510,6 +574,16 @@ module MachO
|
||||
[cmd, cmdsize, string_offsets[:name], timestamp, current_version,
|
||||
compatibility_version].pack(format) + string_payload
|
||||
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
|
||||
|
||||
# A load command representing some aspect of the dynamic linker, depending
|
||||
@ -546,6 +620,13 @@ module MachO
|
||||
cmdsize = SIZEOF + string_payload.bytesize
|
||||
[cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {DylinkerCommand}
|
||||
def to_h
|
||||
{
|
||||
"name" => name.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command used to indicate dynamic libraries used in prebinding.
|
||||
@ -576,6 +657,15 @@ module MachO
|
||||
@nmodules = nmodules
|
||||
@linked_modules = linked_modules
|
||||
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
|
||||
|
||||
# A load command used to represent threads.
|
||||
@ -641,6 +731,20 @@ module MachO
|
||||
@reserved5 = reserved5
|
||||
@reserved6 = reserved6
|
||||
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
|
||||
|
||||
# A load command containing the address of the dynamic shared library
|
||||
@ -675,6 +779,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@umbrella = LCStr.new(self, umbrella)
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SubFrameworkCommand}
|
||||
def to_h
|
||||
{
|
||||
"umbrella" => umbrella.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command signifying membership of a subumbrella containing the name
|
||||
@ -696,6 +807,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@sub_umbrella = LCStr.new(self, sub_umbrella)
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SubUmbrellaCommand}
|
||||
def to_h
|
||||
{
|
||||
"sub_umbrella" => sub_umbrella.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command signifying a sublibrary of a shared library. Corresponds
|
||||
@ -717,6 +835,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@sub_library = LCStr.new(self, sub_library)
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SubLibraryCommand}
|
||||
def to_h
|
||||
{
|
||||
"sub_library" => sub_library.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command signifying a shared library that is a subframework of
|
||||
@ -738,6 +863,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@sub_client = LCStr.new(self, sub_client)
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SubClientCommand}
|
||||
def to_h
|
||||
{
|
||||
"sub_client" => sub_client.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# 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
|
||||
attr_reader :nsyms
|
||||
|
||||
# @return the string table's offset
|
||||
# @return [Integer] the string table's offset
|
||||
attr_reader :stroff
|
||||
|
||||
# @return the string table size in bytes
|
||||
# @return [Integer] the string table size in bytes
|
||||
attr_reader :strsize
|
||||
|
||||
# @see MachOStructure::FORMAT
|
||||
@ -771,6 +903,16 @@ module MachO
|
||||
@stroff = stroff
|
||||
@strsize = strsize
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SymtabCommand}
|
||||
def to_h
|
||||
{
|
||||
"symoff" => symoff,
|
||||
"nsyms" => nsyms,
|
||||
"stroff" => stroff,
|
||||
"strsize" => strsize,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command containing symbolic information needed to support data
|
||||
@ -864,6 +1006,30 @@ module MachO
|
||||
@locreloff = locreloff
|
||||
@nlocrel = nlocrel
|
||||
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
|
||||
|
||||
# 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)
|
||||
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
|
||||
# by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
|
||||
class TwolevelHintsTable
|
||||
@ -927,6 +1102,14 @@ module MachO
|
||||
@isub_image = blob >> 24
|
||||
@itoc = blob & 0x00FFFFFF
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {TwolevelHint}
|
||||
def to_h
|
||||
{
|
||||
"isub_image" => isub_image,
|
||||
"itoc" => itoc,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -950,6 +1133,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@cksum = cksum
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {PrebindCksumCommand}
|
||||
def to_h
|
||||
{
|
||||
"cksum" => cksum,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command representing an rpath, which specifies a path that should
|
||||
@ -984,6 +1174,13 @@ module MachO
|
||||
cmdsize = SIZEOF + string_payload.bytesize
|
||||
[cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {RpathCommand}
|
||||
def to_h
|
||||
{
|
||||
"path" => path.to_h,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command representing the offsets and sizes of a blob of data in
|
||||
@ -1011,6 +1208,14 @@ module MachO
|
||||
@dataoff = dataoff
|
||||
@datasize = datasize
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {LinkeditDataCommand}
|
||||
def to_h
|
||||
{
|
||||
"dataoff" => dataoff,
|
||||
"datasize" => datasize,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command representing the offset to and size of an encrypted
|
||||
@ -1040,20 +1245,20 @@ module MachO
|
||||
@cryptsize = cryptsize
|
||||
@cryptid = cryptid
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {EncryptionInfoCommand}
|
||||
def to_h
|
||||
{
|
||||
"cryptoff" => cryptoff,
|
||||
"cryptsize" => cryptsize,
|
||||
"cryptid" => cryptid,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command representing the offset to and size of an encrypted
|
||||
# segment. Corresponds to LC_ENCRYPTION_INFO_64.
|
||||
class EncryptionInfoCommand64 < LoadCommand
|
||||
# @return [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
|
||||
|
||||
class EncryptionInfoCommand64 < EncryptionInfoCommand
|
||||
# @return [Integer] 64-bit padding value
|
||||
attr_reader :pad
|
||||
|
||||
@ -1067,12 +1272,16 @@ module MachO
|
||||
|
||||
# @api private
|
||||
def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
|
||||
super(view, cmd, cmdsize)
|
||||
@cryptoff = cryptoff
|
||||
@cryptsize = cryptsize
|
||||
@cryptid = cryptid
|
||||
super(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
|
||||
@pad = pad
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {EncryptionInfoCommand64}
|
||||
def to_h
|
||||
{
|
||||
"pad" => pad,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command containing the minimum OS version on which the binary
|
||||
@ -1121,6 +1330,16 @@ module MachO
|
||||
|
||||
segs.join(".")
|
||||
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
|
||||
|
||||
# A load command containing the minimum OS version on which
|
||||
@ -1156,6 +1375,40 @@ module MachO
|
||||
@tool_entries = ToolEntries.new(view, ntools)
|
||||
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
|
||||
# by a {BuildVersionCommand} (`LC_BUILD_VERSION`).
|
||||
class ToolEntries
|
||||
@ -1181,37 +1434,23 @@ module MachO
|
||||
# @return [Integer] the tool's version number
|
||||
attr_reader :version
|
||||
|
||||
# @param tool 32-bit integer
|
||||
# # @param version 32-bit integer
|
||||
# @param tool [Integer] 32-bit integer
|
||||
# @param version [Integer] 32-bit integer
|
||||
# @api private
|
||||
def initialize(tool, version)
|
||||
@tool = tool
|
||||
@version = version
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {Tool}
|
||||
def to_h
|
||||
{
|
||||
"tool" => tool,
|
||||
"version" => version,
|
||||
}
|
||||
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
|
||||
|
||||
# A load command containing the file offsets and sizes of the new
|
||||
@ -1272,6 +1511,22 @@ module MachO
|
||||
@export_off = export_off
|
||||
@export_size = export_size
|
||||
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
|
||||
|
||||
# A load command containing linker options embedded in object files.
|
||||
@ -1293,6 +1548,13 @@ module MachO
|
||||
super(view, cmd, cmdsize)
|
||||
@count = count
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {LinkerOptionCommand}
|
||||
def to_h
|
||||
{
|
||||
"count" => count,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command specifying the offset of main(). Corresponds to LC_MAIN.
|
||||
@ -1317,6 +1579,14 @@ module MachO
|
||||
@entryoff = entryoff
|
||||
@stacksize = stacksize
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {EntryPointCommand}
|
||||
def to_h
|
||||
{
|
||||
"entryoff" => entryoff,
|
||||
"stacksize" => stacksize,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# A load command specifying the version of the sources used to build the
|
||||
@ -1350,6 +1620,14 @@ module MachO
|
||||
|
||||
segs.join(".")
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SourceVersionCommand}
|
||||
def to_h
|
||||
{
|
||||
"version" => version,
|
||||
"version_string" => version_string,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# An obsolete load command containing the offset and size of the (GNU style)
|
||||
@ -1375,6 +1653,14 @@ module MachO
|
||||
@offset = offset
|
||||
@size = size
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {SymsegCommand}
|
||||
def to_h
|
||||
{
|
||||
"offset" => offset,
|
||||
"size" => size,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# An obsolete load command containing a free format string table. Each
|
||||
@ -1412,6 +1698,14 @@ module MachO
|
||||
@name = LCStr.new(self, name)
|
||||
@header_addr = header_addr
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {FvmfileCommand}
|
||||
def to_h
|
||||
{
|
||||
"name" => name.to_h,
|
||||
"header_addr" => header_addr,
|
||||
}.merge super
|
||||
end
|
||||
end
|
||||
|
||||
# An obsolete load command containing the path to a library to be loaded
|
||||
@ -1440,6 +1734,52 @@ module MachO
|
||||
@minor_version = minor_version
|
||||
@header_addr = header_addr
|
||||
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
|
||||
|
||||
@ -25,7 +25,7 @@ module MachO
|
||||
# @note load commands are provided in order of ascending offset.
|
||||
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
|
||||
# @return [MachOFile] a new MachOFile
|
||||
def self.new_from_bin(bin)
|
||||
@ -35,7 +35,7 @@ module MachO
|
||||
instance
|
||||
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
|
||||
# @raise [ArgumentError] if the given file does not exist
|
||||
def initialize(filename)
|
||||
@ -219,8 +219,7 @@ module MachO
|
||||
update_sizeofcmds(sizeofcmds - lc.cmdsize)
|
||||
|
||||
# pad the space after the load commands to preserve offsets
|
||||
null_pad = "\x00" * lc.cmdsize
|
||||
@raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, null_pad)
|
||||
@raw_data.insert(header.class.bytesize + sizeofcmds - lc.cmdsize, Utils.nullpad(lc.cmdsize))
|
||||
|
||||
populate_fields if options.fetch(:repopulate, true)
|
||||
end
|
||||
@ -252,6 +251,33 @@ module MachO
|
||||
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.
|
||||
# @example
|
||||
# file.dylib_id # => 'libBar.dylib'
|
||||
@ -408,6 +434,14 @@ module MachO
|
||||
File.open(@filename, "wb") { |f| f.write(@raw_data) }
|
||||
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
|
||||
|
||||
# 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
|
||||
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
|
||||
# @api private
|
||||
SECTION_FLAGS = {
|
||||
@ -104,7 +108,7 @@ module MachO
|
||||
attr_reader :reserved2
|
||||
|
||||
# @see MachOStructure::FORMAT
|
||||
FORMAT = "a16a16L=9".freeze
|
||||
FORMAT = "Z16Z16L=9".freeze
|
||||
|
||||
# @see MachOStructure::SIZEOF
|
||||
SIZEOF = 68
|
||||
@ -125,16 +129,14 @@ module MachO
|
||||
@reserved2 = reserved2
|
||||
end
|
||||
|
||||
# @return [String] the section's name, with any trailing NULL characters
|
||||
# removed
|
||||
# @return [String] the section's name
|
||||
def section_name
|
||||
sectname.delete("\x00")
|
||||
sectname
|
||||
end
|
||||
|
||||
# @return [String] the parent segment's name, with any trailing NULL
|
||||
# characters removed
|
||||
# @return [String] the parent segment's name
|
||||
def segment_name
|
||||
segname.delete("\x00")
|
||||
segname
|
||||
end
|
||||
|
||||
# @return [Boolean] whether the section is empty (i.e, {size} is 0)
|
||||
@ -151,6 +153,23 @@ module MachO
|
||||
return false if flag.nil?
|
||||
flags & flag == flag
|
||||
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
|
||||
|
||||
# Represents a section of a segment for 64-bit architectures.
|
||||
@ -159,7 +178,7 @@ module MachO
|
||||
attr_reader :reserved3
|
||||
|
||||
# @see MachOStructure::FORMAT
|
||||
FORMAT = "a16a16Q=2L=8".freeze
|
||||
FORMAT = "Z16Z16Q=2L=8".freeze
|
||||
|
||||
# @see MachOStructure::SIZEOF
|
||||
SIZEOF = 80
|
||||
@ -171,6 +190,13 @@ module MachO
|
||||
nreloc, flags, reserved1, reserved2)
|
||||
@reserved3 = reserved3
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {Section64}
|
||||
def to_h
|
||||
{
|
||||
"reserved3" => reserved3,
|
||||
}.merge super
|
||||
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))
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {MachOStructure}.
|
||||
def to_h
|
||||
{
|
||||
"structure" => {
|
||||
"format" => self.class::FORMAT,
|
||||
"bytesize" => self.class.bytesize,
|
||||
},
|
||||
}
|
||||
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
|
||||
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
|
||||
# little.
|
||||
# @param format [String] the format string being converted
|
||||
@ -46,11 +56,11 @@ module MachO
|
||||
strings.each do |key, string|
|
||||
offsets[key] = next_offset
|
||||
payload << string
|
||||
payload << "\x00"
|
||||
payload << Utils.nullpad(1)
|
||||
next_offset += string.bytesize + 1
|
||||
end
|
||||
|
||||
payload << "\x00" * padding_for(fixed_offset + payload.bytesize, alignment)
|
||||
payload << Utils.nullpad(padding_for(fixed_offset + payload.bytesize, alignment))
|
||||
[payload, offsets]
|
||||
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
|
||||
@offset = offset
|
||||
end
|
||||
|
||||
# @return [Hash] a hash representation of this {MachOView}.
|
||||
def to_h
|
||||
{
|
||||
"endianness" => endianness,
|
||||
"offset" => offset,
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user