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 # Shared object file 15 dynamic_shared_object = 3 16 # Core dump file 17 core_dump = 4 18 19 20class MachineType(IntEnum): 21 # Not specified 22 unspecified = 0 23 # SPARC 24 sparc = 2 25 # IA32 (x86) 26 x86 = 3 27 # MIPS 28 mips = 8 29 # 32-bit subset of SPARC V9 30 sparc32plus = 18 31 # IBM POWER and PowerPC 32 ppc = 20 33 # IBM PowerPC 64 34 ppc64 = 21 35 # ARM 36 arm = 40 37 # SPARC V9 (64-bit) 38 sparc64 = 43 39 # IA64 (Itanium) 40 ia64 = 50 41 # x86-64 (AMD64, Intel64, x64) 42 x86_64 = 62 43 # Intel Knights Ferry 44 l1om = 180 45 # Intel Knights Corner 46 k1om = 181 47 # ARMv8 AArch64 48 arm64 = 183 49 # ATI/AMD GPU code (for any GPU arch) 50 cal = 125 51 # nVidia CUDA GPU code (for any GPU arch) 52 cuda = 190 53 # HSAIL code (32-bit ELF) 54 hsail32 = 0xAF5A 55 # HSAIL code (64-bit ELF) 56 hsail64 = 0xAF5B 57 58 59class FormatVersion(IntEnum): 60 # Invalid version 61 invalid = 0 62 # Current version 63 current = 1 64 65 66class ElfClass(IntEnum): 67 # Invalid class 68 invalid = 0 69 # 32-bit ELF 70 class32 = 1 71 # 64-bit ELF 72 class64 = 2 73 74 75class DataEncoding(IntEnum): 76 # Invalid data encoding 77 invalid = 0 78 # Least significant byte first (Little-Endian) 79 little_endian = 1 80 # Most significant byte first (Big-Endian) 81 big_endian = 2 82 83 84class OSABI(IntEnum): 85 # No extensions or unspecified 86 none = 0 87 # GNU Linux 88 gnu = 3 89 # ATI/AMD GPU ABI 90 cal = 100 91 92 93class FileIdentification: 94 def __init__(self, abi): 95 self.abi = abi 96 self.file_version = FormatVersion.current 97 98 @property 99 def as_bytearray(self): 100 identification = bytearray(16) 101 identification[0] = 0x7F 102 identification[1] = ord('E') 103 identification[2] = ord('L') 104 identification[3] = ord('F') 105 identification[4] = self.abi.elf_class 106 identification[5] = self.abi.elf_data_encoding 107 identification[6] = self.file_version 108 return identification 109 110 111class FileHeader: 112 def __init__(self, abi): 113 import peachpy.formats.elf.section 114 import peachpy.abi 115 if not isinstance(abi, peachpy.abi.ABI): 116 raise TypeError("ABI %s must be represented by an ABI object" % str(abi)) 117 if not abi.is_elf_compatible: 118 raise ValueError("ABI %s is not compatible with ELF" % str(abi)) 119 self.abi = abi 120 121 self.identification = FileIdentification(self.abi) 122 if self.abi.elf_class == ElfClass.class32: 123 # Size of ELF32 file header, in bytes 124 self.file_header_size = 52 125 # Size of program header, in bytes. All program headers have the same size. 126 self.program_header_entry_size = 32 127 # Size of a section header, in bytes. All sections have the same size. 128 self.section_header_entry_size = 40 129 else: 130 # Size of ELF64 file header, in bytes 131 self.file_header_size = 64 132 # Size of program header, in bytes. All program headers have the same size. 133 self.program_header_entry_size = 56 134 # Size of a section header, in bytes. All sections have the same size. 135 self.section_header_entry_size = 64 136 137 self.size = self.file_header_size 138 self.file_type = FileType.object 139 self.file_version = FormatVersion.current 140 self.entry_address = None 141 self.program_header_table_offset = None 142 self.section_header_table_offset = None 143 self.flags = 0 144 # Number of program headers in the program header table. 145 self.program_header_entries_count = 0 146 # Number of section headers in the section header table. 147 self.section_header_entries_count = 0 148 # Index of the section header for a section which contains section name string table. 149 # Usually this section is called ".shstrtab" 150 self.section_name_string_table_index = peachpy.formats.elf.section.SectionIndex.undefined 151 152 @property 153 def as_bytearray(self): 154 import peachpy.encoder 155 encoder = peachpy.encoder.Encoder(self.abi.endianness, self.abi.elf_bitness) 156 157 return self.identification.as_bytearray + \ 158 encoder.uint16(self.file_type) + \ 159 encoder.uint16(self.abi.elf_machine_type) + \ 160 encoder.uint32(self.file_version) + \ 161 encoder.unsigned_offset(self.entry_address or 0) + \ 162 encoder.unsigned_offset(self.program_header_table_offset or 0) + \ 163 encoder.unsigned_offset(self.section_header_table_offset or 0) + \ 164 encoder.uint32(self.flags) + \ 165 encoder.uint16(self.file_header_size) + \ 166 encoder.uint16(self.program_header_entry_size) + \ 167 encoder.uint16(self.program_header_entries_count) + \ 168 encoder.uint16(self.section_header_entry_size) + \ 169 encoder.uint16(self.section_header_entries_count) + \ 170 encoder.uint16(self.section_name_string_table_index) 171