1+ require "forwardable"
2+
13module MachO
24 # Represents a "Fat" file, which contains a header, a listing of available
35 # architectures, and one or more Mach-O binaries.
46 # @see https://en.wikipedia.org/wiki/Mach-O#Multi-architecture_binaries
57 # @see MachO::MachOFile
68 class FatFile
9+ extend Forwardable
10+
711 # @return [String] the filename loaded from, or nil if loaded from a binary string
812 attr_accessor :filename
913
@@ -74,72 +78,43 @@ def serialize
7478 @raw_data
7579 end
7680
77- # @return [Boolean] true if the file is of type `MH_OBJECT`, false otherwise
78- def object?
79- machos . first . object?
80- end
81-
82- # @return [Boolean] true if the file is of type `MH_EXECUTE`, false otherwise
83- def executable?
84- machos . first . executable?
85- end
86-
87- # @return [Boolean] true if the file is of type `MH_FVMLIB`, false otherwise
88- def fvmlib?
89- machos . first . fvmlib?
90- end
91-
92- # @return [Boolean] true if the file is of type `MH_CORE`, false otherwise
93- def core?
94- machos . first . core?
95- end
96-
97- # @return [Boolean] true if the file is of type `MH_PRELOAD`, false otherwise
98- def preload?
99- machos . first . preload?
100- end
101-
102- # @return [Boolean] true if the file is of type `MH_DYLIB`, false otherwise
103- def dylib?
104- machos . first . dylib?
105- end
106-
107- # @return [Boolean] true if the file is of type `MH_DYLINKER`, false otherwise
108- def dylinker?
109- machos . first . dylinker?
110- end
111-
112- # @return [Boolean] true if the file is of type `MH_BUNDLE`, false otherwise
113- def bundle?
114- machos . first . bundle?
115- end
116-
117- # @return [Boolean] true if the file is of type `MH_DSYM`, false otherwise
118- def dsym?
119- machos . first . dsym?
120- end
121-
122- # @return [Boolean] true if the file is of type `MH_KEXT_BUNDLE`, false otherwise
123- def kext?
124- machos . first . kext?
125- end
126-
127- # @return [Fixnum] the file's magic number
128- def magic
129- header . magic
130- end
81+ # @!method object?
82+ # @return (see MachO::MachOFile#object?)
83+ # @!method executable?
84+ # @return (see MachO::MachOFile#executable?)
85+ # @!method fvmlib?
86+ # @return (see MachO::MachOFile#fvmlib?)
87+ # @!method core?
88+ # @return (see MachO::MachOFile#core?)
89+ # @!method preload?
90+ # @return (see MachO::MachOFile#preload?)
91+ # @!method dylib?
92+ # @return (see MachO::MachOFile#dylib?)
93+ # @!method dylinker?
94+ # @return (see MachO::MachOFile#dylinker?)
95+ # @!method bundle?
96+ # @return (see MachO::MachOFile#bundle?)
97+ # @!method dsym?
98+ # @return (see MachO::MachOFile#dsym?)
99+ # @!method kext?
100+ # @return (see MachO::MachOFile#kext?)
101+ # @!method filetype
102+ # @return (see MachO::MachOFile#filetype)
103+ # @!method dylib_id
104+ # @return (see MachO::MachOFile#dylib_id)
105+ def_delegators :canonical_macho , :object? , :executable? , :fvmlib? ,
106+ :core? , :preload? , :dylib? , :dylinker? , :bundle? ,
107+ :dsym? , :kext? , :filetype , :dylib_id
108+
109+ # @!method magic
110+ # @return (see MachO::Headers::FatHeader#magic)
111+ def_delegators :header , :magic
131112
132113 # @return [String] a string representation of the file's magic number
133114 def magic_string
134115 Headers ::MH_MAGICS [ magic ]
135116 end
136117
137- # The file's type. Assumed to be the same for every Mach-O within.
138- # @return [Symbol] the filetype
139- def filetype
140- machos . first . filetype
141- end
142-
143118 # Populate the instance's fields with the raw Fat Mach-O data.
144119 # @return [void]
145120 # @note This method is public, but should (almost) never need to be called.
@@ -155,15 +130,6 @@ def dylib_load_commands
155130 machos . map ( &:dylib_load_commands ) . flatten
156131 end
157132
158- # The file's dylib ID. If the file is not a dylib, returns `nil`.
159- # @example
160- # file.dylib_id # => 'libBar.dylib'
161- # @return [String, nil] the file's dylib ID
162- # @see MachO::MachOFile#linked_dylibs
163- def dylib_id
164- machos . first . dylib_id
165- end
166-
167133 # Changes the file's dylib ID to `new_id`. If the file is not a dylib, does nothing.
168134 # @example
169135 # file.change_dylib_id('libFoo.dylib')
@@ -395,5 +361,13 @@ def each_macho(options = {})
395361 # Non-strict mode: Raise first error if *all* Mach-O slices failed.
396362 raise errors . first if errors . size == machos . size
397363 end
364+
365+ # Return a single-arch Mach-O that represents this fat Mach-O for purposes
366+ # of delegation.
367+ # @return [MachO::MachOFile] the Mach-O file
368+ # @api private
369+ def canonical_macho
370+ machos . first
371+ end
398372 end
399373end
0 commit comments