]> git.saurik.com Git - apple/ld64.git/blobdiff - src/abstraction/MachOFileAbstraction.hpp
ld64-274.1.tar.gz
[apple/ld64.git] / src / abstraction / MachOFileAbstraction.hpp
index a9a69a7a54a7205f8af748df52af1efc914fb14d..a417877b7e7c5745cbe421a8cd16c8c1ad5b37ba 100644 (file)
 #include <mach-o/fat.h>
 #include <mach-o/stab.h>
 #include <mach-o/reloc.h>
-#include <mach-o/ppc/reloc.h>
 #include <mach-o/x86_64/reloc.h>
-#include <mach-o/arm/reloc.h>
 #include <mach-o/compact_unwind_encoding.h>
 #include <mach/machine.h>
+#include <stddef.h>
+#include <libunwind.h>
 
 #include "FileAbstraction.hpp"
 
+#include "configure.h"
 
 // stuff that will eventually go away once newer cctools headers are widespread
 #ifndef LC_LOAD_UPWARD_DYLIB
@@ -53,9 +54,7 @@
 #ifndef CPU_SUBTYPE_ARM_V7
        #define CPU_SUBTYPE_ARM_V7                      ((cpu_subtype_t) 9)
 #endif
-#ifndef ARM_THUMB_32BIT_BRANCH
-       #define ARM_THUMB_32BIT_BRANCH  7 
-#endif
+
 #ifndef N_ARM_THUMB_DEF
        #define N_ARM_THUMB_DEF 0x0008 
 #endif
        #define N_SYMBOL_RESOLVER 0x100
 #endif
 
+#ifndef N_AST
+       #define N_AST 0x32
+#endif
+
 #ifndef LC_FUNCTION_STARTS
        #define LC_FUNCTION_STARTS      0x26
 #endif
        #define LC_DYLD_ENVIRONMENT     0x27
 #endif
 
