ruby-macho 0.2.6 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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