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 ⇒ Fixnum
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 ⇒ Fixnum
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 267 268 269 |
# File 'lib/macho/fat_file.rb', line 263 def write! if filename.nil? raise MachOError, "cannot write to a default file when initialized from a binary string" else File.open(@filename, "wb") { |f| f.write(@raw_data) } end end |