X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/a645023da60d22e86be13f7b4d97adeff8bc6665..ec29ba20dfd4abc0cb74366b39dda06af136e073:/src/abstraction/MachOFileAbstraction.hpp?ds=sidebyside diff --git a/src/abstraction/MachOFileAbstraction.hpp b/src/abstraction/MachOFileAbstraction.hpp index a9a69a7..cfedc81 100644 --- a/src/abstraction/MachOFileAbstraction.hpp +++ b/src/abstraction/MachOFileAbstraction.hpp @@ -30,14 +30,15 @@ #include #include #include -#include #include -#include #include #include +#include +#include #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 @@ -193,6 +192,10 @@ #define N_SYMBOL_RESOLVER 0x100 #endif +#ifndef N_AST + #define N_AST 0x32 +#endif + #ifndef LC_FUNCTION_STARTS #define LC_FUNCTION_STARTS 0x26 #endif @@ -205,11 +208,396 @@ #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 + + +// ( (delta-uleb128)+ )+ +#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 :== FromToSection+ +// FromToSection :== ToOffset+ +// ToOffset :== FromOffset+ +// FromOffset :== +#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 +#endif + // hack until newer 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 +1412,37 @@ private: // // mach-o encyrption info load command // +template struct macho_encryption_info_content {}; +template <> struct macho_encryption_info_content > { struct encryption_info_command fields; }; +template <> struct macho_encryption_info_content > { struct encryption_info_command_64 fields; }; +template <> struct macho_encryption_info_content > { struct encryption_info_command fields; }; +template <> struct macho_encryption_info_content > { struct encryption_info_command_64 fields; }; + + template 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

entry; }; @@ -1251,8 +1649,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 +1663,137 @@ private: }; +// +// mach-o __LD, __compact_unwind section in object files +// +template +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

,_codeStart); } + static uint32_t personalityFieldOffset() INLINE { return offsetof(macho_compact_unwind_entry

,_personality); } + static uint32_t lsdaFieldOffset() INLINE { return offsetof(macho_compact_unwind_entry

,_lsda); } + +private: + pint_t _codeStart; + uint32_t _codeLen; + uint32_t _compactUnwindInfo; + pint_t _personality; + pint_t _lsda; +}; + + +// +// mach-o source version load command +// +template +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 +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 +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 +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__