File: file.py

package info (click to toggle)
python-peachpy 0.0~git20211013.257881e-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 2,452 kB
  • sloc: python: 29,286; ansic: 54; makefile: 44; cpp: 31
file content (172 lines) | stat: -rw-r--r-- 5,313 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# This file is part of PeachPy package and is licensed under the Simplified BSD license.
#    See license.rst for the full text of the license.

from enum import IntEnum


class FileType(IntEnum):
    # No file type
    null = 0
    # Relocatable file
    object = 1
    # Executable file
    executable = 2
    # Shared object file
    dynamic_shared_object = 3
    # Core dump file
    core_dump = 4


class MachineType(IntEnum):
    # Not specified
    unspecified = 0
    # SPARC
    sparc = 2
    # IA32 (x86)
    x86 = 3
    # MIPS
    mips = 8
    # 32-bit subset of SPARC V9
    sparc32plus = 18
    # IBM POWER and PowerPC
    ppc = 20
    # IBM PowerPC 64
    ppc64 = 21
    # ARM
    arm = 40
    # SPARC V9 (64-bit)
    sparc64 = 43
    # IA64 (Itanium)
    ia64 = 50
    # x86-64 (AMD64, Intel64, x64)
    x86_64 = 62
    # Intel Knights Ferry
    l1om = 180
    # Intel Knights Corner
    k1om = 181
    # ARMv8 AArch64
    arm64 = 183
    # ATI/AMD GPU code (for any GPU arch)
    cal = 125
    # nVidia CUDA GPU code (for any GPU arch)
    cuda = 190
    # HSAIL code (32-bit ELF)
    hsail32 = 0xAF5A
    # HSAIL code (64-bit ELF)
    hsail64 = 0xAF5B


class FormatVersion(IntEnum):
    # Invalid version
    invalid = 0
    # Current version
    current = 1


class ElfClass(IntEnum):
    # Invalid class
    invalid = 0
    # 32-bit ELF
    class32 = 1
    # 64-bit ELF
    class64 = 2


class DataEncoding(IntEnum):
    # Invalid data encoding
    invalid = 0
    # Least significant byte first (Little-Endian)
    little_endian = 1
    # Most significant byte first (Big-Endian)
    big_endian = 2


class OSABI(IntEnum):
    # No extensions or unspecified
    none = 0
    # GNU Linux
    gnu = 3
    # FreeBSD
    freebsd = 9
    # ATI/AMD GPU ABI
    cal = 100


class FileIdentification:
    def __init__(self, abi):
        self.abi = abi
        self.file_version = FormatVersion.current

    @property
    def as_bytearray(self):
        identification = bytearray(16)
        identification[0] = 0x7F
        identification[1] = ord('E')
        identification[2] = ord('L')
        identification[3] = ord('F')
        identification[4] = self.abi.elf_class
        identification[5] = self.abi.elf_data_encoding
        identification[6] = self.file_version
        return identification


class FileHeader:
    def __init__(self, abi):
        import peachpy.formats.elf.section
        import peachpy.abi
        if not isinstance(abi, peachpy.abi.ABI):
            raise TypeError("ABI %s must be represented by an ABI object" % str(abi))
        if not abi.is_elf_compatible:
            raise ValueError("ABI %s is not compatible with ELF" % str(abi))
        self.abi = abi

        self.identification = FileIdentification(self.abi)
        if self.abi.elf_class == ElfClass.class32:
            # Size of ELF32 file header, in bytes
            self.file_header_size = 52
            # Size of program header, in bytes. All program headers have the same size.
            self.program_header_entry_size = 32
            # Size of a section header, in bytes. All sections have the same size.
            self.section_header_entry_size = 40
        else:
            # Size of ELF64 file header, in bytes
            self.file_header_size = 64
            # Size of program header, in bytes. All program headers have the same size.
            self.program_header_entry_size = 56
            # Size of a section header, in bytes. All sections have the same size.
            self.section_header_entry_size = 64

        self.size = self.file_header_size
        self.file_type = FileType.object
        self.file_version = FormatVersion.current
        self.entry_address = None
        self.program_header_table_offset = None
        self.section_header_table_offset = None
        self.flags = 0
        # Number of program headers in the program header table.
        self.program_header_entries_count = 0
        # Number of section headers in the section header table.
        self.section_header_entries_count = 0
        # Index of the section header for a section which contains section name string table.
        # Usually this section is called ".shstrtab"
        self.section_name_string_table_index = peachpy.formats.elf.section.SectionIndex.undefined

    @property
    def as_bytearray(self):
        import peachpy.encoder
        encoder = peachpy.encoder.Encoder(self.abi.endianness, self.abi.elf_bitness)

        return self.identification.as_bytearray + \
            encoder.uint16(self.file_type) + \
            encoder.uint16(self.abi.elf_machine_type) + \
            encoder.uint32(self.file_version) + \
            encoder.unsigned_offset(self.entry_address or 0) + \
            encoder.unsigned_offset(self.program_header_table_offset or 0) + \
            encoder.unsigned_offset(self.section_header_table_offset or 0) + \
            encoder.uint32(self.flags) + \
            encoder.uint16(self.file_header_size) + \
            encoder.uint16(self.program_header_entry_size) + \
            encoder.uint16(self.program_header_entries_count) + \
            encoder.uint16(self.section_header_entry_size) + \
            encoder.uint16(self.section_header_entries_count) + \
            encoder.uint16(self.section_name_string_table_index)