PyNerva 0.0.5__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.

Potentially problematic release.


This version of PyNerva might be problematic. Click here for more details.

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 +2405 -0
  8. nervapy/arm/generic.py +10797 -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.5.dist-info/METADATA +310 -0
  72. pynerva-0.0.5.dist-info/RECORD +74 -0
  73. pynerva-0.0.5.dist-info/WHEEL +4 -0
  74. pynerva-0.0.5.dist-info/licenses/LICENSE.rst +15 -0
@@ -0,0 +1,424 @@
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
+ def optional_rex(r, rm, force_rex=False):
6
+ assert r in {0, 1}, "REX.R must be 0 or 1"
7
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
8
+ from nervapy.x86_64.registers import Register
9
+
10
+ assert isinstance(
11
+ rm, (Register, MemoryAddress, RIPRelativeOffset)
12
+ ), "rm is expected to be a register or a memory address"
13
+ b = 0
14
+ x = 0
15
+ if isinstance(rm, Register):
16
+ b = rm.hcode
17
+ elif isinstance(rm, MemoryAddress):
18
+ if rm.base is not None:
19
+ b = rm.base.hcode
20
+ if rm.index is not None:
21
+ x = rm.index.hcode
22
+ # If REX.R, REX.X, and REX.B are all zeroes, REX prefix can be omitted
23
+ if (r | x | b) == 0 and not force_rex:
24
+ return bytearray()
25
+ else:
26
+ return bytearray([0x40 | (r << 2) | (x << 1) | b])
27
+
28
+
29
+ def rex(w, r, rm):
30
+ assert w in {0, 1}, "REX.W must be 0 or 1"
31
+ assert r in {0, 1}, "REX.R must be 0 or 1"
32
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
33
+
34
+ assert isinstance(
35
+ rm, (MemoryAddress, RIPRelativeOffset)
36
+ ), "rm is expected to be a memory address"
37
+ b = 0
38
+ x = 0
39
+ if isinstance(rm, MemoryAddress):
40
+ if rm.base is not None:
41
+ b = rm.base.hcode
42
+ if rm.index is not None:
43
+ x = rm.index.hcode
44
+ return bytearray([0x40 | (w << 3) | (r << 2) | (x << 1) | b])
45
+
46
+
47
+ def vex2(lpp, r, rm, vvvv=0, force_vex3=False):
48
+ # 2-byte VEX prefix:
49
+ # Requires: VEX.W = 0, VEX.mmmmm = 0b00001 and VEX.B = VEX.X = 0
50
+ # +----------------+
51
+ # Byte 0: | Bits 0-7: 0xC5 |
52
+ # +----------------+
53
+ #
54
+ # +-----------+----------------+----------+--------------+
55
+ # Byte 1: | Bit 7: ~R | Bits 3-6 ~vvvv | Bit 2: L | Bits 0-1: pp |
56
+ # +-----------+----------------+----------+--------------+
57
+ #
58
+ #
59
+ # 3-byte VEX prefix:
60
+ # +----------------+
61
+ # Byte 0: | Bits 0-7: 0xC4 |
62
+ # +----------------+
63
+ #
64
+ # +-----------+-----------+-----------+-------------------+
65
+ # Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: 0b00001 |
66
+ # +-----------+-----------+-----------+-------------------+
67
+ #
68
+ # +----------+-----------------+----------+--------------+
69
+ # Byte 2: | Bit 7: 0 | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
70
+ # +----------+-----------------+----------+--------------+
71
+ assert lpp & ~0b111 == 0, "VEX.Lpp must be a 3-bit mask"
72
+ assert r & ~0b1 == 0, "VEX.R must be a single-bit mask"
73
+ assert vvvv & ~0b1111 == 0, "VEX.vvvv must be a 4-bit mask"
74
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
75
+ from nervapy.x86_64.registers import Register
76
+
77
+ assert rm is None or isinstance(
78
+ rm, (Register, MemoryAddress, RIPRelativeOffset)
79
+ ), "rm is expected to be a register, a memory address, a rip-relative offset, or None"
80
+ b = 0
81
+ x = 0
82
+ if rm is not None:
83
+ if isinstance(rm, Register):
84
+ b = rm.hcode
85
+ elif isinstance(rm, MemoryAddress):
86
+ if rm.base is not None:
87
+ b = rm.base.hcode
88
+ if rm.index is not None:
89
+ x = rm.index.hcode
90
+ # If VEX.B and VEX.X are zeroes, 2-byte VEX prefix can be used
91
+ if (x | b) == 0 and not force_vex3:
92
+ return bytearray([0xC5, 0xF8 ^ (r << 7) ^ (vvvv << 3) ^ lpp])
93
+ else:
94
+ return bytearray(
95
+ [0xC4, 0xE1 ^ (r << 7) ^ (x << 6) ^ (b << 5), 0x78 ^ (vvvv << 3) ^ lpp]
96
+ )
97
+
98
+
99
+ def vex3(escape, mmmmm, w____lpp, r, rm, vvvv=0):
100
+ # 3-byte VEX/XOP prefix
101
+ # +-----------------------------------+
102
+ # Byte 0: | Bits 0-7: 0xC4 (VEX) / 0x8F (XOP) |
103
+ # +-----------------------------------+
104
+ #
105
+ # +-----------+-----------+-----------+-----------------+
106
+ # Byte 1: | Bit 7: ~R | Bit 6: ~X | Bit 5: ~B | Bits 0-4: mmmmm |
107
+ # +-----------+-----------+-----------+-----------------+
108
+ #
109
+ # +----------+-----------------+----------+--------------+
110
+ # Byte 2: | Bit 7: W | Bits 3-6: ~vvvv | Bit 2: L | Bits 0-1: pp |
111
+ # +----------+-----------------+----------+--------------+
112
+ assert escape in {
113
+ 0xC4,
114
+ 0x8F,
115
+ }, "escape must be a 3-byte VEX (0xC4) or XOP (0x8F) prefix"
116
+ assert (
117
+ w____lpp & ~0b10000111 == 0
118
+ ), "VEX.W____Lpp is expected to have no bits set except 0, 1, 2 and 7"
119
+ assert mmmmm & ~0b11111 == 0, "VEX.m-mmmm is expected to be a 5-bit mask"
120
+ assert r & ~0b1 == 0, "VEX.R must be a single-bit mask"
121
+ assert vvvv & ~0b1111 == 0, "VEX.vvvv must be a 4-bit mask"
122
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
123
+
124
+ assert isinstance(
125
+ rm, (MemoryAddress, RIPRelativeOffset)
126
+ ), "rm is expected to be a memory address or a rip-relative offset"
127
+ b = 0
128
+ x = 0
129
+ if isinstance(rm, MemoryAddress):
130
+ if rm.base is not None:
131
+ b = rm.base.hcode
132
+ if rm.index is not None:
133
+ x = rm.index.hcode
134
+ return bytearray(
135
+ [
136
+ escape,
137
+ 0xE0 ^ (r << 7) ^ (x << 6) ^ (b << 5) ^ mmmmm,
138
+ 0x78 ^ (vvvv << 3) ^ w____lpp,
139
+ ]
140
+ )
141
+
142
+
143
+ def evex(mm, w____1pp, ll, rr, rm, Vvvvv=0, aaa=0, z=0, b=0):
144
+ assert mm & ~0b11 == 0, "EVEX.mm must be a 2-bit mask"
145
+ assert (
146
+ w____1pp & ~0b10000011 == 0b100
147
+ ), "EVEX.W____1pp is expected to have no bits set except 0, 1, 2, and 7"
148
+ assert ll & ~0b11 == 0, "EVEX.L'L must be a 2-bit mask"
149
+ assert rr & ~0b11 == 0, "EVEX.R'R must be a 2-bit mask"
150
+ assert Vvvvv & ~0b11111 == 0, "EVEX.v'vvvv must be a 5-bit mask"
151
+ assert aaa & ~0b111 == 0, "EVEX.aaa must be a 3-bit mask"
152
+ assert z & ~0b1 == 0, "EVEX.z must be a single-bit mask"
153
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
154
+ from nervapy.x86_64.registers import (Register, XMMRegister, YMMRegister,
155
+ ZMMRegister)
156
+
157
+ assert rm is None or isinstance(
158
+ rm, (Register, MemoryAddress, RIPRelativeOffset)
159
+ ), "rm is expected to be a register, a memory address, or None"
160
+ r_, r = rr >> 1, rr & 1
161
+ v_, vvvv = Vvvvv >> 4, Vvvvv & 0b1111
162
+ b_ = 0
163
+ x = 0
164
+ if rm is not None:
165
+ if isinstance(rm, Register):
166
+ b_ = rm.hcode
167
+ x = rm.ecode
168
+ elif isinstance(rm, MemoryAddress):
169
+ if rm.base is not None:
170
+ b_ = rm.base.hcode
171
+ if rm.index is not None:
172
+ x = rm.index.hcode
173
+ if isinstance(rm.index, (XMMRegister, YMMRegister, ZMMRegister)):
174
+ v_ = rm.index.ecode
175
+ p0 = (r << 7) | (x << 6) | (b_ << 5) | (r_ << 4) | mm
176
+ p1 = w____1pp | (vvvv << 3)
177
+ p2 = (z << 7) | (ll << 5) | (b << 4) | (v_ << 3) | aaa
178
+ # p0: invert RXBR' (bits 4-7)
179
+ # p1: invert vvvv (bits 3-6)
180
+ # p2: invert V' (bit 3)
181
+ return bytearray([0x62, p0 ^ 0xF0, p1 ^ 0x78, p2 ^ 0x08])
182
+
183
+
184
+ def modrm_sib_disp(reg, rm, force_sib=False, min_disp=0, disp8xN=None):
185
+ from nervapy.util import ilog2, is_int, is_sint8
186
+ from nervapy.x86_64.operand import MemoryAddress, RIPRelativeOffset
187
+ from nervapy.x86_64.registers import r13, rbp, rsp
188
+
189
+ assert is_int(reg) and 0 <= reg <= 7, "Constant reg value expected, got " + str(reg)
190
+ assert isinstance(rm, (MemoryAddress, RIPRelativeOffset))
191
+
192
+ if disp8xN is None:
193
+ disp8xN = 1
194
+ assert disp8xN in [1, 2, 4, 8, 16, 32, 64]
195
+
196
+ # ModR/M byte
197
+ # +----------------+---------------+--------------+
198
+ # | Bits 6-7: mode | Bits 3-5: reg | Bits 0-2: rm |
199
+ # +----------------+---------------+--------------+
200
+ #
201
+ # SIB byte
202
+ # +-----------------+-----------------+----------------+
203
+ # | Bits 6-7: scale | Bits 3-5: index | Bits 0-2: base |
204
+ # +-----------------+-----------------+----------------+
205
+ if isinstance(rm, MemoryAddress):
206
+ # TODO: support global addresses, including rip-relative addresses
207
+ assert (
208
+ rm.base is not None or rm.index is not None
209
+ ), "Global addressing is not yet supported"
210
+ if not force_sib and rm.index is None and rm.base.lcode != 0b100:
211
+ # No SIB byte
212
+ if (
213
+ rm.displacement == 0
214
+ and rm.base != rbp
215
+ and rm.base != r13
216
+ and min_disp <= 0
217
+ ):
218
+ # ModRM.mode = 0 (no displacement)
219
+
220
+ assert (
221
+ rm.base.lcode != 0b100
222
+ ), "rsp/r12 are not encodable as a base register (interpreted as SIB indicator)"
223
+ assert (
224
+ rm.base.lcode != 0b101
225
+ ), "rbp/r13 is not encodable as a base register (interpreted as disp32 address)"
226
+ return bytearray([(reg << 3) | rm.base.lcode])
227
+ elif (
228
+ (rm.displacement % disp8xN == 0)
229
+ and is_sint8(rm.displacement // disp8xN)
230
+ and min_disp <= 1
231
+ ):
232
+ # ModRM.mode = 1 (8-bit displacement)
233
+
234
+ assert (
235
+ rm.base.lcode != 0b100
236
+ ), "rsp/r12 are not encodable as a base register (interpreted as SIB indicator)"
237
+ return bytearray(
238
+ [
239
+ 0x40 | (reg << 3) | rm.base.lcode,
240
+ (rm.displacement // disp8xN) & 0xFF,
241
+ ]
242
+ )
243
+ else:
244
+ # ModRM.mode == 2 (32-bit displacement)
245
+
246
+ assert (
247
+ rm.base.lcode != 0b100
248
+ ), "rsp/r12 are not encodable as a base register (interpreted as SIB indicator)"
249
+ return bytearray(
250
+ [
251
+ 0x80 | (reg << 3) | rm.base.lcode,
252
+ rm.displacement & 0xFF,
253
+ (rm.displacement >> 8) & 0xFF,
254
+ (rm.displacement >> 16) & 0xFF,
255
+ (rm.displacement >> 24) & 0xFF,
256
+ ]
257
+ )
258
+ else:
259
+ # All encodings below use ModRM.rm = 4 (0b100) to indicate the presence of SIB
260
+
261
+ assert (
262
+ rsp != rm.index
263
+ ), "rsp is not encodable as an index register (interpreted as no index)"
264
+ # Index = 4 (0b100) denotes no-index encoding
265
+ index = 0x4 if rm.index is None else rm.index.lcode
266
+ scale = 0 if rm.scale is None else ilog2(rm.scale)
267
+ if rm.base is None:
268
+ # SIB.base = 5 (0b101) and ModRM.mode = 0 indicates no-base encoding with disp32
269
+
270
+ return bytearray(
271
+ [
272
+ (reg << 3) | 0x4,
273
+ (scale << 6) | (index << 3) | 0x5,
274
+ rm.displacement & 0xFF,
275
+ (rm.displacement >> 8) & 0xFF,
276
+ (rm.displacement >> 16) & 0xFF,
277
+ (rm.displacement >> 24) & 0xFF,
278
+ ]
279
+ )
280
+ else:
281
+ if rm.displacement == 0 and rm.base.lcode != 0b101 and min_disp <= 0:
282
+ # ModRM.mode == 0 (no displacement)
283
+
284
+ assert (
285
+ rm.base.lcode != 0b101
286
+ ), "rbp/r13 is not encodable as a base register (interpreted as disp32 address)"
287
+ return bytearray(
288
+ [(reg << 3) | 0x4, (scale << 6) | (index << 3) | rm.base.lcode]
289
+ )
290
+ elif (
291
+ (rm.displacement % disp8xN == 0)
292
+ and is_sint8(rm.displacement // disp8xN)
293
+ and min_disp <= 1
294
+ ):
295
+ # ModRM.mode == 1 (8-bit displacement)
296
+
297
+ return bytearray(
298
+ [
299
+ (reg << 3) | 0x44,
300
+ (scale << 6) | (index << 3) | rm.base.lcode,
301
+ (rm.displacement // disp8xN) & 0xFF,
302
+ ]
303
+ )
304
+ else:
305
+ # ModRM.mode == 2 (32-bit displacement)
306
+
307
+ return bytearray(
308
+ [
309
+ (reg << 3) | 0x84,
310
+ (scale << 6) | (index << 3) | rm.base.lcode,
311
+ rm.displacement & 0xFF,
312
+ (rm.displacement >> 8) & 0xFF,
313
+ (rm.displacement >> 16) & 0xFF,
314
+ (rm.displacement >> 24) & 0xFF,
315
+ ]
316
+ )
317
+ elif isinstance(rm, RIPRelativeOffset):
318
+ # ModRM.mode == 0 and ModeRM.rm == 5 (0b101) indicates (rip + disp32) addressing
319
+ return bytearray(
320
+ [
321
+ 0b00000101 | (reg << 3),
322
+ rm.offset & 0xFF,
323
+ (rm.offset >> 8) & 0xFF,
324
+ (rm.offset >> 16) & 0xFF,
325
+ (rm.offset >> 24) & 0xFF,
326
+ ]
327
+ )
328
+
329
+
330
+ def nop(length):
331
+ assert 1 <= length <= 15
332
+ # Note: the generated NOPs must be allowed by NaCl validator, see
333
+ # https://src.chromium.org/viewvc/native_client/trunk/src/native_client/src/trusted/validator_ragel/instruction_definitions/general_purpose_instructions.def
334
+ # https://src.chromium.org/viewvc/native_client/trunk/src/native_client/src/trusted/validator_ragel/instruction_definitions/nops.def
335
+ return {
336
+ 1: bytearray([0x90]),
337
+ 2: bytearray([0x40, 0x90]),
338
+ 3: bytearray([0x0F, 0x1F, 0x00]),
339
+ 4: bytearray([0x0F, 0x1F, 0x40, 0x00]),
340
+ 5: bytearray([0x0F, 0x1F, 0x44, 0x00, 0x00]),
341
+ 6: bytearray([0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00]),
342
+ 7: bytearray([0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00]),
343
+ 8: bytearray([0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]),
344
+ 9: bytearray([0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]),
345
+ 10: bytearray([0x66, 0x2E, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]),
346
+ 11: bytearray(
347
+ [0x66, 0x66, 0x2E, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]
348
+ ),
349
+ 12: bytearray(
350
+ [0x66, 0x66, 0x66, 0x2E, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]
351
+ ),
352
+ 13: bytearray(
353
+ [
354
+ 0x66,
355
+ 0x66,
356
+ 0x66,
357
+ 0x66,
358
+ 0x2E,
359
+ 0x0F,
360
+ 0x1F,
361
+ 0x84,
362
+ 0x00,
363
+ 0x00,
364
+ 0x00,
365
+ 0x00,
366
+ 0x00,
367
+ ]
368
+ ),
369
+ 14: bytearray(
370
+ [
371
+ 0x66,
372
+ 0x66,
373
+ 0x66,
374
+ 0x66,
375
+ 0x66,
376
+ 0x2E,
377
+ 0x0F,
378
+ 0x1F,
379
+ 0x84,
380
+ 0x00,
381
+ 0x00,
382
+ 0x00,
383
+ 0x00,
384
+ 0x00,
385
+ ]
386
+ ),
387
+ 15: bytearray(
388
+ [
389
+ 0x66,
390
+ 0x66,
391
+ 0x66,
392
+ 0x66,
393
+ 0x66,
394
+ 0x66,
395
+ 0x2E,
396
+ 0x0F,
397
+ 0x1F,
398
+ 0x84,
399
+ 0x00,
400
+ 0x00,
401
+ 0x00,
402
+ 0x00,
403
+ 0x00,
404
+ ]
405
+ ),
406
+ }[length]
407
+
408
+
409
+ class Flags:
410
+ AccumulatorOp0 = 0x01
411
+ AccumulatorOp1 = 0x02
412
+ Rel8Label = 0x04
413
+ Rel32Label = 0x08
414
+ ModRMSIBDisp = 0x10
415
+ OptionalREX = 0x20
416
+ VEX2 = 0x40
417
+
418
+
419
+ class Options:
420
+ Disp8 = 0x01
421
+ Disp32 = 0x02
422
+ SIB = 0x04
423
+ REX = 0x08
424
+ VEX3 = 0x10