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.
Files changed (74) hide show
  1. nervapy/__init__.py +50 -0
  2. nervapy/abi.py +91 -0
  3. nervapy/arm/__init__.py +124 -0
  4. nervapy/arm/__main__.py +0 -0
  5. nervapy/arm/abi.py +138 -0
  6. nervapy/arm/formats.py +49 -0
  7. nervapy/arm/function.py +2465 -0
  8. nervapy/arm/generic.py +10796 -0
  9. nervapy/arm/instructions.py +519 -0
  10. nervapy/arm/isa.py +409 -0
  11. nervapy/arm/literal_pool.py +331 -0
  12. nervapy/arm/microarchitecture.py +211 -0
  13. nervapy/arm/pseudo.py +652 -0
  14. nervapy/arm/registers.py +1458 -0
  15. nervapy/arm/vfpneon.py +4092 -0
  16. nervapy/arm.py +13 -0
  17. nervapy/c/__init__.py +1 -0
  18. nervapy/c/types.py +436 -0
  19. nervapy/codegen.py +99 -0
  20. nervapy/common/__init__.py +4 -0
  21. nervapy/common/function.py +5 -0
  22. nervapy/common/regalloc.py +121 -0
  23. nervapy/constant_data.py +282 -0
  24. nervapy/encoder.py +246 -0
  25. nervapy/formats/__init__.py +2 -0
  26. nervapy/formats/elf/__init__.py +4 -0
  27. nervapy/formats/elf/file.py +178 -0
  28. nervapy/formats/elf/image.py +106 -0
  29. nervapy/formats/elf/section.py +422 -0
  30. nervapy/formats/elf/symbol.py +281 -0
  31. nervapy/formats/macho/__init__.py +2 -0
  32. nervapy/formats/macho/file.py +123 -0
  33. nervapy/formats/macho/image.py +143 -0
  34. nervapy/formats/macho/section.py +322 -0
  35. nervapy/formats/macho/symbol.py +158 -0
  36. nervapy/formats/mscoff/__init__.py +8 -0
  37. nervapy/formats/mscoff/image.py +132 -0
  38. nervapy/formats/mscoff/section.py +181 -0
  39. nervapy/formats/mscoff/symbol.py +148 -0
  40. nervapy/function.py +136 -0
  41. nervapy/literal.py +731 -0
  42. nervapy/loader.py +188 -0
  43. nervapy/name.py +159 -0
  44. nervapy/parse.py +52 -0
  45. nervapy/stream.py +58 -0
  46. nervapy/util.py +126 -0
  47. nervapy/writer.py +518 -0
  48. nervapy/x86_64/__init__.py +324 -0
  49. nervapy/x86_64/__main__.py +407 -0
  50. nervapy/x86_64/abi.py +517 -0
  51. nervapy/x86_64/amd.py +6464 -0
  52. nervapy/x86_64/avx.py +102029 -0
  53. nervapy/x86_64/crypto.py +1533 -0
  54. nervapy/x86_64/encoding.py +424 -0
  55. nervapy/x86_64/fma.py +19138 -0
  56. nervapy/x86_64/function.py +2707 -0
  57. nervapy/x86_64/generic.py +23384 -0
  58. nervapy/x86_64/instructions.py +500 -0
  59. nervapy/x86_64/isa.py +476 -0
  60. nervapy/x86_64/lower.py +126 -0
  61. nervapy/x86_64/mask.py +2593 -0
  62. nervapy/x86_64/meta.py +143 -0
  63. nervapy/x86_64/mmxsse.py +17265 -0
  64. nervapy/x86_64/nacl.py +327 -0
  65. nervapy/x86_64/operand.py +1204 -0
  66. nervapy/x86_64/options.py +21 -0
  67. nervapy/x86_64/pseudo.py +686 -0
  68. nervapy/x86_64/registers.py +1225 -0
  69. nervapy/x86_64/types.py +17 -0
  70. nervapy/x86_64/uarch.py +580 -0
  71. pynerva-0.0.7.dist-info/METADATA +310 -0
  72. pynerva-0.0.7.dist-info/RECORD +74 -0
  73. pynerva-0.0.7.dist-info/WHEEL +4 -0
  74. pynerva-0.0.7.dist-info/licenses/LICENSE.rst +15 -0
