1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
 
   3  * Copyright (c) 2005-2010 Apple Inc. All rights reserved.
 
   5  * @APPLE_LICENSE_HEADER_START@
 
   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
 
  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.
 
  22  * @APPLE_LICENSE_HEADER_END@
 
  24 #ifndef __MACH_O_FILE_ABSTRACTION__
 
  25 #define __MACH_O_FILE_ABSTRACTION__
 
  27 #include <mach-o/loader.h>
 
  28 #include <mach-o/nlist.h>
 
  29 #include <mach-o/reloc.h>
 
  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>
 
  35 #include <mach-o/arm/reloc.h>
 
  36 #include <mach-o/compact_unwind_encoding.h>
 
  37 #include <mach/machine.h>
 
  39 #include "FileAbstraction.hpp"
 
  42 // stuff that will eventually go away once newer cctools headers are widespread
 
  43 #ifndef LC_LOAD_UPWARD_DYLIB
 
  44         #define LC_LOAD_UPWARD_DYLIB (0x23|LC_REQ_DYLD) /* load of dylib whose initializers run later */
 
  47 #ifndef CPU_SUBTYPE_ARM_V5TEJ
 
  48         #define CPU_SUBTYPE_ARM_V5TEJ           ((cpu_subtype_t) 7)
 
  50 #ifndef CPU_SUBTYPE_ARM_XSCALE
 
  51         #define CPU_SUBTYPE_ARM_XSCALE          ((cpu_subtype_t) 8)
 
  53 #ifndef CPU_SUBTYPE_ARM_V7
 
  54         #define CPU_SUBTYPE_ARM_V7                      ((cpu_subtype_t) 9)
 
  56 #ifndef ARM_THUMB_32BIT_BRANCH
 
  57         #define ARM_THUMB_32BIT_BRANCH  7 
 
  59 #ifndef N_ARM_THUMB_DEF
 
  60         #define N_ARM_THUMB_DEF 0x0008 
 
  62 #ifndef MH_DEAD_STRIPPABLE_DYLIB
 
  63         #define MH_DEAD_STRIPPABLE_DYLIB 0x400000
 
  65 #ifndef MH_KEXT_BUNDLE
 
  66         #define MH_KEXT_BUNDLE 11
 
  69         #define LC_DYLD_INFO    0x22    /* compressed dyld information */
 
  70         #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD)    /* compressed dyld information only */
 
  72         struct dyld_info_command {
 
  73            uint32_t   cmd;              /* LC_DYLD_INFO or LC_DYLD_INFO_ONLY */
 
  74            uint32_t   cmdsize;          /* sizeof(struct dyld_info_command) */
 
  75                 uint32_t   rebase_off;  /* file offset to rebase info  */
 
  76                 uint32_t   rebase_size; /* size of rebase info   */
 
  77                 uint32_t   bind_off;    /* file offset to binding info   */
 
  78                 uint32_t   bind_size;   /* size of binding info  */
 
  79                 uint32_t   weak_bind_off;       /* file offset to weak binding info   */
 
  80                 uint32_t   weak_bind_size;  /* size of weak binding info  */
 
  81                 uint32_t   lazy_bind_off;       /* file offset to lazy binding info */
 
  82                 uint32_t   lazy_bind_size;  /* size of lazy binding infs */
 
  83                 uint32_t   export_off;  /* file offset to lazy binding info */
 
  84                 uint32_t   export_size; /* size of lazy binding infs */
 
  87         #define REBASE_TYPE_POINTER                                     1
 
  88         #define REBASE_TYPE_TEXT_ABSOLUTE32                             2
 
  89         #define REBASE_TYPE_TEXT_PCREL32                                3
 
  91         #define REBASE_OPCODE_MASK                                      0xF0
 
  92         #define REBASE_IMMEDIATE_MASK                                   0x0F
 
  93         #define REBASE_OPCODE_DONE                                      0x00
 
  94         #define REBASE_OPCODE_SET_TYPE_IMM                              0x10
 
  95         #define REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB               0x20
 
  96         #define REBASE_OPCODE_ADD_ADDR_ULEB                             0x30
 
  97         #define REBASE_OPCODE_ADD_ADDR_IMM_SCALED                       0x40
 
  98         #define REBASE_OPCODE_DO_REBASE_IMM_TIMES                       0x50
 
  99         #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES                      0x60
 
 100         #define REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB                   0x70
 
 101         #define REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB        0x80
 
 103         #define BIND_TYPE_POINTER                                       1
 
 104         #define BIND_TYPE_TEXT_ABSOLUTE32                               2
 
 105         #define BIND_TYPE_TEXT_PCREL32                                  3
 
 107         #define BIND_SPECIAL_DYLIB_SELF                                  0
 
 108         #define BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE                      -1
 
 109         #define BIND_SPECIAL_DYLIB_FLAT_LOOKUP                          -2
 
 111         #define BIND_SYMBOL_FLAGS_WEAK_IMPORT                           0x1
 
 112         #define BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION                   0x8
 
 114         #define BIND_OPCODE_MASK                                        0xF0
 
 115         #define BIND_IMMEDIATE_MASK                                     0x0F
 
 116         #define BIND_OPCODE_DONE                                        0x00
 
 117         #define BIND_OPCODE_SET_DYLIB_ORDINAL_IMM                       0x10
 
 118         #define BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB                      0x20
 
 119         #define BIND_OPCODE_SET_DYLIB_SPECIAL_IMM                       0x30
 
 120         #define BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM               0x40
 
 121         #define BIND_OPCODE_SET_TYPE_IMM                                0x50
 
 122         #define BIND_OPCODE_SET_ADDEND_SLEB                             0x60
 
 123         #define BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB                 0x70
 
 124         #define BIND_OPCODE_ADD_ADDR_ULEB                               0x80
 
 125         #define BIND_OPCODE_DO_BIND                                     0x90
 
 126         #define BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB                       0xA0
 
 127         #define BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED                 0xB0
 
 128         #define BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB            0xC0
 
 130         #define EXPORT_SYMBOL_FLAGS_KIND_MASK                           0x03
 
 131         #define EXPORT_SYMBOL_FLAGS_KIND_REGULAR                        0x00
 
 132         #define EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL                   0x01
 
 133         #define EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION                     0x04
 
 134         #define EXPORT_SYMBOL_FLAGS_INDIRECT_DEFINITION                 0x08
 
 135         #define EXPORT_SYMBOL_FLAGS_HAS_SPECIALIZATIONS                 0x10
 
 139 #ifndef S_THREAD_LOCAL_REGULAR
 
 140         #define S_THREAD_LOCAL_REGULAR                   0x11
 
 143 #ifndef S_THREAD_LOCAL_ZEROFILL
 
 144         #define S_THREAD_LOCAL_ZEROFILL                  0x12
 
 147 #ifndef S_THREAD_LOCAL_VARIABLES
 
 148         #define S_THREAD_LOCAL_VARIABLES                 0x13
 
 151 #ifndef S_THREAD_LOCAL_VARIABLE_POINTERS
 
 152         #define S_THREAD_LOCAL_VARIABLE_POINTERS         0x14
 
 155 #ifndef S_THREAD_LOCAL_INIT_FUNCTION_POINTERS
 
 156         #define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS    0x15
 
 159 #ifndef MH_HAS_TLV_DESCRIPTORS
 
 160         #define MH_HAS_TLV_DESCRIPTORS 0x800000
 
 163 #ifndef X86_64_RELOC_TLV
 
 164         #define X86_64_RELOC_TLV    9
 
 167 #define GENERIC_RLEOC_TLV  5
 
 169 #ifndef EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER
 
 170         #define EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER 0x10
 
 173 #ifndef EXPORT_SYMBOL_FLAGS_REEXPORT
 
 174         #define EXPORT_SYMBOL_FLAGS_REEXPORT 0x08
 
 177 // type internal to linker
 
 178 #define BIND_TYPE_OVERRIDE_OF_WEAKDEF_IN_DYLIB 0
 
 180 #ifndef LC_VERSION_MIN_MACOSX
 
 181         #define LC_VERSION_MIN_MACOSX   0x24
 
 182         #define LC_VERSION_MIN_IPHONEOS         0x25
 
 184         struct version_min_command {
 
 185                 uint32_t        cmd;            /* LC_VERSION_MIN_MACOSX or LC_VERSION_MIN_IPHONEOS  */
 
 186                 uint32_t        cmdsize;        /* sizeof(struct min_version_command) */
 
 187                 uint32_t        version;        /* X.Y.Z is encoded in nibbles xxxx.yy.zz */
 
 188                 uint32_t        reserved;       /* zero */
 
 192 #ifndef N_SYMBOL_RESOLVER
 
 193         #define N_SYMBOL_RESOLVER 0x100
 
 196 #ifndef LC_FUNCTION_STARTS
 
 197         #define LC_FUNCTION_STARTS      0x26
 
 200 #ifndef MH_NO_HEAP_EXECUTION
 
 201         #define MH_NO_HEAP_EXECUTION 0x1000000
 
 204 #ifndef LC_DYLD_ENVIRONMENT
 
 205         #define LC_DYLD_ENVIRONMENT     0x27
 
 208 // hack until newer <mach-o/arm/reloc.h> everywhere
 
 209 #define ARM_RELOC_HALF 8
 
 210 #define ARM_RELOC_HALF_SECTDIFF 9
 
 214 // This abstraction layer makes every mach-o file look like a 64-bit mach-o file with native endianness
 
 220 // mach-o file header
 
 222 template <typename P> struct macho_header_content {};
 
 223 template <> struct macho_header_content<Pointer32<BigEndian> >    { mach_header         fields; };
 
 224 template <> struct macho_header_content<Pointer64<BigEndian> >    { mach_header_64      fields; };
 
 225 template <> struct macho_header_content<Pointer32<LittleEndian> > { mach_header         fields; };
 
 226 template <> struct macho_header_content<Pointer64<LittleEndian> > { mach_header_64      fields; };
 
 228 template <typename P>
 
 231         uint32_t                magic() const                                   INLINE { return E::get32(header.fields.magic); }
 
 232         void                    set_magic(uint32_t value)               INLINE { E::set32(header.fields.magic, value); }
 
 234         uint32_t                cputype() const                                 INLINE { return E::get32(header.fields.cputype); }
 
 235         void                    set_cputype(uint32_t value)             INLINE { E::set32((uint32_t&)header.fields.cputype, value); }
 
 237         uint32_t                cpusubtype() const                              INLINE { return E::get32(header.fields.cpusubtype); }
 
 238         void                    set_cpusubtype(uint32_t value)  INLINE { E::set32((uint32_t&)header.fields.cpusubtype, value); }
 
 240         uint32_t                filetype() const                                INLINE { return E::get32(header.fields.filetype); }
 
 241         void                    set_filetype(uint32_t value)    INLINE { E::set32(header.fields.filetype, value); }
 
 243         uint32_t                ncmds() const                                   INLINE { return E::get32(header.fields.ncmds); }
 
 244         void                    set_ncmds(uint32_t value)               INLINE { E::set32(header.fields.ncmds, value); }
 
 246         uint32_t                sizeofcmds() const                              INLINE { return E::get32(header.fields.sizeofcmds); }
 
 247         void                    set_sizeofcmds(uint32_t value)  INLINE { E::set32(header.fields.sizeofcmds, value); }
 
 249         uint32_t                flags() const                                   INLINE { return E::get32(header.fields.flags); }
 
 250         void                    set_flags(uint32_t value)               INLINE { E::set32(header.fields.flags, value); }
 
 252         uint32_t                reserved() const                                INLINE { return E::get32(header.fields.reserved); }
 
 253         void                    set_reserved(uint32_t value)    INLINE { E::set32(header.fields.reserved, value); }
 
 255         typedef typename P::E           E;
 
 257         macho_header_content<P> header;
 
 262 // mach-o load command
 
 264 template <typename P>
 
 265 class macho_load_command {
 
 267         uint32_t                cmd() const                                             INLINE { return E::get32(command.cmd); }
 
 268         void                    set_cmd(uint32_t value)                 INLINE { E::set32(command.cmd, value); }
 
 270         uint32_t                cmdsize() const                                 INLINE { return E::get32(command.cmdsize); }
 
 271         void                    set_cmdsize(uint32_t value)             INLINE { E::set32(command.cmdsize, value); }
 
 273         typedef typename P::E           E;
 
 275         load_command    command;
 
 280 // mach-o segment load command
 
 282 template <typename P> struct macho_segment_content {};
 
 283 template <> struct macho_segment_content<Pointer32<BigEndian> >    { segment_command    fields; enum { CMD = LC_SEGMENT         }; };
 
 284 template <> struct macho_segment_content<Pointer64<BigEndian> >    { segment_command_64 fields; enum { CMD = LC_SEGMENT_64      }; };
 
 285 template <> struct macho_segment_content<Pointer32<LittleEndian> > { segment_command    fields; enum { CMD = LC_SEGMENT         }; };
 
 286 template <> struct macho_segment_content<Pointer64<LittleEndian> > { segment_command_64 fields; enum { CMD = LC_SEGMENT_64      }; };
 
 288 template <typename P>
 
 289 class macho_segment_command {
 
 291         uint32_t                cmd() const                                             INLINE { return E::get32(segment.fields.cmd); }
 
 292         void                    set_cmd(uint32_t value)                 INLINE { E::set32(segment.fields.cmd, value); }
 
 294         uint32_t                cmdsize() const                                 INLINE { return E::get32(segment.fields.cmdsize); }
 
 295         void                    set_cmdsize(uint32_t value)             INLINE { E::set32(segment.fields.cmdsize, value); }
 
 297         const char*             segname() const                                 INLINE { return segment.fields.segname; }
 
 298         void                    set_segname(const char* value)  INLINE { strncpy(segment.fields.segname, value, 16); }
 
 300         uint64_t                vmaddr() const                                  INLINE { return P::getP(segment.fields.vmaddr); }
 
 301         void                    set_vmaddr(uint64_t value)              INLINE { P::setP(segment.fields.vmaddr, value); }
 
 303         uint64_t                vmsize() const                                  INLINE { return P::getP(segment.fields.vmsize); }
 
 304         void                    set_vmsize(uint64_t value)              INLINE { P::setP(segment.fields.vmsize, value); }
 
 306         uint64_t                fileoff() const                                 INLINE { return P::getP(segment.fields.fileoff); }
 
 307         void                    set_fileoff(uint64_t value)             INLINE { P::setP(segment.fields.fileoff, value); }
 
 309         uint64_t                filesize() const                                INLINE { return P::getP(segment.fields.filesize); }
 
 310         void                    set_filesize(uint64_t value)    INLINE { P::setP(segment.fields.filesize, value); }
 
 312         uint32_t                maxprot() const                                 INLINE { return E::get32(segment.fields.maxprot); }
 
 313         void                    set_maxprot(uint32_t value)             INLINE { E::set32((uint32_t&)segment.fields.maxprot, value); }
 
 315         uint32_t                initprot() const                                INLINE { return E::get32(segment.fields.initprot); }
 
 316         void                    set_initprot(uint32_t value)    INLINE { E::set32((uint32_t&)segment.fields.initprot, value); }
 
 318         uint32_t                nsects() const                                  INLINE { return E::get32(segment.fields.nsects); }
 
 319         void                    set_nsects(uint32_t value)              INLINE { E::set32(segment.fields.nsects, value); }
 
 321         uint32_t                flags() const                                   INLINE { return E::get32(segment.fields.flags); }
 
 322         void                    set_flags(uint32_t value)               INLINE { E::set32(segment.fields.flags, value); }
 
 325                 CMD = macho_segment_content<P>::CMD
 
 328         typedef typename P::E           E;
 
 330         macho_segment_content<P>        segment;
 
 337 template <typename P> struct macho_section_content {};
 
 338 template <> struct macho_section_content<Pointer32<BigEndian> >    { section    fields; };
 
 339 template <> struct macho_section_content<Pointer64<BigEndian> >    { section_64 fields; };
 
 340 template <> struct macho_section_content<Pointer32<LittleEndian> > { section    fields; };
 
 341 template <> struct macho_section_content<Pointer64<LittleEndian> > { section_64 fields; };
 
 343 template <typename P>
 
 344 class macho_section {
 
 346         const char*             sectname() const                                INLINE { return section.fields.sectname; }
 
 347         void                    set_sectname(const char* value) INLINE { strncpy(section.fields.sectname, value, 16); }
 
 349         const char*             segname() const                                 INLINE { return section.fields.segname; }
 
 350         void                    set_segname(const char* value)  INLINE { strncpy(section.fields.segname, value, 16); }
 
 352         uint64_t                addr() const                                    INLINE { return P::getP(section.fields.addr); }
 
 353         void                    set_addr(uint64_t value)                INLINE { P::setP(section.fields.addr, value); }
 
 355         uint64_t                size() const                                    INLINE { return P::getP(section.fields.size); }
 
 356         void                    set_size(uint64_t value)                INLINE { P::setP(section.fields.size, value); }
 
 358         uint32_t                offset() const                                  INLINE { return E::get32(section.fields.offset); }
 
 359         void                    set_offset(uint32_t value)              INLINE { E::set32(section.fields.offset, value); }
 
 361         uint32_t                align() const                                   INLINE { return E::get32(section.fields.align); }
 
 362         void                    set_align(uint32_t value)               INLINE { E::set32(section.fields.align, value); }
 
 364         uint32_t                reloff() const                                  INLINE { return E::get32(section.fields.reloff); }
 
 365         void                    set_reloff(uint32_t value)              INLINE { E::set32(section.fields.reloff, value); }
 
 367         uint32_t                nreloc() const                                  INLINE { return E::get32(section.fields.nreloc); }
 
 368         void                    set_nreloc(uint32_t value)              INLINE { E::set32(section.fields.nreloc, value); }
 
 370         uint32_t                flags() const                                   INLINE { return E::get32(section.fields.flags); }
 
 371         void                    set_flags(uint32_t value)               INLINE { E::set32(section.fields.flags, value); }
 
 373         uint32_t                reserved1() const                               INLINE { return E::get32(section.fields.reserved1); }
 
 374         void                    set_reserved1(uint32_t value)   INLINE { E::set32(section.fields.reserved1, value); }
 
 376         uint32_t                reserved2() const                               INLINE { return E::get32(section.fields.reserved2); }
 
 377         void                    set_reserved2(uint32_t value)   INLINE { E::set32(section.fields.reserved2, value); }
 
 379         typedef typename P::E           E;
 
 381         macho_section_content<P>        section;
 
 386 // mach-o dylib load command
 
 388 template <typename P>
 
 389 class macho_dylib_command {
 
 391         uint32_t                cmd() const                                                                     INLINE { return E::get32(fields.cmd); }
 
 392         void                    set_cmd(uint32_t value)                                         INLINE { E::set32(fields.cmd, value); }
 
 394         uint32_t                cmdsize() const                                                         INLINE { return E::get32(fields.cmdsize); }
 
 395         void                    set_cmdsize(uint32_t value)                                     INLINE { E::set32(fields.cmdsize, value); }
 
 397         uint32_t                name_offset() const                                                     INLINE { return E::get32(fields.dylib.name.offset); }
 
 398         void                    set_name_offset(uint32_t value)                         INLINE { E::set32(fields.dylib.name.offset, value);  }
 
 400         uint32_t                timestamp() const                                                       INLINE { return E::get32(fields.dylib.timestamp); }
 
 401         void                    set_timestamp(uint32_t value)                           INLINE { E::set32(fields.dylib.timestamp, value); }
 
 403         uint32_t                current_version() const                                         INLINE { return E::get32(fields.dylib.current_version); }
 
 404         void                    set_current_version(uint32_t value)                     INLINE { E::set32(fields.dylib.current_version, value); }
 
 406         uint32_t                compatibility_version() const                           INLINE { return E::get32(fields.dylib.compatibility_version); }
 
 407         void                    set_compatibility_version(uint32_t value)       INLINE { E::set32(fields.dylib.compatibility_version, value); }
 
 409         const char*             name() const                                                            INLINE { return (const char*)&fields + name_offset(); }
 
 410         void                    set_name_offset()                                                       INLINE { set_name_offset(sizeof(fields)); }
 
 412         typedef typename P::E           E;
 
 414         dylib_command   fields;
 
 419 // mach-o dylinker load command
 
 421 template <typename P>
 
 422 class macho_dylinker_command {
 
 424         uint32_t                cmd() const                                                     INLINE { return E::get32(fields.cmd); }
 
 425         void                    set_cmd(uint32_t value)                         INLINE { E::set32(fields.cmd, value); }
 
 427         uint32_t                cmdsize() const                                         INLINE { return E::get32(fields.cmdsize); }
 
 428         void                    set_cmdsize(uint32_t value)                     INLINE { E::set32(fields.cmdsize, value); }
 
 430         uint32_t                name_offset() const                                     INLINE { return E::get32(fields.name.offset); }
 
 431         void                    set_name_offset(uint32_t value)         INLINE { E::set32(fields.name.offset, value);  }
 
 433         const char*             name() const                                            INLINE { return (const char*)&fields + name_offset(); }
 
 434         void                    set_name_offset()                                       INLINE { set_name_offset(sizeof(fields)); }
 
 436         typedef typename P::E           E;
 
 438         dylinker_command        fields;
 
 443 // mach-o sub_framework load command
 
 445 template <typename P>
 
 446 class macho_sub_framework_command {
 
 448         uint32_t                cmd() const                                                     INLINE { return E::get32(fields.cmd); }
 
 449         void                    set_cmd(uint32_t value)                         INLINE { E::set32(fields.cmd, value); }
 
 451         uint32_t                cmdsize() const                                         INLINE { return E::get32(fields.cmdsize); }
 
 452         void                    set_cmdsize(uint32_t value)                     INLINE { E::set32(fields.cmdsize, value); }
 
 454         uint32_t                umbrella_offset() const                         INLINE { return E::get32(fields.umbrella.offset); }
 
 455         void                    set_umbrella_offset(uint32_t value)     INLINE { E::set32(fields.umbrella.offset, value);  }
 
 457         const char*             umbrella() const                                        INLINE { return (const char*)&fields + umbrella_offset(); }
 
 458         void                    set_umbrella_offset()                           INLINE { set_umbrella_offset(sizeof(fields)); }
 
 460         typedef typename P::E           E;
 
 462         sub_framework_command   fields;
 
 467 // mach-o sub_client load command
 
 469 template <typename P>
 
 470 class macho_sub_client_command {
 
 472         uint32_t                cmd() const                                                     INLINE { return E::get32(fields.cmd); }
 
 473         void                    set_cmd(uint32_t value)                         INLINE { E::set32(fields.cmd, value); }
 
 475         uint32_t                cmdsize() const                                         INLINE { return E::get32(fields.cmdsize); }
 
 476         void                    set_cmdsize(uint32_t value)                     INLINE { E::set32(fields.cmdsize, value); }
 
 478         uint32_t                client_offset() const                           INLINE { return E::get32(fields.client.offset); }
 
 479         void                    set_client_offset(uint32_t value)       INLINE { E::set32(fields.client.offset, value);  }
 
 481         const char*             client() const                                          INLINE { return (const char*)&fields + client_offset(); }
 
 482         void                    set_client_offset()                                     INLINE { set_client_offset(sizeof(fields)); }
 
 484         typedef typename P::E           E;
 
 486         sub_client_command      fields;
 
 491 // mach-o sub_umbrella load command
 
 493 template <typename P>
 
 494 class macho_sub_umbrella_command {
 
 496         uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
 
 497         void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
 
 499         uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
 
 500         void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
 
 502         uint32_t                sub_umbrella_offset() const                             INLINE { return E::get32(fields.sub_umbrella.offset); }
 
 503         void                    set_sub_umbrella_offset(uint32_t value) INLINE { E::set32(fields.sub_umbrella.offset, value);  }
 
 505         const char*             sub_umbrella() const                                    INLINE { return (const char*)&fields + sub_umbrella_offset(); }
 
 506         void                    set_sub_umbrella_offset()                               INLINE { set_sub_umbrella_offset(sizeof(fields)); }
 
 508         typedef typename P::E           E;
 
 510         sub_umbrella_command    fields;
 
 515 // mach-o sub_library load command
 
 517 template <typename P>
 
 518 class macho_sub_library_command {
 
 520         uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
 
 521         void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
 
 523         uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
 
 524         void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
 
 526         uint32_t                sub_library_offset() const                              INLINE { return E::get32(fields.sub_library.offset); }
 
 527         void                    set_sub_library_offset(uint32_t value)  INLINE { E::set32(fields.sub_library.offset, value);  }
 
 529         const char*             sub_library() const                                             INLINE { return (const char*)&fields + sub_library_offset(); }
 
 530         void                    set_sub_library_offset()                                INLINE { set_sub_library_offset(sizeof(fields)); }
 
 532         typedef typename P::E           E;
 
 534         sub_library_command     fields;
 
 539 // mach-o uuid load command
 
 541 template <typename P>
 
 542 class macho_uuid_command {
 
 544         uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
 
 545         void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
 
 547         uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
 
 548         void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
 
 550         const uint8_t*  uuid() const                                                    INLINE { return fields.uuid; }
 
 551         void                    set_uuid(const uint8_t u[16])                   INLINE { memcpy(&fields.uuid, u, 16); }
 
 553         typedef typename P::E           E;
 
 560 // mach-o routines load command
 
 562 template <typename P> struct macho_routines_content {};
 
 563 template <> struct macho_routines_content<Pointer32<BigEndian> >    { routines_command          fields; enum { CMD = LC_ROUTINES        }; };
 
 564 template <> struct macho_routines_content<Pointer64<BigEndian> >        { routines_command_64   fields; enum { CMD = LC_ROUTINES_64     }; };
 
 565 template <> struct macho_routines_content<Pointer32<LittleEndian> > { routines_command          fields; enum { CMD = LC_ROUTINES        }; };
 
 566 template <> struct macho_routines_content<Pointer64<LittleEndian> > { routines_command_64       fields; enum { CMD = LC_ROUTINES_64     }; };
 
 568 template <typename P>
 
 569 class macho_routines_command {
 
 571         uint32_t                cmd() const                                                     INLINE { return E::get32(routines.fields.cmd); }
 
 572         void                    set_cmd(uint32_t value)                         INLINE { E::set32(routines.fields.cmd, value); }
 
 574         uint32_t                cmdsize() const                                         INLINE { return E::get32(routines.fields.cmdsize); }
 
 575         void                    set_cmdsize(uint32_t value)                     INLINE { E::set32(routines.fields.cmdsize, value); }
 
 577         uint64_t                init_address() const                            INLINE { return P::getP(routines.fields.init_address); }
 
 578         void                    set_init_address(uint64_t value)        INLINE { P::setP(routines.fields.init_address, value); }
 
 580         uint64_t                init_module() const                                     INLINE { return P::getP(routines.fields.init_module); }
 
 581         void                    set_init_module(uint64_t value)         INLINE { P::setP(routines.fields.init_module, value); }
 
 583         uint64_t                reserved1() const                                       INLINE { return P::getP(routines.fields.reserved1); }
 
 584         void                    set_reserved1(uint64_t value)           INLINE { P::setP(routines.fields.reserved1, value); }
 
 586         uint64_t                reserved2() const                                       INLINE { return P::getP(routines.fields.reserved2); }
 
 587         void                    set_reserved2(uint64_t value)           INLINE { P::setP(routines.fields.reserved2, value); }
 
 589         uint64_t                reserved3() const                                       INLINE { return P::getP(routines.fields.reserved3); }
 
 590         void                    set_reserved3(uint64_t value)           INLINE { P::setP(routines.fields.reserved3, value); }
 
 592         uint64_t                reserved4() const                                       INLINE { return P::getP(routines.fields.reserved4); }
 
 593         void                    set_reserved4(uint64_t value)           INLINE { P::setP(routines.fields.reserved4, value); }
 
 595         uint64_t                reserved5() const                                       INLINE { return P::getP(routines.fields.reserved5); }
 
 596         void                    set_reserved5(uint64_t value)           INLINE { P::setP(routines.fields.reserved5, value); }
 
 598         uint64_t                reserved6() const                                       INLINE { return P::getP(routines.fields.reserved6); }
 
 599         void                    set_reserved6(uint64_t value)           INLINE { P::setP(routines.fields.reserved6, value); }
 
 601         typedef typename P::E           E;
 
 603                 CMD = macho_routines_content<P>::CMD
 
 606         macho_routines_content<P>       routines;
 
 611 // mach-o symbol table load command
 
 613 template <typename P>
 
 614 class macho_symtab_command {
 
 616         uint32_t                cmd() const                                     INLINE { return E::get32(fields.cmd); }
 
 617         void                    set_cmd(uint32_t value)         INLINE { E::set32(fields.cmd, value); }
 
 619         uint32_t                cmdsize() const                         INLINE { return E::get32(fields.cmdsize); }
 
 620         void                    set_cmdsize(uint32_t value)     INLINE { E::set32(fields.cmdsize, value); }
 
 622         uint32_t                symoff() const                          INLINE { return E::get32(fields.symoff); }
 
 623         void                    set_symoff(uint32_t value)      INLINE { E::set32(fields.symoff, value);  }
 
 625         uint32_t                nsyms() const                           INLINE { return E::get32(fields.nsyms); }
 
 626         void                    set_nsyms(uint32_t value)       INLINE { E::set32(fields.nsyms, value);  }
 
 628         uint32_t                stroff() const                          INLINE { return E::get32(fields.stroff); }
 
 629         void                    set_stroff(uint32_t value)      INLINE { E::set32(fields.stroff, value);  }
 
 631         uint32_t                strsize() const                         INLINE { return E::get32(fields.strsize); }
 
 632         void                    set_strsize(uint32_t value)     INLINE { E::set32(fields.strsize, value);  }
 
 635         typedef typename P::E           E;
 
 637         symtab_command  fields;
 
 642 // mach-o dynamic symbol table load command
 
 644 template <typename P>
 
 645 class macho_dysymtab_command {
 
 647         uint32_t                cmd() const                                                     INLINE { return E::get32(fields.cmd); }
 
 648         void                    set_cmd(uint32_t value)                         INLINE { E::set32(fields.cmd, value); }
 
 650         uint32_t                cmdsize() const                                         INLINE { return E::get32(fields.cmdsize); }
 
 651         void                    set_cmdsize(uint32_t value)                     INLINE { E::set32(fields.cmdsize, value); }
 
 653         uint32_t                ilocalsym() const                                       INLINE { return E::get32(fields.ilocalsym); }
 
 654         void                    set_ilocalsym(uint32_t value)           INLINE { E::set32(fields.ilocalsym, value);  }
 
 656         uint32_t                nlocalsym() const                                       INLINE { return E::get32(fields.nlocalsym); }
 
 657         void                    set_nlocalsym(uint32_t value)           INLINE { E::set32(fields.nlocalsym, value);  }
 
 659         uint32_t                iextdefsym() const                                      INLINE { return E::get32(fields.iextdefsym); }
 
 660         void                    set_iextdefsym(uint32_t value)          INLINE { E::set32(fields.iextdefsym, value);  }
 
 662         uint32_t                nextdefsym() const                                      INLINE { return E::get32(fields.nextdefsym); }
 
 663         void                    set_nextdefsym(uint32_t value)          INLINE { E::set32(fields.nextdefsym, value);  }
 
 665         uint32_t                iundefsym() const                                       INLINE { return E::get32(fields.iundefsym); }
 
 666         void                    set_iundefsym(uint32_t value)           INLINE { E::set32(fields.iundefsym, value);  }
 
 668         uint32_t                nundefsym() const                                       INLINE { return E::get32(fields.nundefsym); }
 
 669         void                    set_nundefsym(uint32_t value)           INLINE { E::set32(fields.nundefsym, value);  }
 
 671         uint32_t                tocoff() const                                          INLINE { return E::get32(fields.tocoff); }
 
 672         void                    set_tocoff(uint32_t value)                      INLINE { E::set32(fields.tocoff, value);  }
 
 674         uint32_t                ntoc() const                                            INLINE { return E::get32(fields.ntoc); }
 
 675         void                    set_ntoc(uint32_t value)                        INLINE { E::set32(fields.ntoc, value);  }
 
 677         uint32_t                modtaboff() const                                       INLINE { return E::get32(fields.modtaboff); }
 
 678         void                    set_modtaboff(uint32_t value)           INLINE { E::set32(fields.modtaboff, value);  }
 
 680         uint32_t                nmodtab() const                                         INLINE { return E::get32(fields.nmodtab); }
 
 681         void                    set_nmodtab(uint32_t value)                     INLINE { E::set32(fields.nmodtab, value);  }
 
 683         uint32_t                extrefsymoff() const                            INLINE { return E::get32(fields.extrefsymoff); }
 
 684         void                    set_extrefsymoff(uint32_t value)        INLINE { E::set32(fields.extrefsymoff, value);  }
 
 686         uint32_t                nextrefsyms() const                                     INLINE { return E::get32(fields.nextrefsyms); }
 
 687         void                    set_nextrefsyms(uint32_t value)         INLINE { E::set32(fields.nextrefsyms, value);  }
 
 689         uint32_t                indirectsymoff() const                          INLINE { return E::get32(fields.indirectsymoff); }
 
 690         void                    set_indirectsymoff(uint32_t value)      INLINE { E::set32(fields.indirectsymoff, value);  }
 
 692         uint32_t                nindirectsyms() const                           INLINE { return E::get32(fields.nindirectsyms); }
 
 693         void                    set_nindirectsyms(uint32_t value)       INLINE { E::set32(fields.nindirectsyms, value);  }
 
 695         uint32_t                extreloff() const                                       INLINE { return E::get32(fields.extreloff); }
 
 696         void                    set_extreloff(uint32_t value)           INLINE { E::set32(fields.extreloff, value);  }
 
 698         uint32_t                nextrel() const                                         INLINE { return E::get32(fields.nextrel); }
 
 699         void                    set_nextrel(uint32_t value)                     INLINE { E::set32(fields.nextrel, value);  }
 
 701         uint32_t                locreloff() const                                       INLINE { return E::get32(fields.locreloff); }
 
 702         void                    set_locreloff(uint32_t value)           INLINE { E::set32(fields.locreloff, value);  }
 
 704         uint32_t                nlocrel() const                                         INLINE { return E::get32(fields.nlocrel); }
 
 705         void                    set_nlocrel(uint32_t value)                     INLINE { E::set32(fields.nlocrel, value);  }
 
 707         typedef typename P::E           E;
 
 709         dysymtab_command        fields;
 
 716 // mach-o module table entry (for compatibility with old ld/dyld)
 
 718 template <typename P> struct macho_dylib_module_content {};
 
 719 template <> struct macho_dylib_module_content<Pointer32<BigEndian> >    { struct dylib_module           fields; };
 
 720 template <> struct macho_dylib_module_content<Pointer32<LittleEndian> > { struct dylib_module           fields; };
 
 721 template <> struct macho_dylib_module_content<Pointer64<BigEndian> >    { struct dylib_module_64        fields; };
 
 722 template <> struct macho_dylib_module_content<Pointer64<LittleEndian> > { struct dylib_module_64        fields; };
 
 724 template <typename P>
 
 725 class macho_dylib_module {
 
 727         uint32_t                module_name() const                             INLINE { return E::get32(module.fields.module_name); }
 
 728         void                    set_module_name(uint32_t value) INLINE { E::set32(module.fields.module_name, value);  }
 
 730         uint32_t                iextdefsym() const                              INLINE { return E::get32(module.fields.iextdefsym); }
 
 731         void                    set_iextdefsym(uint32_t value)  INLINE { E::set32(module.fields.iextdefsym, value);  }
 
 733         uint32_t                nextdefsym() const                              INLINE { return E::get32(module.fields.nextdefsym); }
 
 734         void                    set_nextdefsym(uint32_t value)  INLINE { E::set32(module.fields.nextdefsym, value);  }
 
 736         uint32_t                irefsym() const                                 INLINE { return E::get32(module.fields.irefsym); }
 
 737         void                    set_irefsym(uint32_t value)             INLINE { E::set32(module.fields.irefsym, value);  }
 
 739         uint32_t                nrefsym() const                                 INLINE { return E::get32(module.fields.nrefsym); }
 
 740         void                    set_nrefsym(uint32_t value)             INLINE { E::set32(module.fields.nrefsym, value);  }
 
 742         uint32_t                ilocalsym() const                               INLINE { return E::get32(module.fields.ilocalsym); }
 
 743         void                    set_ilocalsym(uint32_t value)   INLINE { E::set32(module.fields.ilocalsym, value);  }
 
 745         uint32_t                nlocalsym() const                               INLINE { return E::get32(module.fields.nlocalsym); }
 
 746         void                    set_nlocalsym(uint32_t value)   INLINE { E::set32(module.fields.nlocalsym, value);  }
 
 748         uint32_t                iextrel() const                                 INLINE { return E::get32(module.fields.iextrel); }
 
 749         void                    set_iextrel(uint32_t value)             INLINE { E::set32(module.fields.iextrel, value);  }
 
 751         uint32_t                nextrel() const                                 INLINE { return E::get32(module.fields.nextrel); }
 
 752         void                    set_nextrel(uint32_t value)             INLINE { E::set32(module.fields.nextrel, value);  }
 
 754         uint16_t                iinit() const                                   INLINE { return E::get32(module.fields.iinit_iterm) & 0xFFFF; }
 
 755         uint16_t                iterm() const                                   INLINE { return E::get32(module.fields.iinit_iterm) > 16; }
 
 756         void                    set_iinit_iterm(uint16_t init, uint16_t term)   INLINE { E::set32(module.fields.iinit_iterm, (term<<16) | (init &0xFFFF));  }
 
 758         uint16_t                ninit() const                                   INLINE { return E::get32(module.fields.ninit_nterm) & 0xFFFF; }
 
 759         uint16_t                nterm() const                                   INLINE { return E::get32(module.fields.ninit_nterm) > 16; }
 
 760         void                    set_ninit_nterm(uint16_t init, uint16_t term)   INLINE { E::set32(module.fields.ninit_nterm, (term<<16) | (init &0xFFFF));  }
 
 762         uint64_t                objc_module_info_addr() const                           INLINE { return P::getP(module.fields.objc_module_info_addr); }
 
 763         void                    set_objc_module_info_addr(uint64_t value)       INLINE { P::setP(module.fields.objc_module_info_addr, value);  }
 
 765         uint32_t                objc_module_info_size() const                           INLINE { return E::get32(module.fields.objc_module_info_size); }
 
 766         void                    set_objc_module_info_size(uint32_t value)       INLINE { E::set32(module.fields.objc_module_info_size, value);  }
 
 769         typedef typename P::E           E;
 
 771         macho_dylib_module_content<P>   module;
 
 776 // mach-o dylib_reference entry
 
 778 template <typename P>
 
 779 class macho_dylib_reference {
 
 781         uint32_t                isym() const                            INLINE { return E::getBits(fields, 0, 24); }
 
 782         void                    set_isym(uint32_t value)        INLINE { E::setBits(fields, value, 0, 24); }
 
 784         uint8_t                 flags() const                           INLINE { return E::getBits(fields, 24, 8); }
 
 785         void                    set_flags(uint8_t value)        INLINE { E::setBits(fields, value, 24, 8); }
 
 787         typedef typename P::E           E;
 
 795 // mach-o two-level hints load command
 
 797 template <typename P>
 
 798 class macho_dylib_table_of_contents {
 
 800         uint32_t                symbol_index() const                            INLINE { return E::get32(fields.symbol_index); }
 
 801         void                    set_symbol_index(uint32_t value)        INLINE { E::set32(fields.symbol_index, value); }
 
 803         uint32_t                module_index() const                            INLINE { return E::get32(fields.module_index); }
 
 804         void                    set_module_index(uint32_t value)        INLINE { E::set32(fields.module_index, value);  }
 
 806         typedef typename P::E           E;
 
 808         dylib_table_of_contents fields;
 
 814 // mach-o two-level hints load command
 
 816 template <typename P>
 
 817 class macho_twolevel_hints_command {
 
 819         uint32_t                cmd() const                                     INLINE { return E::get32(fields.cmd); }
 
 820         void                    set_cmd(uint32_t value)         INLINE { E::set32(fields.cmd, value); }
 
 822         uint32_t                cmdsize() const                         INLINE { return E::get32(fields.cmdsize); }
 
 823         void                    set_cmdsize(uint32_t value)     INLINE { E::set32(fields.cmdsize, value); }
 
 825         uint32_t                offset() const                          INLINE { return E::get32(fields.offset); }
 
 826         void                    set_offset(uint32_t value)      INLINE { E::set32(fields.offset, value);  }
 
 828         uint32_t                nhints() const                          INLINE { return E::get32(fields.nhints); }
 
 829         void                    set_nhints(uint32_t value)      INLINE { E::set32(fields.nhints, value);  }
 
 831         typedef typename P::E           E;
 
 833         twolevel_hints_command  fields;
 
 838 // mach-o threads load command
 
 840 template <typename P>
 
 841 class macho_thread_command {
 
 843         uint32_t                cmd() const                                                                                     INLINE { return E::get32(fields.cmd); }
 
 844         void                    set_cmd(uint32_t value)                                                         INLINE { E::set32(fields.cmd, value); }
 
 846         uint32_t                cmdsize() const                                                                         INLINE { return E::get32(fields.cmdsize); }
 
 847         void                    set_cmdsize(uint32_t value)                                                     INLINE { E::set32(fields.cmdsize, value); }
 
 849         uint32_t                flavor() const                                                                          INLINE { return E::get32(fields_flavor); }
 
 850         void                    set_flavor(uint32_t value)                                                      INLINE { E::set32(fields_flavor, value);  }
 
 852         uint32_t                count() const                                                                           INLINE { return E::get32(fields_count); }
 
 853         void                    set_count(uint32_t value)                                                       INLINE { E::set32(fields_count, value);  }
 
 855         uint64_t                thread_register(uint32_t index) const                           INLINE { return P::getP(thread_registers[index]); }
 
 856         void                    set_thread_register(uint32_t index, uint64_t value)     INLINE { P::setP(thread_registers[index], value); }
 
 858         typedef typename P::E           E;
 
 859         typedef typename P::uint_t      pint_t;
 
 861         struct thread_command   fields;
 
 862         uint32_t                                fields_flavor;
 
 863         uint32_t                                fields_count;
 
 864         pint_t                                  thread_registers[1];
 
 871 template <typename P>
 
 872 class macho_linkedit_data_command {
 
 874         uint32_t                cmd() const                                     INLINE { return E::get32(fields.cmd); }
 
 875         void                    set_cmd(uint32_t value)         INLINE { E::set32(fields.cmd, value); }
 
 877         uint32_t                cmdsize() const                         INLINE { return E::get32(fields.cmdsize); }
 
 878         void                    set_cmdsize(uint32_t value)     INLINE { E::set32(fields.cmdsize, value); }
 
 880         uint32_t                dataoff() const                         INLINE { return E::get32(fields.dataoff); }
 
 881         void                    set_dataoff(uint32_t value)     INLINE { E::set32(fields.dataoff, value);  }
 
 883         uint32_t                datasize() const                        INLINE { return E::get32(fields.datasize); }
 
 884         void                    set_datasize(uint32_t value)INLINE { E::set32(fields.datasize, value);  }
 
 887         typedef typename P::E           E;
 
 889         struct linkedit_data_command    fields;
 
 896 template <typename P>
 
 897 class macho_rpath_command {
 
 899         uint32_t                cmd() const                                             INLINE { return E::get32(fields.cmd); }
 
 900         void                    set_cmd(uint32_t value)                 INLINE { E::set32(fields.cmd, value); }
 
 902         uint32_t                cmdsize() const                                 INLINE { return E::get32(fields.cmdsize); }
 
 903         void                    set_cmdsize(uint32_t value)             INLINE { E::set32(fields.cmdsize, value); }
 
 905         uint32_t                path_offset() const                             INLINE { return E::get32(fields.path.offset); }
 
 906         void                    set_path_offset(uint32_t value) INLINE { E::set32(fields.path.offset, value);  }
 
 908         const char*             path() const                                    INLINE { return (const char*)&fields + path_offset(); }
 
 909         void                    set_path_offset()                               INLINE { set_path_offset(sizeof(fields)); }
 
 912         typedef typename P::E           E;
 
 914         struct rpath_command    fields;
 
 920 // mach-o symbol table entry 
 
 922 template <typename P> struct macho_nlist_content {};
 
 923 template <> struct macho_nlist_content<Pointer32<BigEndian> >    { struct nlist         fields; };
 
 924 template <> struct macho_nlist_content<Pointer64<BigEndian> >    { struct nlist_64      fields; };
 
 925 template <> struct macho_nlist_content<Pointer32<LittleEndian> > { struct nlist         fields; };
 
 926 template <> struct macho_nlist_content<Pointer64<LittleEndian> > { struct nlist_64      fields; };
 
 928 template <typename P>
 
 931         uint32_t                n_strx() const                                  INLINE { return E::get32(entry.fields.n_un.n_strx); }
 
 932         void                    set_n_strx(uint32_t value)              INLINE { E::set32((uint32_t&)entry.fields.n_un.n_strx, value); }
 
 934         uint8_t                 n_type() const                                  INLINE { return entry.fields.n_type; }
 
 935         void                    set_n_type(uint8_t value)               INLINE { entry.fields.n_type = value; }
 
 937         uint8_t                 n_sect() const                                  INLINE { return entry.fields.n_sect; }
 
 938         void                    set_n_sect(uint8_t value)               INLINE { entry.fields.n_sect = value; }
 
 940         uint16_t                n_desc() const                                  INLINE { return E::get16(entry.fields.n_desc); }
 
 941         void                    set_n_desc(uint16_t value)              INLINE { E::set16((uint16_t&)entry.fields.n_desc, value); }
 
 943         uint64_t                n_value() const                                 INLINE { return P::getP(entry.fields.n_value); }
 
 944         void                    set_n_value(uint64_t value)             INLINE { P::setP(entry.fields.n_value, value); }
 
 946         typedef typename P::E           E;
 
 948         macho_nlist_content<P>  entry;
 
 954 // mach-o relocation info
 
 956 template <typename P>
 
 957 class macho_relocation_info {
 
 959         uint32_t                r_address() const                               INLINE { return E::get32(address); }
 
 960         void                    set_r_address(uint32_t value)   INLINE { E::set32(address, value); }
 
 962         uint32_t                r_symbolnum() const                             INLINE { return E::getBits(other, 0, 24); }
 
 963         void                    set_r_symbolnum(uint32_t value) INLINE { E::setBits(other, value, 0, 24); }
 
 965         bool                    r_pcrel() const                                 INLINE { return E::getBits(other, 24, 1); }
 
 966         void                    set_r_pcrel(bool value)                 INLINE { E::setBits(other, value, 24, 1); }     
 
 968         uint8_t                 r_length() const                                INLINE { return E::getBits(other, 25, 2); }
 
 969         void                    set_r_length(uint8_t value)             INLINE { E::setBits(other, value, 25, 2); }
 
 971         bool                    r_extern() const                                INLINE { return E::getBits(other, 27, 1); }
 
 972         void                    set_r_extern(bool value)                INLINE { E::setBits(other, value, 27, 1); }
 
 974         uint8_t                 r_type() const                                  INLINE { return E::getBits(other, 28, 4); }
 
 975         void                    set_r_type(uint8_t value)               INLINE { E::setBits(other, value, 28, 4); }
 
 977         void                    set_r_length()                                  INLINE { set_r_length((sizeof(typename P::uint_t)==8) ? 3 : 2); }
 
 979         typedef typename P::E           E;
 
 987 // mach-o scattered relocation info
 
 988 // The bit fields are always in big-endian order (see mach-o/reloc.h)
 
 990 template <typename P>
 
 991 class macho_scattered_relocation_info {
 
 993         bool                    r_scattered() const                     INLINE { return BigEndian::getBitsRaw(E::get32(other), 0, 1); }
 
 994         void                    set_r_scattered(bool x)         INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 0, 1);  E::set32(other, temp); }
 
 996         bool                    r_pcrel() const                         INLINE { return BigEndian::getBitsRaw(E::get32(other), 1, 1); }
 
 997         void                    set_r_pcrel(bool x)                     INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 1, 1);  E::set32(other, temp); }
 
 999         uint8_t                 r_length() const                        INLINE { return BigEndian::getBitsRaw(E::get32(other), 2, 2); }
 
1000         void                    set_r_length(uint8_t x)         INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 2, 2);  E::set32(other, temp); }
 
1002         uint8_t                 r_type() const                          INLINE { return BigEndian::getBitsRaw(E::get32(other), 4, 4); }
 
1003         void                    set_r_type(uint8_t x)           INLINE { uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 4, 4);  E::set32(other, temp); }
 
1005         uint32_t                r_address() const                       INLINE { return BigEndian::getBitsRaw(E::get32(other), 8, 24); }
 
1006         void                    set_r_address(uint32_t x)                       { if ( x > 0x00FFFFFF ) throw "scattered reloc r_address too large"; 
 
1007                                                                                                                 uint32_t temp = E::get32(other); BigEndian::setBitsRaw(temp, x, 8, 24);  E::set32(other, temp); }
 
1009         uint32_t                r_value() const                         INLINE { return E::get32(value); }
 
1010         void                    set_r_value(uint32_t x)         INLINE { E::set32(value, x); }
 
1012         uint32_t                r_other() const                         INLINE { return other; }
 
1014         void                    set_r_length()                          INLINE { set_r_length((sizeof(typename P::uint_t)==8) ? 3 : 2); }
 
1016         typedef typename P::E           E;
 
1025 // mach-o encyrption info load command
 
1027 template <typename P>
 
1028 class macho_encryption_info_command {
 
1030         uint32_t                cmd() const                                             INLINE { return E::get32(fields.cmd); }
 
1031         void                    set_cmd(uint32_t value)                 INLINE { E::set32(fields.cmd, value); }
 
1033         uint32_t                cmdsize() const                                 INLINE { return E::get32(fields.cmdsize); }
 
1034         void                    set_cmdsize(uint32_t value)             INLINE { E::set32(fields.cmdsize, value); }
 
1036         uint32_t                cryptoff() const                                INLINE { return E::get32(fields.cryptoff); }
 
1037         void                    set_cryptoff(uint32_t value)    INLINE { E::set32(fields.cryptoff, value);  }
 
1039         uint32_t                cryptsize() const                               INLINE { return E::get32(fields.cryptsize); }
 
1040         void                    set_cryptsize(uint32_t value)   INLINE { E::set32(fields.cryptsize, value);  }
 
1042         uint32_t                cryptid() const                                 INLINE { return E::get32(fields.cryptid); }
 
1043         void                    set_cryptid(uint32_t value)             INLINE { E::set32(fields.cryptid, value);  }
 
1045         typedef typename P::E           E;
 
1047         encryption_info_command fields;
 
1052 // start of __unwind_info section  
 
1054 template <typename P>
 
1055 class macho_unwind_info_section_header {
 
1057         uint32_t                version() const                                                                                 INLINE { return E::get32(fields.version); }
 
1058         void                    set_version(uint32_t value)                                                             INLINE { E::set32(fields.version, value); }
 
1060         uint32_t                commonEncodingsArraySectionOffset() const                               INLINE { return E::get32(fields.commonEncodingsArraySectionOffset); }
 
1061         void                    set_commonEncodingsArraySectionOffset(uint32_t value)   INLINE { E::set32(fields.commonEncodingsArraySectionOffset, value); }
 
1063         uint32_t                commonEncodingsArrayCount() const                                               INLINE { return E::get32(fields.commonEncodingsArrayCount); }
 
1064         void                    set_commonEncodingsArrayCount(uint32_t value)                   INLINE { E::set32(fields.commonEncodingsArrayCount, value); }
 
1066         uint32_t                personalityArraySectionOffset() const                                   INLINE { return E::get32(fields.personalityArraySectionOffset); }
 
1067         void                    set_personalityArraySectionOffset(uint32_t value)               INLINE { E::set32(fields.personalityArraySectionOffset, value); }
 
1069         uint32_t                personalityArrayCount() const                                                   INLINE { return E::get32(fields.personalityArrayCount); }
 
1070         void                    set_personalityArrayCount(uint32_t value)                               INLINE { E::set32(fields.personalityArrayCount, value); }
 
1072         uint32_t                indexSectionOffset() const                                                              INLINE { return E::get32(fields.indexSectionOffset); }
 
1073         void                    set_indexSectionOffset(uint32_t value)                                  INLINE { E::set32(fields.indexSectionOffset, value); }
 
1075         uint32_t                indexCount() const                                                                              INLINE { return E::get32(fields.indexCount); }
 
1076         void                    set_indexCount(uint32_t value)                                                  INLINE { E::set32(fields.indexCount, value); }
 
1078         typedef typename P::E           E;
 
1080         unwind_info_section_header      fields;
 
1086 // uwind first level index entry  
 
1088 template <typename P>
 
1089 class macho_unwind_info_section_header_index_entry {
 
1091         uint32_t                functionOffset() const                                                          INLINE { return E::get32(fields.functionOffset); }
 
1092         void                    set_functionOffset(uint32_t value)                                      INLINE { E::set32(fields.functionOffset, value); }
 
1094         uint32_t                secondLevelPagesSectionOffset() const                           INLINE { return E::get32(fields.secondLevelPagesSectionOffset); }
 
1095         void                    set_secondLevelPagesSectionOffset(uint32_t value)       INLINE { E::set32(fields.secondLevelPagesSectionOffset, value); }
 
1097         uint32_t                lsdaIndexArraySectionOffset() const                                     INLINE { return E::get32(fields.lsdaIndexArraySectionOffset); }
 
1098         void                    set_lsdaIndexArraySectionOffset(uint32_t value)         INLINE { E::set32(fields.lsdaIndexArraySectionOffset, value); }
 
1100         typedef typename P::E           E;
 
1102         unwind_info_section_header_index_entry  fields;
 
1109 template <typename P>
 
1110 class macho_unwind_info_section_header_lsda_index_entry {
 
1112         uint32_t                functionOffset() const                                                          INLINE { return E::get32(fields.functionOffset); }
 
1113         void                    set_functionOffset(uint32_t value)                                      INLINE { E::set32(fields.functionOffset, value); }
 
1115         uint32_t                lsdaOffset() const                                                                      INLINE { return E::get32(fields.lsdaOffset); }
 
1116         void                    set_lsdaOffset(uint32_t value)                                          INLINE { E::set32(fields.lsdaOffset, value); }
 
1118         typedef typename P::E           E;
 
1120         unwind_info_section_header_lsda_index_entry     fields;
 
1125 // regular second level entry  
 
1127 template <typename P>
 
1128 class macho_unwind_info_regular_second_level_entry {
 
1130         uint32_t                functionOffset() const                                                          INLINE { return E::get32(fields.functionOffset); }
 
1131         void                    set_functionOffset(uint32_t value)                                      INLINE { E::set32(fields.functionOffset, value); }
 
1133         uint32_t                encoding() const                                                                        INLINE { return E::get32(fields.encoding); }
 
1134         void                    set_encoding(uint32_t value)                                            INLINE { E::set32(fields.encoding, value); }
 
1136         typedef typename P::E           E;
 
1138         unwind_info_regular_second_level_entry  fields;
 
1143 // start of second level regular page  
 
1145 template <typename P>
 
1146 class macho_unwind_info_regular_second_level_page_header {
 
1148         uint32_t                kind() const                                                            INLINE { return E::get32(fields.kind); }
 
1149         void                    set_kind(uint32_t value)                                        INLINE { E::set32(fields.kind, value); }
 
1151         uint16_t                entryPageOffset() const                                         INLINE { return E::get16(fields.entryPageOffset); }
 
1152         void                    set_entryPageOffset(uint16_t value)                     INLINE { E::set16((uint16_t&)fields.entryPageOffset, value); }
 
1154         uint16_t                entryCount() const                                                      INLINE { return E::get16(fields.entryCount); }
 
1155         void                    set_entryCount(uint16_t value)                          INLINE { E::set16((uint16_t&)fields.entryCount, value); }
 
1157         typedef typename P::E           E;
 
1159         unwind_info_regular_second_level_page_header    fields;
 
1164 // start of second level compressed page  
 
1166 template <typename P>
 
1167 class macho_unwind_info_compressed_second_level_page_header {
 
1169         uint32_t                kind() const                                                            INLINE { return E::get32(fields.kind); }
 
1170         void                    set_kind(uint32_t value)                                        INLINE { E::set32(fields.kind, value); }
 
1172         uint16_t                entryPageOffset() const                                         INLINE { return E::get16(fields.entryPageOffset); }
 
1173         void                    set_entryPageOffset(uint16_t value)                     INLINE { E::set16((uint16_t&)fields.entryPageOffset, value); }
 
1175         uint16_t                entryCount() const                                                      INLINE { return E::get16(fields.entryCount); }
 
1176         void                    set_entryCount(uint16_t value)                          INLINE { E::set16((uint16_t&)fields.entryCount, value); }
 
1178         uint16_t                encodingsPageOffset() const                                     INLINE { return E::get16(fields.encodingsPageOffset); }
 
1179         void                    set_encodingsPageOffset(uint16_t value)         INLINE { E::set16((uint16_t&)fields.encodingsPageOffset, value); }
 
1181         uint16_t                encodingsCount() const                                          INLINE { return E::get16(fields.encodingsCount); }
 
1182         void                    set_encodingsCount(uint16_t value)                      INLINE { E::set16((uint16_t&)fields.encodingsCount, value); }
 
1184         typedef typename P::E           E;
 
1186         unwind_info_compressed_second_level_page_header fields;
 
1191 // compressed dyld info load command
 
1193 template <typename P>
 
1194 class macho_dyld_info_command {
 
1196         uint32_t                cmd() const                                     INLINE { return E::get32(fields.cmd); }
 
1197         void                    set_cmd(uint32_t value)         INLINE { E::set32(fields.cmd, value); }
 
1199         uint32_t                cmdsize() const                         INLINE { return E::get32(fields.cmdsize); }
 
1200         void                    set_cmdsize(uint32_t value)     INLINE { E::set32(fields.cmdsize, value); }
 
1202         uint32_t                rebase_off() const                              INLINE { return E::get32(fields.rebase_off); }
 
1203         void                    set_rebase_off(uint32_t value)  INLINE { E::set32(fields.rebase_off, value);  }
 
1205         uint32_t                rebase_size() const                             INLINE { return E::get32(fields.rebase_size); }
 
1206         void                    set_rebase_size(uint32_t value) INLINE { E::set32(fields.rebase_size, value);  }
 
1208         uint32_t                bind_off() const                                INLINE { return E::get32(fields.bind_off); }
 
1209         void                    set_bind_off(uint32_t value)    INLINE { E::set32(fields.bind_off, value);  }
 
1211         uint32_t                bind_size() const                               INLINE { return E::get32(fields.bind_size); }
 
1212         void                    set_bind_size(uint32_t value)   INLINE { E::set32(fields.bind_size, value);  }
 
1214         uint32_t                weak_bind_off() const                           INLINE { return E::get32(fields.weak_bind_off); }
 
1215         void                    set_weak_bind_off(uint32_t value)       INLINE { E::set32(fields.weak_bind_off, value);  }
 
1217         uint32_t                weak_bind_size() const                          INLINE { return E::get32(fields.weak_bind_size); }
 
1218         void                    set_weak_bind_size(uint32_t value)      INLINE { E::set32(fields.weak_bind_size, value);  }
 
1220         uint32_t                lazy_bind_off() const                           INLINE { return E::get32(fields.lazy_bind_off); }
 
1221         void                    set_lazy_bind_off(uint32_t value)       INLINE { E::set32(fields.lazy_bind_off, value);  }
 
1223         uint32_t                lazy_bind_size() const                          INLINE { return E::get32(fields.lazy_bind_size); }
 
1224         void                    set_lazy_bind_size(uint32_t value)      INLINE { E::set32(fields.lazy_bind_size, value);  }
 
1226         uint32_t                export_off() const                              INLINE { return E::get32(fields.export_off); }
 
1227         void                    set_export_off(uint32_t value)  INLINE { E::set32(fields.export_off, value);  }
 
1229         uint32_t                export_size() const                             INLINE { return E::get32(fields.export_size); }
 
1230         void                    set_export_size(uint32_t value) INLINE { E::set32(fields.export_size, value);  }
 
1233         typedef typename P::E           E;
 
1235         dyld_info_command       fields;
 
1240 // mach-o version load command
 
1242 template <typename P>
 
1243 class macho_version_min_command {
 
1245         uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
 
1246         void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
 
1248         uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
 
1249         void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
 
1251         uint32_t                version() const                                                 INLINE { return fields.version; }
 
1252         void                    set_version(uint32_t value)                             INLINE { E::set32(fields.version, value); }
 
1254         uint32_t                reserved() const                                                INLINE { return fields.reserved; }
 
1255         void                    set_reserved(uint32_t value)                    INLINE { E::set32(fields.reserved, value); }
 
1257         typedef typename P::E           E;
 
1259         version_min_command     fields;
 
1264 #endif  // __MACH_O_FILE_ABSTRACTION__