+#ifndef LC_DATA_IN_CODE
+       #define LC_DATA_IN_CODE 0x29 /* table of non-instructions in __text */
+       struct data_in_code_entry {
+               uint32_t        offset;
+               uint16_t        length;
+               uint16_t        kind;
+       };
+#endif
+
+#ifndef LC_DYLIB_CODE_SIGN_DRS
+       #define LC_DYLIB_CODE_SIGN_DRS 0x2B
+#endif
+
+#ifndef LC_ENCRYPTION_INFO_64
+       #define LC_ENCRYPTION_INFO_64 0x2C
+  struct encryption_info_command_64 {
+     uint32_t  cmd;            
+     uint32_t  cmdsize;
+     uint32_t  cryptoff;
+     uint32_t  cryptsize;
+     uint32_t  cryptid;
+     uint32_t  pad;
+  };
+#endif
+
+#ifndef MH_APP_EXTENSION_SAFE
+       #define MH_APP_EXTENSION_SAFE 0x02000000
+#endif
+
+#ifndef N_ALT_ENTRY
+       #define N_ALT_ENTRY 0x0200
+#endif
+
+#ifndef CPU_SUBTYPE_ARM_V7F
+  #define CPU_SUBTYPE_ARM_V7F    ((cpu_subtype_t) 10)
+#endif
+#ifndef CPU_SUBTYPE_ARM_V7K
+  #define CPU_SUBTYPE_ARM_V7K    ((cpu_subtype_t) 12)
+#endif
+#ifndef CPU_SUBTYPE_ARM_V7S
+  #define CPU_SUBTYPE_ARM_V7S    ((cpu_subtype_t) 11)
+#endif
+
+
+
+// hack until arm64 headers are worked out
+#ifndef CPU_TYPE_ARM64
+       #define CPU_TYPE_ARM64                  (CPU_TYPE_ARM | CPU_ARCH_ABI64)
+#endif
+#ifndef CPU_SUBTYPE_ARM64_ALL
+       #define CPU_SUBTYPE_ARM64_ALL   0
+#endif
+#ifndef CPU_SUBTYPE_ARM64_V8
+       #define CPU_SUBTYPE_ARM64_V8    1
+#endif
+
+#define ARM64_RELOC_UNSIGNED            0 // for pointers
+#define ARM64_RELOC_SUBTRACTOR          1 // must be followed by a ARM64_RELOC_UNSIGNED
+#define ARM64_RELOC_BRANCH26            2 // a B/BL instruction with 26-bit displacement
+#define ARM64_RELOC_PAGE21              3 // pc-rel distance to page of target
+#define ARM64_RELOC_PAGEOFF12           4 // offset within page, scaled by r_length
+#define ARM64_RELOC_GOT_LOAD_PAGE21     5 // pc-rel distance to page of GOT slot
+#define ARM64_RELOC_GOT_LOAD_PAGEOFF12  6 // offset within page of GOT slot, scaled by r_length
+#define ARM64_RELOC_POINTER_TO_GOT      7 // for pointers to GOT slots
+#define ARM64_RELOC_TLVP_LOAD_PAGE21    8 // pc-rel distance to page of TLVP slot
+#define ARM64_RELOC_TLVP_LOAD_PAGEOFF12 9 // offset within page of TLVP slot, scaled by r_length
+#define ARM64_RELOC_ADDEND                             10 // r_symbolnum is addend for next reloc
+
+
+
+#define UNW_ARM64_X0     0
+#define UNW_ARM64_X1     1
+#define UNW_ARM64_X2     2
+#define UNW_ARM64_X3     3
+#define UNW_ARM64_X4     4
+#define UNW_ARM64_X5     5
+#define UNW_ARM64_X6     6
+#define UNW_ARM64_X7     7
+#define UNW_ARM64_X8     8
+#define UNW_ARM64_X9     9
+#define UNW_ARM64_X10   10
+#define UNW_ARM64_X11   11
+#define UNW_ARM64_X12   12
+#define UNW_ARM64_X13   13
+#define UNW_ARM64_X14   14
+#define UNW_ARM64_X15   15
+#define UNW_ARM64_X16   16
+#define UNW_ARM64_X17   17
+#define UNW_ARM64_X18   18
+#define UNW_ARM64_X19   19
+#define UNW_ARM64_X20   20
+#define UNW_ARM64_X21   21
+#define UNW_ARM64_X22   22
+#define UNW_ARM64_X23   23
+#define UNW_ARM64_X24   24
+#define UNW_ARM64_X25   25
+#define UNW_ARM64_X26   26
+#define UNW_ARM64_X27   27
+#define UNW_ARM64_X28   28
+#define UNW_ARM64_X29   29  
+#define UNW_ARM64_FP    29
+#define UNW_ARM64_X30   30  
+#define UNW_ARM64_LR    30
+#define UNW_ARM64_X31   31  
+#define UNW_ARM64_SP    31
+#define UNW_ARM64_D0    64
+#define UNW_ARM64_D1    65
+#define UNW_ARM64_D2    66
+#define UNW_ARM64_D3    67
+#define UNW_ARM64_D4    68
+#define UNW_ARM64_D5    69
+#define UNW_ARM64_D6    70
+#define UNW_ARM64_D7    71
+#define UNW_ARM64_D8    72
+#define UNW_ARM64_D9    73
+#define UNW_ARM64_D10   74
+#define UNW_ARM64_D11   75
+#define UNW_ARM64_D12   76
+#define UNW_ARM64_D13   77
+#define UNW_ARM64_D14   78
+#define UNW_ARM64_D15   79
+#define UNW_ARM64_D16   80
+#define UNW_ARM64_D17   81
+#define UNW_ARM64_D18   82
+#define UNW_ARM64_D19   83
+#define UNW_ARM64_D20   84
+#define UNW_ARM64_D21   85
+#define UNW_ARM64_D22   86
+#define UNW_ARM64_D23   87
+#define UNW_ARM64_D24   88
+#define UNW_ARM64_D25   89
+#define UNW_ARM64_D26   90
+#define UNW_ARM64_D27   91
+#define UNW_ARM64_D28   92
+#define UNW_ARM64_D29   93
+#define UNW_ARM64_D30   94
+#define UNW_ARM64_D31   95
+
+#define UNWIND_ARM64_MODE_MASK                          0x0F000000
+#define UNWIND_ARM64_MODE_FRAME_OLD                     0x01000000
+#define UNWIND_ARM64_MODE_FRAMELESS                     0x02000000
+#define UNWIND_ARM64_MODE_DWARF                         0x03000000
+#define UNWIND_ARM64_MODE_FRAME                         0x04000000
+    
+#define UNWIND_ARM64_FRAME_X19_X20_PAIR                 0x00000001
+#define UNWIND_ARM64_FRAME_X21_X22_PAIR                 0x00000002
+#define UNWIND_ARM64_FRAME_X23_X24_PAIR                 0x00000004
+#define UNWIND_ARM64_FRAME_X25_X26_PAIR                 0x00000008
+#define UNWIND_ARM64_FRAME_X27_X28_PAIR                 0x00000010
+#define UNWIND_ARM64_FRAME_D8_D9_PAIR                   0x00000100
+#define UNWIND_ARM64_FRAME_D10_D11_PAIR                 0x00000200
+#define UNWIND_ARM64_FRAME_D12_D13_PAIR                 0x00000400
+#define UNWIND_ARM64_FRAME_D14_D15_PAIR                 0x00000800
+
+#define UNWIND_ARM64_FRAMELESS_STACK_SIZE_MASK                 0x00FFF000
+
+#define UNWIND_ARM64_FRAME_X21_X22_PAIR_OLD                 0x00000001
+#define UNWIND_ARM64_FRAME_X23_X24_PAIR_OLD                 0x00000002
+#define UNWIND_ARM64_FRAME_X25_X26_PAIR_OLD                 0x00000004
+#define UNWIND_ARM64_FRAME_X27_X28_PAIR_OLD                 0x00000008
+#define UNWIND_ARM64_FRAME_D8_D9_PAIR_OLD                   0x00000010
+#define UNWIND_ARM64_FRAME_D10_D11_PAIR_OLD                 0x00000020
+#define UNWIND_ARM64_FRAME_D12_D13_PAIR_OLD                 0x00000040
+#define UNWIND_ARM64_FRAME_D14_D15_PAIR_OLD                 0x00000080
+
+
+#define UNWIND_ARM64_DWARF_SECTION_OFFSET               0x00FFFFFF
+
+#define UNW_ARM_D31 287
+
+
+#ifndef LC_SOURCE_VERSION
+       #define LC_SOURCE_VERSION 0x2A
+       struct source_version_command {
+               uint32_t  cmd;  /* LC_SOURCE_VERSION */
+               uint32_t  cmdsize;      /* 16 */
+               uint64_t  version;      /* A.B.C.D.E packed as a24.b10.c10.d10.e10 */
+       };
+#endif
+
+#ifndef LC_MAIN
+       #define LC_MAIN (0x28|LC_REQ_DYLD) /* replacement for LC_UNIXTHREAD */
+       struct entry_point_command {
+               uint32_t  cmd;  /* LC_MAIN only used in MH_EXECUTE filetypes */
+               uint32_t  cmdsize;      /* 24 */
+               uint64_t  entryoff;     /* file (__TEXT) offset of main() */
+               uint64_t  stacksize;/* if not zero, initial stack size */
+       };
+#endif
+
+#ifndef LC_DYLIB_CODE_SIGN_DRS
+       #define LC_DYLIB_CODE_SIGN_DRS 0x2B 
+#endif 
+
+#ifndef LC_LINKER_OPTION 
+       #define LC_LINKER_OPTION   0x2D
+
+       struct linker_option_command {
+               uint32_t        cmd;      /*LC_LINKER_OPTION only used in MH_OBJECT filetypes */
+               uint32_t        cmdsize;
+               uint32_t        count;    /* number of strings */
+               /* concatenation of zero terminated UTF8 strings.  Zero filled at end to align */
+       };
+#endif
+
+#ifndef LC_LINKER_OPTIMIZATION_HINTS 
+       #define LC_LINKER_OPTIMIZATION_HINTS   0x2E
+       #define LOH_ARM64_ADRP_ADRP                             1
+       #define LOH_ARM64_ADRP_LDR                              2
+       #define LOH_ARM64_ADRP_ADD_LDR                  3
+       #define LOH_ARM64_ADRP_LDR_GOT_LDR              4
+       #define LOH_ARM64_ADRP_ADD_STR                  5
+       #define LOH_ARM64_ADRP_LDR_GOT_STR              6
+       #define LOH_ARM64_ADRP_ADD                              7
+       #define LOH_ARM64_ADRP_LDR_GOT                  8
+#endif
+
+#ifndef LC_VERSION_MIN_TVOS
+       #define LC_VERSION_MIN_TVOS                     0x2F
+#endif
+
+#ifndef LC_VERSION_MIN_WATCHOS
+       #define LC_VERSION_MIN_WATCHOS          0x30
+#endif
+
+#ifndef EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
+       #define EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE                       0x02
+#endif
+
+#ifndef CPU_SUBTYPE_ARM_V8
+       #define CPU_SUBTYPE_ARM_V8              ((cpu_subtype_t) 13) 
+#endif
+
+#ifndef CPU_SUBTYPE_ARM_V6M
+       #define CPU_SUBTYPE_ARM_V6M             ((cpu_subtype_t) 14) 
+#endif 
+
+#ifndef CPU_SUBTYPE_ARM_V7M
+       #define CPU_SUBTYPE_ARM_V7M             ((cpu_subtype_t) 15) 
+#endif 
+
+#ifndef CPU_SUBTYPE_ARM_V7EM
+       #define CPU_SUBTYPE_ARM_V7EM    ((cpu_subtype_t) 16) 
+#endif 
+
+#ifndef CPU_SUBTYPE_X86_64_H
+       #define CPU_SUBTYPE_X86_64_H    ((cpu_subtype_t) 8) 
+#endif 
+
+#define UNWIND_ARM_MODE_MASK                          0x0F000000
+#define UNWIND_ARM_MODE_FRAME                         0x01000000
+#define UNWIND_ARM_MODE_FRAME_D                       0x02000000
+#define UNWIND_ARM_MODE_DWARF                         0x04000000
+#define  UNWIND_ARM_FRAME_STACK_ADJUST_MASK           0x00C00000
+
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R4                0x00000001
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R5                0x00000002
+#define UNWIND_ARM_FRAME_FIRST_PUSH_R6                0x00000004
+  
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R8               0x00000008
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R9               0x00000010
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R10              0x00000020
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R11              0x00000040
+#define UNWIND_ARM_FRAME_SECOND_PUSH_R12              0x00000080
+#define UNWIND_ARM_FRAME_D_REG_COUNT_MASK             0x00000F00
+#define UNWIND_ARM_DWARF_SECTION_OFFSET               0x00FFFFFF
+
+
+// ( <opcode> (delta-uleb128)+ <zero> )+ <zero>
+#define DYLD_CACHE_ADJ_V1_POINTER_32           0x01
+#define DYLD_CACHE_ADJ_V1_POINTER_64           0x02
+#define DYLD_CACHE_ADJ_V1_ADRP                         0x03
+#define DYLD_CACHE_ADJ_V1_ARM_THUMB_MOVT       0x10 // thru 0x1F
+#define DYLD_CACHE_ADJ_V1_ARM_MOVT                     0x20 // thru 0x2F
+
+
+// Whole                :== <new-marker> <count> FromToSection+
+// FromToSection :== <from-sect-index> <to-sect-index> <count> ToOffset+
+// ToOffset             :== <to-sect-offset-delta> <count> FromOffset+
+// FromOffset   :== <kind> <count> <from-sect-offset-delta>
+#define DYLD_CACHE_ADJ_V2_FORMAT                               0x7F
+
+#define DYLD_CACHE_ADJ_V2_POINTER_32                   0x01
+#define DYLD_CACHE_ADJ_V2_POINTER_64                   0x02
+#define DYLD_CACHE_ADJ_V2_DELTA_32                         0x03
+#define DYLD_CACHE_ADJ_V2_DELTA_64                         0x04
+#define DYLD_CACHE_ADJ_V2_ARM64_ADRP                   0x05
+#define DYLD_CACHE_ADJ_V2_ARM64_OFF12                  0x06
+#define DYLD_CACHE_ADJ_V2_ARM64_BR26                   0x07
+#define DYLD_CACHE_ADJ_V2_ARM_MOVW_MOVT                        0x08
+#define DYLD_CACHE_ADJ_V2_ARM_BR24                             0x09
+#define DYLD_CACHE_ADJ_V2_THUMB_MOVW_MOVT              0x0A
+#define DYLD_CACHE_ADJ_V2_THUMB_BR22                   0x0B
+#define DYLD_CACHE_ADJ_V2_IMAGE_OFF_32                 0x0C
+
+
+
+// kind target-address fixup-addr [adj] 
+
+
+
+struct ArchInfo {
+       const char*                     archName;
+       cpu_type_t                      cpuType;
+       cpu_subtype_t           cpuSubType;
+       const char*                     llvmTriplePrefix;
+       const char*                     llvmTriplePrefixAlt;
+       bool                            isSubType;
+       bool                            supportsThumb2;
+};
+
+static const ArchInfo archInfoArray[] = {
+#if SUPPORT_ARCH_x86_64
+       { "x86_64", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL, "x86_64-",  "", true, false },
+#endif
+#if SUPPORT_ARCH_x86_64h
+       { "x86_64h", CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_H,      "x86_64h-",  "", true, false },
+#endif
+#if SUPPORT_ARCH_i386
+       { "i386",   CPU_TYPE_I386,   CPU_SUBTYPE_I386_ALL,   "i386-",    "", false, false },
+#endif
+#if SUPPORT_ARCH_armv4t
+       { "armv4t", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V4T,    "armv4t-",  "", true,  false },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv5
+       { "armv5", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V5TEJ,  "armv5e-",  "", true,  false },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv6
+       { "armv6", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V6,     "armv6-",   "", true,  false },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv7
+       { "armv7", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V7,     "thumbv7-", "armv7-", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv7f
+       { "armv7f", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V7F,    "thumbv7f-", "", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif 
+#if SUPPORT_ARCH_armv7k
+       { "armv7k", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V7K,    "thumbv7k-", "", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv7s
+       { "armv7s", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V7S,    "thumbv7s-", "armv7s", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv6m
+       { "armv6m", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V6M,    "thumbv6m-", "", true,  false },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv7m
+       { "armv7m", CPU_TYPE_ARM,    CPU_SUBTYPE_ARM_V7M,    "thumbv7m-", "armv7m", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv7em
+       { "armv7em", CPU_TYPE_ARM,   CPU_SUBTYPE_ARM_V7EM,   "thumbv7em-", "armv7em", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_armv8
+       { "armv8", CPU_TYPE_ARM,     CPU_SUBTYPE_ARM_V8,     "thumbv8-", "armv8", true,  true },
+       #define SUPPORT_ARCH_arm_any 1
+#endif
+#if SUPPORT_ARCH_arm64
+       { "arm64", CPU_TYPE_ARM64,   CPU_SUBTYPE_ARM64_ALL,  "arm64-",  "aarch64-",  false,  false },
+#endif
+#if SUPPORT_ARCH_arm64v8
+       { "arm64v8", CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_V8,   "arm64v8-",  "aarch64-",   true,  false },
+#endif
+       { NULL, 0, 0, NULL, NULL, false, false }
+};
+
+// weird, but this include must wait until after SUPPORT_ARCH_arm_any is set up
+#if SUPPORT_ARCH_arm_any
+#include <mach-o/arm/reloc.h>
+#endif
+
 // hack until newer <mach-o/arm/reloc.h> everywhere
 #define ARM_RELOC_HALF 8
 #define ARM_RELOC_HALF_SECTDIFF 9
 
 
+
 //
 // This abstraction layer makes every mach-o file look like a 64-bit mach-o file with native endianness
 //
@@ -1024,27 +1411,37 @@ private:
 //
 // mach-o encyrption info load command
 //
+template <typename P> struct macho_encryption_info_content {};
+template <> struct macho_encryption_info_content<Pointer32<BigEndian> >    { struct encryption_info_command            fields; };
+template <> struct macho_encryption_info_content<Pointer64<BigEndian> >           { struct encryption_info_command_64  fields; };
+template <> struct macho_encryption_info_content<Pointer32<LittleEndian> > { struct encryption_info_command            fields; };
+template <> struct macho_encryption_info_content<Pointer64<LittleEndian> > { struct encryption_info_command_64 fields; };
+
+
 template <typename P>
 class macho_encryption_info_command {
 public:
-       uint32_t                cmd() const                                             INLINE { return E::get32(fields.cmd); }
-       void                    set_cmd(uint32_t value)                 INLINE { E::set32(fields.cmd, value); }
+       uint32_t                cmd() const                                             INLINE { return E::get32(entry.fields.cmd); }
+       void                    set_cmd(uint32_t value)                 INLINE { E::set32(entry.fields.cmd, value); }
 
-       uint32_t                cmdsize() const                                 INLINE { return E::get32(fields.cmdsize); }
-       void                    set_cmdsize(uint32_t value)             INLINE { E::set32(fields.cmdsize, value); }
+       uint32_t                cmdsize() const                                 INLINE { return E::get32(entry.fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)             INLINE { E::set32(entry.fields.cmdsize, value); }
 
-       uint32_t                cryptoff() const                                INLINE { return E::get32(fields.cryptoff); }
-       void                    set_cryptoff(uint32_t value)    INLINE { E::set32(fields.cryptoff, value);  }
+       uint32_t                cryptoff() const                                INLINE { return E::get32(entry.fields.cryptoff); }
+       void                    set_cryptoff(uint32_t value)    INLINE { E::set32(entry.fields.cryptoff, value);  }
        
-       uint32_t                cryptsize() const                               INLINE { return E::get32(fields.cryptsize); }
-       void                    set_cryptsize(uint32_t value)   INLINE { E::set32(fields.cryptsize, value);  }
+       uint32_t                cryptsize() const                               INLINE { return E::get32(entry.fields.cryptsize); }
+       void                    set_cryptsize(uint32_t value)   INLINE { E::set32(entry.fields.cryptsize, value);  }
        
-       uint32_t                cryptid() const                                 INLINE { return E::get32(fields.cryptid); }
-       void                    set_cryptid(uint32_t value)             INLINE { E::set32(fields.cryptid, value);  }
+       uint32_t                cryptid() const                                 INLINE { return E::get32(entry.fields.cryptid); }
+       void                    set_cryptid(uint32_t value)             INLINE { E::set32(entry.fields.cryptid, value);  }
        
+       uint32_t                pad() const                                             INLINE { return E::get32(entry.fields.pad); }
+       void                    set_pad(uint32_t value)                 INLINE { E::set32(entry.fields.pad, value);  }
+
        typedef typename P::E           E;
 private:
-       encryption_info_command fields;
+       macho_encryption_info_content<P>        entry;
 };
 
 
@@ -1251,8 +1648,13 @@ public:
        uint32_t                version() const                                                 INLINE { return fields.version; }
        void                    set_version(uint32_t value)                             INLINE { E::set32(fields.version, value); }
 
-       uint32_t                reserved() const                                                INLINE { return fields.reserved; }
-       void                    set_reserved(uint32_t value)                    INLINE { E::set32(fields.reserved, value); }
+#ifdef DICE_KIND_DATA
+       uint32_t                sdk() const                                                             INLINE { return fields.sdk; }
+       void                    set_sdk(uint32_t value)                                 INLINE { E::set32(fields.sdk, value); }
+#else
+       uint32_t                sdk() const                                                             INLINE { return fields.reserved; }
+       void                    set_sdk(uint32_t value)                                 INLINE { E::set32(fields.reserved, value); }
+#endif
 
        typedef typename P::E           E;
 private:
@@ -1260,6 +1662,137 @@ private:
 };
 
 
+//
+// mach-o __LD, __compact_unwind section in object files
+//
+template <typename P>
+class macho_compact_unwind_entry {
+public:
+       typedef typename P::E           E;
+       typedef typename P::uint_t      pint_t;
+
+       pint_t                  codeStart() const                                               INLINE { return P::getP(_codeStart); }
+       void                    set_codeStart(pint_t value)                             INLINE { P::setP(_codeStart, value); }
+
+       uint32_t                codeLen() const                                                 INLINE { return E::get32(_codeLen); }
+       void                    set_codeLen(uint32_t value)                             INLINE { E::set32(_codeLen, value); }
+
+       uint32_t                compactUnwindInfo() const                               INLINE { return E::get32(_compactUnwindInfo); }
+       void                    set_compactUnwindInfo(uint32_t value)   INLINE { E::set32(_compactUnwindInfo, value);  }
+       
+       pint_t                  personality() const                                             INLINE { return P::getP(_personality); }
+       void                    set_personality(pint_t value)                   INLINE { P::setP(_personality, value);  }
+       
+       pint_t                  lsda() const                                                    INLINE { return P::getP(_lsda); }
+       void                    set_lsda(pint_t value)                                  INLINE { P::setP(_lsda, value);  }
+       
+       static uint32_t codeStartFieldOffset()                                  INLINE { return offsetof(macho_compact_unwind_entry<P>,_codeStart); }
+       static uint32_t personalityFieldOffset()                                INLINE { return offsetof(macho_compact_unwind_entry<P>,_personality); }
+       static uint32_t lsdaFieldOffset()                                               INLINE { return offsetof(macho_compact_unwind_entry<P>,_lsda); }
+       
+private:
+       pint_t          _codeStart;
+       uint32_t        _codeLen;
+       uint32_t        _compactUnwindInfo;
+       pint_t          _personality;
+       pint_t          _lsda;
+};
+
+
+//
+// mach-o source version load command
+//
+template <typename P>
+class macho_source_version_command {
+public:
+       uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
+       void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
+
+       uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
+
+       uint64_t                version() const                                                 INLINE { return fields.version; }
+       void                    set_version(uint64_t value)                             INLINE { E::set64(fields.version, value); }
+
+       typedef typename P::E           E;
+private:
+       source_version_command  fields;
+};
+
+
+//
+// mach-o source version load command
+//
+template <typename P>
+class macho_entry_point_command {
+public:
+       uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
+       void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
+
+       uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
+
+       uint64_t                entryoff() const                                                INLINE { return fields.entryoff; }
+       void                    set_entryoff(uint64_t value)                    INLINE { E::set64(fields.entryoff, value); }
+
+       uint64_t                stacksize() const                                               INLINE { return fields.stacksize; }
+       void                    set_stacksize(uint64_t value)                   INLINE { E::set64(fields.stacksize, value); }
+
+       typedef typename P::E           E;
+private:
+       entry_point_command     fields;
+};
+
+
+
+template <typename P>
+class macho_data_in_code_entry {
+public:
+       uint32_t                offset() const                                                          INLINE { return E::get32(fields.offset); }
+       void                    set_offset(uint32_t value)                                      INLINE { E::set32(fields.offset, value); }
+
+       uint16_t                length() const                                                          INLINE { return E::get16(fields.length); }
+       void                    set_length(uint16_t value)                                      INLINE { E::set16((uint16_t&)fields.length, value); }
+
+       uint16_t                kind() const                                                            INLINE { return E::get16(fields.kind); }
+       void                    set_kind(uint16_t value)                                        INLINE { E::set16((uint16_t&)fields.kind, value); }
+
+       typedef typename P::E           E;
+private:
+       data_in_code_entry      fields;
+};
+
+#ifndef DICE_KIND_DATA
+  #define DICE_KIND_DATA              0x0001 
+  #define DICE_KIND_JUMP_TABLE8       0x0002 
+  #define DICE_KIND_JUMP_TABLE16      0x0003 
+  #define DICE_KIND_JUMP_TABLE32      0x0004 
+  #define DICE_KIND_ABS_JUMP_TABLE32  0x0005 
+#endif
+
+template <typename P>
+class macho_linker_option_command {
+public:
+       uint32_t                cmd() const                                                             INLINE { return E::get32(fields.cmd); }
+       void                    set_cmd(uint32_t value)                                 INLINE { E::set32(fields.cmd, value); }
+
+       uint32_t                cmdsize() const                                                 INLINE { return E::get32(fields.cmdsize); }
+       void                    set_cmdsize(uint32_t value)                             INLINE { E::set32(fields.cmdsize, value); }
+
+       uint64_t                count() const                                                   INLINE { return fields.count; }
+       void                    set_count(uint32_t value)                               INLINE { E::set32(fields.count, value); }
+
+       const char*             buffer() const                                                  INLINE { return ((char*)&fields) + sizeof(linker_option_command); }
+       char*                   buffer()                                                                INLINE { return ((char*)&fields) + sizeof(linker_option_command); }
+
+       typedef typename P::E           E;
+private:
+       linker_option_command   fields;
+};
+
+
+
+
 
 #endif // __MACH_O_FILE_ABSTRACTION__