Class: MachO::FatFile
- Inherits:
-
Object
- Object
- MachO::FatFile
- Extended by:
- Forwardable
- Defined in:
- lib/macho/fat_file.rb
Overview
Represents a "Fat" file, which contains a header, a listing of available architectures, and one or more Mach-O binaries.
Instance Attribute Summary collapse
-
#fat_archs ⇒ Array<Headers::FatArch>
readonly
An array of fat architectures.
-
#filename ⇒ String
The filename loaded from, or nil if loaded from a binary string.
-
#header ⇒ Headers::FatHeader
readonly
The file's header.
-
#machos ⇒ Array<MachOFile>
readonly
An array of Mach-O binaries.
Class Method Summary collapse
-
.new_from_bin(bin) ⇒ FatFile
Creates a new FatFile instance from a binary string.
-
.new_from_machos(*machos) ⇒ FatFile
Creates a new FatFile from the given (single-arch) Mach-Os.
Instance Method Summary collapse
-
#add_rpath(path, options = {}) ⇒ void
Add the given runtime path to the file's Mach-Os.
-
#bundle? ⇒ Boolean
Whether or not the file is of type
MH_BUNDLE. -
#change_dylib_id(new_id, options = {}) ⇒ void
(also: #dylib_id=)
Changes the file's dylib ID to
new_id. -
#change_install_name(old_name, new_name, options = {}) ⇒ void
(also: #change_dylib)
Changes all dependent shared library install names from
old_nametonew_name. -
#change_rpath(old_path, new_path, options = {}) ⇒ void
Change the runtime path
old_pathtonew_pathin the file's Mach-Os. -
#core? ⇒ Boolean
Whether or not the file is of type
MH_CORE. -
#delete_rpath(path, options = {}) ⇒ Object
Delete the given runtime path from the file's Mach-Os.
-
#dsym? ⇒ Boolean
Whether or not the file is of type
MH_DSYM. -
#dylib? ⇒ Boolean
Whether or not the file is of type
MH_DYLIB. -
#dylib_id ⇒ String?
The Mach-O's dylib ID.
-
#dylib_load_commands ⇒ Array<LoadCommands::DylibCommand>
All load commands responsible for loading dylibs in the file's Mach-O's.
-
#dylinker? ⇒ Boolean
Whether or not the file is of type
MH_DYLINKER. -
#executable? ⇒ Boolean
Whether or not the file is of type
MH_EXECUTE. -
#extract(cputype) ⇒ MachOFile?
Extract a Mach-O with the given CPU type from the file.
-
#filetype ⇒ Symbol
A string representation of the Mach-O's filetype.
-
#fvmlib? ⇒ Boolean
Whether or not the file is of type
MH_FVMLIB. -
#initialize(filename) ⇒ FatFile
constructor
Creates a new FatFile from the given filename.
-
#initialize_from_bin(bin) ⇒ Object
private
Initializes a new FatFile instance from a binary string.
-
#kext? ⇒ Boolean
Whether or not the file is of type
MH_KEXT_BUNDLE. -
#linked_dylibs ⇒ Array<String>
All shared libraries linked to the file's Mach-Os.
-
#magic ⇒ Integer
The magic number of the header (and file).
-
#magic_string ⇒ String
A string representation of the file's magic number.
-
#object? ⇒ Boolean
Whether or not the file is of type
MH_OBJECT. -
#populate_fields ⇒ void
Populate the instance's fields with the raw Fat Mach-O data.
-
#preload? ⇒ Boolean
Whether or not the file is of type
MH_PRELOAD. -
#rpaths ⇒ Array<String>
All runtime paths associated with the file's Mach-Os.
-
#serialize ⇒ String
The file's raw fat data.
-
#write(filename) ⇒ void
Write all (fat) data to the given filename.
-
#write! ⇒ void
Write all (fat) data to the file used to initialize the instance.
Constructor Details
#initialize(filename) ⇒ FatFile
Creates a new FatFile from the given filename.
58 59 60 61 62 63 64 |
# File 'lib/macho/fat_file.rb', line 58 def initialize(filename) raise ArgumentError, "#{filename}: no such file" unless File.file?(filename) @filename = filename @raw_data = File.open(@filename, "rb", &:read) populate_fields end |
Instance Attribute Details
#fat_archs ⇒ Array<Headers::FatArch> (readonly)
Returns an array of fat architectures.
18 19 20 |
# File 'lib/macho/fat_file.rb', line 18 def fat_archs @fat_archs end |
#filename ⇒ String
Returns the filename loaded from, or nil if loaded from a binary string.
12 13 14 |
# File 'lib/macho/fat_file.rb', line 12 def filename @filename end |
#header ⇒ Headers::FatHeader (readonly)
Returns the file's header.
15 16 17 |
# File 'lib/macho/fat_file.rb', line 15 def header @header end |
#machos ⇒ Array<MachOFile> (readonly)
Returns an array of Mach-O binaries.
21 22 23 |
# File 'lib/macho/fat_file.rb', line 21 def machos @machos end |
Class Method Details
.new_from_bin(bin) ⇒ FatFile
Creates a new FatFile instance from a binary string.
48 49 50 51 52 53 |
# File 'lib/macho/fat_file.rb', line 48 def self.new_from_bin(bin) instance = allocate instance.initialize_from_bin(bin) instance end |
.new_from_machos(*machos) ⇒ FatFile
Creates a new FatFile from the given (single-arch) Mach-Os
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/macho/fat_file.rb', line 26 def self.new_from_machos(*machos) header = Headers::FatHeader.new(Headers::FAT_MAGIC, machos.size) offset = Headers::FatHeader.bytesize + (machos.size * Headers::FatArch.bytesize) fat_archs = [] machos.each do |macho| fat_archs << Headers::FatArch.new(macho.header.cputype, macho.header.cpusubtype, offset, macho.serialize.bytesize, macho.alignment) offset += macho.serialize.bytesize end bin = header.serialize bin << fat_archs.map(&:serialize).join bin << machos.map(&:serialize).join new_from_bin(bin) end |
Instance Method Details
#add_rpath(path, options = {}) ⇒ void
This method returns an undefined value.
Add the given runtime path to the file's Mach-Os.
220 221 222 223 224 225 226 |
# File 'lib/macho/fat_file.rb', line 220 def add_rpath(path, = {}) each_macho() do |macho| macho.add_rpath(path, ) end repopulate_raw_machos end |
#bundle? ⇒ Boolean
Returns whether or not the file is of type MH_BUNDLE.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#change_dylib_id(new_id, options = {}) ⇒ void Also known as: dylib_id=
This method returns an undefined value.
Changes the file's dylib ID to new_id. If the file is not a dylib,
does nothing.
144 145 146 147 148 149 150 151 152 153 |
# File 'lib/macho/fat_file.rb', line 144 def change_dylib_id(new_id, = {}) raise ArgumentError, "argument must be a String" unless new_id.is_a?(String) return unless machos.all?(&:dylib?) each_macho() do |macho| macho.change_dylib_id(new_id, ) end repopulate_raw_machos end |
#change_install_name(old_name, new_name, options = {}) ⇒ void Also known as: change_dylib
This method returns an undefined value.
Changes all dependent shared library install names from old_name to
new_name. In a fat file, this changes install names in all internal
Mach-Os.
179 180 181 182 183 184 185 |
# File 'lib/macho/fat_file.rb', line 179 def change_install_name(old_name, new_name, = {}) each_macho() do |macho| macho.change_install_name(old_name, new_name, ) end repopulate_raw_machos end |
#change_rpath(old_path, new_path, options = {}) ⇒ void
This method returns an undefined value.
Change the runtime path old_path to new_path in the file's Mach-Os.
205 206 207 208 209 210 211 |
# File 'lib/macho/fat_file.rb', line 205 def change_rpath(old_path, new_path, = {}) each_macho() do |macho| macho.change_rpath(old_path, new_path, ) end repopulate_raw_machos end |
#core? ⇒ Boolean
Returns whether or not the file is of type MH_CORE.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#delete_rpath(path, options = {}) ⇒ Object
Delete the given runtime path from the file's Mach-Os.
235 236 237 238 239 240 241 |
# File 'lib/macho/fat_file.rb', line 235 def delete_rpath(path, = {}) each_macho() do |macho| macho.delete_rpath(path, ) end repopulate_raw_machos end |
#dsym? ⇒ Boolean
Returns whether or not the file is of type MH_DSYM.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#dylib? ⇒ Boolean
Returns whether or not the file is of type MH_DYLIB.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#dylib_id ⇒ String?
Returns the Mach-O's dylib ID.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#dylib_load_commands ⇒ Array<LoadCommands::DylibCommand>
All load commands responsible for loading dylibs in the file's Mach-O's.
129 130 131 |
# File 'lib/macho/fat_file.rb', line 129 def dylib_load_commands machos.map(&:dylib_load_commands).flatten end |
#dylinker? ⇒ Boolean
Returns whether or not the file is of type MH_DYLINKER.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#executable? ⇒ Boolean
Returns whether or not the file is of type MH_EXECUTE.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#extract(cputype) ⇒ MachOFile?
Extract a Mach-O with the given CPU type from the file.
248 249 250 |
# File 'lib/macho/fat_file.rb', line 248 def extract(cputype) machos.select { |macho| macho.cputype == cputype }.first end |
#filetype ⇒ Symbol
Returns a string representation of the Mach-O's filetype.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#fvmlib? ⇒ Boolean
Returns whether or not the file is of type MH_FVMLIB.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#initialize_from_bin(bin) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Initializes a new FatFile instance from a binary string.
69 70 71 72 73 |
# File 'lib/macho/fat_file.rb', line 69 def initialize_from_bin(bin) @filename = nil @raw_data = bin populate_fields end |
#kext? ⇒ Boolean
Returns whether or not the file is of type MH_KEXT_BUNDLE.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#linked_dylibs ⇒ Array<String>
All shared libraries linked to the file's Mach-Os.
160 161 162 163 164 165 |
# File 'lib/macho/fat_file.rb', line 160 def linked_dylibs # Individual architectures in a fat binary can link to different subsets # of libraries, but at this point we want to have the full picture, i.e. # the union of all libraries used by all architectures. machos.map(&:linked_dylibs).flatten.uniq end |
#magic ⇒ Integer
Returns the magic number of the header (and file).
111 |
# File 'lib/macho/fat_file.rb', line 111 def_delegators :header, :magic |
#magic_string ⇒ String
Returns a string representation of the file's magic number.
114 115 116 |
# File 'lib/macho/fat_file.rb', line 114 def magic_string Headers::MH_MAGICS[magic] end |
#object? ⇒ Boolean
Returns whether or not the file is of type MH_OBJECT.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#populate_fields ⇒ void
This method is public, but should (almost) never need to be called.
This method returns an undefined value.
Populate the instance's fields with the raw Fat Mach-O data.
121 122 123 124 125 |
# File 'lib/macho/fat_file.rb', line 121 def populate_fields @header = populate_fat_header @fat_archs = populate_fat_archs @machos = populate_machos end |
#preload? ⇒ Boolean
Returns whether or not the file is of type MH_PRELOAD.
105 106 107 |
# File 'lib/macho/fat_file.rb', line 105 def_delegators :canonical_macho, :object?, :executable?, :fvmlib?, :core?, :preload?, :dylib?, :dylinker?, :bundle?, :dsym?, :kext?, :filetype, :dylib_id |
#rpaths ⇒ Array<String>
All runtime paths associated with the file's Mach-Os.
192 193 194 195 |
# File 'lib/macho/fat_file.rb', line 192 def rpaths # Can individual architectures have different runtime paths? machos.map(&:rpaths).flatten.uniq end |
#serialize ⇒ String
The file's raw fat data.
77 78 79 |
# File 'lib/macho/fat_file.rb', line 77 def serialize @raw_data end |
#write(filename) ⇒ void
This method returns an undefined value.
Write all (fat) data to the given filename.
255 256 257 |
# File 'lib/macho/fat_file.rb', line 255 def write(filename) File.open(filename, "wb") { |f| f.write(@raw_data) } end |
#write! ⇒ void
Overwrites all data in the file!
This method returns an undefined value.
Write all (fat) data to the file used to initialize the instance.
263 264 265 266 |
# File 'lib/macho/fat_file.rb', line 263 def write! raise MachOError, "no initial file to write to" if filename.nil? File.open(@filename, "wb") { |f| f.write(@raw_data) } end |