1# This file is part of PeachPy package and is licensed under the Simplified BSD license. 2# See license.rst for the full text of the license. 3 4from enum import IntEnum 5 6 7class FileType(IntEnum): 8 # No file type 9 null = 0 10 # Relocatable file 11 object = 1 12 # Executable file 13 executable = 2 14 # Fixed VM shared library (?) 15 fixed_vm_library = 3 16 # Core dump file 17 core_dump = 4 18 # Preloaded executable file 19 preloaded_executable = 5 20 # Dynamically bound shared library 21 dynamic_library = 6 22 # Dynamic linker (dyld) 23 dynamic_linker = 7 24 # Dynamically bound bundle file 25 dynamic_bundle = 8 26 # Shared library stub for build-time linking (no section content) 27 dynamic_library_stub = 9 28 # Companion file with debug sections only 29 debug_symbols = 10 30 # Kernel-mode driver 31 kext_bundle = 11 32 33 34class CpuType(IntEnum): 35 x86 = 0x00000007 36 x86_64 = 0x01000007 37 arm = 0x0000000C 38 arm64 = 0x0100000C 39 ppc = 0x00000012 40 ppc64 = 0x01000012 41 42 abi64 = 0x01000000 43 44 45class PPCCpuSubType(IntEnum): 46 all = 0 47 # PowerPC G3 48 powerpc750 = 9 49 # PowerPC G4 50 powerpc7400 = 10 51 # PowerPC G4+ 52 powerpc7450 = 11 53 # PowerPC G5 54 powerpc970 = 100 55 56 57class X86CpuSubType(IntEnum): 58 all = 3 59 60 61class ARMCpuSubType(IntEnum): 62 all = 0 63 # ARM 1176 64 v6 = 6 65 # ARM Cortex-A8 66 v7 = 9 67 # Cortex-A9 (ARMv7 + MP extension + NEON-HP, de-facto useless, removed from Clang) 68 v7f = 10 69 # Swift (ARMv7 + MP extension + VFPv4/NEONv2 + DIV) 70 v7s = 11 71 # Marvell Kirkwood (ARMv7 + XScale extension + WMMXv2 + Armada extension, no NEON) 72 v7k = 12 73 # Cyclone 74 v8 = 13 75 76 77class ARM64CpuSubType(IntEnum): 78 all = 0 79 # Cyclone 80 v8 = 1 81 82 83class MachHeader: 84 def __init__(self, abi): 85 import peachpy.x86_64 86 import peachpy.arm 87 88 self.abi = abi 89 self.size = {4: 28, 8: 32}[abi.pointer_size] 90 if abi == peachpy.x86_64.abi.system_v_x86_64_abi: 91 # 64-bit 92 self.magic = 0xFEEDFACF 93 self.cpu_type = CpuType.x86_64 94 self.cpu_subtype = X86CpuSubType.all 95 else: 96 raise ValueError("Unsupported ABI: %s" % str(abi)) 97 self.file_type = FileType.object 98 self.commands_count = 0 99 self.commands_size = 0 100 self.flags = 0 101 102 @staticmethod 103 def get_size(abi): 104 from peachpy.abi import ABI 105 assert isinstance(abi, ABI) 106 assert abi.pointer_size in [4, 8] 107 108 return {4: 24, 8: 32}[abi.pointer_size] 109 110 def encode(self, encoder): 111 bytes = encoder.uint32(self.magic) + \ 112 encoder.uint32(self.cpu_type) + \ 113 encoder.uint32(self.cpu_subtype) + \ 114 encoder.uint32(self.file_type) + \ 115 encoder.uint32(self.commands_count) + \ 116 encoder.uint32(self.commands_size) + \ 117 encoder.uint32(self.flags) 118 if self.abi.pointer_size == 8: 119 bytes += bytearray(4) 120 return bytes 121