kompiler 0.3.1 → 0.3.2
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 +13 -5
- data/lib/kompiler/directives.rb +29 -0
- data/lib/kompiler/wrappers/macho_wrapper.rb +441 -0
- data/lib/kompiler/wrappers.rb +1 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12bbbb642809ac234ac1cfdcd59b3d43362c0ba284a6286656fecc2cf5024e99
|
4
|
+
data.tar.gz: 86e653003489923b7a63bd24b0d6019b07fde08c10c8dc426357dca265b3445e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e729dfc9ee22702200ea082beef419bdbcbaa6bc2ba5a4cadbc2899f6442c6f65c163ec90675ce8d8e2fe41cd80e97cee445fb7386547e78f5569016bbba69ed
|
7
|
+
data.tar.gz: d88ba4f53b56086cae6e63f8308058f3f28735f8db671d122c3eecbd3270e5443a1945407b7e8e73b15859758897992f2183481f667282fea29ee57f47f2b494
|
data/bin/kompile
CHANGED
@@ -107,7 +107,7 @@ Available wrapping formats:
|
|
107
107
|
none
|
108
108
|
elf.obj
|
109
109
|
elf.exec
|
110
|
-
mach-o.obj
|
110
|
+
mach-o.obj
|
111
111
|
mach-o.exec [not implemented yet]
|
112
112
|
|
113
113
|
Additional options for wrapping are:
|
@@ -115,6 +115,7 @@ Additional options for wrapping are:
|
|
115
115
|
--elf-class=<class> Specifies the ELF file's class to either 32 or 64 (default is 64)
|
116
116
|
--mach-o-machine=<cputype.subtype> Specifies Mach-O header's cputype and subtype
|
117
117
|
to be the type provided
|
118
|
+
--mach-o-archtype=<type> Specifies the file architecture type to either 32 or 64 (default is 64)
|
118
119
|
|
119
120
|
Available options:
|
120
121
|
--help, -h Prints this information
|
@@ -261,7 +262,7 @@ code = File.binread(in_filename)
|
|
261
262
|
|
262
263
|
detailed_out = Kompiler::CompilerFunctions.detailed_compile(code)
|
263
264
|
|
264
|
-
#
|
265
|
+
# pp detailed_out
|
265
266
|
|
266
267
|
out = nil
|
267
268
|
|
@@ -295,10 +296,17 @@ when "elf.exec"
|
|
295
296
|
symbols = Kompiler::Wrappers::ELF.labels_to_symbols(labels)
|
296
297
|
out = Kompiler::Wrappers::ELF.wrap_exec(code, symbols, machine: elf_machine, elf_class: elf_class)
|
297
298
|
when "mach-o.obj"
|
298
|
-
|
299
|
-
|
299
|
+
macho_cpu = arg_keys.filter{_1[0] == "mach-o-machine"}[0]
|
300
|
+
macho_cpu = (macho_cpu != nil) ? macho_cpu[1] : "0.0"
|
301
|
+
cputype, cpusubtype = macho_cpu.split(".").map(&:to_i)
|
302
|
+
|
303
|
+
arch_type = arg_keys.filter{_1[0] == "mach-o-archtype"}[0]
|
304
|
+
arch_type = (arch_type != nil) ? arch_type[1].to_i : 64
|
305
|
+
|
306
|
+
symbols = Kompiler::Wrappers::MachO.labels_to_symbols(labels)
|
307
|
+
out = Kompiler::Wrappers::MachO.wrap_obj(code, symbols, cputype: cputype, cpusubtype: cpusubtype, arch_type: arch_type)
|
300
308
|
when "mach-o.exec"
|
301
|
-
puts "Mach-O not yet implemented."
|
309
|
+
puts "Mach-O executable not yet implemented."
|
302
310
|
exit
|
303
311
|
end
|
304
312
|
|
data/lib/kompiler/directives.rb
CHANGED
@@ -519,6 +519,35 @@ end
|
|
519
519
|
|
520
520
|
state[:line_i] += 1
|
521
521
|
|
522
|
+
state
|
523
|
+
end
|
524
|
+
},
|
525
|
+
{
|
526
|
+
keyword: "info",
|
527
|
+
func: lambda do |operands, state|
|
528
|
+
|
529
|
+
begin
|
530
|
+
info_name = operands[0][:definition]
|
531
|
+
info_value = operands[1][:definition]
|
532
|
+
rescue
|
533
|
+
puts "Incorrect use of the \".info\" directive."
|
534
|
+
end
|
535
|
+
|
536
|
+
|
537
|
+
state[:line_i] += 1
|
538
|
+
|
539
|
+
context_info = {}
|
540
|
+
|
541
|
+
context_info[:current_address] = state[:current_address]
|
542
|
+
|
543
|
+
context_info[:line_i] = state[:line_i]
|
544
|
+
|
545
|
+
state[:extra_state][:info_entries] ||= Hash.new
|
546
|
+
|
547
|
+
state[:extra_state][:info_entries][info_name] ||= Array.new
|
548
|
+
|
549
|
+
state[:extra_state][:info_entries][info_name] << {context_info: context_info, input_str: info_value, input_full: operands[1]}
|
550
|
+
|
522
551
|
state
|
523
552
|
end
|
524
553
|
}
|
@@ -0,0 +1,441 @@
|
|
1
|
+
require 'kompiler/wrappers/packed_bytes'
|
2
|
+
|
3
|
+
|
4
|
+
module Kompiler
|
5
|
+
|
6
|
+
module Wrappers
|
7
|
+
|
8
|
+
|
9
|
+
module MachO
|
10
|
+
|
11
|
+
MH_MAGIC_32 = 0xfeedface
|
12
|
+
MH_MAGIC_64 = 0xfeedfacf
|
13
|
+
|
14
|
+
|
15
|
+
def self.wrap_obj code, symbols, arch_type: 64, cputype: 0, cpusubtype: 0
|
16
|
+
|
17
|
+
segments = [
|
18
|
+
{
|
19
|
+
name: "__TEXT",
|
20
|
+
vaddr: 0,
|
21
|
+
vsize: code.bytesize,
|
22
|
+
maxprot: 7,
|
23
|
+
initprot: 7,
|
24
|
+
flags: 0,
|
25
|
+
|
26
|
+
sections: [
|
27
|
+
{
|
28
|
+
name: "__text",
|
29
|
+
vaddr: 0,
|
30
|
+
vsize: 0,
|
31
|
+
align: 1,
|
32
|
+
flags: 0,
|
33
|
+
content: code,
|
34
|
+
},
|
35
|
+
]
|
36
|
+
}
|
37
|
+
]
|
38
|
+
|
39
|
+
|
40
|
+
output = MachO.build(segments: segments, symbols: symbols, arch_type: arch_type, cputype: cputype, cpusubtype: cpusubtype, filetype: 1, align_section_contents: false)
|
41
|
+
|
42
|
+
return output
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
def self.build_macho_header arch_type: 64, cputype: 0, cpusubtype: 0, filetype: 0, ncmds: 0, sizeofcmds: 0, flags: 0
|
53
|
+
|
54
|
+
macho_header = PackedBytes.new
|
55
|
+
|
56
|
+
case arch_type
|
57
|
+
when 64
|
58
|
+
macho_header.uint32 MH_MAGIC_64
|
59
|
+
when 32
|
60
|
+
macho_header.uint32 MH_MAGIC_32
|
61
|
+
end
|
62
|
+
|
63
|
+
macho_header.uint32 cputype
|
64
|
+
macho_header.uint32 cpusubtype
|
65
|
+
|
66
|
+
macho_header.uint32 filetype
|
67
|
+
|
68
|
+
macho_header.uint32 ncmds
|
69
|
+
|
70
|
+
macho_header.uint32 sizeofcmds
|
71
|
+
|
72
|
+
macho_header.uint32 flags
|
73
|
+
|
74
|
+
if arch_type == 64
|
75
|
+
# Reserved field in 64-bit
|
76
|
+
macho_header.uint32 0
|
77
|
+
end
|
78
|
+
|
79
|
+
return macho_header
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Build a Mach-O file from the input segments, symbols and other pre-built load commands
|
84
|
+
#
|
85
|
+
# Arguments:
|
86
|
+
# segments - list of segments to include in the file (structure below)
|
87
|
+
# symbols - list of symbols to be included inside a single symtab (structure below)
|
88
|
+
# prebuilt_lcs - a list of other already built load commands (strings) to be included in the file
|
89
|
+
# arch_type - architecture type, either 32- or 64-bit (default is 64)
|
90
|
+
# cputype - Mach-O header cputype field
|
91
|
+
# cpusubtype - Mach-O header cpusubtype field
|
92
|
+
# filetype - Mach-O file type
|
93
|
+
# align_section_contents - specifies whether to align the contents of each section to its alignment boundary (default is false)
|
94
|
+
#
|
95
|
+
# Segment structure:
|
96
|
+
# name - the segment's name
|
97
|
+
# vaddr - virtual load address of the segment
|
98
|
+
# vsize - virtual size in memory of the segment
|
99
|
+
# maxprot - Mach-O segment maxprot field
|
100
|
+
# initprot - Mach-O segment initprot field
|
101
|
+
# flags - Mach-O segment flags field
|
102
|
+
# sections - a list of segment's section (structure below)
|
103
|
+
#
|
104
|
+
# Segment section structure:
|
105
|
+
# name - the section's name
|
106
|
+
# vaddr - virtual load address of section
|
107
|
+
# vsize - virtual size in memory of the section
|
108
|
+
# align - section's byte alignment
|
109
|
+
# flags - section's flags
|
110
|
+
# content - section's content
|
111
|
+
#
|
112
|
+
# Symbol structure:
|
113
|
+
# name - symbol's name
|
114
|
+
# value - symbol's value
|
115
|
+
# type - symbol's type field value
|
116
|
+
# sect - symbol's sect field value
|
117
|
+
# desc - symbol's desc field value
|
118
|
+
#
|
119
|
+
def self.build segments: [], symbols: [], prebuilt_lcs: [], arch_type: 64, cputype: 0, cpusubtype: 0, filetype: 0, align_section_contents: false
|
120
|
+
|
121
|
+
file_content = PackedBytes.new
|
122
|
+
|
123
|
+
case arch_type
|
124
|
+
when 32
|
125
|
+
flexval_size = 4
|
126
|
+
when 64
|
127
|
+
flexval_size = 8
|
128
|
+
end
|
129
|
+
|
130
|
+
segment_entry_size = 4 * 2 + 16 + flexval_size * 4 + 4 * 2 + 4 * 2
|
131
|
+
|
132
|
+
section_entry_size = 16 + 16 + flexval_size * 2 + 7 * 4
|
133
|
+
|
134
|
+
if arch_type == 64
|
135
|
+
section_entry_size += 4 # one more reserved field for 64-bit
|
136
|
+
end
|
137
|
+
|
138
|
+
symtab_entry_size = 4 * 6
|
139
|
+
|
140
|
+
|
141
|
+
n_sections = 1
|
142
|
+
|
143
|
+
prebuilt_lcs_size = prebuilt_lcs.map(&:bytesize).sum
|
144
|
+
|
145
|
+
cmds_size = segment_entry_size + section_entry_size * n_sections + symtab_entry_size + prebuilt_lcs_size
|
146
|
+
|
147
|
+
|
148
|
+
n_cmds = segments.size + 1 + prebuilt_lcs.size # One segment (with possibly multiple sections), one symtab
|
149
|
+
|
150
|
+
macho_header = build_macho_header(
|
151
|
+
arch_type: 64,
|
152
|
+
cputype: cputype,
|
153
|
+
cpusubtype: cpusubtype,
|
154
|
+
filetype: filetype,
|
155
|
+
ncmds: n_cmds,
|
156
|
+
sizeofcmds: cmds_size,
|
157
|
+
flags: 0
|
158
|
+
)
|
159
|
+
|
160
|
+
|
161
|
+
file_content.add macho_header
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
# Calculate where all of the content can be placed
|
166
|
+
contents_offset = cmds_size + file_content.result.bytesize
|
167
|
+
|
168
|
+
|
169
|
+
contents = ""
|
170
|
+
|
171
|
+
|
172
|
+
|
173
|
+
segments.each do |segment|
|
174
|
+
|
175
|
+
raise "Segment name is larger than 16 characters" if segment[:name].bytesize > 16
|
176
|
+
|
177
|
+
start_size = contents.bytesize
|
178
|
+
|
179
|
+
segment[:sections].each_with_index do |section, section_i|
|
180
|
+
|
181
|
+
raise "Section name \"#{section[:name]}\" is larger than 16 characters" if section[:name].bytesize > 16
|
182
|
+
|
183
|
+
section[:align] ||= 1
|
184
|
+
|
185
|
+
raise "Section alignment value cannot be 0" if section[:align] == 0
|
186
|
+
|
187
|
+
sec_offset = contents_offset + contents.bytesize
|
188
|
+
|
189
|
+
pad_amount = 0
|
190
|
+
if (sec_offset % section[:align] != 0) && align_sections
|
191
|
+
pad_amount = section[:align] - (sec_offset % section[:align])
|
192
|
+
end
|
193
|
+
|
194
|
+
sec_offset += pad_amount
|
195
|
+
contents << "\0" * pad_amount
|
196
|
+
|
197
|
+
section[:file_offset] = sec_offset
|
198
|
+
|
199
|
+
if section_i == 0
|
200
|
+
segment[:file_offset] = sec_offset
|
201
|
+
start_size = contents.bytesize
|
202
|
+
end
|
203
|
+
|
204
|
+
contents << section[:content]
|
205
|
+
|
206
|
+
section[:vaddr] ||= 0
|
207
|
+
section[:vsize] ||= section[:content].bytesize
|
208
|
+
end
|
209
|
+
|
210
|
+
end_size = contents.bytesize
|
211
|
+
|
212
|
+
segment[:file_offset] ||= 0
|
213
|
+
segment[:filesize] = end_size - start_size
|
214
|
+
|
215
|
+
segment[:vaddr] ||= 0
|
216
|
+
segment[:vsize] ||= segment[:filesize]
|
217
|
+
|
218
|
+
segment[:flags] ||= 0
|
219
|
+
|
220
|
+
segment[:maxprot] ||= 0
|
221
|
+
segment[:initprot] ||= 0
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
|
227
|
+
symtab_contents = PackedBytes.new
|
228
|
+
|
229
|
+
sym_strtab_contents = "\0"
|
230
|
+
|
231
|
+
symbols.each do |symbol|
|
232
|
+
if symbol.keys.include? :name
|
233
|
+
symbol[:name_offset] = sym_strtab_contents.bytesize
|
234
|
+
sym_strtab_contents << symbol[:name] + "\0"
|
235
|
+
else
|
236
|
+
symbol[:name_offset] = 0
|
237
|
+
end
|
238
|
+
|
239
|
+
symtab_contents.uint32 symbol[:name_offset]
|
240
|
+
symtab_contents.uint8 symbol[:type]
|
241
|
+
symtab_contents.uint8 symbol[:sect]
|
242
|
+
symtab_contents.uint16 symbol[:desc]
|
243
|
+
symtab_contents.bytes symbol[:value], flexval_size
|
244
|
+
end
|
245
|
+
|
246
|
+
|
247
|
+
symtab_offset = contents.bytesize + contents_offset
|
248
|
+
symtab_align = 8
|
249
|
+
|
250
|
+
if symtab_offset % symtab_align != 0
|
251
|
+
pad = (symtab_align - (symtab_offset % symtab_align))
|
252
|
+
contents << "\0" * pad
|
253
|
+
symtab_offset += pad
|
254
|
+
end
|
255
|
+
|
256
|
+
contents << symtab_contents.result
|
257
|
+
|
258
|
+
sym_strtab_offset = contents.bytesize + contents_offset
|
259
|
+
|
260
|
+
contents << sym_strtab_contents
|
261
|
+
|
262
|
+
|
263
|
+
|
264
|
+
load_commands = PackedBytes.new
|
265
|
+
|
266
|
+
|
267
|
+
segments.each do |segment|
|
268
|
+
|
269
|
+
case arch_type
|
270
|
+
when 64
|
271
|
+
load_commands.uint32 0x19 # LC_SEGMENT_64
|
272
|
+
when 32
|
273
|
+
load_commands.uint32 0x1 # LC_SEGMENT
|
274
|
+
end
|
275
|
+
|
276
|
+
load_commands.uint32 segment_entry_size + section_entry_size * segment[:sections].size
|
277
|
+
|
278
|
+
load_commands.bytes segment[:name] + "\0" * (16 - segment[:name].bytesize)
|
279
|
+
|
280
|
+
load_commands.bytes segment[:vaddr], flexval_size
|
281
|
+
load_commands.bytes segment[:vsize], flexval_size
|
282
|
+
|
283
|
+
load_commands.bytes segment[:file_offset], flexval_size
|
284
|
+
load_commands.bytes segment[:filesize], flexval_size
|
285
|
+
|
286
|
+
load_commands.uint32 segment[:maxprot]
|
287
|
+
load_commands.uint32 segment[:initprot]
|
288
|
+
|
289
|
+
load_commands.uint32 segment[:sections].size
|
290
|
+
|
291
|
+
load_commands.uint32 segment[:flags]
|
292
|
+
|
293
|
+
|
294
|
+
|
295
|
+
segment[:sections].each do |section|
|
296
|
+
|
297
|
+
load_commands.bytes section[:name] + "\0" * (16 - section[:name].bytesize)
|
298
|
+
load_commands.bytes segment[:name] + "\0" * (16 - segment[:name].bytesize)
|
299
|
+
|
300
|
+
load_commands.bytes section[:vaddr], flexval_size
|
301
|
+
load_commands.bytes section[:vsize], flexval_size
|
302
|
+
|
303
|
+
load_commands.uint32 section[:file_offset]
|
304
|
+
load_commands.uint32 section[:align]
|
305
|
+
|
306
|
+
load_commands.uint32 0 # reloff
|
307
|
+
load_commands.uint32 0 # nreloc
|
308
|
+
|
309
|
+
load_commands.uint32 section[:flags]
|
310
|
+
|
311
|
+
load_commands.uint32 0 # reserved 1
|
312
|
+
load_commands.uint32 0 # reserved 2
|
313
|
+
|
314
|
+
if arch_type == 64
|
315
|
+
load_commands.uint32 0 # reserved 3 (only in 64-bit)
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
# Symtab load command
|
324
|
+
|
325
|
+
load_commands.uint32 0x2 # LC_SYMTAB
|
326
|
+
load_commands.uint32 symtab_entry_size
|
327
|
+
|
328
|
+
load_commands.uint32 symtab_offset
|
329
|
+
load_commands.uint32 symbols.size
|
330
|
+
|
331
|
+
load_commands.uint32 sym_strtab_offset
|
332
|
+
load_commands.uint32 sym_strtab_contents.bytesize
|
333
|
+
|
334
|
+
|
335
|
+
load_commands.add prebuilt_lcs
|
336
|
+
|
337
|
+
|
338
|
+
file_content.add load_commands
|
339
|
+
|
340
|
+
|
341
|
+
file_content.add contents
|
342
|
+
|
343
|
+
|
344
|
+
return file_content.result
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
|
349
|
+
# Converts a hash of label name-address pairs into section symbols suitable for the MachO.build method
|
350
|
+
#
|
351
|
+
# Arguments:
|
352
|
+
# labels - the hash of labels
|
353
|
+
# section_index - index of the section the symbols belong to (default is 1)
|
354
|
+
# external - specifies if the label is external or not (default is false)
|
355
|
+
# private_external - specifies if the label is private external or not (default is false)
|
356
|
+
# debug_entry - specifies if the label is a debug entry or not (default is false)
|
357
|
+
def self.labels_to_symbols labels,
|
358
|
+
out = []
|
359
|
+
labels.each do |name, value|
|
360
|
+
out << create_symbol(name: name, value: value, type: :sect, external: false, section_number: 1)
|
361
|
+
end
|
362
|
+
return out
|
363
|
+
end
|
364
|
+
|
365
|
+
|
366
|
+
# Creates a symbol from input information suitable for the MachO.build method
|
367
|
+
#
|
368
|
+
# Arguments:
|
369
|
+
# name - the symbol's name
|
370
|
+
# value - the symbol's value
|
371
|
+
# type - the symbol's type: :undef, :abs, :sect, :prebound, :indirect (default is :sect)
|
372
|
+
# private_external - specifies whether the symbol is private external (default is false)
|
373
|
+
# external - specifies whether the symbol is external (default is false)
|
374
|
+
# debug_entry - specifies whether the symbol is a debugging entry (default is false)
|
375
|
+
# options - options depending on the symbol's type
|
376
|
+
#
|
377
|
+
# Type == :sect options:
|
378
|
+
# section_number - section number the symbol is defined in
|
379
|
+
#
|
380
|
+
def self.create_symbol name: nil, value: nil, type: :sect, private_external: false, external: false, debug_entry: false, **options
|
381
|
+
|
382
|
+
raise "No name provided for the symbol" if name == nil
|
383
|
+
raise "No value provided for the symbol" if value == nil
|
384
|
+
|
385
|
+
symbol = {name: name, value: value}
|
386
|
+
|
387
|
+
type_encodings = {undef: 0x0, abs: 0x2, sect: 0xe, prebound: 0xc, indirect: 0xa}
|
388
|
+
encoded_type = type_encodings[type]
|
389
|
+
|
390
|
+
raise "Unknown symbol type \"#{type}\" - must be :undef, :abs, :sect, :prebound, or :indirect." if encoded_type == nil
|
391
|
+
|
392
|
+
|
393
|
+
pext_bit = 0x0
|
394
|
+
if private_external == true
|
395
|
+
pext_bit = 0x10
|
396
|
+
end
|
397
|
+
|
398
|
+
ext_bit = 0x0
|
399
|
+
if external == true
|
400
|
+
ext_bit = 0x1
|
401
|
+
end
|
402
|
+
|
403
|
+
debug_entry_bit = 0x0
|
404
|
+
if debug_entry == true
|
405
|
+
debug_entry_bit = 0xe
|
406
|
+
end
|
407
|
+
|
408
|
+
type_field = encoded_type | pext_bit | ext_bit | debug_entry_bit
|
409
|
+
|
410
|
+
symbol[:type] = type_field
|
411
|
+
|
412
|
+
|
413
|
+
case type
|
414
|
+
when :undef
|
415
|
+
symbol[:sect] = 0
|
416
|
+
when :abs
|
417
|
+
symbol[:sect] = 0
|
418
|
+
when :sect
|
419
|
+
section_number = options[:section_number] || 0
|
420
|
+
raise "Section number too high - maximum is 255." if section_number > 255
|
421
|
+
symbol[:sect] = section_number
|
422
|
+
when :prebound
|
423
|
+
symbol[:sect] = 0
|
424
|
+
when :indirect
|
425
|
+
symbol[:sect] = 0
|
426
|
+
end
|
427
|
+
|
428
|
+
symbol[:desc] = 0
|
429
|
+
|
430
|
+
return symbol
|
431
|
+
end
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
end # Kompiler::Wrappers::MachO
|
436
|
+
|
437
|
+
end # Kompiler::Wrappers
|
438
|
+
|
439
|
+
end # Kompiler
|
440
|
+
|
441
|
+
|
data/lib/kompiler/wrappers.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.
|
4
|
+
version: 0.3.2
|
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-04-
|
11
|
+
date: 2025-04-06 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
|
@@ -42,6 +42,7 @@ files:
|
|
42
42
|
- lib/kompiler/parsers.rb
|
43
43
|
- lib/kompiler/wrappers.rb
|
44
44
|
- lib/kompiler/wrappers/elf_wrapper.rb
|
45
|
+
- lib/kompiler/wrappers/macho_wrapper.rb
|
45
46
|
- lib/kompiler/wrappers/packed_bytes.rb
|
46
47
|
homepage: https://github.com/kyryloshy/kompiler
|
47
48
|
licenses:
|