]>
Commit | Line | Data |
---|---|---|
d696c285 A |
1 | /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- |
2 | * | |
2f2f92e4 | 3 | * Copyright (c) 2005-2008 Apple Inc. All rights reserved. |
d696c285 A |
4 | * |
5 | * @APPLE_LICENSE_HEADER_START@ | |
6 | * | |
7 | * This file contains Original Code and/or Modifications of Original Code | |
8 | * as defined in and that are subject to the Apple Public Source License | |
9 | * Version 2.0 (the 'License'). You may not use this file except in | |
10 | * compliance with the License. Please obtain a copy of the License at | |
11 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
12 | * file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. | |
19 | * Please see the License for the specific language governing rights and | |
20 | * limitations under the License. | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | #ifndef __MACH_O_FILE_ABSTRACTION__ | |
25 | #define __MACH_O_FILE_ABSTRACTION__ | |
26 | ||
27 | #include <mach-o/loader.h> | |
28 | #include <mach-o/nlist.h> | |
29 | #include <mach-o/reloc.h> | |
2f2f92e4 A |
30 | #include <mach-o/fat.h> |
31 | #include <mach-o/stab.h> | |
32 | #include <mach-o/reloc.h> | |
33 | #include <mach-o/ppc/reloc.h> | |
34 | #include <mach-o/x86_64/reloc.h> | |
d696c285 A |
35 | #include <mach/machine.h> |
36 | ||
d696c285 A |
37 | #include "FileAbstraction.hpp" |
38 | #include "Architectures.hpp" | |
39 | ||
2f2f92e4 A |
40 | // stuff that will eventually go away once newer cctools headers are widespread |
41 | #ifndef LC_LAZY_LOAD_DYLIB | |
42 | #define LC_LAZY_LOAD_DYLIB 0x20 | |
43 | #endif | |
44 | #ifndef S_LAZY_DYLIB_SYMBOL_POINTERS | |
45 | #define S_LAZY_DYLIB_SYMBOL_POINTERS 0x10 | |
46 | #endif | |
47 | #ifndef CPU_SUBTYPE_ARM_V5TEJ | |
48 | #define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) | |
49 | #endif | |
50 | #ifndef CPU_SUBTYPE_ARM_XSCALE | |
51 | #define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) | |
52 | #endif | |
53 | #ifndef CPU_SUBTYPE_ARM_V7 | |
54 | #define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) | |
55 | #endif | |
56 | #ifndef N_ARM_THUMB_DEF | |
57 | #define N_ARM_THUMB_DEF 0x0008 | |
58 | #endif | |
59 | enum reloc_type_arm | |
60 | { | |
61 | ARM_RELOC_VANILLA, /* generic relocation as discribed above */ | |
62 | ARM_RELOC_PAIR, /* the second relocation entry of a pair */ | |
63 | ARM_RELOC_SECTDIFF, /* a PAIR follows with subtract symbol value */ | |
64 | ARM_RELOC_LOCAL_SECTDIFF, /* like ARM_RELOC_SECTDIFF, but the symbol | |
65 | referenced was local. */ | |
66 | ARM_RELOC_PB_LA_PTR,/* prebound lazy pointer */ | |
67 | ARM_RELOC_BR24, /* 24 bit branch displacement (to a word address) */ | |
68 | ARM_THUMB_RELOC_BR22, /* 22 bit branch displacement (to a half-word | |
69 | address) */ | |
70 | }; | |
71 | ||
72 | #ifndef LC_ENCRYPTION_INFO | |
73 | #define LC_ENCRYPTION_INFO 0x21 | |
74 | struct encryption_info_command { | |
75 | uint32_t cmd; | |
76 | uint32_t cmdsize; | |
77 | uint32_t cryptoff; /* file offset of encrypted range */ | |
78 | uint32_t cryptsize; /* file size of encrypted range */ | |
79 | uint32_t cryptid; /* which enryption system, 0 means not-encrypted yet */ | |
80 | }; | |
81 | #endif | |
d696c285 A |
82 | |
83 | ||
84 | // | |
85 | // This abstraction layer makes every mach-o file look like a 64-bit mach-o file with native endianness | |
86 | // | |
87 | ||
88 | ||
89 | ||
90 | // | |
91 | // mach-o file header | |
92 | // | |
93 | template <typename P> struct macho_header_content {}; | |
94 | template <> struct macho_header_content<Pointer32<BigEndian> > { mach_header fields; }; | |
95 | template <> struct macho_header_content<Pointer64<BigEndian> > { mach_header_64 fields; }; | |
96 | template <> struct macho_header_content<Pointer32<LittleEndian> > { mach_header fields; }; | |
97 | template <> struct macho_header_content<Pointer64<LittleEndian> > { mach_header_64 fields; }; | |
98 | ||
99 | template <typename P> | |
100 | class macho_header { | |
101 | public: | |
102 | uint32_t magic() const INLINE { return E::get32(header.fields.magic); } | |
103 | void set_magic(uint32_t value) INLINE { E::set32(header.fields.magic, value); } | |
104 | ||
105 | uint32_t cputype() const INLINE { return E::get32(header.fields.cputype); } | |
106 | void set_cputype(uint32_t value) INLINE { E::set32((uint32_t&)header.fields.cputype, value); } | |
107 | ||
108 | uint32_t cpusubtype() const INLINE { return E::get32(header.fields.cpusubtype); } | |
109 | void set_cpusubtype(uint32_t value) INLINE { E::set32((uint32_t&)header.fields.cpusubtype, value); } | |
110 | ||
111 | uint32_t filetype() const INLINE { return E::get32(header.fields.filetype); } | |
112 | void set_filetype(uint32_t value) INLINE { E::set32(header.fields.filetype, value); } | |
113 | ||
114 | uint32_t ncmds() const INLINE { return E::get32(header.fields.ncmds); } | |
115 | void set_ncmds(uint32_t value) INLINE { E::set32(header.fields.ncmds, value); } | |
116 | ||
117 | uint32_t sizeofcmds() const INLINE { return E::get32(header.fields.sizeofcmds); } | |
118 | void set_sizeofcmds(uint32_t value) INLINE { E::set32(header.fields.sizeofcmds, value); } | |
119 | ||
120 | uint32_t flags() const INLINE { return E::get32(header.fields.flags); } | |
121 | void set_flags(uint32_t value) INLINE { E::set32(header.fields.flags, value); } | |
122 | ||
123 | uint32_t reserved() const INLINE { return E::get32(header.fields.reserved); } | |
124 | void set_reserved(uint32_t value) INLINE { E::set32(header.fields.reserved, value); } | |
125 | ||
126 | typedef typename P::E E; | |
127 | private: | |
128 | macho_header_content<P> header; | |
129 | }; | |
130 | ||
131 | ||
132 | // | |
133 | // mach-o load command | |
134 | // | |
135 | template <typename P> | |
136 | class macho_load_command { | |
137 | public: | |
138 | uint32_t cmd() const INLINE { return E::get32(command.cmd); } | |
139 | void set_cmd(uint32_t value) INLINE { E::set32(command.cmd, value); } | |
140 | ||
141 | uint32_t cmdsize() const INLINE { return E::get32(command.cmdsize); } | |
142 | void set_cmdsize(uint32_t value) INLINE { E::set32(command.cmdsize, value); } | |
143 | ||
144 | typedef typename P::E E; | |
145 | private: | |
146 | load_command command; | |
147 | }; | |
148 | ||
149 | ||
150 | // | |
151 | // mach-o segment load command | |
152 | // | |
153 | template <typename P> struct macho_segment_content {}; | |
154 | template <> struct macho_segment_content<Pointer32<BigEndian> > { segment_command fields; enum { CMD = LC_SEGMENT }; }; | |
155 | template <> struct macho_segment_content<Pointer64<BigEndian> > { segment_command_64 fields; enum { CMD = LC_SEGMENT_64 }; }; | |
156 | template <> struct macho_segment_content<Pointer32<LittleEndian> > { segment_command fields; enum { CMD = LC_SEGMENT }; }; | |
157 | template <> struct macho_segment_content<Pointer64<LittleEndian> > { segment_command_64 fields; enum { CMD = LC_SEGMENT_64 }; }; | |
158 | ||
159 | template <typename P> | |
160 | class macho_segment_command { | |
161 | public: | |
162 | uint32_t cmd() const INLINE { return E::get32(segment.fields.cmd); } | |
163 | void set_cmd(uint32_t value) INLINE { E::set32(segment.fields.cmd, value); } | |
164 | ||
165 | uint32_t cmdsize() const INLINE { return E::get32(segment.fields.cmdsize); } | |
166 | void set_cmdsize(uint32_t value) INLINE { E::set32(segment.fields.cmdsize, value); } | |
167 | ||
168 | const char* segname() const INLINE { return segment.fields.segname; } | |
69a49097 | 169 | void set_segname(const char* value) INLINE { strncpy(segment.fields.segname, value, 16); } |
d696c285 A |
170 | |
171 | uint64_t vmaddr() const INLINE { return P::getP(segment.fields.vmaddr); } | |
172 | void set_vmaddr(uint64_t value) INLINE { P::setP(segment.fields.vmaddr, value); } | |
173 | ||
174 | uint64_t vmsize() const INLINE { return P::getP(segment.fields.vmsize); } | |
175 | void set_vmsize(uint64_t value) INLINE { P::setP(segment.fields.vmsize, value); } | |
176 | ||
177 | uint64_t fileoff() const INLINE { return P::getP(segment.fields.fileoff); } | |
178 | void set_fileoff(uint64_t value) INLINE { P::setP(segment.fields.fileoff, value); } | |
179 | ||
180 | uint64_t filesize() const INLINE { return P::getP(segment.fields.filesize); } | |
181 | void set_filesize(uint64_t value) INLINE { P::setP(segment.fields.filesize, value); } | |
182 | ||
183 | uint32_t maxprot() const INLINE { return E::get32(segment.fields.maxprot); } | |
184 | void set_maxprot(uint32_t value) INLINE { E::set32((uint32_t&)segment.fields.maxprot, value); } | |
185 | ||
186 | uint32_t initprot() const INLINE { return E::get32(segment.fields.initprot); } | |
187 | void set_initprot(uint32_t value) INLINE { E::set32((uint32_t&)segment.fields.initprot, value); } | |
188 | ||
189 | uint32_t nsects() const INLINE { return E::get32(segment.fields.nsects); } | |
190 | void set_nsects(uint32_t value) INLINE { E::set32(segment.fields.nsects, value); } | |
191 | ||
192 | uint32_t flags() const INLINE { return E::get32(segment.fields.flags); } | |
193 | void set_flags(uint32_t value) INLINE { E::set32(segment.fields.flags, value); } | |
194 | ||
195 | enum { | |
196 | CMD = macho_segment_content<P>::CMD | |
197 | }; | |
198 | ||
199 | typedef typename P::E E; | |
200 | private: | |
201 | macho_segment_content<P> segment; | |
202 | }; | |
203 | ||
204 | ||
205 | // | |
206 | // mach-o section | |
207 | // | |
208 | template <typename P> struct macho_section_content {}; | |
209 | template <> struct macho_section_content<Pointer32<BigEndian> > { section fields; }; | |
210 | template <> struct macho_section_content<Pointer64<BigEndian> > { section_64 fields; }; | |
211 | template <> struct macho_section_content<Pointer32<LittleEndian> > { section fields; }; | |
212 | template <> struct macho_section_content<Pointer64<LittleEndian> > { section_64 fields; }; | |
213 | ||
214 | template <typename P> | |
215 | class macho_section { | |
216 | public: | |
217 | const char* sectname() const INLINE { return section.fields.sectname; } | |
69a49097 | 218 | void set_sectname(const char* value) INLINE { strncpy(section.fields.sectname, value, 16); } |
d696c285 A |
219 | |
220 | const char* segname() const INLINE { return section.fields.segname; } | |
69a49097 | 221 | void set_segname(const char* value) INLINE { strncpy(section.fields.segname, value, 16); } |
d696c285 A |
222 | |
223 | uint64_t addr() const INLINE { return P::getP(section.fields.addr); } | |
224 | void set_addr(uint64_t value) INLINE { P::setP(section.fields.addr, value); } | |
225 | ||
226 | uint64_t size() const INLINE { return P::getP(section.fields.size); } | |
227 | void set_size(uint64_t value) INLINE { P::setP(section.fields.size, value); } | |
228 | ||
229 | uint32_t offset() const INLINE { return E::get32(section.fields.offset); } | |
230 | void set_offset(uint32_t value) INLINE { E::set32(section.fields.offset, value); } | |
231 | ||
232 | uint32_t align() const INLINE { return E::get32(section.fields.align); } | |
233 | void set_align(uint32_t value) INLINE { E::set32(section.fields.align, value); } | |
234 | ||
235 | uint32_t reloff() const INLINE { return E::get32(section.fields.reloff); } | |
236 | void set_reloff(uint32_t value) INLINE { E::set32(section.fields.reloff, value); } | |
237 | ||
238 | uint32_t nreloc() const INLINE { return E::get32(section.fields.nreloc); } | |
239 | void set_nreloc(uint32_t value) INLINE { E::set32(section.fields.nreloc, value); } | |
240 | ||
241 | uint32_t flags() const INLINE { return E::get32(section.fields.flags); } | |
242 | void set_flags(uint32_t value) INLINE { E::set32(section.fields.flags, value); } | |
243 | ||
244 | uint32_t reserved1() const INLINE { return E::get32(section.fields.reserved1); } | |
245 | void set_reserved1(uint32_t value) INLINE { E::set32(section.fields.reserved1, value); } | |
246 | ||
247 | uint32_t reserved2() const INLINE { return E::get32(section.fields.reserved2); } | |
248 | void set_reserved2(uint32_t value) INLINE { E::set32(section.fields.reserved2, value); } | |
249 | ||
250 | typedef typename P::E E; | |
251 | private: | |
252 | macho_section_content<P> section; | |
253 | }; | |
254 | ||
255 | ||
256 | // | |
257 | // mach-o dylib load command | |
258 | // | |
259 | template <typename P> | |
260 | class macho_dylib_command { | |
261 | public: | |
262 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
263 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
264 | ||
265 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
266 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
267 | ||
268 | uint32_t name_offset() const INLINE { return E::get32(fields.dylib.name.offset); } | |
269 | void set_name_offset(uint32_t value) INLINE { E::set32(fields.dylib.name.offset, value); } | |
270 | ||
271 | uint32_t timestamp() const INLINE { return E::get32(fields.dylib.timestamp); } | |
272 | void set_timestamp(uint32_t value) INLINE { E::set32(fields.dylib.timestamp, value); } | |
273 | ||
274 | uint32_t current_version() const INLINE { return E::get32(fields.dylib.current_version); } | |
275 | void set_current_version(uint32_t value) INLINE { E::set32(fields.dylib.current_version, value); } | |
276 | ||
277 | uint32_t compatibility_version() const INLINE { return E::get32(fields.dylib.compatibility_version); } | |
278 | void set_compatibility_version(uint32_t value) INLINE { E::set32(fields.dylib.compatibility_version, value); } | |
279 | ||
280 | const char* name() const INLINE { return (const char*)&fields + name_offset(); } | |
281 | void set_name_offset() INLINE { set_name_offset(sizeof(fields)); } | |
282 | ||
283 | typedef typename P::E E; | |
284 | private: | |
285 | dylib_command fields; | |
286 | }; | |
287 | ||
288 | ||
289 | // | |
290 | // mach-o dylinker load command | |
291 | // | |
292 | template <typename P> | |
293 | class macho_dylinker_command { | |
294 | public: | |
295 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
296 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
297 | ||
298 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
299 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
300 | ||
301 | uint32_t name_offset() const INLINE { return E::get32(fields.name.offset); } | |
302 | void set_name_offset(uint32_t value) INLINE { E::set32(fields.name.offset, value); } | |
303 | ||
304 | const char* name() const INLINE { return (const char*)&fields + name_offset(); } | |
305 | void set_name_offset() INLINE { set_name_offset(sizeof(fields)); } | |
306 | ||
307 | typedef typename P::E E; | |
308 | private: | |
309 | dylinker_command fields; | |
310 | }; | |
311 | ||
312 | ||
313 | // | |
314 | // mach-o sub_framework load command | |
315 | // | |
316 | template <typename P> | |
317 | class macho_sub_framework_command { | |
318 | public: | |
319 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
320 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
321 | ||
322 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
323 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
324 | ||
325 | uint32_t umbrella_offset() const INLINE { return E::get32(fields.umbrella.offset); } | |
326 | void set_umbrella_offset(uint32_t value) INLINE { E::set32(fields.umbrella.offset, value); } | |
327 | ||
328 | const char* umbrella() const INLINE { return (const char*)&fields + umbrella_offset(); } | |
329 | void set_umbrella_offset() INLINE { set_umbrella_offset(sizeof(fields)); } | |
330 | ||
331 | typedef typename P::E E; | |
332 | private: | |
333 | sub_framework_command fields; | |
334 | }; | |
335 | ||
336 | ||
337 | // | |
338 | // mach-o sub_client load command | |
339 | // | |
340 | template <typename P> | |
341 | class macho_sub_client_command { | |
342 | public: | |
343 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
344 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
345 | ||
346 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
347 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
348 | ||
349 | uint32_t client_offset() const INLINE { return E::get32(fields.client.offset); } | |
350 | void set_client_offset(uint32_t value) INLINE { E::set32(fields.client.offset, value); } | |
351 | ||
352 | const char* client() const INLINE { return (const char*)&fields + client_offset(); } | |
353 | void set_client_offset() INLINE { set_client_offset(sizeof(fields)); } | |
354 | ||
355 | typedef typename P::E E; | |
356 | private: | |
357 | sub_client_command fields; | |
358 | }; | |
359 | ||
360 | ||
361 | // | |
362 | // mach-o sub_umbrella load command | |
363 | // | |
364 | template <typename P> | |
365 | class macho_sub_umbrella_command { | |
366 | public: | |
367 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
368 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
369 | ||
370 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
371 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
372 | ||
373 | uint32_t sub_umbrella_offset() const INLINE { return E::get32(fields.sub_umbrella.offset); } | |
374 | void set_sub_umbrella_offset(uint32_t value) INLINE { E::set32(fields.sub_umbrella.offset, value); } | |
375 | ||
376 | const char* sub_umbrella() const INLINE { return (const char*)&fields + sub_umbrella_offset(); } | |
377 | void set_sub_umbrella_offset() INLINE { set_sub_umbrella_offset(sizeof(fields)); } | |
378 | ||
379 | typedef typename P::E E; | |
380 | private: | |
381 | sub_umbrella_command fields; | |
382 | }; | |
383 | ||
384 | ||
385 | // | |
386 | // mach-o sub_library load command | |
387 | // | |
388 | template <typename P> | |
389 | class macho_sub_library_command { | |
390 | public: | |
391 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
392 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
393 | ||
394 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
395 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
396 | ||
397 | uint32_t sub_library_offset() const INLINE { return E::get32(fields.sub_library.offset); } | |
398 | void set_sub_library_offset(uint32_t value) INLINE { E::set32(fields.sub_library.offset, value); } | |
399 | ||
400 | const char* sub_library() const INLINE { return (const char*)&fields + sub_library_offset(); } | |
401 | void set_sub_library_offset() INLINE { set_sub_library_offset(sizeof(fields)); } | |
402 | ||
403 | typedef typename P::E E; | |
404 | private: | |
405 | sub_library_command fields; | |
406 | }; | |
407 | ||
408 | ||
409 | // | |
410 | // mach-o uuid load command | |
411 | // | |
412 | template <typename P> | |
413 | class macho_uuid_command { | |
414 | public: | |
415 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
416 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
417 | ||
418 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
419 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
420 | ||
421 | const uint8_t* uuid() const INLINE { return fields.uuid; } | |
422 | void set_uuid(uint8_t uuid[16]) INLINE { memcpy(&fields.uuid, uuid, 16); } | |
423 | ||
424 | typedef typename P::E E; | |
425 | private: | |
426 | uuid_command fields; | |
427 | }; | |
428 | ||
429 | ||
430 | // | |
431 | // mach-o routines load command | |
432 | // | |
433 | template <typename P> struct macho_routines_content {}; | |
434 | template <> struct macho_routines_content<Pointer32<BigEndian> > { routines_command fields; enum { CMD = LC_ROUTINES }; }; | |
435 | template <> struct macho_routines_content<Pointer64<BigEndian> > { routines_command_64 fields; enum { CMD = LC_ROUTINES_64 }; }; | |
436 | template <> struct macho_routines_content<Pointer32<LittleEndian> > { routines_command fields; enum { CMD = LC_ROUTINES }; }; | |
437 | template <> struct macho_routines_content<Pointer64<LittleEndian> > { routines_command_64 fields; enum { CMD = LC_ROUTINES_64 }; }; | |
438 | ||
439 | template <typename P> | |
440 | class macho_routines_command { | |
441 | public: | |
442 | uint32_t cmd() const INLINE { return E::get32(routines.fields.cmd); } | |
443 | void set_cmd(uint32_t value) INLINE { E::set32(routines.fields.cmd, value); } | |
444 | ||
445 | uint32_t cmdsize() const INLINE { return E::get32(routines.fields.cmdsize); } | |
446 | void set_cmdsize(uint32_t value) INLINE { E::set32(routines.fields.cmdsize, value); } | |
447 | ||
448 | uint64_t init_address() const INLINE { return P::getP(routines.fields.init_address); } | |
449 | void set_init_address(uint64_t value) INLINE { P::setP(routines.fields.init_address, value); } | |
450 | ||
451 | uint64_t init_module() const INLINE { return P::getP(routines.fields.init_module); } | |
452 | void set_init_module(uint64_t value) INLINE { P::setP(routines.fields.init_module, value); } | |
453 | ||
454 | uint64_t reserved1() const INLINE { return P::getP(routines.fields.reserved1); } | |
455 | void set_reserved1(uint64_t value) INLINE { P::setP(routines.fields.reserved1, value); } | |
456 | ||
457 | uint64_t reserved2() const INLINE { return P::getP(routines.fields.reserved2); } | |
458 | void set_reserved2(uint64_t value) INLINE { P::setP(routines.fields.reserved2, value); } | |
459 | ||
460 | uint64_t reserved3() const INLINE { return P::getP(routines.fields.reserved3); } | |
461 | void set_reserved3(uint64_t value) INLINE { P::setP(routines.fields.reserved3, value); } | |
462 | ||
463 | uint64_t reserved4() const INLINE { return P::getP(routines.fields.reserved4); } | |
464 | void set_reserved4(uint64_t value) INLINE { P::setP(routines.fields.reserved4, value); } | |
465 | ||
466 | uint64_t reserved5() const INLINE { return P::getP(routines.fields.reserved5); } | |
467 | void set_reserved5(uint64_t value) INLINE { P::setP(routines.fields.reserved5, value); } | |
468 | ||
469 | uint64_t reserved6() const INLINE { return P::getP(routines.fields.reserved6); } | |
470 | void set_reserved6(uint64_t value) INLINE { P::setP(routines.fields.reserved6, value); } | |
471 | ||
472 | typedef typename P::E E; | |
473 | enum { | |
474 | CMD = macho_routines_content<P>::CMD | |
475 | }; | |
476 | private: | |
477 | macho_routines_content<P> routines; | |
478 | }; | |
479 | ||
480 | ||
481 | // | |
482 | // mach-o symbol table load command | |
483 | // | |
484 | template <typename P> | |
485 | class macho_symtab_command { | |
486 | public: | |
487 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
488 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
489 | ||
490 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
491 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
492 | ||
493 | uint32_t symoff() const INLINE { return E::get32(fields.symoff); } | |
494 | void set_symoff(uint32_t value) INLINE { E::set32(fields.symoff, value); } | |
495 | ||
496 | uint32_t nsyms() const INLINE { return E::get32(fields.nsyms); } | |
497 | void set_nsyms(uint32_t value) INLINE { E::set32(fields.nsyms, value); } | |
498 | ||
499 | uint32_t stroff() const INLINE { return E::get32(fields.stroff); } | |
500 | void set_stroff(uint32_t value) INLINE { E::set32(fields.stroff, value); } | |
501 | ||
502 | uint32_t strsize() const INLINE { return E::get32(fields.strsize); } | |
503 | void set_strsize(uint32_t value) INLINE { E::set32(fields.strsize, value); } | |
504 | ||
505 | ||
506 | typedef typename P::E E; | |
507 | private: | |
508 | symtab_command fields; | |
509 | }; | |
510 | ||
511 | ||
512 | // | |
513 | // mach-o dynamic symbol table load command | |
514 | // | |
515 | template <typename P> | |
516 | class macho_dysymtab_command { | |
517 | public: | |
518 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
519 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
520 | ||
521 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
522 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
523 | ||
524 | uint32_t ilocalsym() const INLINE { return E::get32(fields.ilocalsym); } | |
525 | void set_ilocalsym(uint32_t value) INLINE { E::set32(fields.ilocalsym, value); } | |
526 | ||
527 | uint32_t nlocalsym() const INLINE { return E::get32(fields.nlocalsym); } | |
528 | void set_nlocalsym(uint32_t value) INLINE { E::set32(fields.nlocalsym, value); } | |
529 | ||
530 | uint32_t iextdefsym() const INLINE { return E::get32(fields.iextdefsym); } | |
531 | void set_iextdefsym(uint32_t value) INLINE { E::set32(fields.iextdefsym, value); } | |
532 | ||
533 | uint32_t nextdefsym() const INLINE { return E::get32(fields.nextdefsym); } | |
534 | void set_nextdefsym(uint32_t value) INLINE { E::set32(fields.nextdefsym, value); } | |
535 | ||
536 | uint32_t iundefsym() const INLINE { return E::get32(fields.iundefsym); } | |
537 | void set_iundefsym(uint32_t value) INLINE { E::set32(fields.iundefsym, value); } | |
538 | ||
539 | uint32_t nundefsym() const INLINE { return E::get32(fields.nundefsym); } | |
540 | void set_nundefsym(uint32_t value) INLINE { E::set32(fields.nundefsym, value); } | |
541 | ||
542 | uint32_t tocoff() const INLINE { return E::get32(fields.tocoff); } | |
543 | void set_tocoff(uint32_t value) INLINE { E::set32(fields.tocoff, value); } | |
544 | ||
545 | uint32_t ntoc() const INLINE { return E::get32(fields.ntoc); } | |
546 | void set_ntoc(uint32_t value) INLINE { E::set32(fields.ntoc, value); } | |
547 | ||
548 | uint32_t modtaboff() const INLINE { return E::get32(fields.modtaboff); } | |
549 | void set_modtaboff(uint32_t value) INLINE { E::set32(fields.modtaboff, value); } | |
550 | ||
551 | uint32_t nmodtab() const INLINE { return E::get32(fields.nmodtab); } | |
552 | void set_nmodtab(uint32_t value) INLINE { E::set32(fields.nmodtab, value); } | |
553 | ||
554 | uint32_t extrefsymoff() const INLINE { return E::get32(fields.extrefsymoff); } | |
555 | void set_extrefsymoff(uint32_t value) INLINE { E::set32(fields.extrefsymoff, value); } | |
556 | ||
557 | uint32_t nextrefsyms() const INLINE { return E::get32(fields.nextrefsyms); } | |
558 | void set_nextrefsyms(uint32_t value) INLINE { E::set32(fields.nextrefsyms, value); } | |
559 | ||
560 | uint32_t indirectsymoff() const INLINE { return E::get32(fields.indirectsymoff); } | |
561 | void set_indirectsymoff(uint32_t value) INLINE { E::set32(fields.indirectsymoff, value); } | |
562 | ||
563 | uint32_t nindirectsyms() const INLINE { return E::get32(fields.nindirectsyms); } | |
564 | void set_nindirectsyms(uint32_t value) INLINE { E::set32(fields.nindirectsyms, value); } | |
565 | ||
566 | uint32_t extreloff() const INLINE { return E::get32(fields.extreloff); } | |
567 | void set_extreloff(uint32_t value) INLINE { E::set32(fields.extreloff, value); } | |
568 | ||
569 | uint32_t nextrel() const INLINE { return E::get32(fields.nextrel); } | |
570 | void set_nextrel(uint32_t value) INLINE { E::set32(fields.nextrel, value); } | |
571 | ||
572 | uint32_t locreloff() const INLINE { return E::get32(fields.locreloff); } | |
573 | void set_locreloff(uint32_t value) INLINE { E::set32(fields.locreloff, value); } | |
574 | ||
575 | uint32_t nlocrel() const INLINE { return E::get32(fields.nlocrel); } | |
576 | void set_nlocrel(uint32_t value) INLINE { E::set32(fields.nlocrel, value); } | |
577 | ||
578 | typedef typename P::E E; | |
579 | private: | |
580 | dysymtab_command fields; | |
581 | }; | |
582 | ||
583 | ||
a61fdf0a A |
584 | |
585 | ||
586 | // | |
587 | // mach-o module table entry (for compatibility with old ld/dyld) | |
588 | // | |
589 | template <typename P> struct macho_dylib_module_content {}; | |
590 | template <> struct macho_dylib_module_content<Pointer32<BigEndian> > { struct dylib_module fields; }; | |
591 | template <> struct macho_dylib_module_content<Pointer32<LittleEndian> > { struct dylib_module fields; }; | |
592 | template <> struct macho_dylib_module_content<Pointer64<BigEndian> > { struct dylib_module_64 fields; }; | |
593 | template <> struct macho_dylib_module_content<Pointer64<LittleEndian> > { struct dylib_module_64 fields; }; | |
594 | ||
595 | template <typename P> | |
596 | class macho_dylib_module { | |
597 | public: | |
598 | uint32_t module_name() const INLINE { return E::get32(module.fields.module_name); } | |
599 | void set_module_name(uint32_t value) INLINE { E::set32(module.fields.module_name, value); } | |
600 | ||
601 | uint32_t iextdefsym() const INLINE { return E::get32(module.fields.iextdefsym); } | |
602 | void set_iextdefsym(uint32_t value) INLINE { E::set32(module.fields.iextdefsym, value); } | |
603 | ||
604 | uint32_t nextdefsym() const INLINE { return E::get32(module.fields.nextdefsym); } | |
605 | void set_nextdefsym(uint32_t value) INLINE { E::set32(module.fields.nextdefsym, value); } | |
606 | ||
607 | uint32_t irefsym() const INLINE { return E::get32(module.fields.irefsym); } | |
608 | void set_irefsym(uint32_t value) INLINE { E::set32(module.fields.irefsym, value); } | |
609 | ||
610 | uint32_t nrefsym() const INLINE { return E::get32(module.fields.nrefsym); } | |
611 | void set_nrefsym(uint32_t value) INLINE { E::set32(module.fields.nrefsym, value); } | |
612 | ||
613 | uint32_t ilocalsym() const INLINE { return E::get32(module.fields.ilocalsym); } | |
614 | void set_ilocalsym(uint32_t value) INLINE { E::set32(module.fields.ilocalsym, value); } | |
615 | ||
616 | uint32_t nlocalsym() const INLINE { return E::get32(module.fields.nlocalsym); } | |
617 | void set_nlocalsym(uint32_t value) INLINE { E::set32(module.fields.nlocalsym, value); } | |
618 | ||
619 | uint32_t iextrel() const INLINE { return E::get32(module.fields.iextrel); } | |
620 | void set_iextrel(uint32_t value) INLINE { E::set32(module.fields.iextrel, value); } | |
621 | ||
622 | uint32_t nextrel() const INLINE { return E::get32(module.fields.nextrel); } | |
623 | void set_nextrel(uint32_t value) INLINE { E::set32(module.fields.nextrel, value); } | |
624 | ||
625 | uint16_t iinit() const INLINE { return E::get32(module.fields.iinit_iterm) & 0xFFFF; } | |
626 | uint16_t iterm() const INLINE { return E::get32(module.fields.iinit_iterm) > 16; } | |
627 | void set_iinit_iterm(uint16_t init, uint16_t term) INLINE { E::set32(module.fields.iinit_iterm, (term<<16) | (init &0xFFFF)); } | |
628 | ||
629 | uint16_t ninit() const INLINE { return E::get32(module.fields.ninit_nterm) & 0xFFFF; } | |
630 | uint16_t nterm() const INLINE { return E::get32(module.fields.ninit_nterm) > 16; } | |
631 | void set_ninit_nterm(uint16_t init, uint16_t term) INLINE { E::set32(module.fields.ninit_nterm, (term<<16) | (init &0xFFFF)); } | |
632 | ||
633 | uint64_t objc_module_info_addr() const INLINE { return P::getP(module.fields.objc_module_info_addr); } | |
634 | void set_objc_module_info_addr(uint64_t value) INLINE { P::setP(module.fields.objc_module_info_addr, value); } | |
635 | ||
636 | uint32_t objc_module_info_size() const INLINE { return E::get32(module.fields.objc_module_info_size); } | |
637 | void set_objc_module_info_size(uint32_t value) INLINE { E::set32(module.fields.objc_module_info_size, value); } | |
638 | ||
639 | ||
640 | typedef typename P::E E; | |
641 | private: | |
642 | macho_dylib_module_content<P> module; | |
643 | }; | |
644 | ||
645 | ||
646 | // | |
647 | // mach-o dylib_reference entry | |
648 | // | |
649 | template <typename P> | |
650 | class macho_dylib_reference { | |
651 | public: | |
652 | uint32_t isym() const INLINE { return E::getBits(fields, 0, 24); } | |
653 | void set_isym(uint32_t value) INLINE { E::setBits(fields, value, 0, 24); } | |
654 | ||
655 | uint8_t flags() const INLINE { return E::getBits(fields, 24, 8); } | |
656 | void set_flags(uint8_t value) INLINE { E::setBits(fields, value, 24, 8); } | |
657 | ||
658 | typedef typename P::E E; | |
659 | private: | |
660 | uint32_t fields; | |
661 | }; | |
662 | ||
663 | ||
664 | ||
665 | // | |
666 | // mach-o two-level hints load command | |
667 | // | |
668 | template <typename P> | |
669 | class macho_dylib_table_of_contents { | |
670 | public: | |
671 | uint32_t symbol_index() const INLINE { return E::get32(fields.symbol_index); } | |
672 | void set_symbol_index(uint32_t value) INLINE { E::set32(fields.symbol_index, value); } | |
673 | ||
674 | uint32_t module_index() const INLINE { return E::get32(fields.module_index); } | |
675 | void set_module_index(uint32_t value) INLINE { E::set32(fields.module_index, value); } | |
676 | ||
677 | typedef typename P::E E; | |
678 | private: | |
679 | dylib_table_of_contents fields; | |
680 | }; | |
681 | ||
682 | ||
683 | ||
d696c285 A |
684 | // |
685 | // mach-o two-level hints load command | |
686 | // | |
687 | template <typename P> | |
688 | class macho_twolevel_hints_command { | |
689 | public: | |
690 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
691 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
692 | ||
693 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
694 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
695 | ||
696 | uint32_t offset() const INLINE { return E::get32(fields.offset); } | |
697 | void set_offset(uint32_t value) INLINE { E::set32(fields.offset, value); } | |
698 | ||
699 | uint32_t nhints() const INLINE { return E::get32(fields.nhints); } | |
700 | void set_nhints(uint32_t value) INLINE { E::set32(fields.nhints, value); } | |
701 | ||
702 | typedef typename P::E E; | |
703 | private: | |
704 | twolevel_hints_command fields; | |
705 | }; | |
706 | ||
707 | ||
708 | // | |
709 | // mach-o threads load command | |
710 | // | |
711 | template <typename P> | |
712 | class macho_thread_command { | |
713 | public: | |
714 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
715 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
716 | ||
717 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
718 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
719 | ||
720 | uint32_t flavor() const INLINE { return E::get32(fields_flavor); } | |
721 | void set_flavor(uint32_t value) INLINE { E::set32(fields_flavor, value); } | |
722 | ||
723 | uint32_t count() const INLINE { return E::get32(fields_count); } | |
724 | void set_count(uint32_t value) INLINE { E::set32(fields_count, value); } | |
725 | ||
726 | uint64_t thread_register(uint32_t index) const INLINE { return P::getP(thread_registers[index]); } | |
727 | void set_thread_register(uint32_t index, uint64_t value) INLINE { P::setP(thread_registers[index], value); } | |
728 | ||
729 | typedef typename P::E E; | |
730 | typedef typename P::uint_t pint_t; | |
731 | private: | |
732 | struct thread_command fields; | |
733 | uint32_t fields_flavor; | |
734 | uint32_t fields_count; | |
735 | pint_t thread_registers[1]; | |
736 | }; | |
737 | ||
738 | ||
a61fdf0a A |
739 | // |
740 | // mach-o misc data | |
741 | // | |
742 | template <typename P> | |
743 | class macho_linkedit_data_command { | |
744 | public: | |
745 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
746 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
747 | ||
748 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
749 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
750 | ||
751 | uint32_t dataoff() const INLINE { return E::get32(fields.dataoff); } | |
752 | void set_dataoff(uint32_t value) INLINE { E::set32(fields.dataoff, value); } | |
753 | ||
754 | uint32_t datasize() const INLINE { return E::get32(fields.datasize); } | |
755 | void set_datasize(uint32_t value)INLINE { E::set32(fields.datasize, value); } | |
756 | ||
757 | ||
758 | typedef typename P::E E; | |
759 | private: | |
2f2f92e4 | 760 | struct linkedit_data_command fields; |
a61fdf0a A |
761 | }; |
762 | ||
763 | ||
764 | // | |
765 | // mach-o rpath | |
766 | // | |
767 | template <typename P> | |
768 | class macho_rpath_command { | |
769 | public: | |
770 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
771 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
772 | ||
773 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
774 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
775 | ||
776 | uint32_t path_offset() const INLINE { return E::get32(fields.path.offset); } | |
777 | void set_path_offset(uint32_t value) INLINE { E::set32(fields.path.offset, value); } | |
778 | ||
779 | const char* path() const INLINE { return (const char*)&fields + path_offset(); } | |
780 | void set_path_offset() INLINE { set_path_offset(sizeof(fields)); } | |
781 | ||
782 | ||
783 | typedef typename P::E E; | |
784 | private: | |
2f2f92e4 | 785 | struct rpath_command fields; |
a61fdf0a A |
786 | }; |
787 | ||
d696c285 A |
788 | |
789 | ||
790 | // | |
791 | // mach-o symbol table entry | |
792 | // | |
793 | template <typename P> struct macho_nlist_content {}; | |
794 | template <> struct macho_nlist_content<Pointer32<BigEndian> > { struct nlist fields; }; | |
795 | template <> struct macho_nlist_content<Pointer64<BigEndian> > { struct nlist_64 fields; }; | |
796 | template <> struct macho_nlist_content<Pointer32<LittleEndian> > { struct nlist fields; }; | |
797 | template <> struct macho_nlist_content<Pointer64<LittleEndian> > { struct nlist_64 fields; }; | |
798 | ||
799 | template <typename P> | |
800 | class macho_nlist { | |
801 | public: | |
802 | uint32_t n_strx() const INLINE { return E::get32(entry.fields.n_un.n_strx); } | |
803 | void set_n_strx(uint32_t value) INLINE { E::set32((uint32_t&)entry.fields.n_un.n_strx, value); } | |
804 | ||
805 | uint8_t n_type() const INLINE { return entry.fields.n_type; } | |
806 | void set_n_type(uint8_t value) INLINE { entry.fields.n_type = value; } | |
807 | ||
808 | uint8_t n_sect() const INLINE { return entry.fields.n_sect; } | |
809 | void set_n_sect(uint8_t value) INLINE { entry.fields.n_sect = value; } | |
810 | ||
811 | uint16_t n_desc() const INLINE { return E::get16(entry.fields.n_desc); } | |
812 | void set_n_desc(uint16_t value) INLINE { E::set16((uint16_t&)entry.fields.n_desc, value); } | |
813 | ||
814 | uint64_t n_value() const INLINE { return P::getP(entry.fields.n_value); } | |
815 | void set_n_value(uint64_t value) INLINE { P::setP(entry.fields.n_value, value); } | |
816 | ||
817 | typedef typename P::E E; | |
818 | private: | |
819 | macho_nlist_content<P> entry; | |
820 | }; | |
821 | ||
822 | ||
823 | ||
824 | // | |
825 | // mach-o relocation info | |
826 | // | |
827 | template <typename P> | |
828 | class macho_relocation_info { | |
829 | public: | |
830 | uint32_t r_address() const INLINE { return E::get32(address); } | |
831 | void set_r_address(uint32_t value) INLINE { E::set32(address, value); } | |
832 | ||
833 | uint32_t r_symbolnum() const INLINE { return E::getBits(other, 0, 24); } | |
834 | void set_r_symbolnum(uint32_t value) INLINE { E::setBits(other, value, 0, 24); } | |
835 | ||
836 | bool r_pcrel() const INLINE { return E::getBits(other, 24, 1); } | |
837 | void set_r_pcrel(bool value) INLINE { E::setBits(other, value, 24, 1); } | |
838 | ||
839 | uint8_t r_length() const INLINE { return E::getBits(other, 25, 2); } | |
840 | void set_r_length(uint8_t value) INLINE { E::setBits(other, value, 25, 2); } | |
841 | ||
842 | bool r_extern() const INLINE { return E::getBits(other, 27, 1); } | |
843 | void set_r_extern(bool value) INLINE { E::setBits(other, value, 27, 1); } | |
844 | ||
845 | uint8_t r_type() const INLINE { return E::getBits(other, 28, 4); } | |
846 | void set_r_type(uint8_t value) INLINE { E::setBits(other, value, 28, 4); } | |
847 | ||
848 | void set_r_length() INLINE { set_r_length((sizeof(typename P::uint_t)==8) ? 3 : 2); } | |
849 | ||
850 | typedef typename P::E E; | |
851 | private: | |
852 | uint32_t address; | |
853 | uint32_t other; | |
854 | }; | |
855 | ||
856 | ||
857 | // | |
858 | // mach-o scattered relocation info | |
859 | // The bit fields are always in big-endian order (see mach-o/reloc.h) | |
860 | // | |
861 | template <typename P> | |
862 | class macho_scattered_relocation_info { | |
863 | public: | |
864 | bool r_scattered() const INLINE { return BigEndian::getBitsRaw(E::get32(other), 0, 1); } | |
865 | void set_r_scattered(bool x) INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 0, 1); E::set32(other, temp); } | |
866 | ||
867 | bool r_pcrel() const INLINE { return BigEndian::getBitsRaw(E::get32(other), 1, 1); } | |
868 | void set_r_pcrel(bool x) INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 1, 1); E::set32(other, temp); } | |
869 | ||
870 | uint8_t r_length() const INLINE { return BigEndian::getBitsRaw(E::get32(other), 2, 2); } | |
871 | void set_r_length(uint8_t x) INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 2, 2); E::set32(other, temp); } | |
872 | ||
873 | uint8_t r_type() const INLINE { return BigEndian::getBitsRaw(E::get32(other), 4, 4); } | |
874 | void set_r_type(uint8_t x) INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 4, 4); E::set32(other, temp); } | |
875 | ||
876 | uint32_t r_address() const INLINE { return BigEndian::getBitsRaw(E::get32(other), 8, 24); } | |
a61fdf0a A |
877 | void set_r_address(uint32_t x) { if ( x > 0x00FFFFFF ) throw "scattered reloc r_address too large"; |
878 | uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 8, 24); E::set32(other, temp); } | |
d696c285 A |
879 | |
880 | uint32_t r_value() const INLINE { return E::get32(value); } | |
881 | void set_r_value(uint32_t x) INLINE { E::set32(value, x); } | |
882 | ||
883 | uint32_t r_other() const INLINE { return other; } | |
884 | ||
a61fdf0a A |
885 | void set_r_length() INLINE { set_r_length((sizeof(typename P::uint_t)==8) ? 3 : 2); } |
886 | ||
d696c285 A |
887 | typedef typename P::E E; |
888 | private: | |
889 | uint32_t other; | |
890 | uint32_t value; | |
891 | }; | |
892 | ||
893 | ||
894 | ||
2f2f92e4 A |
895 | // |
896 | // mach-o encyrption info load command | |
897 | // | |
898 | template <typename P> | |
899 | class macho_encryption_info_command { | |
900 | public: | |
901 | uint32_t cmd() const INLINE { return E::get32(fields.cmd); } | |
902 | void set_cmd(uint32_t value) INLINE { E::set32(fields.cmd, value); } | |
903 | ||
904 | uint32_t cmdsize() const INLINE { return E::get32(fields.cmdsize); } | |
905 | void set_cmdsize(uint32_t value) INLINE { E::set32(fields.cmdsize, value); } | |
906 | ||
907 | uint32_t cryptoff() const INLINE { return E::get32(fields.cryptoff); } | |
908 | void set_cryptoff(uint32_t value) INLINE { E::set32(fields.cryptoff, value); } | |
909 | ||
910 | uint32_t cryptsize() const INLINE { return E::get32(fields.cryptsize); } | |
911 | void set_cryptsize(uint32_t value) INLINE { E::set32(fields.cryptsize, value); } | |
912 | ||
913 | uint32_t cryptid() const INLINE { return E::get32(fields.cryptid); } | |
914 | void set_cryptid(uint32_t value) INLINE { E::set32(fields.cryptid, value); } | |
915 | ||
916 | typedef typename P::E E; | |
917 | private: | |
918 | encryption_info_command fields; | |
919 | }; | |
d696c285 A |
920 | |
921 | ||
922 | ||
923 | #endif // __MACH_O_FILE_ABSTRACTION__ | |
924 | ||
925 |