nervapy/writer.py ADDED
@@ -0,0 +1,518 @@
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
+ active_writers = []
5
+
6
+
7
+ class TextWriter(object):
8
+ def __init__(self, output_path):
9
+ super(TextWriter, self).__init__()
10
+ self.output_path = output_path
11
+ self.prologue = []
12
+ self.content = []
13
+ self.epilogue = []
14
+
15
+ def __enter__(self):
16
+ global active_writers
17
+ active_writers.append(self)
18
+ self.output_file = open(self.output_path, "w")
19
+ return self
20
+
21
+ def __exit__(self, exc_type, exc_value, traceback):
22
+ global active_writers
23
+ active_writers.remove(self)
24
+ if exc_type is None:
25
+ self.output_file.write(self.serialize())
26
+ self.output_file.close()
27
+ self.output_file = None
28
+ else:
29
+ import os
30
+
31
+ os.unlink(self.output_file.name)
32
+ self.output_file = None
33
+ raise
34
+
35
+ def serialize(self):
36
+ import os
37
+
38
+ prologue = self.prologue
39
+ if not isinstance(prologue, str):
40
+ prologue = os.linesep.join(map(str, prologue))
41
+ if prologue:
42
+ prologue += os.linesep * 3
43
+
44
+ content = self.content
45
+ if not isinstance(content, str):
46
+ content = os.linesep.join(map(str, content))
47
+
48
+ epilogue = self.epilogue
49
+ if not isinstance(epilogue, str):
50
+ epilogue = os.linesep.join(map(str, epilogue))
51
+ if epilogue:
52
+ epilogue = os.linesep * 3 + epilogue
53
+
54
+ return prologue + content + epilogue
55
+
56
+
57
+ class AssemblyWriter(TextWriter):
58
+ def __init__(self, output_path, assembly_format, input_path=None):
59
+ super(AssemblyWriter, self).__init__(output_path)
60
+ if assembly_format not in {"go", "nasm", "masm", "gas"}:
61
+ raise ValueError("Unknown assembly format: %s" % assembly_format)
62
+ self.assembly_format = assembly_format
63
+ self.comment_prefix = {"go": "//", "nasm": ";", "masm": ";", "gas": "#"}[
64
+ assembly_format
65
+ ]
66
+
67
+ if assembly_format == "go":
68
+ from os import linesep
69
+
70
+ self.prologue = "// +build !noasm" + linesep
71
+ else:
72
+ self.prologue = ""
73
+
74
+ import nervapy
75
+
76
+ if input_path is not None:
77
+ self.prologue += (
78
+ "{escape} Generated by PeachPy {version} from {filename}".format(
79
+ escape=self.comment_prefix,
80
+ version=nervapy.__version__,
81
+ filename=input_path,
82
+ )
83
+ )
84
+ else:
85
+ self.prologue += "{escape} Generated by PeachPy {version}".format(
86
+ escape=self.comment_prefix, version=nervapy.__version__
87
+ )
88
+ self.prologue_lines = len(self.prologue.splitlines()) + 3
89
+
90
+ def add_function(self, function):
91
+ import nervapy.x86_64.function
92
+
93
+ assert isinstance(
94
+ function, nervapy.x86_64.function.ABIFunction
95
+ ), "Function must be finalized with an ABI before its assembly can be used"
96
+
97
+ function_lines = function.format(
98
+ self.assembly_format,
99
+ line_separator=None,
100
+ line_number=self.prologue_lines + len(self.content),
101
+ )
102
+ self.content += function_lines
103
+
104
+
105
+ class ImageWriter(object):
106
+ def __init__(self, output_path):
107
+ super(ImageWriter, self).__init__()
108
+ self.output_path = output_path
109
+
110
+ def __enter__(self):
111
+ global active_writers
112
+ active_writers.append(self)
113
+ self.output_file = open(self.output_path, "wb", buffering=0)
114
+ return self
115
+
116
+ def __exit__(self, exc_type, exc_value, traceback):
117
+ global active_writers
118
+ active_writers.remove(self)
119
+ if exc_type is None:
120
+ self.output_file.write(self.encode())
121
+ self.output_file.close()
122
+ self.output_file = None
123
+ else:
124
+ import os
125
+
126
+ os.unlink(self.output_file.name)
127
+ self.output_file = None
128
+ raise
129
+
130
+ def encode(self):
131
+ return bytearray()
132
+
133
+
134
+ class ELFWriter(ImageWriter):
135
+ def __init__(self, output_path, abi, input_path=None):
136
+ super(ELFWriter, self).__init__(output_path)
137
+ from nervapy.formats.elf.image import Image
138
+ from nervapy.formats.elf.section import ProgramBitsSection, TextSection
139
+
140
+ self.abi = abi
141
+ self.image = Image(abi, input_path)
142
+ self.text_section = TextSection()
143
+ self.image.add_section(self.text_section)
144
+ self.gnu_stack_section = ProgramBitsSection(".note.GNU-stack", allocate=False)
145
+ self.image.add_section(self.gnu_stack_section)
146
+ self.text_rela_section = None
147
+ self.rodata_section = None
148
+
149
+ def encode(self):
150
+ return self.image.as_bytearray
151
+
152
+ def add_function(self, function):
153
+ import nervapy.x86_64.function
154
+ from nervapy.util import roundup
155
+
156
+ assert isinstance(
157
+ function, nervapy.x86_64.function.ABIFunction
158
+ ), "Function must be finalized with an ABI before its assembly can be used"
159
+
160
+ encoded_function = function.encode()
161
+
162
+ code_offset = len(self.text_section.content)
163
+ code_padding = bytearray(
164
+ [encoded_function.code_section.alignment_byte]
165
+ * (
166
+ roundup(code_offset, encoded_function.code_section.alignment)
167
+ - code_offset
168
+ )
169
+ )
170
+ self.text_section.content += code_padding
171
+ code_offset += len(code_padding)
172
+ self.text_section.content += encoded_function.code_section.content
173
+ self.text_section.alignment = max(
174
+ self.text_section.alignment, encoded_function.code_section.alignment
175
+ )
176
+
177
+ const_offset = 0
178
+ if encoded_function.const_section.content:
179
+ if self.rodata_section is None:
180
+ from nervapy.formats.elf.section import ReadOnlyDataSection
181
+
182
+ self.rodata_section = ReadOnlyDataSection()
183
+ self.image.add_section(self.rodata_section)
184
+ const_offset = self.rodata_section.get_content_size(self.abi)
185
+ const_padding = bytearray(
186
+ [encoded_function.const_section.alignment_byte]
187
+ * (
188
+ roundup(const_offset, encoded_function.const_section.alignment)
189
+ - const_offset
190
+ )
191
+ )
192
+ self.rodata_section.content += const_padding
193
+ const_offset += len(const_padding)
194
+ self.rodata_section.content += encoded_function.const_section.content
195
+ self.rodata_section.alignment = max(
196
+ self.rodata_section.alignment, encoded_function.const_section.alignment
197
+ )
198
+
199
+ # Map from symbol name to symbol index
200
+ from nervapy.formats.elf.symbol import (Symbol, SymbolBinding,
201
+ SymbolType)
202
+
203
+ symbol_map = dict()
204
+ for symbol in encoded_function.const_section.symbols:
205
+ const_symbol = Symbol()
206
+ const_symbol.name = function.mangled_name + "." + symbol.name
207
+ const_symbol.value = const_offset + symbol.offset
208
+ const_symbol.size = symbol.size
209
+ const_symbol.section = self.rodata_section
210
+ const_symbol.binding = SymbolBinding.local
211
+ const_symbol.type = SymbolType.data_object
212
+ self.image.symtab.add(const_symbol)
213
+ symbol_map[symbol] = const_symbol
214
+
215
+ if encoded_function.code_section.relocations:
216
+ if self.text_rela_section is None:
217
+ from nervapy.formats.elf.section import \
218
+ RelocationsWithAddendSection
219
+
220
+ self.text_rela_section = RelocationsWithAddendSection(
221
+ self.text_section, self.image.symtab
222
+ )
223
+ self.image.add_section(self.text_rela_section)
224
+
225
+ from nervapy.formats.elf.symbol import (RelocationType,
226
+ RelocationWithAddend)
227
+
228
+ for relocation in encoded_function.code_section.relocations:
229
+ elf_relocation = RelocationWithAddend(
230
+ RelocationType.x86_64_pc32,
231
+ code_offset + relocation.offset,
232
+ symbol_map[relocation.symbol],
233
+ relocation.offset - relocation.program_counter,
234
+ )
235
+ self.text_rela_section.add(elf_relocation)
236
+
237
+ function_symbol = Symbol()
238
+ function_symbol.name = function.mangled_name
239
+ function_symbol.value = code_offset
240
+ function_symbol.content_size = len(encoded_function.code_section)
241
+ function_symbol.section = self.text_section
242
+ function_symbol.binding = SymbolBinding.global_
243
+ function_symbol.type = SymbolType.function
244
+ self.image.symtab.add(function_symbol)
245
+
246
+
247
+ class MachOWriter(ImageWriter):
248
+ def __init__(self, output_path, abi):
249
+ super(MachOWriter, self).__init__(output_path)
250
+
251
+ from nervapy.formats.macho.image import Image
252
+
253
+ self.abi = abi
254
+ self.image = Image(abi)
255
+
256
+ def encode(self):
257
+ return self.image.encode()
258
+
259
+ def add_function(self, function):
260
+ import nervapy.x86_64.function
261
+
262
+ assert isinstance(
263
+ function, nervapy.x86_64.function.ABIFunction
264
+ ), "Function must be finalized with an ABI before its assembly can be used"
265
+
266
+ from nervapy.formats.macho.symbol import (Relocation, RelocationType,
267
+ Symbol, SymbolDescription,
268
+ SymbolType, SymbolVisibility)
269
+ from nervapy.util import roundup
270
+
271
+ encoded_function = function.encode()
272
+
273
+ code_offset = len(self.image.text_section.content)
274
+ code_padding = bytearray(
275
+ [encoded_function.code_section.alignment_byte]
276
+ * (
277
+ roundup(code_offset, encoded_function.code_section.alignment)
278
+ - code_offset
279
+ )
280
+ )
281
+ self.image.text_section.content += code_padding
282
+ code_offset += len(code_padding)
283
+ self.image.text_section.content += encoded_function.code_section.content
284
+ self.image.text_section.alignment = max(
285
+ self.image.text_section.alignment, encoded_function.code_section.alignment
286
+ )
287
+
288
+ const_offset = self.image.const_section.content_size
289
+ const_padding = bytearray(
290
+ [encoded_function.const_section.alignment_byte]
291
+ * (
292
+ roundup(const_offset, encoded_function.const_section.alignment)
293
+ - const_offset
294
+ )
295
+ )
296
+ self.image.const_section.content += const_padding
297
+ const_offset += len(const_padding)
298
+ self.image.const_section.content += encoded_function.const_section.content
299
+ self.image.const_section.alignment = max(
300
+ self.image.const_section.alignment, encoded_function.const_section.alignment
301
+ )
302
+
303
+ # Map from PeachPy symbol to Mach-O symbol
304
+ symbol_map = dict()
305
+ for symbol in encoded_function.const_section.symbols:
306
+ macho_symbol = Symbol(
307
+ "_" + function.mangled_name + "." + symbol.name,
308
+ SymbolType.section_relative,
309
+ self.image.const_section,
310
+ const_offset + symbol.offset,
311
+ )
312
+ macho_symbol.description = SymbolDescription.defined
313
+ self.image.symbol_table.add_symbol(macho_symbol)
314
+ symbol_map[symbol] = macho_symbol
315
+
316
+ for relocation in encoded_function.code_section.relocations:
317
+ macho_relocation = Relocation(
318
+ RelocationType.x86_64_signed,
319
+ code_offset + relocation.offset,
320
+ 4,
321
+ symbol_map[relocation.symbol],
322
+ is_pc_relative=True,
323
+ )
324
+ relocation_addend = relocation.offset + 4 - relocation.program_counter
325
+ if relocation_addend != 0:
326
+ self.image.text_section.content[code_offset + relocation.offset] = (
327
+ relocation_addend & 0xFF
328
+ )
329
+ self.image.text_section.content[code_offset + relocation.offset + 1] = (
330
+ relocation_addend >> 8
331
+ ) & 0xFF
332
+ self.image.text_section.content[code_offset + relocation.offset + 2] = (
333
+ relocation_addend >> 16
334
+ ) & 0xFF
335
+ self.image.text_section.content[code_offset + relocation.offset + 3] = (
336
+ relocation_addend >> 24
337
+ ) & 0xFF
338
+
339
+ self.image.text_section.relocations.append(macho_relocation)
340
+
341
+ function_symbol = Symbol(
342
+ "_" + function.mangled_name,
343
+ SymbolType.section_relative,
344
+ self.image.text_section,
345
+ value=code_offset,
346
+ )
347
+ function_symbol.description = SymbolDescription.defined
348
+ function_symbol.visibility = SymbolVisibility.external
349
+ self.image.symbol_table.add_symbol(function_symbol)
350
+
351
+
352
+ class MSCOFFWriter(ImageWriter):
353
+ def __init__(self, output_path, abi, input_path=None):
354
+ super(MSCOFFWriter, self).__init__(output_path)
355
+
356
+ from nervapy.formats.mscoff import (Image, ReadOnlyDataSection,
357
+ TextSection)
358
+
359
+ self.output_path = output_path
360
+ self.abi = abi
361
+ self.image = Image(abi, input_path)
362
+ self.text_section = TextSection()
363
+ self.image.add_section(self.text_section)
364
+ self.rdata_section = ReadOnlyDataSection()
365
+ self.image.add_section(self.rdata_section)
366
+
367
+ def encode(self):
368
+ return self.image.encode()
369
+
370
+ def add_function(self, function):
371
+ import nervapy.x86_64.function
372
+
373
+ assert isinstance(
374
+ function, nervapy.x86_64.function.ABIFunction
375
+ ), "Function must be finalized with an ABI before its assembly can be used"
376
+ from nervapy.formats.mscoff import (Relocation, RelocationType,
377
+ StorageClass, Symbol, SymbolType)
378
+ from nervapy.util import roundup
379
+
380
+ encoded_function = function.encode()
381
+
382
+ code_offset = len(self.text_section.content)
383
+ code_padding = bytearray(
384
+ [encoded_function.code_section.alignment_byte]
385
+ * (
386
+ roundup(code_offset, encoded_function.code_section.alignment)
387
+ - code_offset
388
+ )
389
+ )
390
+ self.text_section.content += code_padding
391
+ code_offset += len(code_padding)
392
+ self.text_section.content += encoded_function.code_section.content
393
+ self.text_section.alignment = max(
394
+ self.text_section.alignment, encoded_function.code_section.alignment
395
+ )
396
+
397
+ rdata_offset = self.rdata_section.content_size
398
+ rdata_padding = bytearray(
399
+ [encoded_function.const_section.alignment_byte]
400
+ * (
401
+ roundup(rdata_offset, encoded_function.const_section.alignment)
402
+ - rdata_offset
403
+ )
404
+ )
405
+ self.rdata_section.content += rdata_padding
406
+ rdata_offset += len(rdata_padding)
407
+ self.rdata_section.content += encoded_function.const_section.content
408
+ self.rdata_section.alignment = max(
409
+ self.rdata_section.alignment, encoded_function.const_section.alignment
410
+ )
411
+
412
+ # Map from PeachPy symbol to Mach-O symbol
413
+ symbol_map = dict()
414
+ for symbol in encoded_function.const_section.symbols:
415
+ mscoff_symbol = Symbol()
416
+ mscoff_symbol.name = symbol.name
417
+ mscoff_symbol.value = rdata_offset + symbol.offset
418
+ mscoff_symbol.section = self.rdata_section
419
+ mscoff_symbol.symbol_type = SymbolType.non_function
420
+ mscoff_symbol.storage_class = StorageClass.static
421
+ self.image.add_symbol(mscoff_symbol)
422
+ symbol_map[symbol] = mscoff_symbol
423
+
424
+ for relocation in encoded_function.code_section.relocations:
425
+ relocation_type_map = {
426
+ 4: RelocationType.x86_64_relocation_offset32,
427
+ 5: RelocationType.x86_64_relocation_plus_1_offset32,
428
+ 6: RelocationType.x86_64_relocation_plus_2_offset32,
429
+ 7: RelocationType.x86_64_relocation_plus_3_offset32,
430
+ 8: RelocationType.x86_64_relocation_plus_4_offset32,
431
+ 9: RelocationType.x86_64_relocation_plus_5_offset32,
432
+ }
433
+ relocation_type = relocation_type_map[
434
+ relocation.program_counter - relocation.offset
435
+ ]
436
+ mscoff_relocation = Relocation(
437
+ relocation_type,
438
+ code_offset + relocation.offset,
439
+ symbol_map[relocation.symbol],
440
+ )
441
+ self.text_section.relocations.append(mscoff_relocation)
442
+
443
+ function_symbol = Symbol()
444
+ function_symbol.name = function.mangled_name
445
+ function_symbol.value = code_offset
446
+ function_symbol.section = self.text_section
447
+ function_symbol.symbol_type = SymbolType.function
448
+ function_symbol.storage_class = StorageClass.external
449
+ self.image.add_symbol(function_symbol)
450
+
451
+
452
+ class MetadataWriter(TextWriter):
453
+ def __init__(self, output_path):
454
+ super(MetadataWriter, self).__init__(output_path)
455
+ self.metadata = []
456
+
457
+ def add_function(self, function):
458
+ import nervapy.x86_64.function
459
+
460
+ assert isinstance(
461
+ function, nervapy.x86_64.function.ABIFunction
462
+ ), "Function must be finalized with an ABI before its assembly can be used"
463
+
464
+ self.metadata.append(function.metadata)
465
+
466
+
467
+ class JSONMetadataWriter(MetadataWriter):
468
+ def __init__(self, output_path):
469
+ super(JSONMetadataWriter, self).__init__(output_path)
470
+
471
+ def serialize(self):
472
+ import json
473
+
474
+ return json.dumps(self.metadata)
475
+
476
+
477
+ class CHeaderWriter(TextWriter):
478
+ def __init__(self, output_path, input_path=None):
479
+ super(CHeaderWriter, self).__init__(output_path)
480
+
481
+ import nervapy
482
+
483
+ if input_path is not None:
484
+ self.prologue = [
485
+ "/* Generated by PeachPy %s from %s */"
486
+ % (nervapy.__version__, input_path)
487
+ ]
488
+ else:
489
+ self.prologue = ["/* Generated by PeachPy %s */" % nervapy.__version__]
490
+ self.prologue += [
491
+ "",
492
+ "#pragma once",
493
+ "",
494
+ "#ifdef __cplusplus",
495
+ 'extern "C" {',
496
+ "#endif",
497
+ ]
498
+ self.epilogue = ["#ifdef __cplusplus", '} /* extern "C" */', "#endif", ""]
499
+
500
+ def add_function(self, function):
501
+ import nervapy.x86_64.function
502
+
503
+ assert isinstance(
504
+ function, nervapy.x86_64.function.ABIFunction
505
+ ), "Function must be finalized with an ABI before its assembly can be used"
506
+
507
+ return_type = (
508
+ "void" if function.result_type is None else str(function.result_type)
509
+ )
510
+ arguments = [str(arg.c_type) + " " + arg.name for arg in function.arguments]
511
+ self.content.append(
512
+ return_type
513
+ + " "
514
+ + function.mangled_name
515
+ + "("
516
+ + ", ".join(arguments)
517
+ + ");"
518
+ )