#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
#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
//
//
// 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;
};
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:
};
+//
+// 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__