PyNerva 0.0.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nervapy/__init__.py +50 -0
- nervapy/abi.py +91 -0
- nervapy/arm/__init__.py +124 -0
- nervapy/arm/__main__.py +0 -0
- nervapy/arm/abi.py +138 -0
- nervapy/arm/formats.py +49 -0
- nervapy/arm/function.py +2465 -0
- nervapy/arm/generic.py +10796 -0
- nervapy/arm/instructions.py +519 -0
- nervapy/arm/isa.py +409 -0
- nervapy/arm/literal_pool.py +331 -0
- nervapy/arm/microarchitecture.py +211 -0
- nervapy/arm/pseudo.py +652 -0
- nervapy/arm/registers.py +1458 -0
- nervapy/arm/vfpneon.py +4092 -0
- nervapy/arm.py +13 -0
- nervapy/c/__init__.py +1 -0
- nervapy/c/types.py +436 -0
- nervapy/codegen.py +99 -0
- nervapy/common/__init__.py +4 -0
- nervapy/common/function.py +5 -0
- nervapy/common/regalloc.py +121 -0
- nervapy/constant_data.py +282 -0
- nervapy/encoder.py +246 -0
- nervapy/formats/__init__.py +2 -0
- nervapy/formats/elf/__init__.py +4 -0
- nervapy/formats/elf/file.py +178 -0
- nervapy/formats/elf/image.py +106 -0
- nervapy/formats/elf/section.py +422 -0
- nervapy/formats/elf/symbol.py +281 -0
- nervapy/formats/macho/__init__.py +2 -0
- nervapy/formats/macho/file.py +123 -0
- nervapy/formats/macho/image.py +143 -0
- nervapy/formats/macho/section.py +322 -0
- nervapy/formats/macho/symbol.py +158 -0
- nervapy/formats/mscoff/__init__.py +8 -0
- nervapy/formats/mscoff/image.py +132 -0
- nervapy/formats/mscoff/section.py +181 -0
- nervapy/formats/mscoff/symbol.py +148 -0
- nervapy/function.py +136 -0
- nervapy/literal.py +731 -0
- nervapy/loader.py +188 -0
- nervapy/name.py +159 -0
- nervapy/parse.py +52 -0
- nervapy/stream.py +58 -0
- nervapy/util.py +126 -0
- nervapy/writer.py +518 -0
- nervapy/x86_64/__init__.py +324 -0
- nervapy/x86_64/__main__.py +407 -0
- nervapy/x86_64/abi.py +517 -0
- nervapy/x86_64/amd.py +6464 -0
- nervapy/x86_64/avx.py +102029 -0
- nervapy/x86_64/crypto.py +1533 -0
- nervapy/x86_64/encoding.py +424 -0
- nervapy/x86_64/fma.py +19138 -0
- nervapy/x86_64/function.py +2707 -0
- nervapy/x86_64/generic.py +23384 -0
- nervapy/x86_64/instructions.py +500 -0
- nervapy/x86_64/isa.py +476 -0
- nervapy/x86_64/lower.py +126 -0
- nervapy/x86_64/mask.py +2593 -0
- nervapy/x86_64/meta.py +143 -0
- nervapy/x86_64/mmxsse.py +17265 -0
- nervapy/x86_64/nacl.py +327 -0
- nervapy/x86_64/operand.py +1204 -0
- nervapy/x86_64/options.py +21 -0
- nervapy/x86_64/pseudo.py +686 -0
- nervapy/x86_64/registers.py +1225 -0
- nervapy/x86_64/types.py +17 -0
- nervapy/x86_64/uarch.py +580 -0
- pynerva-0.0.7.dist-info/METADATA +310 -0
- pynerva-0.0.7.dist-info/RECORD +74 -0
- pynerva-0.0.7.dist-info/WHEEL +4 -0
- pynerva-0.0.7.dist-info/licenses/LICENSE.rst +15 -0
|
@@ -0,0 +1,281 @@
|
|
|
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
|
+
|
|
4
|
+
from enum import IntEnum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class SymbolBinding(IntEnum):
|
|
8
|
+
local = 0
|
|
9
|
+
global_ = 1
|
|
10
|
+
weak = 2
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SymbolType:
|
|
14
|
+
# No type specified (e.g. an absolute symbol)
|
|
15
|
+
unspecified = 0
|
|
16
|
+
# Data object
|
|
17
|
+
data_object = 1
|
|
18
|
+
# Function entry point
|
|
19
|
+
function = 2
|
|
20
|
+
# Symbol associated with a section
|
|
21
|
+
section = 3
|
|
22
|
+
# Source file associated with the object file
|
|
23
|
+
file = 4
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class Symbol:
|
|
27
|
+
def __init__(self):
|
|
28
|
+
# Symbol name
|
|
29
|
+
self.name = None
|
|
30
|
+
# Value of the symbol (typically offset from the section)
|
|
31
|
+
self.value = None
|
|
32
|
+
# Size of the data object (0 if size is unknown or meaningless)
|
|
33
|
+
self.size = 0
|
|
34
|
+
# Binding attribute
|
|
35
|
+
self.binding = 0
|
|
36
|
+
# Type attribute
|
|
37
|
+
self.type = 0
|
|
38
|
+
# The relevant section in the section header table
|
|
39
|
+
self.section = None
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def get_entry_size(abi):
|
|
43
|
+
from nervapy.abi import ABI
|
|
44
|
+
|
|
45
|
+
assert isinstance(abi, ABI)
|
|
46
|
+
assert abi.elf_bitness in [32, 64]
|
|
47
|
+
|
|
48
|
+
return {32: 16, 64: 24}[abi.elf_bitness]
|
|
49
|
+
|
|
50
|
+
def encode(self, encoder, name_index_map, section_index_map):
|
|
51
|
+
import nervapy.encoder
|
|
52
|
+
|
|
53
|
+
assert isinstance(encoder, nervapy.encoder.Encoder)
|
|
54
|
+
assert encoder.bitness in [32, 64]
|
|
55
|
+
assert self.name in name_index_map
|
|
56
|
+
from nervapy.formats.elf.section import SectionIndex
|
|
57
|
+
|
|
58
|
+
assert (
|
|
59
|
+
self.section is None
|
|
60
|
+
or isinstance(self.section, SectionIndex)
|
|
61
|
+
or self.section in section_index_map
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
name_index = name_index_map[self.name]
|
|
65
|
+
section_index = SectionIndex.absolute
|
|
66
|
+
if self.section is not None:
|
|
67
|
+
if isinstance(self.section, SectionIndex):
|
|
68
|
+
section_index = self.section
|
|
69
|
+
else:
|
|
70
|
+
section_index = section_index_map[self.section]
|
|
71
|
+
if encoder.bitness == 32:
|
|
72
|
+
return (
|
|
73
|
+
encoder.uint32(name_index)
|
|
74
|
+
+ encoder.uint32(self.value)
|
|
75
|
+
+ encoder.uint32(self.size)
|
|
76
|
+
+ encoder.uint8((self.binding << 4) | (self.type & 0xF))
|
|
77
|
+
+ encoder.uint8(0)
|
|
78
|
+
+ encoder.uint16(section_index)
|
|
79
|
+
)
|
|
80
|
+
else:
|
|
81
|
+
return (
|
|
82
|
+
encoder.uint32(name_index)
|
|
83
|
+
+ encoder.uint8((self.binding << 4) | (self.type & 0xF))
|
|
84
|
+
+ encoder.uint8(0)
|
|
85
|
+
+ encoder.uint16(section_index)
|
|
86
|
+
+ encoder.uint64(self.value)
|
|
87
|
+
+ encoder.uint64(self.size)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class RelocationType(IntEnum):
|
|
92
|
+
x86_32 = 1
|
|
93
|
+
x86_pc32 = 2
|
|
94
|
+
x86_got32 = 3
|
|
95
|
+
x86_plt32 = 4
|
|
96
|
+
x86_copy = 5
|
|
97
|
+
x86_glob_dat = 6
|
|
98
|
+
x86_jmp_slot = 7
|
|
99
|
+
x86_relative = 8
|
|
100
|
+
x86_gotoff = 9
|
|
101
|
+
x86_gotpc = 10
|
|
102
|
+
|
|
103
|
+
x86_64_64 = 1
|
|
104
|
+
x86_64_pc32 = 2
|
|
105
|
+
x86_64_got32 = 3
|
|
106
|
+
x86_64_plt32 = 4
|
|
107
|
+
x86_64_copy = 5
|
|
108
|
+
x86_64_glob_dat = 6
|
|
109
|
+
x86_64_jump_slot = 7
|
|
110
|
+
x86_64_relative = 8
|
|
111
|
+
x86_64_gotpcrel = 9
|
|
112
|
+
x86_64_32 = 10
|
|
113
|
+
x86_64_32s = 11
|
|
114
|
+
x86_64_16 = 12
|
|
115
|
+
x86_64_pc16 = 13
|
|
116
|
+
x86_64_8 = 14
|
|
117
|
+
x86_64_pc8 = 15
|
|
118
|
+
x86_64_dtpmod64 = 16
|
|
119
|
+
x86_64_dtpoff64 = 17
|
|
120
|
+
x86_64_tpoff64 = 18
|
|
121
|
+
x86_64_tlsgd = 19
|
|
122
|
+
x86_64_tlsld = 20
|
|
123
|
+
x86_64_dtpoff32 = 21
|
|
124
|
+
x86_64_gottpoff = 22
|
|
125
|
+
x86_64_tpoff32 = 23
|
|
126
|
+
x86_64_pc64 = 24
|
|
127
|
+
x86_64_gotoff64 = 25
|
|
128
|
+
x86_64_gotpc32 = 26
|
|
129
|
+
x86_64_got64 = 27
|
|
130
|
+
x86_64_gotpcrel64 = 28
|
|
131
|
+
x86_64_gotpc64 = 29
|
|
132
|
+
x86_64_gotplt64 = 30
|
|
133
|
+
x86_64_pltoff64 = 31
|
|
134
|
+
x86_64_size32 = 32
|
|
135
|
+
x86_64_size64 = 33
|
|
136
|
+
x86_64_gotpc32_tlsdesc = 34
|
|
137
|
+
x86_64_tlsdesc_call = 35
|
|
138
|
+
x86_64_tlsdesc = 36
|
|
139
|
+
x86_64_irelative = 37
|
|
140
|
+
|
|
141
|
+
arm_abs32 = 2
|
|
142
|
+
arm_rel32 = 3
|
|
143
|
+
arm_ldr_pc_g0 = 4
|
|
144
|
+
arm_abs16 = 5
|
|
145
|
+
arm_abs12 = 6
|
|
146
|
+
arm_thm_abs5 = 7
|
|
147
|
+
arm_abs8 = 8
|
|
148
|
+
arm_sbrel32 = 9
|
|
149
|
+
arm_thm_call = 10
|
|
150
|
+
arm_thm_pc8 = 11
|
|
151
|
+
arm_brel_adj = 12
|
|
152
|
+
arm_tls_desc = 13
|
|
153
|
+
arm_tls_dtpmod32 = 17
|
|
154
|
+
arm_tls_dtpoff32 = 18
|
|
155
|
+
arm_tls_tpoff32 = 19
|
|
156
|
+
arm_copy = 20
|
|
157
|
+
arm_glob_dat = 21
|
|
158
|
+
arm_jump_slot = 22
|
|
159
|
+
arm_relative = 23
|
|
160
|
+
arm_gotoff32 = 24
|
|
161
|
+
arm_base_prel = 25
|
|
162
|
+
arm_got_brel = 26
|
|
163
|
+
arm_plt32 = 27
|
|
164
|
+
arm_call = 28
|
|
165
|
+
arm_jump24 = 29
|
|
166
|
+
arm_thm_jump24 = 30
|
|
167
|
+
arm_base_abs = 31
|
|
168
|
+
arm_target1 = 38
|
|
169
|
+
arm_v4bx = 40
|
|
170
|
+
arm_target2 = 41
|
|
171
|
+
arm_prel31 = 42
|
|
172
|
+
arm_movw_abs_nc = 43
|
|
173
|
+
arm_movt_abs = 44
|
|
174
|
+
arm_movw_prel_nc = 45
|
|
175
|
+
arm_movt_prel = 46
|
|
176
|
+
arm_thm_movw_abs_nc = 47
|
|
177
|
+
arm_thm_movt_abs = 48
|
|
178
|
+
arm_thm_movw_prel_nc = 49
|
|
179
|
+
arm_thm_movt_prel = 50
|
|
180
|
+
arm_thm_jump19 = 51
|
|
181
|
+
arm_thm_jump6 = 52
|
|
182
|
+
arm_thm_alu_prel_11_0 = 53
|
|
183
|
+
arm_thm_pc12 = 54
|
|
184
|
+
arm_abs32_noi = 55
|
|
185
|
+
arm_rel32_noi = 56
|
|
186
|
+
arm_alu_pc_g0_nc = 57
|
|
187
|
+
arm_alu_pc_g0 = 58
|
|
188
|
+
arm_alu_pc_g1_nc = 59
|
|
189
|
+
arm_alu_pc_g1 = 60
|
|
190
|
+
arm_alu_pc_g2 = 61
|
|
191
|
+
arm_ldr_pc_g1 = 62
|
|
192
|
+
arm_ldr_pc_g2 = 63
|
|
193
|
+
arm_ldrs_pc_g0 = 64
|
|
194
|
+
arm_ldrs_pc_g1 = 65
|
|
195
|
+
arm_ldrs_pc_g2 = 66
|
|
196
|
+
arm_ldc_pc_g0 = 67
|
|
197
|
+
arm_ldc_pc_g1 = 68
|
|
198
|
+
arm_ldc_pc_g2 = 69
|
|
199
|
+
arm_alu_sb_g0_nc = 70
|
|
200
|
+
arm_alu_sb_g0 = 71
|
|
201
|
+
arm_alu_sb_g1_nc = 72
|
|
202
|
+
arm_alu_sb_g1 = 73
|
|
203
|
+
arm_alu_sb_g2 = 74
|
|
204
|
+
arm_ldr_sb_g0 = 75
|
|
205
|
+
arm_ldr_sb_g1 = 76
|
|
206
|
+
arm_ldr_sb_g2 = 77
|
|
207
|
+
arm_ldrs_sb_g0 = 78
|
|
208
|
+
arm_ldrs_sb_g1 = 79
|
|
209
|
+
arm_ldrs_sb_g2 = 80
|
|
210
|
+
arm_ldc_sb_g0 = 81
|
|
211
|
+
arm_ldc_sb_g1 = 82
|
|
212
|
+
arm_ldc_sb_g2 = 83
|
|
213
|
+
arm_movw_brel_nc = 84
|
|
214
|
+
arm_movt_brel = 85
|
|
215
|
+
arm_movw_brel = 86
|
|
216
|
+
arm_thm_movw_brel_nc = 87
|
|
217
|
+
arm_thm_movt_brel = 88
|
|
218
|
+
arm_thm_movw_brel = 89
|
|
219
|
+
arm_tls_gotdesc = 90
|
|
220
|
+
arm_tls_call = 91
|
|
221
|
+
arm_tls_descseq = 92
|
|
222
|
+
arm_thm_tls_call = 93
|
|
223
|
+
arm_plt32_abs = 94
|
|
224
|
+
arm_got_abs = 95
|
|
225
|
+
arm_got_prel = 96
|
|
226
|
+
arm_got_brel12 = 97
|
|
227
|
+
arm_gotoff12 = 98
|
|
228
|
+
arm_gotrelax = 99
|
|
229
|
+
arm_thm_jump11 = 102
|
|
230
|
+
arm_thm_jump8 = 103
|
|
231
|
+
arm_tls_gd32 = 104
|
|
232
|
+
arm_tls_ldm32 = 105
|
|
233
|
+
arm_tls_ldo32 = 106
|
|
234
|
+
arm_tls_ie32 = 107
|
|
235
|
+
arm_tls_le32 = 108
|
|
236
|
+
arm_tls_ldo12 = 109
|
|
237
|
+
arm_tls_le12 = 110
|
|
238
|
+
arm_tls_ie12gp = 111
|
|
239
|
+
arm_thm_tls_descseq16 = 129
|
|
240
|
+
arm_thm_tls_descseq32 = 130
|
|
241
|
+
arm_thm_got_brel12 = 131
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
class RelocationWithAddend:
|
|
245
|
+
def __init__(self, type, offset, symbol, addend):
|
|
246
|
+
from nervapy.util import is_sint64, is_uint64
|
|
247
|
+
|
|
248
|
+
assert isinstance(type, RelocationType)
|
|
249
|
+
assert is_uint64(offset)
|
|
250
|
+
assert isinstance(symbol, Symbol)
|
|
251
|
+
assert is_sint64(addend)
|
|
252
|
+
|
|
253
|
+
self.type = type
|
|
254
|
+
self.offset = offset
|
|
255
|
+
self.symbol = symbol
|
|
256
|
+
self.addend = addend
|
|
257
|
+
|
|
258
|
+
@staticmethod
|
|
259
|
+
def get_entry_size(abi):
|
|
260
|
+
from nervapy.abi import ABI
|
|
261
|
+
|
|
262
|
+
assert isinstance(abi, ABI)
|
|
263
|
+
assert abi.elf_bitness in [32, 64]
|
|
264
|
+
|
|
265
|
+
return {32: 12, 64: 24}[abi.elf_bitness]
|
|
266
|
+
|
|
267
|
+
def encode(self, encoder, symbol_index_map):
|
|
268
|
+
import nervapy.encoder
|
|
269
|
+
|
|
270
|
+
assert isinstance(encoder, nervapy.encoder.Encoder)
|
|
271
|
+
assert encoder.bitness in [32, 64]
|
|
272
|
+
assert self.symbol in symbol_index_map
|
|
273
|
+
|
|
274
|
+
symbol_index = symbol_index_map[self.symbol]
|
|
275
|
+
info = (symbol_index << 32) | self.type
|
|
276
|
+
|
|
277
|
+
return (
|
|
278
|
+
encoder.unsigned_offset(self.offset)
|
|
279
|
+
+ encoder.unsigned_offset(info)
|
|
280
|
+
+ encoder.signed_offset(self.addend)
|
|
281
|
+
)
|
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
|
|
4
|
+
from enum import IntEnum
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class 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
|
+
|
|
34
|
+
class 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
|
+
|
|
45
|
+
class 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
|
+
|
|
57
|
+
class X86CpuSubType(IntEnum):
|
|
58
|
+
all = 3
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class 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
|
+
|
|
77
|
+
class ARM64CpuSubType(IntEnum):
|
|
78
|
+
all = 0
|
|
79
|
+
# Cyclone
|
|
80
|
+
v8 = 1
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class MachHeader:
|
|
84
|
+
def __init__(self, abi):
|
|
85
|
+
import nervapy.arm
|
|
86
|
+
import nervapy.x86_64
|
|
87
|
+
|
|
88
|
+
self.abi = abi
|
|
89
|
+
self.size = {4: 28, 8: 32}[abi.pointer_size]
|
|
90
|
+
if abi == nervapy.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 nervapy.abi import ABI
|
|
105
|
+
|
|
106
|
+
assert isinstance(abi, ABI)
|
|
107
|
+
assert abi.pointer_size in [4, 8]
|
|
108
|
+
|
|
109
|
+
return {4: 24, 8: 32}[abi.pointer_size]
|
|
110
|
+
|
|
111
|
+
def encode(self, encoder):
|
|
112
|
+
bytes = (
|
|
113
|
+
encoder.uint32(self.magic)
|
|
114
|
+
+ encoder.uint32(self.cpu_type)
|
|
115
|
+
+ encoder.uint32(self.cpu_subtype)
|
|
116
|
+
+ encoder.uint32(self.file_type)
|
|
117
|
+
+ encoder.uint32(self.commands_count)
|
|
118
|
+
+ encoder.uint32(self.commands_size)
|
|
119
|
+
+ encoder.uint32(self.flags)
|
|
120
|
+
)
|
|
121
|
+
if self.abi.pointer_size == 8:
|
|
122
|
+
bytes += bytearray(4)
|
|
123
|
+
return bytes
|
|
@@ -0,0 +1,143 @@
|
|
|
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
|
+
|
|
4
|
+
|
|
5
|
+
class Image:
|
|
6
|
+
def __init__(self, abi):
|
|
7
|
+
from nervapy.formats.macho.section import (ConstSection, Segment,
|
|
8
|
+
StringTable, SymbolTable,
|
|
9
|
+
TextSection)
|
|
10
|
+
|
|
11
|
+
self.abi = abi
|
|
12
|
+
self.segments = list()
|
|
13
|
+
|
|
14
|
+
self.text_segment = Segment("__TEXT")
|
|
15
|
+
self.add_segment(self.text_segment)
|
|
16
|
+
|
|
17
|
+
self.text_section = TextSection()
|
|
18
|
+
self.text_segment.add_section(self.text_section)
|
|
19
|
+
|
|
20
|
+
self.const_section = ConstSection()
|
|
21
|
+
self.text_segment.add_section(self.const_section)
|
|
22
|
+
|
|
23
|
+
self.string_table = StringTable()
|
|
24
|
+
self.symbol_table = SymbolTable(self.string_table)
|
|
25
|
+
|
|
26
|
+
def add_segment(self, segment):
|
|
27
|
+
from nervapy.formats.macho.section import Segment
|
|
28
|
+
|
|
29
|
+
assert isinstance(segment, Segment)
|
|
30
|
+
|
|
31
|
+
self.segments.append(segment)
|
|
32
|
+
|
|
33
|
+
def encode(self):
|
|
34
|
+
from nervapy.encoder import Encoder
|
|
35
|
+
from nervapy.formats.macho.file import MachHeader
|
|
36
|
+
from nervapy.formats.macho.symbol import Relocation
|
|
37
|
+
from nervapy.util import roundup
|
|
38
|
+
|
|
39
|
+
bitness = {4: 32, 8: 64}[self.abi.pointer_size]
|
|
40
|
+
encoder = Encoder(self.abi.endianness, bitness)
|
|
41
|
+
|
|
42
|
+
mach_header = MachHeader(self.abi)
|
|
43
|
+
mach_header.commands_size = self.symbol_table.command_size
|
|
44
|
+
mach_header.commands_count = 1
|
|
45
|
+
for segment in self.segments:
|
|
46
|
+
mach_header.commands_size += segment.get_command_size(self.abi)
|
|
47
|
+
mach_header.commands_count += 1
|
|
48
|
+
|
|
49
|
+
symbol_offset_map = dict()
|
|
50
|
+
section_offset_map = dict()
|
|
51
|
+
section_address_map = dict()
|
|
52
|
+
section_relocations_map = dict()
|
|
53
|
+
|
|
54
|
+
# Layout the commands
|
|
55
|
+
data_offset = mach_header.get_size(self.abi)
|
|
56
|
+
for segment in self.segments:
|
|
57
|
+
data_offset += segment.get_command_size(self.abi)
|
|
58
|
+
data_offset += self.symbol_table.command_size
|
|
59
|
+
|
|
60
|
+
# Layout section data
|
|
61
|
+
data_address = 0
|
|
62
|
+
for segment in self.segments:
|
|
63
|
+
for section in segment.sections:
|
|
64
|
+
data_offset = roundup(data_offset, section.alignment)
|
|
65
|
+
data_address = roundup(data_address, section.alignment)
|
|
66
|
+
section_offset_map[section] = data_offset
|
|
67
|
+
section_address_map[section] = data_address
|
|
68
|
+
data_offset += section.content_size
|
|
69
|
+
data_address += section.content_size
|
|
70
|
+
data_offset = roundup(data_offset, self.abi.pointer_size)
|
|
71
|
+
|
|
72
|
+
# Layout the relocations
|
|
73
|
+
for segment in self.segments:
|
|
74
|
+
for section in segment.sections:
|
|
75
|
+
if section.relocations:
|
|
76
|
+
section_relocations_map[section] = data_offset
|
|
77
|
+
data_offset += Relocation.size * len(section.relocations)
|
|
78
|
+
|
|
79
|
+
# Layout the symbols
|
|
80
|
+
for symbol in self.symbol_table.symbols:
|
|
81
|
+
symbol_offset_map[symbol] = data_offset
|
|
82
|
+
data_offset += symbol.get_entry_size(self.abi)
|
|
83
|
+
|
|
84
|
+
# Layout the strings
|
|
85
|
+
string_table_offset = data_offset
|
|
86
|
+
|
|
87
|
+
# Create map: section->index
|
|
88
|
+
section_index = 1
|
|
89
|
+
section_index_map = dict()
|
|
90
|
+
for segment in self.segments:
|
|
91
|
+
for section in segment.sections:
|
|
92
|
+
section_index_map[section] = section_index
|
|
93
|
+
section_index += 1
|
|
94
|
+
|
|
95
|
+
# Create map: symbol->index
|
|
96
|
+
symbol_index_map = {
|
|
97
|
+
symbol: index for index, symbol in enumerate(self.symbol_table.symbols)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Write Mach-O header
|
|
101
|
+
data = mach_header.encode(encoder)
|
|
102
|
+
|
|
103
|
+
# Write commands
|
|
104
|
+
for segment in self.segments:
|
|
105
|
+
data += segment.encode_command(
|
|
106
|
+
encoder,
|
|
107
|
+
section_offset_map,
|
|
108
|
+
section_address_map,
|
|
109
|
+
section_relocations_map,
|
|
110
|
+
)
|
|
111
|
+
data += self.symbol_table.encode_command(
|
|
112
|
+
encoder, symbol_offset_map, string_table_offset
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
# Write section data
|
|
116
|
+
for segment in self.segments:
|
|
117
|
+
for section in segment.sections:
|
|
118
|
+
padding = bytearray(roundup(len(data), section.alignment) - len(data))
|
|
119
|
+
data += padding + section.content
|
|
120
|
+
padding = bytearray(roundup(len(data), self.abi.pointer_size) - len(data))
|
|
121
|
+
data += padding
|
|
122
|
+
|
|
123
|
+
# Write relocations
|
|
124
|
+
for segment in self.segments:
|
|
125
|
+
for section in segment.sections:
|
|
126
|
+
for relocation in section.relocations:
|
|
127
|
+
data += relocation.encode(
|
|
128
|
+
encoder, section_index_map, symbol_index_map
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
# Write symbols
|
|
132
|
+
for symbol in self.symbol_table.symbols:
|
|
133
|
+
data += symbol.encode(
|
|
134
|
+
encoder,
|
|
135
|
+
self.string_table.string_index_map,
|
|
136
|
+
section_index_map,
|
|
137
|
+
section_address_map,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
# Write string table
|
|
141
|
+
data += self.string_table.encode()
|
|
142
|
+
|
|
143
|
+
return data
|