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
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
|
+
)
|