ruby-macho 0.2.6 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1314 +1,1317 @@
1
1
  module MachO
2
- # load commands added after OS X 10.1 need to be bitwise ORed with
3
- # LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
4
- # @api private
5
- LC_REQ_DYLD = 0x80000000
6
-
7
- # association of load commands to symbol representations
8
- # @api private
9
- LOAD_COMMANDS = {
10
- 0x1 => :LC_SEGMENT,
11
- 0x2 => :LC_SYMTAB,
12
- 0x3 => :LC_SYMSEG,
13
- 0x4 => :LC_THREAD,
14
- 0x5 => :LC_UNIXTHREAD,
15
- 0x6 => :LC_LOADFVMLIB,
16
- 0x7 => :LC_IDFVMLIB,
17
- 0x8 => :LC_IDENT,
18
- 0x9 => :LC_FVMFILE,
19
- 0xa => :LC_PREPAGE,
20
- 0xb => :LC_DYSYMTAB,
21
- 0xc => :LC_LOAD_DYLIB,
22
- 0xd => :LC_ID_DYLIB,
23
- 0xe => :LC_LOAD_DYLINKER,
24
- 0xf => :LC_ID_DYLINKER,
25
- 0x10 => :LC_PREBOUND_DYLIB,
26
- 0x11 => :LC_ROUTINES,
27
- 0x12 => :LC_SUB_FRAMEWORK,
28
- 0x13 => :LC_SUB_UMBRELLA,
29
- 0x14 => :LC_SUB_CLIENT,
30
- 0x15 => :LC_SUB_LIBRARY,
31
- 0x16 => :LC_TWOLEVEL_HINTS,
32
- 0x17 => :LC_PREBIND_CKSUM,
33
- (0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
34
- 0x19 => :LC_SEGMENT_64,
35
- 0x1a => :LC_ROUTINES_64,
36
- 0x1b => :LC_UUID,
37
- (0x1c | LC_REQ_DYLD) => :LC_RPATH,
38
- 0x1d => :LC_CODE_SIGNATURE,
39
- 0x1e => :LC_SEGMENT_SPLIT_INFO,
40
- (0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
41
- 0x20 => :LC_LAZY_LOAD_DYLIB,
42
- 0x21 => :LC_ENCRYPTION_INFO,
43
- 0x22 => :LC_DYLD_INFO,
44
- (0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
45
- (0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
46
- 0x24 => :LC_VERSION_MIN_MACOSX,
47
- 0x25 => :LC_VERSION_MIN_IPHONEOS,
48
- 0x26 => :LC_FUNCTION_STARTS,
49
- 0x27 => :LC_DYLD_ENVIRONMENT,
50
- (0x28 | LC_REQ_DYLD) => :LC_MAIN,
51
- 0x29 => :LC_DATA_IN_CODE,
52
- 0x2a => :LC_SOURCE_VERSION,
53
- 0x2b => :LC_DYLIB_CODE_SIGN_DRS,
54
- 0x2c => :LC_ENCRYPTION_INFO_64,
55
- 0x2d => :LC_LINKER_OPTION,
56
- 0x2e => :LC_LINKER_OPTIMIZATION_HINT,
57
- 0x2f => :LC_VERSION_MIN_TVOS,
58
- 0x30 => :LC_VERSION_MIN_WATCHOS,
59
- }.freeze
60
-
61
- # association of symbol representations to load command constants
62
- # @api private
63
- LOAD_COMMAND_CONSTANTS = LOAD_COMMANDS.invert.freeze
64
-
65
- # load commands responsible for loading dylibs
66
- # @api private
67
- DYLIB_LOAD_COMMANDS = [
68
- :LC_LOAD_DYLIB,
69
- :LC_LOAD_WEAK_DYLIB,
70
- :LC_REEXPORT_DYLIB,
71
- :LC_LAZY_LOAD_DYLIB,
72
- :LC_LOAD_UPWARD_DYLIB,
73
- ].freeze
74
-
75
- # load commands that can be created manually via {LoadCommand.create}
76
- # @api private
77
- CREATABLE_LOAD_COMMANDS = DYLIB_LOAD_COMMANDS + [
78
- :LC_ID_DYLIB,
79
- :LC_RPATH,
80
- :LC_LOAD_DYLINKER,
81
- ].freeze
82
-
83
- # association of load command symbols to string representations of classes
84
- # @api private
85
- LC_STRUCTURES = {
86
- :LC_SEGMENT => "SegmentCommand",
87
- :LC_SYMTAB => "SymtabCommand",
88
- :LC_SYMSEG => "SymsegCommand", # obsolete
89
- :LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such
90
- :LC_UNIXTHREAD => "ThreadCommand",
91
- :LC_LOADFVMLIB => "FvmlibCommand", # obsolete
92
- :LC_IDFVMLIB => "FvmlibCommand", # obsolete
93
- :LC_IDENT => "IdentCommand", # obsolete
94
- :LC_FVMFILE => "FvmfileCommand", # reserved for internal use only
95
- :LC_PREPAGE => "LoadCommand", # reserved for internal use only, no public struct
96
- :LC_DYSYMTAB => "DysymtabCommand",
97
- :LC_LOAD_DYLIB => "DylibCommand",
98
- :LC_ID_DYLIB => "DylibCommand",
99
- :LC_LOAD_DYLINKER => "DylinkerCommand",
100
- :LC_ID_DYLINKER => "DylinkerCommand",
101
- :LC_PREBOUND_DYLIB => "PreboundDylibCommand",
102
- :LC_ROUTINES => "RoutinesCommand",
103
- :LC_SUB_FRAMEWORK => "SubFrameworkCommand",
104
- :LC_SUB_UMBRELLA => "SubUmbrellaCommand",
105
- :LC_SUB_CLIENT => "SubClientCommand",
106
- :LC_SUB_LIBRARY => "SubLibraryCommand",
107
- :LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
108
- :LC_PREBIND_CKSUM => "PrebindCksumCommand",
109
- :LC_LOAD_WEAK_DYLIB => "DylibCommand",
110
- :LC_SEGMENT_64 => "SegmentCommand64",
111
- :LC_ROUTINES_64 => "RoutinesCommand64",
112
- :LC_UUID => "UUIDCommand",
113
- :LC_RPATH => "RpathCommand",
114
- :LC_CODE_SIGNATURE => "LinkeditDataCommand",
115
- :LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
116
- :LC_REEXPORT_DYLIB => "DylibCommand",
117
- :LC_LAZY_LOAD_DYLIB => "DylibCommand",
118
- :LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
119
- :LC_DYLD_INFO => "DyldInfoCommand",
120
- :LC_DYLD_INFO_ONLY => "DyldInfoCommand",
121
- :LC_LOAD_UPWARD_DYLIB => "DylibCommand",
122
- :LC_VERSION_MIN_MACOSX => "VersionMinCommand",
123
- :LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
124
- :LC_FUNCTION_STARTS => "LinkeditDataCommand",
125
- :LC_DYLD_ENVIRONMENT => "DylinkerCommand",
126
- :LC_MAIN => "EntryPointCommand",
127
- :LC_DATA_IN_CODE => "LinkeditDataCommand",
128
- :LC_SOURCE_VERSION => "SourceVersionCommand",
129
- :LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
130
- :LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
131
- :LC_LINKER_OPTION => "LinkerOptionCommand",
132
- :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand",
133
- :LC_VERSION_MIN_TVOS => "VersionMinCommand",
134
- :LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
135
- }.freeze
136
-
137
- # association of segment name symbols to names
138
- # @api private
139
- SEGMENT_NAMES = {
140
- :SEG_PAGEZERO => "__PAGEZERO",
141
- :SEG_TEXT => "__TEXT",
142
- :SEG_DATA => "__DATA",
143
- :SEG_OBJC => "__OBJC",
144
- :SEG_ICON => "__ICON",
145
- :SEG_LINKEDIT => "__LINKEDIT",
146
- :SEG_UNIXSTACK => "__UNIXSTACK",
147
- :SEG_IMPORT => "__IMPORT",
148
- }.freeze
149
-
150
- # association of segment flag symbols to values
151
- # @api private
152
- SEGMENT_FLAGS = {
153
- :SG_HIGHVM => 0x1,
154
- :SG_FVMLIB => 0x2,
155
- :SG_NORELOC => 0x4,
156
- :SG_PROTECTED_VERSION_1 => 0x8,
157
- }.freeze
158
-
159
- # Mach-O load command structure
160
- # This is the most generic load command - only cmd ID and size are
161
- # represented, and no actual data. Used when a more specific class
162
- # isn't available/implemented.
163
- class LoadCommand < MachOStructure
164
- # @return [MachO::MachOView] the raw view associated with the load command
165
- attr_reader :view
166
-
167
- # @return [Fixnum] the load command's identifying number
168
- attr_reader :cmd
169
-
170
- # @return [Fixnum] the size of the load command, in bytes
171
- attr_reader :cmdsize
172
-
173
- # @see MachOStructure::FORMAT
174
- # @api private
175
- FORMAT = "L=2".freeze
2
+ # Classes and constants for parsing load commands in Mach-O binaries.
3
+ module LoadCommands
4
+ # load commands added after OS X 10.1 need to be bitwise ORed with
5
+ # LC_REQ_DYLD to be recognized by the dynamic linder (dyld)
6
+ # @api private
7
+ LC_REQ_DYLD = 0x80000000
8
+
9
+ # association of load commands to symbol representations
10
+ # @api private
11
+ LOAD_COMMANDS = {
12
+ 0x1 => :LC_SEGMENT,
13
+ 0x2 => :LC_SYMTAB,
14
+ 0x3 => :LC_SYMSEG,
15
+ 0x4 => :LC_THREAD,
16
+ 0x5 => :LC_UNIXTHREAD,
17
+ 0x6 => :LC_LOADFVMLIB,
18
+ 0x7 => :LC_IDFVMLIB,
19
+ 0x8 => :LC_IDENT,
20
+ 0x9 => :LC_FVMFILE,
21
+ 0xa => :LC_PREPAGE,
22
+ 0xb => :LC_DYSYMTAB,
23
+ 0xc => :LC_LOAD_DYLIB,
24
+ 0xd => :LC_ID_DYLIB,
25
+ 0xe => :LC_LOAD_DYLINKER,
26
+ 0xf => :LC_ID_DYLINKER,
27
+ 0x10 => :LC_PREBOUND_DYLIB,
28
+ 0x11 => :LC_ROUTINES,
29
+ 0x12 => :LC_SUB_FRAMEWORK,
30
+ 0x13 => :LC_SUB_UMBRELLA,
31
+ 0x14 => :LC_SUB_CLIENT,
32
+ 0x15 => :LC_SUB_LIBRARY,
33
+ 0x16 => :LC_TWOLEVEL_HINTS,
34
+ 0x17 => :LC_PREBIND_CKSUM,
35
+ (0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
36
+ 0x19 => :LC_SEGMENT_64,
37
+ 0x1a => :LC_ROUTINES_64,
38
+ 0x1b => :LC_UUID,
39
+ (0x1c | LC_REQ_DYLD) => :LC_RPATH,
40
+ 0x1d => :LC_CODE_SIGNATURE,
41
+ 0x1e => :LC_SEGMENT_SPLIT_INFO,
42
+ (0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
43
+ 0x20 => :LC_LAZY_LOAD_DYLIB,
44
+ 0x21 => :LC_ENCRYPTION_INFO,
45
+ 0x22 => :LC_DYLD_INFO,
46
+ (0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
47
+ (0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
48
+ 0x24 => :LC_VERSION_MIN_MACOSX,
49
+ 0x25 => :LC_VERSION_MIN_IPHONEOS,
50
+ 0x26 => :LC_FUNCTION_STARTS,
51
+ 0x27 => :LC_DYLD_ENVIRONMENT,
52
+ (0x28 | LC_REQ_DYLD) => :LC_MAIN,
53
+ 0x29 => :LC_DATA_IN_CODE,
54
+ 0x2a => :LC_SOURCE_VERSION,
55
+ 0x2b => :LC_DYLIB_CODE_SIGN_DRS,
56
+ 0x2c => :LC_ENCRYPTION_INFO_64,
57
+ 0x2d => :LC_LINKER_OPTION,
58
+ 0x2e => :LC_LINKER_OPTIMIZATION_HINT,
59
+ 0x2f => :LC_VERSION_MIN_TVOS,
60
+ 0x30 => :LC_VERSION_MIN_WATCHOS,
61
+ }.freeze
62
+
63
+ # association of symbol representations to load command constants
64
+ # @api private
65
+ LOAD_COMMAND_CONSTANTS = LOAD_COMMANDS.invert.freeze
66
+
67
+ # load commands responsible for loading dylibs
68
+ # @api private
69
+ DYLIB_LOAD_COMMANDS = [
70
+ :LC_LOAD_DYLIB,
71
+ :LC_LOAD_WEAK_DYLIB,
72
+ :LC_REEXPORT_DYLIB,
73
+ :LC_LAZY_LOAD_DYLIB,
74
+ :LC_LOAD_UPWARD_DYLIB,
75
+ ].freeze
76
+
77
+ # load commands that can be created manually via {LoadCommand.create}
78
+ # @api private
79
+ CREATABLE_LOAD_COMMANDS = DYLIB_LOAD_COMMANDS + [
80
+ :LC_ID_DYLIB,
81
+ :LC_RPATH,
82
+ :LC_LOAD_DYLINKER,
83
+ ].freeze
84
+
85
+ # association of load command symbols to string representations of classes
86
+ # @api private
87
+ LC_STRUCTURES = {
88
+ :LC_SEGMENT => "SegmentCommand",
89
+ :LC_SYMTAB => "SymtabCommand",
90
+ :LC_SYMSEG => "SymsegCommand", # obsolete
91
+ :LC_THREAD => "ThreadCommand", # seems obsolete, but not documented as such
92
+ :LC_UNIXTHREAD => "ThreadCommand",
93
+ :LC_LOADFVMLIB => "FvmlibCommand", # obsolete
94
+ :LC_IDFVMLIB => "FvmlibCommand", # obsolete
95
+ :LC_IDENT => "IdentCommand", # obsolete
96
+ :LC_FVMFILE => "FvmfileCommand", # reserved for internal use only
97
+ :LC_PREPAGE => "LoadCommand", # reserved for internal use only, no public struct
98
+ :LC_DYSYMTAB => "DysymtabCommand",
99
+ :LC_LOAD_DYLIB => "DylibCommand",
100
+ :LC_ID_DYLIB => "DylibCommand",
101
+ :LC_LOAD_DYLINKER => "DylinkerCommand",
102
+ :LC_ID_DYLINKER => "DylinkerCommand",
103
+ :LC_PREBOUND_DYLIB => "PreboundDylibCommand",
104
+ :LC_ROUTINES => "RoutinesCommand",
105
+ :LC_SUB_FRAMEWORK => "SubFrameworkCommand",
106
+ :LC_SUB_UMBRELLA => "SubUmbrellaCommand",
107
+ :LC_SUB_CLIENT => "SubClientCommand",
108
+ :LC_SUB_LIBRARY => "SubLibraryCommand",
109
+ :LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
110
+ :LC_PREBIND_CKSUM => "PrebindCksumCommand",
111
+ :LC_LOAD_WEAK_DYLIB => "DylibCommand",
112
+ :LC_SEGMENT_64 => "SegmentCommand64",
113
+ :LC_ROUTINES_64 => "RoutinesCommand64",
114
+ :LC_UUID => "UUIDCommand",
115
+ :LC_RPATH => "RpathCommand",
116
+ :LC_CODE_SIGNATURE => "LinkeditDataCommand",
117
+ :LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
118
+ :LC_REEXPORT_DYLIB => "DylibCommand",
119
+ :LC_LAZY_LOAD_DYLIB => "DylibCommand",
120
+ :LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
121
+ :LC_DYLD_INFO => "DyldInfoCommand",
122
+ :LC_DYLD_INFO_ONLY => "DyldInfoCommand",
123
+ :LC_LOAD_UPWARD_DYLIB => "DylibCommand",
124
+ :LC_VERSION_MIN_MACOSX => "VersionMinCommand",
125
+ :LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
126
+ :LC_FUNCTION_STARTS => "LinkeditDataCommand",
127
+ :LC_DYLD_ENVIRONMENT => "DylinkerCommand",
128
+ :LC_MAIN => "EntryPointCommand",
129
+ :LC_DATA_IN_CODE => "LinkeditDataCommand",
130
+ :LC_SOURCE_VERSION => "SourceVersionCommand",
131
+ :LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
132
+ :LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
133
+ :LC_LINKER_OPTION => "LinkerOptionCommand",
134
+ :LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand",
135
+ :LC_VERSION_MIN_TVOS => "VersionMinCommand",
136
+ :LC_VERSION_MIN_WATCHOS => "VersionMinCommand",
137
+ }.freeze
138
+
139
+ # association of segment name symbols to names
140
+ # @api private
141
+ SEGMENT_NAMES = {
142
+ :SEG_PAGEZERO => "__PAGEZERO",
143
+ :SEG_TEXT => "__TEXT",
144
+ :SEG_DATA => "__DATA",
145
+ :SEG_OBJC => "__OBJC",
146
+ :SEG_ICON => "__ICON",
147
+ :SEG_LINKEDIT => "__LINKEDIT",
148
+ :SEG_UNIXSTACK => "__UNIXSTACK",
149
+ :SEG_IMPORT => "__IMPORT",
150
+ }.freeze
151
+
152
+ # association of segment flag symbols to values
153
+ # @api private
154
+ SEGMENT_FLAGS = {
155
+ :SG_HIGHVM => 0x1,
156
+ :SG_FVMLIB => 0x2,
157
+ :SG_NORELOC => 0x4,
158
+ :SG_PROTECTED_VERSION_1 => 0x8,
159
+ }.freeze
160
+
161
+ # Mach-O load command structure
162
+ # This is the most generic load command - only cmd ID and size are
163
+ # represented, and no actual data. Used when a more specific class
164
+ # isn't available/implemented.
165
+ class LoadCommand < MachOStructure
166
+ # @return [MachO::MachOView] the raw view associated with the load command
167
+ attr_reader :view
168
+
169
+ # @return [Fixnum] the load command's identifying number
170
+ attr_reader :cmd
171
+
172
+ # @return [Fixnum] the size of the load command, in bytes
173
+ attr_reader :cmdsize
174
+
175
+ # @see MachOStructure::FORMAT
176
+ # @api private
177
+ FORMAT = "L=2".freeze
176
178
 
177
- # @see MachOStructure::SIZEOF
178
- # @api private
179
- SIZEOF = 8
179
+ # @see MachOStructure::SIZEOF
180
+ # @api private
181
+ SIZEOF = 8
180
182
 
181
- # Instantiates a new LoadCommand given a view into its origin Mach-O
182
- # @param view [MachO::MachOView] the load command's raw view
183
- # @return [MachO::LoadCommand] the new load command
184
- # @api private
185
- def self.new_from_bin(view)
186
- bin = view.raw_data.slice(view.offset, bytesize)
187
- format = Utils.specialize_format(self::FORMAT, view.endianness)
183
+ # Instantiates a new LoadCommand given a view into its origin Mach-O
184
+ # @param view [MachO::MachOView] the load command's raw view
185
+ # @return [MachO::LoadCommands::LoadCommand] the new load command
186
+ # @api private
187
+ def self.new_from_bin(view)
188
+ bin = view.raw_data.slice(view.offset, bytesize)
189
+ format = Utils.specialize_format(self::FORMAT, view.endianness)
188
190
 
189
- new(view, *bin.unpack(format))
190
- end
191
+ new(view, *bin.unpack(format))
192
+ end
191
193
 
192
- # Creates a new (viewless) command corresponding to the symbol provided
193
- # @param cmd_sym [Symbol] the symbol of the load command being created
194
- # @param args [Array] the arguments for the load command being created
195
- def self.create(cmd_sym, *args)
196
- raise LoadCommandNotCreatableError, cmd_sym unless CREATABLE_LOAD_COMMANDS.include?(cmd_sym)
194
+ # Creates a new (viewless) command corresponding to the symbol provided
195
+ # @param cmd_sym [Symbol] the symbol of the load command being created
196
+ # @param args [Array] the arguments for the load command being created
197
+ def self.create(cmd_sym, *args)
198
+ raise LoadCommandNotCreatableError, cmd_sym unless CREATABLE_LOAD_COMMANDS.include?(cmd_sym)
197
199
 
198
- klass = MachO.const_get LC_STRUCTURES[cmd_sym]
199
- cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
200
+ klass = LoadCommands.const_get LC_STRUCTURES[cmd_sym]
201
+ cmd = LOAD_COMMAND_CONSTANTS[cmd_sym]
200
202
 
201
- # cmd will be filled in, view and cmdsize will be left unpopulated
202
- klass_arity = klass.instance_method(:initialize).arity - 3
203
+ # cmd will be filled in, view and cmdsize will be left unpopulated
204
+ klass_arity = klass.instance_method(:initialize).arity - 3
203
205
 
204
- raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity != args.size
206
+ raise LoadCommandCreationArityError.new(cmd_sym, klass_arity, args.size) if klass_arity != args.size
205
207
 
206
- klass.new(nil, cmd, nil, *args)
207
- end
208
+ klass.new(nil, cmd, nil, *args)
209
+ end
208
210
 
209
- # @param view [MachO::MachOView] the load command's raw view
210
- # @param cmd [Fixnum] the load command's identifying number
211
- # @param cmdsize [Fixnum] the size of the load command in bytes
212
- # @api private
213
- def initialize(view, cmd, cmdsize)
214
- @view = view
215
- @cmd = cmd
216
- @cmdsize = cmdsize
217
- end
211
+ # @param view [MachO::MachOView] the load command's raw view
212
+ # @param cmd [Fixnum] the load command's identifying number
213
+ # @param cmdsize [Fixnum] the size of the load command in bytes
214
+ # @api private
215
+ def initialize(view, cmd, cmdsize)
216
+ @view = view
217
+ @cmd = cmd
218
+ @cmdsize = cmdsize
219
+ end
218
220
 
219
- # @return [Boolean] true if the load command can be serialized, false otherwise
220
- def serializable?
221
- CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
222
- end
221
+ # @return [Boolean] true if the load command can be serialized, false otherwise
222
+ def serializable?
223
+ CREATABLE_LOAD_COMMANDS.include?(LOAD_COMMANDS[cmd])
224
+ end
223
225
 
224
- # @param context [MachO::LoadCommand::SerializationContext] the context
225
- # to serialize into
226
- # @return [String, nil] the serialized fields of the load command, or nil
227
- # if the load command can't be serialized
228
- # @api private
229
- def serialize(context)
230
- raise LoadCommandNotSerializableError, LOAD_COMMANDS[cmd] unless serializable?
231
- format = Utils.specialize_format(FORMAT, context.endianness)
232
- [cmd, SIZEOF].pack(format)
233
- end
226
+ # @param context [MachO::LoadCommands::LoadCommand::SerializationContext] the context
227
+ # to serialize into
228
+ # @return [String, nil] the serialized fields of the load command, or nil
229
+ # if the load command can't be serialized
230
+ # @api private
231
+ def serialize(context)
232
+ raise LoadCommandNotSerializableError, LOAD_COMMANDS[cmd] unless serializable?
233
+ format = Utils.specialize_format(FORMAT, context.endianness)
234
+ [cmd, SIZEOF].pack(format)
235
+ end
234
236
 
235
- # @return [Fixnum] the load command's offset in the source file
236
- # @deprecated use {#view} instead
237
- def offset
238
- view.offset
239
- end
237
+ # @return [Fixnum] the load command's offset in the source file
238
+ # @deprecated use {#view} instead
239
+ def offset
240
+ view.offset
241
+ end
240
242
 
241
- # @return [Symbol] a symbol representation of the load command's identifying number
242
- def type
243
- LOAD_COMMANDS[cmd]
244
- end
243
+ # @return [Symbol] a symbol representation of the load command's identifying number
244
+ def type
245
+ LOAD_COMMANDS[cmd]
246
+ end
245
247
 
246
- alias to_sym type
248
+ alias to_sym type
247
249
 
248
- # @return [String] a string representation of the load command's identifying number
249
- def to_s
250
- type.to_s
251
- end
250
+ # @return [String] a string representation of the load command's identifying number
251
+ def to_s
252
+ type.to_s
253
+ end
252
254
 
253
- # Represents a Load Command string. A rough analogue to the lc_str
254
- # struct used internally by OS X. This class allows ruby-macho to
255
- # pretend that strings stored in LCs are immediately available without
256
- # explicit operations on the raw Mach-O data.
257
- class LCStr
258
- # @param lc [MachO::LoadCommand] the load command
259
- # @param lc_str [Fixnum, String] the offset to the beginning of the string,
260
- # or the string itself if not being initialized with a view.
261
- # @raise [MachO::LCStrMalformedError] if the string is malformed
262
- # @todo devise a solution such that the `lc_str` parameter is not
263
- # interpreted differently depending on `lc.view`. The current behavior
264
- # is a hack to allow viewless load command creation.
265
- # @api private
266
- def initialize(lc, lc_str)
267
- view = lc.view
268
-
269
- if view
270
- lc_str_abs = view.offset + lc_str
271
- lc_end = view.offset + lc.cmdsize - 1
272
- raw_string = view.raw_data.slice(lc_str_abs..lc_end)
273
- @string, null_byte, _padding = raw_string.partition("\x00")
274
- raise LCStrMalformedError, lc if null_byte.empty?
275
- @string_offset = lc_str
276
- else
277
- @string = lc_str
278
- @string_offset = 0
255
+ # Represents a Load Command string. A rough analogue to the lc_str
256
+ # struct used internally by OS X. This class allows ruby-macho to
257
+ # pretend that strings stored in LCs are immediately available without
258
+ # explicit operations on the raw Mach-O data.
259
+ class LCStr
260
+ # @param lc [MachO::LoadCommands::LoadCommand] the load command
261
+ # @param lc_str [Fixnum, String] the offset to the beginning of the string,
262
+ # or the string itself if not being initialized with a view.
263
+ # @raise [MachO::LCStrMalformedError] if the string is malformed
264
+ # @todo devise a solution such that the `lc_str` parameter is not
265
+ # interpreted differently depending on `lc.view`. The current behavior
266
+ # is a hack to allow viewless load command creation.
267
+ # @api private
268
+ def initialize(lc, lc_str)
269
+ view = lc.view
270
+
271
+ if view
272
+ lc_str_abs = view.offset + lc_str
273
+ lc_end = view.offset + lc.cmdsize - 1
274
+ raw_string = view.raw_data.slice(lc_str_abs..lc_end)
275
+ @string, null_byte, _padding = raw_string.partition("\x00")
276
+ raise LCStrMalformedError, lc if null_byte.empty?
277
+ @string_offset = lc_str
278
+ else
279
+ @string = lc_str
280
+ @string_offset = 0
281
+ end
279
282
  end
280
- end
281
283
 
282
- # @return [String] a string representation of the LCStr
283
- def to_s
284
- @string
285
- end
284
+ # @return [String] a string representation of the LCStr
285
+ def to_s
286
+ @string
287
+ end
286
288
 
287
- # @return [Fixnum] the offset to the beginning of the string in the load command
288
- def to_i
289
- @string_offset
289
+ # @return [Fixnum] the offset to the beginning of the string in the load command
290
+ def to_i
291
+ @string_offset
292
+ end
290
293
  end
291
- end
292
294
 
293
- # Represents the contextual information needed by a load command to
294
- # serialize itself correctly into a binary string.
295
- class SerializationContext
296
- # @return [Symbol] the endianness of the serialized load command
297
- attr_reader :endianness
295
+ # Represents the contextual information needed by a load command to
296
+ # serialize itself correctly into a binary string.
297
+ class SerializationContext
298
+ # @return [Symbol] the endianness of the serialized load command
299
+ attr_reader :endianness
298
300
 
299
- # @return [Fixnum] the constant alignment value used to pad the serialized load command
300
- attr_reader :alignment
301
+ # @return [Fixnum] the constant alignment value used to pad the serialized load command
302
+ attr_reader :alignment
301
303
 
302
- # @param macho [MachO::MachOFile] the file to contextualize
303
- # @return [MachO::LoadCommand::SerializationContext] the resulting context
304
- def self.context_for(macho)
305
- new(macho.endianness, macho.alignment)
306
- end
304
+ # @param macho [MachO::MachOFile] the file to contextualize
305
+ # @return [MachO::LoadCommands::LoadCommand::SerializationContext] the resulting context
306
+ def self.context_for(macho)
307
+ new(macho.endianness, macho.alignment)
308
+ end
307
309
 
308
- # @param endianness [Symbol] the endianness of the context
309
- # @param alignment [Fixnum] the alignment of the context
310
- # @api private
311
- def initialize(endianness, alignment)
312
- @endianness = endianness
313
- @alignment = alignment
310
+ # @param endianness [Symbol] the endianness of the context
311
+ # @param alignment [Fixnum] the alignment of the context
312
+ # @api private
313
+ def initialize(endianness, alignment)
314
+ @endianness = endianness
315
+ @alignment = alignment
316
+ end
314
317
  end
315
318
  end
316
- end
317
319
 
318
- # A load command containing a single 128-bit unique random number identifying
319
- # an object produced by static link editor. Corresponds to LC_UUID.
320
- class UUIDCommand < LoadCommand
321
- # @return [Array<Fixnum>] the UUID
322
- attr_reader :uuid
320
+ # A load command containing a single 128-bit unique random number identifying
321
+ # an object produced by static link editor. Corresponds to LC_UUID.
322
+ class UUIDCommand < LoadCommand
323
+ # @return [Array<Fixnum>] the UUID
324
+ attr_reader :uuid
323
325
 
324
- # @see MachOStructure::FORMAT
325
- # @api private
326
- FORMAT = "L=2a16".freeze
326
+ # @see MachOStructure::FORMAT
327
+ # @api private
328
+ FORMAT = "L=2a16".freeze
327
329
 
328
- # @see MachOStructure::SIZEOF
329
- # @api private
330
- SIZEOF = 24
330
+ # @see MachOStructure::SIZEOF
331
+ # @api private
332
+ SIZEOF = 24
331
333
 
332
- # @api private
333
- def initialize(view, cmd, cmdsize, uuid)
334
- super(view, cmd, cmdsize)
335
- @uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
336
- end
334
+ # @api private
335
+ def initialize(view, cmd, cmdsize, uuid)
336
+ super(view, cmd, cmdsize)
337
+ @uuid = uuid.unpack("C16") # re-unpack for the actual UUID array
338
+ end
337
339
 
338
- # @return [String] a string representation of the UUID
339
- def uuid_string
340
- hexes = uuid.map { |e| "%02x" % e }
341
- segs = [
342
- hexes[0..3].join, hexes[4..5].join, hexes[6..7].join,
343
- hexes[8..9].join, hexes[10..15].join
344
- ]
340
+ # @return [String] a string representation of the UUID
341
+ def uuid_string
342
+ hexes = uuid.map { |e| "%02x" % e }
343
+ segs = [
344
+ hexes[0..3].join, hexes[4..5].join, hexes[6..7].join,
345
+ hexes[8..9].join, hexes[10..15].join
346
+ ]
345
347
 
346
- segs.join("-")
348
+ segs.join("-")
349
+ end
347
350
  end
348
- end
349
351
 
350
- # A load command indicating that part of this file is to be mapped into
351
- # the task's address space. Corresponds to LC_SEGMENT.
352
- class SegmentCommand < LoadCommand
353
- # @return [String] the name of the segment
354
- attr_reader :segname
352
+ # A load command indicating that part of this file is to be mapped into
353
+ # the task's address space. Corresponds to LC_SEGMENT.
354
+ class SegmentCommand < LoadCommand
355
+ # @return [String] the name of the segment
356
+ attr_reader :segname
355
357
 
356
- # @return [Fixnum] the memory address of the segment
357
- attr_reader :vmaddr
358
+ # @return [Fixnum] the memory address of the segment
359
+ attr_reader :vmaddr
358
360
 
359
- # @return [Fixnum] the memory size of the segment
360
- attr_reader :vmsize
361
+ # @return [Fixnum] the memory size of the segment
362
+ attr_reader :vmsize
361
363
 
362
- # @return [Fixnum] the file offset of the segment
363
- attr_reader :fileoff
364
+ # @return [Fixnum] the file offset of the segment
365
+ attr_reader :fileoff
364
366
 
365
- # @return [Fixnum] the amount to map from the file
366
- attr_reader :filesize
367
+ # @return [Fixnum] the amount to map from the file
368
+ attr_reader :filesize
367
369
 
368
- # @return [Fixnum] the maximum VM protection
369
- attr_reader :maxprot
370
+ # @return [Fixnum] the maximum VM protection
371
+ attr_reader :maxprot
370
372
 
371
- # @return [Fixnum] the initial VM protection
372
- attr_reader :initprot
373
+ # @return [Fixnum] the initial VM protection
374
+ attr_reader :initprot
373
375
 
374
- # @return [Fixnum] the number of sections in the segment
375
- attr_reader :nsects
376
+ # @return [Fixnum] the number of sections in the segment
377
+ attr_reader :nsects
376
378
 
377
- # @return [Fixnum] any flags associated with the segment
378
- attr_reader :flags
379
+ # @return [Fixnum] any flags associated with the segment
380
+ attr_reader :flags
379
381
 
380
- # @see MachOStructure::FORMAT
381
- # @api private
382
- FORMAT = "L=2a16L=4l=2L=2".freeze
383
-
384
- # @see MachOStructure::SIZEOF
385
- # @api private
386
- SIZEOF = 56
382
+ # @see MachOStructure::FORMAT
383
+ # @api private
384
+ FORMAT = "L=2a16L=4l=2L=2".freeze
387
385
 
388
- # @api private
389
- def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
390
- filesize, maxprot, initprot, nsects, flags)
391
- super(view, cmd, cmdsize)
392
- @segname = segname.delete("\x00")
393
- @vmaddr = vmaddr
394
- @vmsize = vmsize
395
- @fileoff = fileoff
396
- @filesize = filesize
397
- @maxprot = maxprot
398
- @initprot = initprot
399
- @nsects = nsects
400
- @flags = flags
401
- end
386
+ # @see MachOStructure::SIZEOF
387
+ # @api private
388
+ SIZEOF = 56
402
389
 
403
- # All sections referenced within this segment.
404
- # @return [Array<MachO::Section>] if the Mach-O is 32-bit
405
- # @return [Array<MachO::Section64>] if the Mach-O is 64-bit
406
- def sections
407
- klass = case self
408
- when MachO::SegmentCommand64
409
- MachO::Section64
410
- when MachO::SegmentCommand
411
- MachO::Section
390
+ # @api private
391
+ def initialize(view, cmd, cmdsize, segname, vmaddr, vmsize, fileoff,
392
+ filesize, maxprot, initprot, nsects, flags)
393
+ super(view, cmd, cmdsize)
394
+ @segname = segname.delete("\x00")
395
+ @vmaddr = vmaddr
396
+ @vmsize = vmsize
397
+ @fileoff = fileoff
398
+ @filesize = filesize
399
+ @maxprot = maxprot
400
+ @initprot = initprot
401
+ @nsects = nsects
402
+ @flags = flags
412
403
  end
413
404
 
414
- bins = view.raw_data[view.offset + self.class.bytesize, nsects * klass.bytesize]
415
- bins.unpack("a#{klass.bytesize}" * nsects).map do |bin|
416
- klass.new_from_bin(view.endianness, bin)
405
+ # All sections referenced within this segment.
406
+ # @return [Array<MachO::Sections::Section>] if the Mach-O is 32-bit
407
+ # @return [Array<MachO::Sections::Section64>] if the Mach-O is 64-bit
408
+ def sections
409
+ klass = case self
410
+ when SegmentCommand64
411
+ MachO::Sections::Section64
412
+ when SegmentCommand
413
+ MachO::Sections::Section
414
+ end
415
+
416
+ bins = view.raw_data[view.offset + self.class.bytesize, nsects * klass.bytesize]
417
+ bins.unpack("a#{klass.bytesize}" * nsects).map do |bin|
418
+ klass.new_from_bin(view.endianness, bin)
419
+ end
417
420
  end
418
- end
419
421
 
420
- # @example
421
- # puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
422
- # @param flag [Symbol] a segment flag symbol
423
- # @return [Boolean] true if `flag` is present in the segment's flag field
424
- def flag?(flag)
425
- flag = SEGMENT_FLAGS[flag]
426
- return false if flag.nil?
427
- flags & flag == flag
422
+ # @example
423
+ # puts "this segment relocated in/to it" if sect.flag?(:SG_NORELOC)
424
+ # @param flag [Symbol] a segment flag symbol
425
+ # @return [Boolean] true if `flag` is present in the segment's flag field
426
+ def flag?(flag)
427
+ flag = SEGMENT_FLAGS[flag]
428
+ return false if flag.nil?
429
+ flags & flag == flag
430
+ end
428
431
  end
429
- end
430
432
 
431
- # A load command indicating that part of this file is to be mapped into
432
- # the task's address space. Corresponds to LC_SEGMENT_64.
433
- class SegmentCommand64 < SegmentCommand
434
- # @see MachOStructure::FORMAT
435
- # @api private
436
- FORMAT = "L=2a16Q=4l=2L=2".freeze
433
+ # A load command indicating that part of this file is to be mapped into
434
+ # the task's address space. Corresponds to LC_SEGMENT_64.
435
+ class SegmentCommand64 < SegmentCommand
436
+ # @see MachOStructure::FORMAT
437
+ # @api private
438
+ FORMAT = "L=2a16Q=4l=2L=2".freeze
437
439
 
438
- # @see MachOStructure::SIZEOF
439
- # @api private
440
- SIZEOF = 72
441
- end
440
+ # @see MachOStructure::SIZEOF
441
+ # @api private
442
+ SIZEOF = 72
443
+ end
442
444
 
443
- # A load command representing some aspect of shared libraries, depending
444
- # on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
445
- # and LC_REEXPORT_DYLIB.
446
- class DylibCommand < LoadCommand
447
- # @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
448
- attr_reader :name
445
+ # A load command representing some aspect of shared libraries, depending
446
+ # on filetype. Corresponds to LC_ID_DYLIB, LC_LOAD_DYLIB, LC_LOAD_WEAK_DYLIB,
447
+ # and LC_REEXPORT_DYLIB.
448
+ class DylibCommand < LoadCommand
449
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the library's path name as an LCStr
450
+ attr_reader :name
449
451
 
450
- # @return [Fixnum] the library's build time stamp
451
- attr_reader :timestamp
452
+ # @return [Fixnum] the library's build time stamp
453
+ attr_reader :timestamp
452
454
 
453
- # @return [Fixnum] the library's current version number
454
- attr_reader :current_version
455
+ # @return [Fixnum] the library's current version number
456
+ attr_reader :current_version
455
457
 
456
- # @return [Fixnum] the library's compatibility version number
457
- attr_reader :compatibility_version
458
+ # @return [Fixnum] the library's compatibility version number
459
+ attr_reader :compatibility_version
458
460
 
459
- # @see MachOStructure::FORMAT
460
- # @api private
461
- FORMAT = "L=6".freeze
461
+ # @see MachOStructure::FORMAT
462
+ # @api private
463
+ FORMAT = "L=6".freeze
462
464
 
463
- # @see MachOStructure::SIZEOF
464
- # @api private
465
- SIZEOF = 24
465
+ # @see MachOStructure::SIZEOF
466
+ # @api private
467
+ SIZEOF = 24
466
468
 
467
- # @api private
468
- def initialize(view, cmd, cmdsize, name, timestamp, current_version, compatibility_version)
469
- super(view, cmd, cmdsize)
470
- @name = LCStr.new(self, name)
471
- @timestamp = timestamp
472
- @current_version = current_version
473
- @compatibility_version = compatibility_version
474
- end
469
+ # @api private
470
+ def initialize(view, cmd, cmdsize, name, timestamp, current_version, compatibility_version)
471
+ super(view, cmd, cmdsize)
472
+ @name = LCStr.new(self, name)
473
+ @timestamp = timestamp
474
+ @current_version = current_version
475
+ @compatibility_version = compatibility_version
476
+ end
475
477
 
476
- # @param context [MachO::LoadCcommand::SerializationContext] the context
477
- # @return [String] the serialized fields of the load command
478
- # @api private
479
- def serialize(context)
480
- format = Utils.specialize_format(FORMAT, context.endianness)
481
- string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
482
- cmdsize = SIZEOF + string_payload.bytesize
483
- [cmd, cmdsize, string_offsets[:name], timestamp, current_version,
484
- compatibility_version].pack(format) + string_payload
478
+ # @param context [MachO::LoadCommands::LoadCommand::SerializationContext] the context
479
+ # @return [String] the serialized fields of the load command
480
+ # @api private
481
+ def serialize(context)
482
+ format = Utils.specialize_format(FORMAT, context.endianness)
483
+ string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
484
+ cmdsize = SIZEOF + string_payload.bytesize
485
+ [cmd, cmdsize, string_offsets[:name], timestamp, current_version,
486
+ compatibility_version].pack(format) + string_payload
487
+ end
485
488
  end
486
- end
487
489
 
488
- # A load command representing some aspect of the dynamic linker, depending
489
- # on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
490
- # LC_DYLD_ENVIRONMENT.
491
- class DylinkerCommand < LoadCommand
492
- # @return [MachO::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
493
- attr_reader :name
490
+ # A load command representing some aspect of the dynamic linker, depending
491
+ # on filetype. Corresponds to LC_ID_DYLINKER, LC_LOAD_DYLINKER, and
492
+ # LC_DYLD_ENVIRONMENT.
493
+ class DylinkerCommand < LoadCommand
494
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the dynamic linker's path name as an LCStr
495
+ attr_reader :name
494
496
 
495
- # @see MachOStructure::FORMAT
496
- # @api private
497
- FORMAT = "L=3".freeze
497
+ # @see MachOStructure::FORMAT
498
+ # @api private
499
+ FORMAT = "L=3".freeze
498
500
 
499
- # @see MachOStructure::SIZEOF
500
- # @api private
501
- SIZEOF = 12
501
+ # @see MachOStructure::SIZEOF
502
+ # @api private
503
+ SIZEOF = 12
502
504
 
503
- # @api private
504
- def initialize(view, cmd, cmdsize, name)
505
- super(view, cmd, cmdsize)
506
- @name = LCStr.new(self, name)
507
- end
505
+ # @api private
506
+ def initialize(view, cmd, cmdsize, name)
507
+ super(view, cmd, cmdsize)
508
+ @name = LCStr.new(self, name)
509
+ end
508
510
 
509
- # @param context [MachO::LoadCcommand::SerializationContext] the context
510
- # @return [String] the serialized fields of the load command
511
- # @api private
512
- def serialize(context)
513
- format = Utils.specialize_format(FORMAT, context.endianness)
514
- string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
515
- cmdsize = SIZEOF + string_payload.bytesize
516
- [cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
511
+ # @param context [MachO::LoadCommands::LoadCommand::SerializationContext] the context
512
+ # @return [String] the serialized fields of the load command
513
+ # @api private
514
+ def serialize(context)
515
+ format = Utils.specialize_format(FORMAT, context.endianness)
516
+ string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :name => name.to_s)
517
+ cmdsize = SIZEOF + string_payload.bytesize
518
+ [cmd, cmdsize, string_offsets[:name]].pack(format) + string_payload
519
+ end
517
520
  end
518
- end
519
521
 
520
- # A load command used to indicate dynamic libraries used in prebinding.
521
- # Corresponds to LC_PREBOUND_DYLIB.
522
- class PreboundDylibCommand < LoadCommand
523
- # @return [MachO::LoadCommand::LCStr] the library's path name as an LCStr
524
- attr_reader :name
522
+ # A load command used to indicate dynamic libraries used in prebinding.
523
+ # Corresponds to LC_PREBOUND_DYLIB.
524
+ class PreboundDylibCommand < LoadCommand
525
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the library's path name as an LCStr
526
+ attr_reader :name
525
527
 
526
- # @return [Fixnum] the number of modules in the library
527
- attr_reader :nmodules
528
+ # @return [Fixnum] the number of modules in the library
529
+ attr_reader :nmodules
528
530
 
529
- # @return [Fixnum] a bit vector of linked modules
530
- attr_reader :linked_modules
531
+ # @return [Fixnum] a bit vector of linked modules
532
+ attr_reader :linked_modules
531
533
 
532
- # @see MachOStructure::FORMAT
533
- # @api private
534
- FORMAT = "L=5".freeze
534
+ # @see MachOStructure::FORMAT
535
+ # @api private
536
+ FORMAT = "L=5".freeze
535
537
 
536
- # @see MachOStructure::SIZEOF
537
- # @api private
538
- SIZEOF = 20
538
+ # @see MachOStructure::SIZEOF
539
+ # @api private
540
+ SIZEOF = 20
539
541
 
540
- # @api private
541
- def initialize(view, cmd, cmdsize, name, nmodules, linked_modules)
542
- super(view, cmd, cmdsize)
543
- @name = LCStr.new(self, name)
544
- @nmodules = nmodules
545
- @linked_modules = linked_modules
542
+ # @api private
543
+ def initialize(view, cmd, cmdsize, name, nmodules, linked_modules)
544
+ super(view, cmd, cmdsize)
545
+ @name = LCStr.new(self, name)
546
+ @nmodules = nmodules
547
+ @linked_modules = linked_modules
548
+ end
546
549
  end
547
- end
548
550
 
549
- # A load command used to represent threads.
550
- # @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize)
551
- class ThreadCommand < LoadCommand
552
- # @see MachOStructure::FORMAT
553
- # @api private
554
- FORMAT = "L=2".freeze
551
+ # A load command used to represent threads.
552
+ # @note cctools-870 has all fields of thread_command commented out except common ones (cmd, cmdsize)
553
+ class ThreadCommand < LoadCommand
554
+ # @see MachOStructure::FORMAT
555
+ # @api private
556
+ FORMAT = "L=2".freeze
555
557
 
556
- # @see MachOStructure::SIZEOF
557
- # @api private
558
- SIZEOF = 8
559
- end
558
+ # @see MachOStructure::SIZEOF
559
+ # @api private
560
+ SIZEOF = 8
561
+ end
560
562
 
561
- # A load command containing the address of the dynamic shared library
562
- # initialization routine and an index into the module table for the module
563
- # that defines the routine. Corresponds to LC_ROUTINES.
564
- class RoutinesCommand < LoadCommand
565
- # @return [Fixnum] the address of the initialization routine
566
- attr_reader :init_address
563
+ # A load command containing the address of the dynamic shared library
564
+ # initialization routine and an index into the module table for the module
565
+ # that defines the routine. Corresponds to LC_ROUTINES.
566
+ class RoutinesCommand < LoadCommand
567
+ # @return [Fixnum] the address of the initialization routine
568
+ attr_reader :init_address
567
569
 
568
- # @return [Fixnum] the index into the module table that the init routine is defined in
569
- attr_reader :init_module
570
+ # @return [Fixnum] the index into the module table that the init routine is defined in
571
+ attr_reader :init_module
570
572
 
571
- # @return [void]
572
- attr_reader :reserved1
573
+ # @return [void]
574
+ attr_reader :reserved1
573
575
 
574
- # @return [void]
575
- attr_reader :reserved2
576
+ # @return [void]
577
+ attr_reader :reserved2
576
578
 
577
- # @return [void]
578
- attr_reader :reserved3
579
+ # @return [void]
580
+ attr_reader :reserved3
579
581
 
580
- # @return [void]
581
- attr_reader :reserved4
582
+ # @return [void]
583
+ attr_reader :reserved4
582
584
 
583
- # @return [void]
584
- attr_reader :reserved5
585
+ # @return [void]
586
+ attr_reader :reserved5
585
587
 
586
- # @return [void]
587
- attr_reader :reserved6
588
+ # @return [void]
589
+ attr_reader :reserved6
588
590
 
589
- # @see MachOStructure::FORMAT
590
- # @api private
591
- FORMAT = "L=10".freeze
591
+ # @see MachOStructure::FORMAT
592
+ # @api private
593
+ FORMAT = "L=10".freeze
592
594
 
593
- # @see MachOStructure::SIZEOF
594
- # @api private
595
- SIZEOF = 40
595
+ # @see MachOStructure::SIZEOF
596
+ # @api private
597
+ SIZEOF = 40
596
598
 
597
- # @api private
598
- def initialize(view, cmd, cmdsize, init_address, init_module, reserved1,
599
- reserved2, reserved3, reserved4, reserved5, reserved6)
600
- super(view, cmd, cmdsize)
601
- @init_address = init_address
602
- @init_module = init_module
603
- @reserved1 = reserved1
604
- @reserved2 = reserved2
605
- @reserved3 = reserved3
606
- @reserved4 = reserved4
607
- @reserved5 = reserved5
608
- @reserved6 = reserved6
599
+ # @api private
600
+ def initialize(view, cmd, cmdsize, init_address, init_module, reserved1,
601
+ reserved2, reserved3, reserved4, reserved5, reserved6)
602
+ super(view, cmd, cmdsize)
603
+ @init_address = init_address
604
+ @init_module = init_module
605
+ @reserved1 = reserved1
606
+ @reserved2 = reserved2
607
+ @reserved3 = reserved3
608
+ @reserved4 = reserved4
609
+ @reserved5 = reserved5
610
+ @reserved6 = reserved6
611
+ end
609
612
  end
610
- end
611
613
 
612
- # A load command containing the address of the dynamic shared library
613
- # initialization routine and an index into the module table for the module
614
- # that defines the routine. Corresponds to LC_ROUTINES_64.
615
- class RoutinesCommand64 < RoutinesCommand
616
- # @see MachOStructure::FORMAT
617
- # @api private
618
- FORMAT = "L=2Q=8".freeze
614
+ # A load command containing the address of the dynamic shared library
615
+ # initialization routine and an index into the module table for the module
616
+ # that defines the routine. Corresponds to LC_ROUTINES_64.
617
+ class RoutinesCommand64 < RoutinesCommand
618
+ # @see MachOStructure::FORMAT
619
+ # @api private
620
+ FORMAT = "L=2Q=8".freeze
619
621
 
620
- # @see MachOStructure::SIZEOF
621
- # @api private
622
- SIZEOF = 72
623
- end
622
+ # @see MachOStructure::SIZEOF
623
+ # @api private
624
+ SIZEOF = 72
625
+ end
624
626
 
625
- # A load command signifying membership of a subframework containing the name
626
- # of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
627
- class SubFrameworkCommand < LoadCommand
628
- # @return [MachO::LoadCommand::LCStr] the umbrella framework name as an LCStr
629
- attr_reader :umbrella
627
+ # A load command signifying membership of a subframework containing the name
628
+ # of an umbrella framework. Corresponds to LC_SUB_FRAMEWORK.
629
+ class SubFrameworkCommand < LoadCommand
630
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the umbrella framework name as an LCStr
631
+ attr_reader :umbrella
630
632
 
631
- # @see MachOStructure::FORMAT
632
- # @api private
633
- FORMAT = "L=3".freeze
633
+ # @see MachOStructure::FORMAT
634
+ # @api private
635
+ FORMAT = "L=3".freeze
634
636
 
635
- # @see MachOStructure::SIZEOF
636
- # @api private
637
- SIZEOF = 12
637
+ # @see MachOStructure::SIZEOF
638
+ # @api private
639
+ SIZEOF = 12
638
640
 
639
- # @api private
640
- def initialize(view, cmd, cmdsize, umbrella)
641
- super(view, cmd, cmdsize)
642
- @umbrella = LCStr.new(self, umbrella)
641
+ # @api private
642
+ def initialize(view, cmd, cmdsize, umbrella)
643
+ super(view, cmd, cmdsize)
644
+ @umbrella = LCStr.new(self, umbrella)
645
+ end
643
646
  end
644
- end
645
647
 
646
- # A load command signifying membership of a subumbrella containing the name
647
- # of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
648
- class SubUmbrellaCommand < LoadCommand
649
- # @return [MachO::LoadCommand::LCStr] the subumbrella framework name as an LCStr
650
- attr_reader :sub_umbrella
648
+ # A load command signifying membership of a subumbrella containing the name
649
+ # of an umbrella framework. Corresponds to LC_SUB_UMBRELLA.
650
+ class SubUmbrellaCommand < LoadCommand
651
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the subumbrella framework name as an LCStr
652
+ attr_reader :sub_umbrella
651
653
 
652
- # @see MachOStructure::FORMAT
653
- # @api private
654
- FORMAT = "L=3".freeze
654
+ # @see MachOStructure::FORMAT
655
+ # @api private
656
+ FORMAT = "L=3".freeze
655
657
 
656
- # @see MachOStructure::SIZEOF
657
- # @api private
658
- SIZEOF = 12
658
+ # @see MachOStructure::SIZEOF
659
+ # @api private
660
+ SIZEOF = 12
659
661
 
660
- # @api private
661
- def initialize(view, cmd, cmdsize, sub_umbrella)
662
- super(view, cmd, cmdsize)
663
- @sub_umbrella = LCStr.new(self, sub_umbrella)
662
+ # @api private
663
+ def initialize(view, cmd, cmdsize, sub_umbrella)
664
+ super(view, cmd, cmdsize)
665
+ @sub_umbrella = LCStr.new(self, sub_umbrella)
666
+ end
664
667
  end
665
- end
666
668
 
667
- # A load command signifying a sublibrary of a shared library. Corresponds
668
- # to LC_SUB_LIBRARY.
669
- class SubLibraryCommand < LoadCommand
670
- # @return [MachO::LoadCommand::LCStr] the sublibrary name as an LCStr
671
- attr_reader :sub_library
669
+ # A load command signifying a sublibrary of a shared library. Corresponds
670
+ # to LC_SUB_LIBRARY.
671
+ class SubLibraryCommand < LoadCommand
672
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the sublibrary name as an LCStr
673
+ attr_reader :sub_library
672
674
 
673
- # @see MachOStructure::FORMAT
674
- # @api private
675
- FORMAT = "L=3".freeze
675
+ # @see MachOStructure::FORMAT
676
+ # @api private
677
+ FORMAT = "L=3".freeze
676
678
 
677
- # @see MachOStructure::SIZEOF
678
- # @api private
679
- SIZEOF = 12
679
+ # @see MachOStructure::SIZEOF
680
+ # @api private
681
+ SIZEOF = 12
680
682
 
681
- # @api private
682
- def initialize(view, cmd, cmdsize, sub_library)
683
- super(view, cmd, cmdsize)
684
- @sub_library = LCStr.new(self, sub_library)
683
+ # @api private
684
+ def initialize(view, cmd, cmdsize, sub_library)
685
+ super(view, cmd, cmdsize)
686
+ @sub_library = LCStr.new(self, sub_library)
687
+ end
685
688
  end
686
- end
687
689
 
688
- # A load command signifying a shared library that is a subframework of
689
- # an umbrella framework. Corresponds to LC_SUB_CLIENT.
690
- class SubClientCommand < LoadCommand
691
- # @return [MachO::LoadCommand::LCStr] the subclient name as an LCStr
692
- attr_reader :sub_client
690
+ # A load command signifying a shared library that is a subframework of
691
+ # an umbrella framework. Corresponds to LC_SUB_CLIENT.
692
+ class SubClientCommand < LoadCommand
693
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the subclient name as an LCStr
694
+ attr_reader :sub_client
693
695
 
694
- # @see MachOStructure::FORMAT
695
- # @api private
696
- FORMAT = "L=3".freeze
696
+ # @see MachOStructure::FORMAT
697
+ # @api private
698
+ FORMAT = "L=3".freeze
697
699
 
698
- # @see MachOStructure::SIZEOF
699
- # @api private
700
- SIZEOF = 12
700
+ # @see MachOStructure::SIZEOF
701
+ # @api private
702
+ SIZEOF = 12
701
703
 
702
- # @api private
703
- def initialize(view, cmd, cmdsize, sub_client)
704
- super(view, cmd, cmdsize)
705
- @sub_client = LCStr.new(self, sub_client)
704
+ # @api private
705
+ def initialize(view, cmd, cmdsize, sub_client)
706
+ super(view, cmd, cmdsize)
707
+ @sub_client = LCStr.new(self, sub_client)
708
+ end
706
709
  end
707
- end
708
710
 
709
- # A load command containing the offsets and sizes of the link-edit 4.3BSD
710
- # "stab" style symbol table information. Corresponds to LC_SYMTAB.
711
- class SymtabCommand < LoadCommand
712
- # @return [Fixnum] the symbol table's offset
713
- attr_reader :symoff
711
+ # A load command containing the offsets and sizes of the link-edit 4.3BSD
712
+ # "stab" style symbol table information. Corresponds to LC_SYMTAB.
713
+ class SymtabCommand < LoadCommand
714
+ # @return [Fixnum] the symbol table's offset
715
+ attr_reader :symoff
714
716
 
715
- # @return [Fixnum] the number of symbol table entries
716
- attr_reader :nsyms
717
+ # @return [Fixnum] the number of symbol table entries
718
+ attr_reader :nsyms
717
719
 
718
- # @return the string table's offset
719
- attr_reader :stroff
720
+ # @return the string table's offset
721
+ attr_reader :stroff
720
722
 
721
- # @return the string table size in bytes
722
- attr_reader :strsize
723
+ # @return the string table size in bytes
724
+ attr_reader :strsize
723
725
 
724
- # @see MachOStructure::FORMAT
725
- # @api private
726
- FORMAT = "L=6".freeze
726
+ # @see MachOStructure::FORMAT
727
+ # @api private
728
+ FORMAT = "L=6".freeze
727
729
 
728
- # @see MachOStructure::SIZEOF
729
- # @api private
730
- SIZEOF = 24
730
+ # @see MachOStructure::SIZEOF
731
+ # @api private
732
+ SIZEOF = 24
731
733
 
732
- # @api private
733
- def initialize(view, cmd, cmdsize, symoff, nsyms, stroff, strsize)
734
- super(view, cmd, cmdsize)
735
- @symoff = symoff
736
- @nsyms = nsyms
737
- @stroff = stroff
738
- @strsize = strsize
734
+ # @api private
735
+ def initialize(view, cmd, cmdsize, symoff, nsyms, stroff, strsize)
736
+ super(view, cmd, cmdsize)
737
+ @symoff = symoff
738
+ @nsyms = nsyms
739
+ @stroff = stroff
740
+ @strsize = strsize
741
+ end
739
742
  end
740
- end
741
743
 
742
- # A load command containing symbolic information needed to support data
743
- # structures used by the dynamic link editor. Corresponds to LC_DYSYMTAB.
744
- class DysymtabCommand < LoadCommand
745
- # @return [Fixnum] the index to local symbols
746
- attr_reader :ilocalsym
744
+ # A load command containing symbolic information needed to support data
745
+ # structures used by the dynamic link editor. Corresponds to LC_DYSYMTAB.
746
+ class DysymtabCommand < LoadCommand
747
+ # @return [Fixnum] the index to local symbols
748
+ attr_reader :ilocalsym
747
749
 
748
- # @return [Fixnum] the number of local symbols
749
- attr_reader :nlocalsym
750
+ # @return [Fixnum] the number of local symbols
751
+ attr_reader :nlocalsym
750
752
 
751
- # @return [Fixnum] the index to externally defined symbols
752
- attr_reader :iextdefsym
753
+ # @return [Fixnum] the index to externally defined symbols
754
+ attr_reader :iextdefsym
753
755
 
754
- # @return [Fixnum] the number of externally defined symbols
755
- attr_reader :nextdefsym
756
+ # @return [Fixnum] the number of externally defined symbols
757
+ attr_reader :nextdefsym
756
758
 
757
- # @return [Fixnum] the index to undefined symbols
758
- attr_reader :iundefsym
759
+ # @return [Fixnum] the index to undefined symbols
760
+ attr_reader :iundefsym
759
761
 
760
- # @return [Fixnum] the number of undefined symbols
761
- attr_reader :nundefsym
762
+ # @return [Fixnum] the number of undefined symbols
763
+ attr_reader :nundefsym
762
764
 
763
- # @return [Fixnum] the file offset to the table of contents
764
- attr_reader :tocoff
765
+ # @return [Fixnum] the file offset to the table of contents
766
+ attr_reader :tocoff
765
767
 
766
- # @return [Fixnum] the number of entries in the table of contents
767
- attr_reader :ntoc
768
+ # @return [Fixnum] the number of entries in the table of contents
769
+ attr_reader :ntoc
768
770
 
769
- # @return [Fixnum] the file offset to the module table
770
- attr_reader :modtaboff
771
+ # @return [Fixnum] the file offset to the module table
772
+ attr_reader :modtaboff
771
773
 
772
- # @return [Fixnum] the number of entries in the module table
773
- attr_reader :nmodtab
774
+ # @return [Fixnum] the number of entries in the module table
775
+ attr_reader :nmodtab
774
776
 
775
- # @return [Fixnum] the file offset to the referenced symbol table
776
- attr_reader :extrefsymoff
777
+ # @return [Fixnum] the file offset to the referenced symbol table
778
+ attr_reader :extrefsymoff
777
779
 
778
- # @return [Fixnum] the number of entries in the referenced symbol table
779
- attr_reader :nextrefsyms
780
+ # @return [Fixnum] the number of entries in the referenced symbol table
781
+ attr_reader :nextrefsyms
780
782
 
781
- # @return [Fixnum] the file offset to the indirect symbol table
782
- attr_reader :indirectsymoff
783
+ # @return [Fixnum] the file offset to the indirect symbol table
784
+ attr_reader :indirectsymoff
783
785
 
784
- # @return [Fixnum] the number of entries in the indirect symbol table
785
- attr_reader :nindirectsyms
786
+ # @return [Fixnum] the number of entries in the indirect symbol table
787
+ attr_reader :nindirectsyms
786
788
 
787
- # @return [Fixnum] the file offset to the external relocation entries
788
- attr_reader :extreloff
789
+ # @return [Fixnum] the file offset to the external relocation entries
790
+ attr_reader :extreloff
789
791
 
790
- # @return [Fixnum] the number of external relocation entries
791
- attr_reader :nextrel
792
+ # @return [Fixnum] the number of external relocation entries
793
+ attr_reader :nextrel
792
794
 
793
- # @return [Fixnum] the file offset to the local relocation entries
794
- attr_reader :locreloff
795
+ # @return [Fixnum] the file offset to the local relocation entries
796
+ attr_reader :locreloff
795
797
 
796
- # @return [Fixnum] the number of local relocation entries
797
- attr_reader :nlocrel
798
+ # @return [Fixnum] the number of local relocation entries
799
+ attr_reader :nlocrel
798
800
 
799
- # @see MachOStructure::FORMAT
800
- # @api private
801
- FORMAT = "L=20".freeze
801
+ # @see MachOStructure::FORMAT
802
+ # @api private
803
+ FORMAT = "L=20".freeze
802
804
 
803
- # @see MachOStructure::SIZEOF
804
- # @api private
805
- SIZEOF = 80
805
+ # @see MachOStructure::SIZEOF
806
+ # @api private
807
+ SIZEOF = 80
806
808
 
807
- # ugh
808
- # @api private
809
- def initialize(view, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
810
- nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
811
- nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
812
- nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
813
- super(view, cmd, cmdsize)
814
- @ilocalsym = ilocalsym
815
- @nlocalsym = nlocalsym
816
- @iextdefsym = iextdefsym
817
- @nextdefsym = nextdefsym
818
- @iundefsym = iundefsym
819
- @nundefsym = nundefsym
820
- @tocoff = tocoff
821
- @ntoc = ntoc
822
- @modtaboff = modtaboff
823
- @nmodtab = nmodtab
824
- @extrefsymoff = extrefsymoff
825
- @nextrefsyms = nextrefsyms
826
- @indirectsymoff = indirectsymoff
827
- @nindirectsyms = nindirectsyms
828
- @extreloff = extreloff
829
- @nextrel = nextrel
830
- @locreloff = locreloff
831
- @nlocrel = nlocrel
809
+ # ugh
810
+ # @api private
811
+ def initialize(view, cmd, cmdsize, ilocalsym, nlocalsym, iextdefsym,
812
+ nextdefsym, iundefsym, nundefsym, tocoff, ntoc, modtaboff,
813
+ nmodtab, extrefsymoff, nextrefsyms, indirectsymoff,
814
+ nindirectsyms, extreloff, nextrel, locreloff, nlocrel)
815
+ super(view, cmd, cmdsize)
816
+ @ilocalsym = ilocalsym
817
+ @nlocalsym = nlocalsym
818
+ @iextdefsym = iextdefsym
819
+ @nextdefsym = nextdefsym
820
+ @iundefsym = iundefsym
821
+ @nundefsym = nundefsym
822
+ @tocoff = tocoff
823
+ @ntoc = ntoc
824
+ @modtaboff = modtaboff
825
+ @nmodtab = nmodtab
826
+ @extrefsymoff = extrefsymoff
827
+ @nextrefsyms = nextrefsyms
828
+ @indirectsymoff = indirectsymoff
829
+ @nindirectsyms = nindirectsyms
830
+ @extreloff = extreloff
831
+ @nextrel = nextrel
832
+ @locreloff = locreloff
833
+ @nlocrel = nlocrel
834
+ end
832
835
  end
833
- end
834
836
 
835
- # A load command containing the offset and number of hints in the two-level
836
- # namespace lookup hints table. Corresponds to LC_TWOLEVEL_HINTS.
837
- class TwolevelHintsCommand < LoadCommand
838
- # @return [Fixnum] the offset to the hint table
839
- attr_reader :htoffset
837
+ # A load command containing the offset and number of hints in the two-level
838
+ # namespace lookup hints table. Corresponds to LC_TWOLEVEL_HINTS.
839
+ class TwolevelHintsCommand < LoadCommand
840
+ # @return [Fixnum] the offset to the hint table
841
+ attr_reader :htoffset
840
842
 
841
- # @return [Fixnum] the number of hints in the hint table
842
- attr_reader :nhints
843
+ # @return [Fixnum] the number of hints in the hint table
844
+ attr_reader :nhints
843
845
 
844
- # @return [MachO::TwolevelHintsCommand::TwolevelHintTable] the hint table
845
- attr_reader :table
846
+ # @return [MachO::LoadCommands::TwolevelHintsCommand::TwolevelHintTable] the hint table
847
+ attr_reader :table
846
848
 
847
- # @see MachOStructure::FORMAT
848
- # @api private
849
- FORMAT = "L=4".freeze
849
+ # @see MachOStructure::FORMAT
850
+ # @api private
851
+ FORMAT = "L=4".freeze
850
852
 
851
- # @see MachOStructure::SIZEOF
852
- # @api private
853
- SIZEOF = 16
853
+ # @see MachOStructure::SIZEOF
854
+ # @api private
855
+ SIZEOF = 16
854
856
 
855
- # @api private
856
- def initialize(view, cmd, cmdsize, htoffset, nhints)
857
- super(view, cmd, cmdsize)
858
- @htoffset = htoffset
859
- @nhints = nhints
860
- @table = TwolevelHintsTable.new(view, htoffset, nhints)
861
- end
857
+ # @api private
858
+ def initialize(view, cmd, cmdsize, htoffset, nhints)
859
+ super(view, cmd, cmdsize)
860
+ @htoffset = htoffset
861
+ @nhints = nhints
862
+ @table = TwolevelHintsTable.new(view, htoffset, nhints)
863
+ end
862
864
 
863
- # A representation of the two-level namespace lookup hints table exposed
864
- # by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
865
- class TwolevelHintsTable
866
- # @return [Array<MachO::TwoLevelHintsTable::TwoLevelHint>] all hints in the table
867
- attr_reader :hints
865
+ # A representation of the two-level namespace lookup hints table exposed
866
+ # by a {TwolevelHintsCommand} (`LC_TWOLEVEL_HINTS`).
867
+ class TwolevelHintsTable
868
+ # @return [Array<MachO::LoadCommands::TwoLevelHintsCommand::TwoLevelHintsTable::TwoLevelHint>] all hints in the table
869
+ attr_reader :hints
868
870
 
869
- # @param view [MachO::MachOView] the view into the current Mach-O
870
- # @param htoffset [Fixnum] the offset of the hints table
871
- # @param nhints [Fixnum] the number of two-level hints in the table
872
- # @api private
873
- def initialize(view, htoffset, nhints)
874
- format = Utils.specialize_format("L=#{nhints}", view.endianness)
875
- raw_table = view.raw_data[htoffset, nhints * 4]
876
- blobs = raw_table.unpack(format)
871
+ # @param view [MachO::MachOView] the view into the current Mach-O
872
+ # @param htoffset [Fixnum] the offset of the hints table
873
+ # @param nhints [Fixnum] the number of two-level hints in the table
874
+ # @api private
875
+ def initialize(view, htoffset, nhints)
876
+ format = Utils.specialize_format("L=#{nhints}", view.endianness)
877
+ raw_table = view.raw_data[htoffset, nhints * 4]
878
+ blobs = raw_table.unpack(format)
877
879
 
878
- @hints = blobs.map { |b| TwolevelHint.new(b) }
879
- end
880
+ @hints = blobs.map { |b| TwolevelHint.new(b) }
881
+ end
880
882
 
881
- # An individual two-level namespace lookup hint.
882
- class TwolevelHint
883
- # @return [Fixnum] the index into the sub-images
884
- attr_reader :isub_image
883
+ # An individual two-level namespace lookup hint.
884
+ class TwolevelHint
885
+ # @return [Fixnum] the index into the sub-images
886
+ attr_reader :isub_image
885
887
 
886
- # @return [Fixnum] the index into the table of contents
887
- attr_reader :itoc
888
+ # @return [Fixnum] the index into the table of contents
889
+ attr_reader :itoc
888
890
 
889
- # @param blob [Fixnum] the 32-bit number containing the lookup hint
890
- # @api private
891
- def initialize(blob)
892
- @isub_image = blob >> 24
893
- @itoc = blob & 0x00FFFFFF
891
+ # @param blob [Fixnum] the 32-bit number containing the lookup hint
892
+ # @api private
893
+ def initialize(blob)
894
+ @isub_image = blob >> 24
895
+ @itoc = blob & 0x00FFFFFF
896
+ end
894
897
  end
895
898
  end
896
899
  end
897
- end
898
900
 
899
- # A load command containing the value of the original checksum for prebound
900
- # files, or zero. Corresponds to LC_PREBIND_CKSUM.
901
- class PrebindCksumCommand < LoadCommand
902
- # @return [Fixnum] the checksum or 0
903
- attr_reader :cksum
901
+ # A load command containing the value of the original checksum for prebound
902
+ # files, or zero. Corresponds to LC_PREBIND_CKSUM.
903
+ class PrebindCksumCommand < LoadCommand
904
+ # @return [Fixnum] the checksum or 0
905
+ attr_reader :cksum
904
906
 
905
- # @see MachOStructure::FORMAT
906
- # @api private
907
- FORMAT = "L=3".freeze
907
+ # @see MachOStructure::FORMAT
908
+ # @api private
909
+ FORMAT = "L=3".freeze
908
910
 
909
- # @see MachOStructure::SIZEOF
910
- # @api private
911
- SIZEOF = 12
911
+ # @see MachOStructure::SIZEOF
912
+ # @api private
913
+ SIZEOF = 12
912
914
 
913
- # @api private
914
- def initialize(view, cmd, cmdsize, cksum)
915
- super(view, cmd, cmdsize)
916
- @cksum = cksum
915
+ # @api private
916
+ def initialize(view, cmd, cmdsize, cksum)
917
+ super(view, cmd, cmdsize)
918
+ @cksum = cksum
919
+ end
917
920
  end
918
- end
919
921
 
920
- # A load command representing an rpath, which specifies a path that should
921
- # be added to the current run path used to find @rpath prefixed dylibs.
922
- # Corresponds to LC_RPATH.
923
- class RpathCommand < LoadCommand
924
- # @return [MachO::LoadCommand::LCStr] the path to add to the run path as an LCStr
925
- attr_reader :path
922
+ # A load command representing an rpath, which specifies a path that should
923
+ # be added to the current run path used to find @rpath prefixed dylibs.
924
+ # Corresponds to LC_RPATH.
925
+ class RpathCommand < LoadCommand
926
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the path to add to the run path as an LCStr
927
+ attr_reader :path
926
928
 
927
- # @see MachOStructure::FORMAT
928
- # @api private
929
- FORMAT = "L=3".freeze
929
+ # @see MachOStructure::FORMAT
930
+ # @api private
931
+ FORMAT = "L=3".freeze
930
932
 
931
- # @see MachOStructure::SIZEOF
932
- # @api private
933
- SIZEOF = 12
933
+ # @see MachOStructure::SIZEOF
934
+ # @api private
935
+ SIZEOF = 12
934
936
 
935
- # @api private
936
- def initialize(view, cmd, cmdsize, path)
937
- super(view, cmd, cmdsize)
938
- @path = LCStr.new(self, path)
939
- end
937
+ # @api private
938
+ def initialize(view, cmd, cmdsize, path)
939
+ super(view, cmd, cmdsize)
940
+ @path = LCStr.new(self, path)
941
+ end
940
942
 
941
- # @param context [MachO::LoadCcommand::SerializationContext] the context
942
- # @return [String] the serialized fields of the load command
943
- # @api private
944
- def serialize(context)
945
- format = Utils.specialize_format(FORMAT, context.endianness)
946
- string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :path => path.to_s)
947
- cmdsize = SIZEOF + string_payload.bytesize
948
- [cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
943
+ # @param context [MachO::LoadCommands::LoadCommand::SerializationContext] the context
944
+ # @return [String] the serialized fields of the load command
945
+ # @api private
946
+ def serialize(context)
947
+ format = Utils.specialize_format(FORMAT, context.endianness)
948
+ string_payload, string_offsets = Utils.pack_strings(SIZEOF, context.alignment, :path => path.to_s)
949
+ cmdsize = SIZEOF + string_payload.bytesize
950
+ [cmd, cmdsize, string_offsets[:path]].pack(format) + string_payload
951
+ end
949
952
  end
950
- end
951
953
 
952
- # A load command representing the offsets and sizes of a blob of data in
953
- # the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
954
- # LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
955
- class LinkeditDataCommand < LoadCommand
956
- # @return [Fixnum] offset to the data in the __LINKEDIT segment
957
- attr_reader :dataoff
954
+ # A load command representing the offsets and sizes of a blob of data in
955
+ # the __LINKEDIT segment. Corresponds to LC_CODE_SIGNATURE, LC_SEGMENT_SPLIT_INFO,
956
+ # LC_FUNCTION_STARTS, LC_DATA_IN_CODE, LC_DYLIB_CODE_SIGN_DRS, and LC_LINKER_OPTIMIZATION_HINT.
957
+ class LinkeditDataCommand < LoadCommand
958
+ # @return [Fixnum] offset to the data in the __LINKEDIT segment
959
+ attr_reader :dataoff
958
960
 
959
- # @return [Fixnum] size of the data in the __LINKEDIT segment
960
- attr_reader :datasize
961
+ # @return [Fixnum] size of the data in the __LINKEDIT segment
962
+ attr_reader :datasize
961
963
 
962
- # @see MachOStructure::FORMAT
963
- # @api private
964
- FORMAT = "L=4".freeze
964
+ # @see MachOStructure::FORMAT
965
+ # @api private
966
+ FORMAT = "L=4".freeze
965
967
 
966
- # @see MachOStructure::SIZEOF
967
- # @api private
968
- SIZEOF = 16
968
+ # @see MachOStructure::SIZEOF
969
+ # @api private
970
+ SIZEOF = 16
969
971
 
970
- # @api private
971
- def initialize(view, cmd, cmdsize, dataoff, datasize)
972
- super(view, cmd, cmdsize)
973
- @dataoff = dataoff
974
- @datasize = datasize
972
+ # @api private
973
+ def initialize(view, cmd, cmdsize, dataoff, datasize)
974
+ super(view, cmd, cmdsize)
975
+ @dataoff = dataoff
976
+ @datasize = datasize
977
+ end
975
978
  end
976
- end
977
979
 
978
- # A load command representing the offset to and size of an encrypted
979
- # segment. Corresponds to LC_ENCRYPTION_INFO.
980
- class EncryptionInfoCommand < LoadCommand
981
- # @return [Fixnum] the offset to the encrypted segment
982
- attr_reader :cryptoff
980
+ # A load command representing the offset to and size of an encrypted
981
+ # segment. Corresponds to LC_ENCRYPTION_INFO.
982
+ class EncryptionInfoCommand < LoadCommand
983
+ # @return [Fixnum] the offset to the encrypted segment
984
+ attr_reader :cryptoff
983
985
 
984
- # @return [Fixnum] the size of the encrypted segment
985
- attr_reader :cryptsize
986
+ # @return [Fixnum] the size of the encrypted segment
987
+ attr_reader :cryptsize
986
988
 
987
- # @return [Fixnum] the encryption system, or 0 if not encrypted yet
988
- attr_reader :cryptid
989
+ # @return [Fixnum] the encryption system, or 0 if not encrypted yet
990
+ attr_reader :cryptid
989
991
 
990
- # @see MachOStructure::FORMAT
991
- # @api private
992
- FORMAT = "L=5".freeze
992
+ # @see MachOStructure::FORMAT
993
+ # @api private
994
+ FORMAT = "L=5".freeze
993
995
 
994
- # @see MachOStructure::SIZEOF
995
- # @api private
996
- SIZEOF = 20
996
+ # @see MachOStructure::SIZEOF
997
+ # @api private
998
+ SIZEOF = 20
997
999
 
998
- # @api private
999
- def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
1000
- super(view, cmd, cmdsize)
1001
- @cryptoff = cryptoff
1002
- @cryptsize = cryptsize
1003
- @cryptid = cryptid
1000
+ # @api private
1001
+ def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid)
1002
+ super(view, cmd, cmdsize)
1003
+ @cryptoff = cryptoff
1004
+ @cryptsize = cryptsize
1005
+ @cryptid = cryptid
1006
+ end
1004
1007
  end
1005
- end
1006
1008
 
1007
- # A load command representing the offset to and size of an encrypted
1008
- # segment. Corresponds to LC_ENCRYPTION_INFO_64.
1009
- class EncryptionInfoCommand64 < LoadCommand
1010
- # @return [Fixnum] the offset to the encrypted segment
1011
- attr_reader :cryptoff
1009
+ # A load command representing the offset to and size of an encrypted
1010
+ # segment. Corresponds to LC_ENCRYPTION_INFO_64.
1011
+ class EncryptionInfoCommand64 < LoadCommand
1012
+ # @return [Fixnum] the offset to the encrypted segment
1013
+ attr_reader :cryptoff
1012
1014
 
1013
- # @return [Fixnum] the size of the encrypted segment
1014
- attr_reader :cryptsize
1015
+ # @return [Fixnum] the size of the encrypted segment
1016
+ attr_reader :cryptsize
1015
1017
 
1016
- # @return [Fixnum] the encryption system, or 0 if not encrypted yet
1017
- attr_reader :cryptid
1018
+ # @return [Fixnum] the encryption system, or 0 if not encrypted yet
1019
+ attr_reader :cryptid
1018
1020
 
1019
- # @return [Fixnum] 64-bit padding value
1020
- attr_reader :pad
1021
+ # @return [Fixnum] 64-bit padding value
1022
+ attr_reader :pad
1021
1023
 
1022
- # @see MachOStructure::FORMAT
1023
- # @api private
1024
- FORMAT = "L=6".freeze
1024
+ # @see MachOStructure::FORMAT
1025
+ # @api private
1026
+ FORMAT = "L=6".freeze
1025
1027
 
1026
- # @see MachOStructure::SIZEOF
1027
- # @api private
1028
- SIZEOF = 24
1028
+ # @see MachOStructure::SIZEOF
1029
+ # @api private
1030
+ SIZEOF = 24
1029
1031
 
1030
- # @api private
1031
- def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
1032
- super(view, cmd, cmdsize)
1033
- @cryptoff = cryptoff
1034
- @cryptsize = cryptsize
1035
- @cryptid = cryptid
1036
- @pad = pad
1032
+ # @api private
1033
+ def initialize(view, cmd, cmdsize, cryptoff, cryptsize, cryptid, pad)
1034
+ super(view, cmd, cmdsize)
1035
+ @cryptoff = cryptoff
1036
+ @cryptsize = cryptsize
1037
+ @cryptid = cryptid
1038
+ @pad = pad
1039
+ end
1037
1040
  end
1038
- end
1039
1041
 
1040
- # A load command containing the minimum OS version on which the binary
1041
- # was built to run. Corresponds to LC_VERSION_MIN_MACOSX and LC_VERSION_MIN_IPHONEOS.
1042
- class VersionMinCommand < LoadCommand
1043
- # @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
1044
- attr_reader :version
1042
+ # A load command containing the minimum OS version on which the binary
1043
+ # was built to run. Corresponds to LC_VERSION_MIN_MACOSX and LC_VERSION_MIN_IPHONEOS.
1044
+ class VersionMinCommand < LoadCommand
1045
+ # @return [Fixnum] the version X.Y.Z packed as x16.y8.z8
1046
+ attr_reader :version
1045
1047
 
1046
- # @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8
1047
- attr_reader :sdk
1048
+ # @return [Fixnum] the SDK version X.Y.Z packed as x16.y8.z8
1049
+ attr_reader :sdk
1048
1050
 
1049
- # @see MachOStructure::FORMAT
1050
- # @api private
1051
- FORMAT = "L=4".freeze
1051
+ # @see MachOStructure::FORMAT
1052
+ # @api private
1053
+ FORMAT = "L=4".freeze
1052
1054
 
1053
- # @see MachOStructure::SIZEOF
1054
- # @api private
1055
- SIZEOF = 16
1055
+ # @see MachOStructure::SIZEOF
1056
+ # @api private
1057
+ SIZEOF = 16
1056
1058
 
1057
- # @api private
1058
- def initialize(view, cmd, cmdsize, version, sdk)
1059
- super(view, cmd, cmdsize)
1060
- @version = version
1061
- @sdk = sdk
1062
- end
1059
+ # @api private
1060
+ def initialize(view, cmd, cmdsize, version, sdk)
1061
+ super(view, cmd, cmdsize)
1062
+ @version = version
1063
+ @sdk = sdk
1064
+ end
1063
1065
 
1064
- # A string representation of the binary's minimum OS version.
1065
- # @return [String] a string representing the minimum OS version.
1066
- def version_string
1067
- binary = "%032b" % version
1068
- segs = [
1069
- binary[0..15], binary[16..23], binary[24..31]
1070
- ].map { |s| s.to_i(2) }
1066
+ # A string representation of the binary's minimum OS version.
1067
+ # @return [String] a string representing the minimum OS version.
1068
+ def version_string
1069
+ binary = "%032b" % version
1070
+ segs = [
1071
+ binary[0..15], binary[16..23], binary[24..31]
1072
+ ].map { |s| s.to_i(2) }
1071
1073
 
1072
- segs.join(".")
1073
- end
1074
+ segs.join(".")
1075
+ end
1074
1076
 
1075
- # A string representation of the binary's SDK version.
1076
- # @return [String] a string representing the SDK version.
1077
- def sdk_string
1078
- binary = "%032b" % sdk
1079
- segs = [
1080
- binary[0..15], binary[16..23], binary[24..31]
1081
- ].map { |s| s.to_i(2) }
1077
+ # A string representation of the binary's SDK version.
1078
+ # @return [String] a string representing the SDK version.
1079
+ def sdk_string
1080
+ binary = "%032b" % sdk
1081
+ segs = [
1082
+ binary[0..15], binary[16..23], binary[24..31]
1083
+ ].map { |s| s.to_i(2) }
1082
1084
 
1083
- segs.join(".")
1085
+ segs.join(".")
1086
+ end
1084
1087
  end
1085
- end
1086
1088
 
1087
- # A load command containing the file offsets and sizes of the new
1088
- # compressed form of the information dyld needs to load the image.
1089
- # Corresponds to LC_DYLD_INFO and LC_DYLD_INFO_ONLY.
1090
- class DyldInfoCommand < LoadCommand
1091
- # @return [Fixnum] the file offset to the rebase information
1092
- attr_reader :rebase_off
1089
+ # A load command containing the file offsets and sizes of the new
1090
+ # compressed form of the information dyld needs to load the image.
1091
+ # Corresponds to LC_DYLD_INFO and LC_DYLD_INFO_ONLY.
1092
+ class DyldInfoCommand < LoadCommand
1093
+ # @return [Fixnum] the file offset to the rebase information
1094
+ attr_reader :rebase_off
1093
1095
 
1094
- # @return [Fixnum] the size of the rebase information
1095
- attr_reader :rebase_size
1096
+ # @return [Fixnum] the size of the rebase information
1097
+ attr_reader :rebase_size
1096
1098
 
1097
- # @return [Fixnum] the file offset to the binding information
1098
- attr_reader :bind_off
1099
+ # @return [Fixnum] the file offset to the binding information
1100
+ attr_reader :bind_off
1099
1101
 
1100
- # @return [Fixnum] the size of the binding information
1101
- attr_reader :bind_size
1102
+ # @return [Fixnum] the size of the binding information
1103
+ attr_reader :bind_size
1102
1104
 
1103
- # @return [Fixnum] the file offset to the weak binding information
1104
- attr_reader :weak_bind_off
1105
+ # @return [Fixnum] the file offset to the weak binding information
1106
+ attr_reader :weak_bind_off
1105
1107
 
1106
- # @return [Fixnum] the size of the weak binding information
1107
- attr_reader :weak_bind_size
1108
+ # @return [Fixnum] the size of the weak binding information
1109
+ attr_reader :weak_bind_size
1108
1110
 
1109
- # @return [Fixnum] the file offset to the lazy binding information
1110
- attr_reader :lazy_bind_off
1111
+ # @return [Fixnum] the file offset to the lazy binding information
1112
+ attr_reader :lazy_bind_off
1111
1113
 
1112
- # @return [Fixnum] the size of the lazy binding information
1113
- attr_reader :lazy_bind_size
1114
+ # @return [Fixnum] the size of the lazy binding information
1115
+ attr_reader :lazy_bind_size
1114
1116
 
1115
- # @return [Fixnum] the file offset to the export information
1116
- attr_reader :export_off
1117
+ # @return [Fixnum] the file offset to the export information
1118
+ attr_reader :export_off
1117
1119
 
1118
- # @return [Fixnum] the size of the export information
1119
- attr_reader :export_size
1120
+ # @return [Fixnum] the size of the export information
1121
+ attr_reader :export_size
1120
1122
 
1121
- # @see MachOStructure::FORMAT
1122
- # @api private
1123
- FORMAT = "L=12".freeze
1123
+ # @see MachOStructure::FORMAT
1124
+ # @api private
1125
+ FORMAT = "L=12".freeze
1124
1126
 
1125
- # @see MachOStructure::SIZEOF
1126
- # @api private
1127
- SIZEOF = 48
1127
+ # @see MachOStructure::SIZEOF
1128
+ # @api private
1129
+ SIZEOF = 48
1128
1130
 
1129
- # @api private
1130
- def initialize(view, cmd, cmdsize, rebase_off, rebase_size, bind_off,
1131
- bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
1132
- lazy_bind_size, export_off, export_size)
1133
- super(view, cmd, cmdsize)
1134
- @rebase_off = rebase_off
1135
- @rebase_size = rebase_size
1136
- @bind_off = bind_off
1137
- @bind_size = bind_size
1138
- @weak_bind_off = weak_bind_off
1139
- @weak_bind_size = weak_bind_size
1140
- @lazy_bind_off = lazy_bind_off
1141
- @lazy_bind_size = lazy_bind_size
1142
- @export_off = export_off
1143
- @export_size = export_size
1131
+ # @api private
1132
+ def initialize(view, cmd, cmdsize, rebase_off, rebase_size, bind_off,
1133
+ bind_size, weak_bind_off, weak_bind_size, lazy_bind_off,
1134
+ lazy_bind_size, export_off, export_size)
1135
+ super(view, cmd, cmdsize)
1136
+ @rebase_off = rebase_off
1137
+ @rebase_size = rebase_size
1138
+ @bind_off = bind_off
1139
+ @bind_size = bind_size
1140
+ @weak_bind_off = weak_bind_off
1141
+ @weak_bind_size = weak_bind_size
1142
+ @lazy_bind_off = lazy_bind_off
1143
+ @lazy_bind_size = lazy_bind_size
1144
+ @export_off = export_off
1145
+ @export_size = export_size
1146
+ end
1144
1147
  end
1145
- end
1146
1148
 
1147
- # A load command containing linker options embedded in object files.
1148
- # Corresponds to LC_LINKER_OPTION.
1149
- class LinkerOptionCommand < LoadCommand
1150
- # @return [Fixnum] the number of strings
1151
- attr_reader :count
1149
+ # A load command containing linker options embedded in object files.
1150
+ # Corresponds to LC_LINKER_OPTION.
1151
+ class LinkerOptionCommand < LoadCommand
1152
+ # @return [Fixnum] the number of strings
1153
+ attr_reader :count
1152
1154
 
1153
- # @see MachOStructure::FORMAT
1154
- # @api private
1155
- FORMAT = "L=3".freeze
1155
+ # @see MachOStructure::FORMAT
1156
+ # @api private
1157
+ FORMAT = "L=3".freeze
1156
1158
 
1157
- # @see MachOStructure::SIZEOF
1158
- # @api private
1159
- SIZEOF = 12
1159
+ # @see MachOStructure::SIZEOF
1160
+ # @api private
1161
+ SIZEOF = 12
1160
1162
 
1161
- # @api private
1162
- def initialize(view, cmd, cmdsize, count)
1163
- super(view, cmd, cmdsize)
1164
- @count = count
1163
+ # @api private
1164
+ def initialize(view, cmd, cmdsize, count)
1165
+ super(view, cmd, cmdsize)
1166
+ @count = count
1167
+ end
1165
1168
  end
1166
- end
1167
1169
 
1168
- # A load command specifying the offset of main(). Corresponds to LC_MAIN.
1169
- class EntryPointCommand < LoadCommand
1170
- # @return [Fixnum] the file (__TEXT) offset of main()
1171
- attr_reader :entryoff
1170
+ # A load command specifying the offset of main(). Corresponds to LC_MAIN.
1171
+ class EntryPointCommand < LoadCommand
1172
+ # @return [Fixnum] the file (__TEXT) offset of main()
1173
+ attr_reader :entryoff
1172
1174
 
1173
- # @return [Fixnum] if not 0, the initial stack size.
1174
- attr_reader :stacksize
1175
+ # @return [Fixnum] if not 0, the initial stack size.
1176
+ attr_reader :stacksize
1175
1177
 
1176
- # @see MachOStructure::FORMAT
1177
- # @api private
1178
- FORMAT = "L=2Q=2".freeze
1178
+ # @see MachOStructure::FORMAT
1179
+ # @api private
1180
+ FORMAT = "L=2Q=2".freeze
1179
1181
 
1180
- # @see MachOStructure::SIZEOF
1181
- # @api private
1182
- SIZEOF = 24
1182
+ # @see MachOStructure::SIZEOF
1183
+ # @api private
1184
+ SIZEOF = 24
1183
1185
 
1184
- # @api private
1185
- def initialize(view, cmd, cmdsize, entryoff, stacksize)
1186
- super(view, cmd, cmdsize)
1187
- @entryoff = entryoff
1188
- @stacksize = stacksize
1186
+ # @api private
1187
+ def initialize(view, cmd, cmdsize, entryoff, stacksize)
1188
+ super(view, cmd, cmdsize)
1189
+ @entryoff = entryoff
1190
+ @stacksize = stacksize
1191
+ end
1189
1192
  end
1190
- end
1191
1193
 
1192
- # A load command specifying the version of the sources used to build the
1193
- # binary. Corresponds to LC_SOURCE_VERSION.
1194
- class SourceVersionCommand < LoadCommand
1195
- # @return [Fixnum] the version packed as a24.b10.c10.d10.e10
1196
- attr_reader :version
1194
+ # A load command specifying the version of the sources used to build the
1195
+ # binary. Corresponds to LC_SOURCE_VERSION.
1196
+ class SourceVersionCommand < LoadCommand
1197
+ # @return [Fixnum] the version packed as a24.b10.c10.d10.e10
1198
+ attr_reader :version
1197
1199
 
1198
- # @see MachOStructure::FORMAT
1199
- # @api private
1200
- FORMAT = "L=2Q=1".freeze
1200
+ # @see MachOStructure::FORMAT
1201
+ # @api private
1202
+ FORMAT = "L=2Q=1".freeze
1201
1203
 
1202
- # @see MachOStructure::SIZEOF
1203
- # @api private
1204
- SIZEOF = 16
1204
+ # @see MachOStructure::SIZEOF
1205
+ # @api private
1206
+ SIZEOF = 16
1205
1207
 
1206
- # @api private
1207
- def initialize(view, cmd, cmdsize, version)
1208
- super(view, cmd, cmdsize)
1209
- @version = version
1210
- end
1208
+ # @api private
1209
+ def initialize(view, cmd, cmdsize, version)
1210
+ super(view, cmd, cmdsize)
1211
+ @version = version
1212
+ end
1211
1213
 
1212
- # A string representation of the sources used to build the binary.
1213
- # @return [String] a string representation of the version
1214
- def version_string
1215
- binary = "%064b" % version
1216
- segs = [
1217
- binary[0..23], binary[24..33], binary[34..43], binary[44..53],
1218
- binary[54..63]
1219
- ].map { |s| s.to_i(2) }
1214
+ # A string representation of the sources used to build the binary.
1215
+ # @return [String] a string representation of the version
1216
+ def version_string
1217
+ binary = "%064b" % version
1218
+ segs = [
1219
+ binary[0..23], binary[24..33], binary[34..43], binary[44..53],
1220
+ binary[54..63]
1221
+ ].map { |s| s.to_i(2) }
1220
1222
 
1221
- segs.join(".")
1223
+ segs.join(".")
1224
+ end
1222
1225
  end
1223
- end
1224
1226
 
1225
- # An obsolete load command containing the offset and size of the (GNU style)
1226
- # symbol table information. Corresponds to LC_SYMSEG.
1227
- class SymsegCommand < LoadCommand
1228
- # @return [Fixnum] the offset to the symbol segment
1229
- attr_reader :offset
1227
+ # An obsolete load command containing the offset and size of the (GNU style)
1228
+ # symbol table information. Corresponds to LC_SYMSEG.
1229
+ class SymsegCommand < LoadCommand
1230
+ # @return [Fixnum] the offset to the symbol segment
1231
+ attr_reader :offset
1230
1232
 
1231
- # @return [Fixnum] the size of the symbol segment in bytes
1232
- attr_reader :size
1233
+ # @return [Fixnum] the size of the symbol segment in bytes
1234
+ attr_reader :size
1233
1235
 
1234
- # @see MachOStructure::FORMAT
1235
- # @api private
1236
- FORMAT = "L=4".freeze
1236
+ # @see MachOStructure::FORMAT
1237
+ # @api private
1238
+ FORMAT = "L=4".freeze
1237
1239
 
1238
- # @see MachOStructure::SIZEOF
1239
- # @api private
1240
- SIZEOF = 16
1240
+ # @see MachOStructure::SIZEOF
1241
+ # @api private
1242
+ SIZEOF = 16
1241
1243
 
1242
- # @api private
1243
- def initialize(view, cmd, cmdsize, offset, size)
1244
- super(view, cmd, cmdsize)
1245
- @offset = offset
1246
- @size = size
1244
+ # @api private
1245
+ def initialize(view, cmd, cmdsize, offset, size)
1246
+ super(view, cmd, cmdsize)
1247
+ @offset = offset
1248
+ @size = size
1249
+ end
1247
1250
  end
1248
- end
1249
1251
 
1250
- # An obsolete load command containing a free format string table. Each string
1251
- # is null-terminated and the command is zero-padded to a multiple of 4.
1252
- # Corresponds to LC_IDENT.
1253
- class IdentCommand < LoadCommand
1254
- # @see MachOStructure::FORMAT
1255
- # @api private
1256
- FORMAT = "L=2".freeze
1252
+ # An obsolete load command containing a free format string table. Each string
1253
+ # is null-terminated and the command is zero-padded to a multiple of 4.
1254
+ # Corresponds to LC_IDENT.
1255
+ class IdentCommand < LoadCommand
1256
+ # @see MachOStructure::FORMAT
1257
+ # @api private
1258
+ FORMAT = "L=2".freeze
1257
1259
 
1258
- # @see MachOStructure::SIZEOF
1259
- # @api private
1260
- SIZEOF = 8
1261
- end
1260
+ # @see MachOStructure::SIZEOF
1261
+ # @api private
1262
+ SIZEOF = 8
1263
+ end
1262
1264
 
1263
- # An obsolete load command containing the path to a file to be loaded into
1264
- # memory. Corresponds to LC_FVMFILE.
1265
- class FvmfileCommand < LoadCommand
1266
- # @return [MachO::LoadCommand::LCStr] the pathname of the file being loaded
1267
- attr_reader :name
1265
+ # An obsolete load command containing the path to a file to be loaded into
1266
+ # memory. Corresponds to LC_FVMFILE.
1267
+ class FvmfileCommand < LoadCommand
1268
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the pathname of the file being loaded
1269
+ attr_reader :name
1268
1270
 
1269
- # @return [Fixnum] the virtual address being loaded at
1270
- attr_reader :header_addr
1271
+ # @return [Fixnum] the virtual address being loaded at
1272
+ attr_reader :header_addr
1271
1273
 
1272
- # @see MachOStructure::FORMAT
1273
- # @api private
1274
- FORMAT = "L=4".freeze
1274
+ # @see MachOStructure::FORMAT
1275
+ # @api private
1276
+ FORMAT = "L=4".freeze
1275
1277
 
1276
- # @see MachOStructure::SIZEOF
1277
- # @api private
1278
- SIZEOF = 16
1278
+ # @see MachOStructure::SIZEOF
1279
+ # @api private
1280
+ SIZEOF = 16
1279
1281
 
1280
- def initialize(view, cmd, cmdsize, name, header_addr)
1281
- super(view, cmd, cmdsize)
1282
- @name = LCStr.new(self, name)
1283
- @header_addr = header_addr
1282
+ def initialize(view, cmd, cmdsize, name, header_addr)
1283
+ super(view, cmd, cmdsize)
1284
+ @name = LCStr.new(self, name)
1285
+ @header_addr = header_addr
1286
+ end
1284
1287
  end
1285
- end
1286
1288
 
1287
- # An obsolete load command containing the path to a library to be loaded into
1288
- # memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
1289
- class FvmlibCommand < LoadCommand
1290
- # @return [MachO::LoadCommand::LCStr] the library's target pathname
1291
- attr_reader :name
1289
+ # An obsolete load command containing the path to a library to be loaded into
1290
+ # memory. Corresponds to LC_LOADFVMLIB and LC_IDFVMLIB.
1291
+ class FvmlibCommand < LoadCommand
1292
+ # @return [MachO::LoadCommands::LoadCommand::LCStr] the library's target pathname
1293
+ attr_reader :name
1292
1294
 
1293
- # @return [Fixnum] the library's minor version number
1294
- attr_reader :minor_version
1295
+ # @return [Fixnum] the library's minor version number
1296
+ attr_reader :minor_version
1295
1297
 
1296
- # @return [Fixnum] the library's header address
1297
- attr_reader :header_addr
1298
+ # @return [Fixnum] the library's header address
1299
+ attr_reader :header_addr
1298
1300
 
1299
- # @see MachOStructure::FORMAT
1300
- # @api private
1301
- FORMAT = "L=5".freeze
1301
+ # @see MachOStructure::FORMAT
1302
+ # @api private
1303
+ FORMAT = "L=5".freeze
1302
1304
 
1303
- # @see MachOStructure::SIZEOF
1304
- # @api private
1305
- SIZEOF = 20
1305
+ # @see MachOStructure::SIZEOF
1306
+ # @api private
1307
+ SIZEOF = 20
1306
1308
 
1307
- def initialize(view, cmd, cmdsize, name, minor_version, header_addr)
1308
- super(view, cmd, cmdsize)
1309
- @name = LCStr.new(self, name)
1310
- @minor_version = minor_version
1311
- @header_addr = header_addr
1309
+ def initialize(view, cmd, cmdsize, name, minor_version, header_addr)
1310
+ super(view, cmd, cmdsize)
1311
+ @name = LCStr.new(self, name)
1312
+ @minor_version = minor_version
1313
+ @header_addr = header_addr
1314
+ end
1312
1315
  end
1313
1316
  end
1314
1317
  end