kompiler 0.3.0.pre.4 → 0.3.0
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.
- checksums.yaml +4 -4
- data/bin/kompile +230 -33
- data/lib/kompiler/arch_manager.rb +10 -1
- data/lib/kompiler/architecture.rb +5 -1
- data/lib/kompiler/architectures/armv8a/instructions.rb +76 -27
- data/lib/kompiler/architectures/armv8a/load.rb +3 -1
- data/lib/kompiler/architectures/armv8a/simd_fp_instructions.rb +1308 -0
- data/lib/kompiler/architectures/armv8a/simd_fp_registers.rb +23 -0
- data/lib/kompiler/architectures/armv8a/sys_registers.rb +3 -0
- data/lib/kompiler/compiler_functions.rb +32 -8
- data/lib/kompiler/config.rb +12 -1
- data/lib/kompiler/directives.rb +13 -0
- data/lib/kompiler/math_ast.rb +29 -1
- data/lib/kompiler/mc_builder.rb +48 -0
- data/lib/kompiler/parsers.rb +21 -0
- data/lib/kompiler/wrappers/elf_wrapper.rb +499 -0
- data/lib/kompiler/wrappers/packed_bytes.rb +68 -0
- data/lib/kompiler/wrappers.rb +1 -0
- data/lib/kompiler.rb +2 -1
- metadata +8 -3
@@ -0,0 +1,499 @@
|
|
1
|
+
#
|
2
|
+
# This file implements ELF Wrappers for raw programs.
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'kompiler/wrappers/packed_bytes'
|
6
|
+
|
7
|
+
|
8
|
+
module Kompiler
|
9
|
+
|
10
|
+
module Wrappers
|
11
|
+
|
12
|
+
module ELF
|
13
|
+
|
14
|
+
# ELF Wrap Object
|
15
|
+
# Wraps a raw program in the ELF relocatable format
|
16
|
+
#
|
17
|
+
# Arguments:
|
18
|
+
# code - raw byte string
|
19
|
+
# symbols - a list of labels and other objects and their corresponding values
|
20
|
+
# options - a hash of configurable options:
|
21
|
+
# elf_class - 32 for ELFClass32 or 64 for ELFClass64 (default is 64)
|
22
|
+
# machine - a raw machine ID to fill in the e_machine field
|
23
|
+
#
|
24
|
+
def self.wrap_obj code, symbols, **options
|
25
|
+
|
26
|
+
elf_class = options[:elf_class] || 64
|
27
|
+
e_machine = options[:machine]
|
28
|
+
|
29
|
+
sections, shstrndx = create_default_sections(code, symbols, elf_class: elf_class).values
|
30
|
+
|
31
|
+
output = build(sections: sections, machine: e_machine, elf_class: elf_class, e_shstrndx: shstrndx, e_type: 1)
|
32
|
+
|
33
|
+
output
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# ELF Wrap Executable
|
38
|
+
# Wraps a raw program in the ELF executable format
|
39
|
+
#
|
40
|
+
# Arguments:
|
41
|
+
# code - raw byte string
|
42
|
+
# options - a hash of configurable options:
|
43
|
+
# elf_class - 32 for ELFClass32 or 64 for ELFClass64 (default is 64)
|
44
|
+
# machine - a raw machine ID to fill in the e_machine field
|
45
|
+
# vaddr - virtual address for the program and entry (default is 0x80000)
|
46
|
+
def self.wrap_exec code, symbols, **options
|
47
|
+
|
48
|
+
elf_class = options[:elf_class] || 64
|
49
|
+
e_machine = options[:machine]
|
50
|
+
vaddr = options[:vaddr] || 0x80000
|
51
|
+
|
52
|
+
sections, shstrndx = create_default_sections(code, symbols, elf_class: elf_class).values
|
53
|
+
|
54
|
+
sections[1][:addr] = vaddr
|
55
|
+
|
56
|
+
segments = [
|
57
|
+
{
|
58
|
+
type: 1, # Loadable segment
|
59
|
+
flags: 7, # Execute, write, read permissions
|
60
|
+
vaddr: vaddr, # Virtual address of segment in memory
|
61
|
+
# content: code,
|
62
|
+
content_section_i: 1,
|
63
|
+
align: 4
|
64
|
+
},
|
65
|
+
]
|
66
|
+
|
67
|
+
output = build(sections: sections, segments: segments, machine: e_machine, elf_class: elf_class, e_type: 2, virtual_entry_address: vaddr, e_shstrndx: shstrndx)
|
68
|
+
|
69
|
+
output
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
# Converts a label hash of name-address pairs into an array of symbols
|
76
|
+
def self.labels_to_symbols labels
|
77
|
+
out = []
|
78
|
+
labels.each do |name, value|
|
79
|
+
out << {name: name, value: value, type: 1, binding: 0}
|
80
|
+
end
|
81
|
+
out
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
# Build ELF
|
86
|
+
# Builds an ELF from provided sections, segments, and other options
|
87
|
+
#
|
88
|
+
# Arguments:
|
89
|
+
# sections - ELF sections (structure below)
|
90
|
+
# segments - ELF segments (structure below)
|
91
|
+
# machine - a raw machine ID for the ELF header
|
92
|
+
# virtual_entry_address - the virtual entry address for the ELF header
|
93
|
+
# elf_class - the ELF class (32 or 64)
|
94
|
+
# e_shstrndx - the value for ELF header's e_shstrndx field (index of the section header string table section)
|
95
|
+
# e_type - the value for ELF header's e_type field (e.g., 1 for relocatable, 3 for executable)
|
96
|
+
#
|
97
|
+
def self.build sections: [], segments: [], machine: nil, virtual_entry_address: 0, elf_class: 64, e_shstrndx: 0, e_type: 0
|
98
|
+
|
99
|
+
raise "Machine ID not specified for the ELF header." if machine == nil
|
100
|
+
|
101
|
+
case elf_class
|
102
|
+
when 64
|
103
|
+
elf_addr = 8
|
104
|
+
elf_off = 8
|
105
|
+
elf_half = 2
|
106
|
+
elf_word = 4
|
107
|
+
elf_char = 1
|
108
|
+
elf_xword = 8
|
109
|
+
elf_header_size = 64
|
110
|
+
elf_shentsize = 64
|
111
|
+
elf_phentsize = 56
|
112
|
+
when 32
|
113
|
+
elf_addr = 4
|
114
|
+
elf_off = 4
|
115
|
+
elf_half = 2
|
116
|
+
elf_word = 4
|
117
|
+
elf_char = 1
|
118
|
+
elf_xword = 4
|
119
|
+
elf_header_size = 52
|
120
|
+
elf_shentsize = 40
|
121
|
+
elf_phentsize = 32
|
122
|
+
else
|
123
|
+
raise "Invalid elf_class - must be 32 or 64."
|
124
|
+
end
|
125
|
+
|
126
|
+
# Calculate section header and program header sizes
|
127
|
+
sh_size = sections.size * elf_shentsize
|
128
|
+
ph_size = segments.size * elf_phentsize
|
129
|
+
|
130
|
+
# Calculate the offsets for the section header and program header
|
131
|
+
# In this method, the section header is placed right after the ELF header, and the program header is placed right after the section header
|
132
|
+
elf_shoff = elf_header_size
|
133
|
+
elf_phoff = elf_shoff + sh_size
|
134
|
+
|
135
|
+
|
136
|
+
file_content = PackedBytes.new
|
137
|
+
|
138
|
+
elf_header = PackedBytes.new
|
139
|
+
|
140
|
+
e_ident = PackedBytes.new
|
141
|
+
|
142
|
+
# Magic number
|
143
|
+
e_ident.bytes [127]
|
144
|
+
e_ident.bytes "ELF"
|
145
|
+
|
146
|
+
# EI_Class
|
147
|
+
case elf_class
|
148
|
+
when 64
|
149
|
+
e_ident.bytes 2, elf_char
|
150
|
+
when 32
|
151
|
+
e_ident.bytes 1, elf_char
|
152
|
+
end
|
153
|
+
|
154
|
+
# EI_Data (LSB)
|
155
|
+
e_ident.bytes 1, elf_char
|
156
|
+
|
157
|
+
|
158
|
+
# EI_Version (current)
|
159
|
+
e_ident.bytes 1, elf_char
|
160
|
+
|
161
|
+
e_ident.align 16, "\0"
|
162
|
+
|
163
|
+
elf_header.add e_ident
|
164
|
+
|
165
|
+
# E_Type (input)
|
166
|
+
elf_header.bytes e_type, elf_half
|
167
|
+
|
168
|
+
# E_Machine (input)
|
169
|
+
elf_header.bytes machine, elf_half
|
170
|
+
|
171
|
+
# E_version (current)
|
172
|
+
elf_header.bytes 1, elf_word
|
173
|
+
|
174
|
+
# E_entry (input)
|
175
|
+
elf_header.bytes virtual_entry_address, elf_addr
|
176
|
+
|
177
|
+
# E_phoff (calculated earlier)
|
178
|
+
# If there aren't any segments, the elf_phoff should be zero
|
179
|
+
if segments.size == 0
|
180
|
+
elf_header.bytes 0, elf_off
|
181
|
+
else
|
182
|
+
elf_header.bytes elf_phoff, elf_off
|
183
|
+
end
|
184
|
+
|
185
|
+
# E_shoff (calculated earlier)
|
186
|
+
# If there aren't any sections, the elf_shoff should be zero
|
187
|
+
if sections.size == 0
|
188
|
+
elf_header.bytes 0, elf_off
|
189
|
+
else
|
190
|
+
elf_header.bytes elf_shoff, elf_off
|
191
|
+
end
|
192
|
+
|
193
|
+
# E_flags
|
194
|
+
elf_header.bytes 0, elf_word
|
195
|
+
|
196
|
+
# E_ehsize (ELF header size)
|
197
|
+
elf_header.bytes elf_header_size, elf_half
|
198
|
+
|
199
|
+
# E_phentsize
|
200
|
+
elf_header.bytes elf_phentsize, elf_half
|
201
|
+
|
202
|
+
# E_phnum
|
203
|
+
elf_header.bytes segments.size, elf_half
|
204
|
+
|
205
|
+
# E_shentsize
|
206
|
+
elf_header.bytes elf_shentsize, elf_half
|
207
|
+
|
208
|
+
# E_shnum
|
209
|
+
elf_header.bytes sections.size, elf_half
|
210
|
+
|
211
|
+
# E_shstrndx
|
212
|
+
elf_header.bytes e_shstrndx, elf_half
|
213
|
+
|
214
|
+
file_content.add elf_header
|
215
|
+
|
216
|
+
|
217
|
+
# Used later
|
218
|
+
sections_contents_offset = elf_phoff + ph_size
|
219
|
+
|
220
|
+
sections_content = PackedBytes.new
|
221
|
+
|
222
|
+
sections.each_with_index do |section, section_i|
|
223
|
+
if !section.keys.include?(:content)
|
224
|
+
section[:size] = 0
|
225
|
+
section[:offset] = 0
|
226
|
+
next
|
227
|
+
end
|
228
|
+
|
229
|
+
matching_segments = segments.filter{_1[:content_section_i] == section_i}
|
230
|
+
|
231
|
+
largest_alignment = matching_segments.map{|segment| segment[:align] || 1}.max || 1
|
232
|
+
|
233
|
+
file_offset = sections_content.result.bytesize + sections_contents_offset
|
234
|
+
|
235
|
+
if file_offset % largest_alignment != 0
|
236
|
+
sections_content.bytes [0] * (largest_alignment - (file_offset % largest_alignment))
|
237
|
+
end
|
238
|
+
|
239
|
+
section[:size] = section[:content].bytesize
|
240
|
+
section[:offset] = sections_content.result.bytesize + sections_contents_offset
|
241
|
+
|
242
|
+
matching_segments.each do |segment|
|
243
|
+
segment[:offset] = 0 if !segment.keys.include?(:offset)
|
244
|
+
segment[:offset] += section[:offset]
|
245
|
+
|
246
|
+
segment[:size] = section[:size] if !segment.keys.include?(:size)
|
247
|
+
end
|
248
|
+
|
249
|
+
sections_content.add section[:content]
|
250
|
+
end
|
251
|
+
|
252
|
+
|
253
|
+
segments_content = PackedBytes.new
|
254
|
+
|
255
|
+
segments_contents_offset = sections_contents_offset + sections_content.result.bytesize
|
256
|
+
|
257
|
+
segments.each_with_index do |segment, segment_i|
|
258
|
+
|
259
|
+
if !segment.keys.include?(:align)
|
260
|
+
segment[:align] = 1
|
261
|
+
end
|
262
|
+
|
263
|
+
if !segment.keys.include?(:vaddr)
|
264
|
+
segment[:vaddr] = 0
|
265
|
+
end
|
266
|
+
|
267
|
+
if !segment.keys.include?(:paddr)
|
268
|
+
segment[:paddr] = segment[:vaddr]
|
269
|
+
end
|
270
|
+
|
271
|
+
if segment.keys.include?(:content)
|
272
|
+
segment[:size] = segment[:content].bytesize
|
273
|
+
end
|
274
|
+
|
275
|
+
if !segment.keys.include?(:vsize)
|
276
|
+
segment[:vsize] = segment[:size]
|
277
|
+
end
|
278
|
+
|
279
|
+
if segment[:vaddr] % segment[:align] != 0
|
280
|
+
raise "Improper segment at index #{segment_i} - the virtual address is not aligned to the specified alignment boundary."
|
281
|
+
end
|
282
|
+
|
283
|
+
|
284
|
+
if segment.keys.include? :content_section_i
|
285
|
+
next
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
# ELF requires file_offset and vaddr to be a multiple of the alignment value
|
290
|
+
|
291
|
+
file_offset = segments_contents_offset + segments_content.result.bytesize
|
292
|
+
|
293
|
+
pad_amount = 0
|
294
|
+
if file_offset % segment[:align] != 0
|
295
|
+
pad_amount = segment[:align] - (file_offset % segment[:align])
|
296
|
+
end
|
297
|
+
|
298
|
+
segments_content.bytes "\0" * pad_amount
|
299
|
+
|
300
|
+
segment[:offset] = segments_content.result.bytesize + segments_contents_offset
|
301
|
+
segments_content.add segment[:content]
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
|
306
|
+
sh = PackedBytes.new
|
307
|
+
|
308
|
+
sections.each do |section|
|
309
|
+
sh.bytes section[:name_offset], elf_word
|
310
|
+
sh.bytes section[:type], elf_word
|
311
|
+
sh.bytes section[:flags], elf_xword
|
312
|
+
sh.bytes section[:addr], elf_addr
|
313
|
+
sh.bytes section[:offset], elf_off
|
314
|
+
sh.bytes section[:size], elf_xword
|
315
|
+
sh.bytes section[:link], elf_word
|
316
|
+
sh.bytes section[:info], elf_word
|
317
|
+
sh.bytes section[:addralign], elf_xword
|
318
|
+
sh.bytes section[:entsize], elf_xword
|
319
|
+
end
|
320
|
+
|
321
|
+
|
322
|
+
file_content.add sh
|
323
|
+
|
324
|
+
|
325
|
+
ph = PackedBytes.new
|
326
|
+
|
327
|
+
segments.each do |segment|
|
328
|
+
ph.bytes segment[:type], elf_word
|
329
|
+
ph.bytes segment[:flags], elf_word
|
330
|
+
ph.bytes segment[:offset], elf_off
|
331
|
+
ph.bytes segment[:vaddr], elf_addr
|
332
|
+
ph.bytes segment[:paddr], elf_addr
|
333
|
+
ph.bytes segment[:size], elf_xword
|
334
|
+
ph.bytes segment[:vsize], elf_xword
|
335
|
+
ph.bytes segment[:align], elf_xword
|
336
|
+
end
|
337
|
+
|
338
|
+
file_content.add ph
|
339
|
+
|
340
|
+
|
341
|
+
file_content.add sections_content
|
342
|
+
|
343
|
+
file_content.add segments_content
|
344
|
+
|
345
|
+
|
346
|
+
return file_content.result
|
347
|
+
end
|
348
|
+
|
349
|
+
|
350
|
+
|
351
|
+
# Builds a basic section structure with one progbits section and one symbol table
|
352
|
+
|
353
|
+
def self.create_default_sections program_bytes, symbols, elf_class: 64
|
354
|
+
|
355
|
+
case elf_class
|
356
|
+
when 64
|
357
|
+
symtab_ent_size = 24
|
358
|
+
elf_char = 1
|
359
|
+
elf_half = 2
|
360
|
+
elf_word = 4
|
361
|
+
elf_addr = 8
|
362
|
+
elf_off = 8
|
363
|
+
elf_xword = 8
|
364
|
+
when 32
|
365
|
+
symtab_ent_size = 16
|
366
|
+
elf_char = 1
|
367
|
+
elf_half = 2
|
368
|
+
elf_word = 4
|
369
|
+
elf_addr = 8
|
370
|
+
elf_off = 8
|
371
|
+
elf_xword = 8
|
372
|
+
end
|
373
|
+
|
374
|
+
sym_strtab_section_index = 3
|
375
|
+
sh_strtab_section_index = 4
|
376
|
+
symtab_section_index = 2
|
377
|
+
progbits_section_index = 1
|
378
|
+
|
379
|
+
sections = [
|
380
|
+
# First section is all zeros
|
381
|
+
{
|
382
|
+
type: 0,
|
383
|
+
flags: 0,
|
384
|
+
addr: 0,
|
385
|
+
link: 0,
|
386
|
+
info: 0,
|
387
|
+
addralign: 0,
|
388
|
+
entsize: 0,
|
389
|
+
},
|
390
|
+
{
|
391
|
+
name: ".text",
|
392
|
+
type: 1,
|
393
|
+
flags: 7,
|
394
|
+
addr: 0,
|
395
|
+
link: 0,
|
396
|
+
info: 0,
|
397
|
+
addralign: 4,
|
398
|
+
entsize: 0,
|
399
|
+
content: program_bytes,
|
400
|
+
},
|
401
|
+
{
|
402
|
+
name: ".symtab",
|
403
|
+
type: 2,
|
404
|
+
flags: 0,
|
405
|
+
addr: 0,
|
406
|
+
link: sym_strtab_section_index, # Index of string table used for symbol names
|
407
|
+
info: symbols.size + 1, # Index of first non-local symbol
|
408
|
+
addralign: 0,
|
409
|
+
entsize: symtab_ent_size,
|
410
|
+
content: "",
|
411
|
+
},
|
412
|
+
{
|
413
|
+
name: ".strtab",
|
414
|
+
type: 3,
|
415
|
+
flags: 0,
|
416
|
+
addr: 0,
|
417
|
+
link: 0,
|
418
|
+
info: 0,
|
419
|
+
addralign: 0,
|
420
|
+
entsize: 0,
|
421
|
+
content: "",
|
422
|
+
},
|
423
|
+
{
|
424
|
+
name: ".shstrtab",
|
425
|
+
type: 3,
|
426
|
+
flags: 0,
|
427
|
+
addr: 0,
|
428
|
+
link: 0,
|
429
|
+
info: 0,
|
430
|
+
addralign: 0,
|
431
|
+
entsize: 0,
|
432
|
+
content: "",
|
433
|
+
},
|
434
|
+
]
|
435
|
+
|
436
|
+
symtab = PackedBytes.new
|
437
|
+
|
438
|
+
# First section is all zeros
|
439
|
+
symtab.bytes [0] * symtab_ent_size
|
440
|
+
|
441
|
+
|
442
|
+
symtab_string_table_content = "\0".encode("ASCII")
|
443
|
+
|
444
|
+
symbols.each do |symbol|
|
445
|
+
|
446
|
+
if symbol.keys.include? :name
|
447
|
+
name_offset = symtab_string_table_content.bytesize
|
448
|
+
symtab_string_table_content << symbol[:name] + "\0"
|
449
|
+
else
|
450
|
+
name_offset = 0
|
451
|
+
end
|
452
|
+
|
453
|
+
# name
|
454
|
+
symtab.bytes name_offset, elf_word
|
455
|
+
|
456
|
+
symbol_info = symbol[:type] | (symbol[:binding] << 4)
|
457
|
+
|
458
|
+
# info
|
459
|
+
symtab.bytes symbol_info, elf_char
|
460
|
+
|
461
|
+
# other (must be zero)
|
462
|
+
symtab.bytes 0, elf_char
|
463
|
+
|
464
|
+
# section index of where the symbol is located
|
465
|
+
symtab.bytes progbits_section_index, elf_half
|
466
|
+
|
467
|
+
# symbol value
|
468
|
+
symtab.bytes symbol[:value], elf_addr
|
469
|
+
|
470
|
+
# symbol size
|
471
|
+
symbol_size = symbol[:size] || 0
|
472
|
+
symtab.bytes symbol_size, elf_xword
|
473
|
+
end
|
474
|
+
|
475
|
+
sections[symtab_section_index][:content] = symtab.result
|
476
|
+
sections[sym_strtab_section_index][:content] = symtab_string_table_content
|
477
|
+
|
478
|
+
|
479
|
+
sections_string_table_content = "\0"
|
480
|
+
|
481
|
+
sections.each_with_index do |section, section_i|
|
482
|
+
if section.keys.include? :name
|
483
|
+
section[:name_offset] = sections_string_table_content.bytesize
|
484
|
+
sections_string_table_content << section[:name] + "\0"
|
485
|
+
else
|
486
|
+
section[:name_offset] = 0
|
487
|
+
end
|
488
|
+
end
|
489
|
+
|
490
|
+
sections[sh_strtab_section_index][:content] = sections_string_table_content
|
491
|
+
|
492
|
+
return {sections: sections, shstrndx: sh_strtab_section_index}
|
493
|
+
|
494
|
+
end
|
495
|
+
|
496
|
+
end # Kompiler::ELF
|
497
|
+
end # Kompiler::Wrappers
|
498
|
+
|
499
|
+
end # Kompiler
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class PackedBytes
|
2
|
+
def initialize bytes = ""
|
3
|
+
@bytes = bytes.dup
|
4
|
+
end
|
5
|
+
|
6
|
+
def uint8 n
|
7
|
+
n = [n] if n.is_a? Numeric
|
8
|
+
@bytes << n.pack("C*")
|
9
|
+
end
|
10
|
+
|
11
|
+
def uint16 n
|
12
|
+
n = [n] if n.is_a? Numeric
|
13
|
+
@bytes << n.pack("S<*")
|
14
|
+
end
|
15
|
+
|
16
|
+
def uint32 n
|
17
|
+
n = [n] if n.is_a? Numeric
|
18
|
+
@bytes << n.pack("L<*")
|
19
|
+
end
|
20
|
+
|
21
|
+
def uint64 n
|
22
|
+
n = [n] if n.is_a? Numeric
|
23
|
+
@bytes << n.pack("Q<*")
|
24
|
+
end
|
25
|
+
|
26
|
+
def bytes bytes, n_bytes=nil
|
27
|
+
if n_bytes == nil
|
28
|
+
if bytes.is_a? PackedBytes
|
29
|
+
@bytes += bytes.result
|
30
|
+
elsif bytes.is_a? String
|
31
|
+
@bytes += bytes
|
32
|
+
elsif bytes.is_a? Array
|
33
|
+
@bytes += bytes.pack("C*")
|
34
|
+
end
|
35
|
+
else
|
36
|
+
case n_bytes
|
37
|
+
when 1
|
38
|
+
self.uint8 bytes
|
39
|
+
when 2
|
40
|
+
self.uint16 bytes
|
41
|
+
when 4
|
42
|
+
self.uint32 bytes
|
43
|
+
when 8
|
44
|
+
self.uint64 bytes
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
alias_method :add, :bytes
|
49
|
+
|
50
|
+
def align n_bytes, pad_byte="\0"
|
51
|
+
if @bytes.size % n_bytes == 0
|
52
|
+
return
|
53
|
+
else
|
54
|
+
@bytes << pad_byte * (n_bytes - (@bytes.size % n_bytes))
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def result
|
59
|
+
@bytes
|
60
|
+
end
|
61
|
+
alias_method :get_bytes, :result
|
62
|
+
|
63
|
+
def to_file filename
|
64
|
+
File.binwrite filename, self.result
|
65
|
+
end
|
66
|
+
alias_method :write, :to_file
|
67
|
+
alias_method :save, :to_file
|
68
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'kompiler/wrappers/elf_wrapper'
|
data/lib/kompiler.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kompiler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.0
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kyryl Shyshko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2025-02
|
11
|
+
date: 2025-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: 'Kompiler is a low-level, modular and extendable compiler for any architecture.
|
14
14
|
By default Kompiler supports ARMv8-a, but other architecture extensions can be downloaded
|
@@ -30,6 +30,8 @@ files:
|
|
30
30
|
- lib/kompiler/architectures/armv8a/instructions.rb
|
31
31
|
- lib/kompiler/architectures/armv8a/load.rb
|
32
32
|
- lib/kompiler/architectures/armv8a/registers.rb
|
33
|
+
- lib/kompiler/architectures/armv8a/simd_fp_instructions.rb
|
34
|
+
- lib/kompiler/architectures/armv8a/simd_fp_registers.rb
|
33
35
|
- lib/kompiler/architectures/armv8a/sys_instructions.rb
|
34
36
|
- lib/kompiler/architectures/armv8a/sys_registers.rb
|
35
37
|
- lib/kompiler/compiler_functions.rb
|
@@ -38,6 +40,9 @@ files:
|
|
38
40
|
- lib/kompiler/math_ast.rb
|
39
41
|
- lib/kompiler/mc_builder.rb
|
40
42
|
- lib/kompiler/parsers.rb
|
43
|
+
- lib/kompiler/wrappers.rb
|
44
|
+
- lib/kompiler/wrappers/elf_wrapper.rb
|
45
|
+
- lib/kompiler/wrappers/packed_bytes.rb
|
41
46
|
homepage: https://github.com/kyryloshy/kompiler
|
42
47
|
licenses:
|
43
48
|
- Apache-2.0
|
@@ -59,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
59
64
|
- !ruby/object:Gem::Version
|
60
65
|
version: '0'
|
61
66
|
requirements: []
|
62
|
-
rubygems_version: 3.
|
67
|
+
rubygems_version: 3.4.10
|
63
68
|
signing_key:
|
64
69
|
specification_version: 4
|
65
70
|
summary: Kir's compiler for low-level machine code
|