kompiler 0.3.2 → 0.3.4
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 +373 -73
- data/lib/kompiler/alias_manager.rb +160 -0
- data/lib/kompiler/architectures/armv8a/instructions.rb +42 -0
- data/lib/kompiler/config/aliases +0 -0
- data/lib/kompiler/directives.rb +361 -5
- data/lib/kompiler/math_ast.rb +2 -2
- data/lib/kompiler/parsers.rb +1 -1
- data/lib/kompiler/wrappers/elf_wrapper.rb +2 -2
- data/lib/kompiler/wrappers/macho_wrapper.rb +889 -56
- data/lib/kompiler/wrappers/packed_bytes.rb +18 -4
- data/lib/kompiler.rb +1 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70dad0d1372236affa1fba712fff8b5a7d07d5cb99aa13fe41f4e39b92294901
|
4
|
+
data.tar.gz: 38345074dffd505b6ba7f99283bc851ed17e0d7afc7df684933e8bd3420854b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 42997a073796509d38379a196c0caafd0dfa3e5ee3c0f588072dd936dd84220e4186a963d78f75525075d79a72d549667daaae79915f60629bdca3b51b06461e
|
7
|
+
data.tar.gz: 925cccfb86ddd19a56798b8af0070e7217678fa4a0d3159064057885e40790a26a3b7e07ccc4775bd2a93614f428082bab8c8b68fe13c18c191fd456a1236330
|
data/bin/kompile
CHANGED
@@ -15,7 +15,7 @@
|
|
15
15
|
# limitations under the License.
|
16
16
|
|
17
17
|
require 'kompiler'
|
18
|
-
|
18
|
+
require 'fileutils'
|
19
19
|
|
20
20
|
arg_string = ARGV.join(" ")
|
21
21
|
|
@@ -26,10 +26,18 @@ arg_letters = []
|
|
26
26
|
|
27
27
|
current_i = 0
|
28
28
|
|
29
|
-
permitted_word_chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a + ["_", ".", "-"]
|
29
|
+
permitted_word_chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a + ["_", ".", "-", "[", "]"]
|
30
30
|
|
31
31
|
whitespace_chars = ["\t", " "]
|
32
32
|
|
33
|
+
|
34
|
+
$positive_opts = ["true", "yes"]
|
35
|
+
$negative_opts = ["false", "no"]
|
36
|
+
|
37
|
+
$bool_opts = $positive_opts + $negative_opts
|
38
|
+
|
39
|
+
|
40
|
+
|
33
41
|
def get_word string, permitted_word_chars, offset = 0
|
34
42
|
if string[0] == '"'
|
35
43
|
str_content, n_parsed = Kompiler::Parsers.parse_str(string[offset..])
|
@@ -77,7 +85,17 @@ while current_i < arg_string.size
|
|
77
85
|
|
78
86
|
letters, current_i = get_word(arg_string, permitted_word_chars, current_i)
|
79
87
|
|
80
|
-
|
88
|
+
if arg_string[current_i] == "="
|
89
|
+
current_i += 1
|
90
|
+
value, current_i = get_word(arg_string, permitted_word_chars, current_i)
|
91
|
+
|
92
|
+
arg_keys << [letters, value]
|
93
|
+
elsif whitespace_chars.include?(arg_string[current_i]) || current_i == arg_string.size
|
94
|
+
arg_letters += letters.chars
|
95
|
+
else
|
96
|
+
puts "Unrecognized argument syntax at index #{current_i}"
|
97
|
+
exit
|
98
|
+
end
|
81
99
|
|
82
100
|
next
|
83
101
|
end
|
@@ -90,6 +108,44 @@ end
|
|
90
108
|
|
91
109
|
|
92
110
|
|
111
|
+
|
112
|
+
def get_number str
|
113
|
+
bool, val = Kompiler::Parsers.check_immediate_operand(str)
|
114
|
+
return (bool == false) ? nil : val
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
def get_arg_key arg_keys, keys, default_value=0
|
119
|
+
keys = [keys] if !keys.is_a?(Array)
|
120
|
+
filtered = arg_keys.filter{keys.include? _1[0]}[0]
|
121
|
+
value = (filtered != nil) ? filtered[1] : default_value
|
122
|
+
return value
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
class String
|
127
|
+
def to_num
|
128
|
+
status, val = Kompiler::Parsers.check_immediate_operand(self)
|
129
|
+
return (status == false) ? nil : val[:value]
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def is_bool_opt opt
|
135
|
+
$bool_opts.include?(opt)
|
136
|
+
end
|
137
|
+
|
138
|
+
def is_pos_bool opt
|
139
|
+
$positive_opts.include? opt
|
140
|
+
end
|
141
|
+
|
142
|
+
def is_neg_bool opt
|
143
|
+
$negative_opts.include? opt
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
|
93
149
|
# Print the help screen if requested
|
94
150
|
if arg_opts.include?("help") || arg_letters.include?("h")
|
95
151
|
puts """Usage: kompile <input_file> [<output_file>] [compile_options]
|
@@ -100,35 +156,170 @@ Compile a file:
|
|
100
156
|
output_file Path to the output file (optional, default is out.bin)
|
101
157
|
|
102
158
|
Compilation options:
|
103
|
-
--arch=<arch_name
|
104
|
-
--wrap=<format
|
159
|
+
--arch=<arch_name>, -ar Compile for the specified architecture (optional, default is armv8a)
|
160
|
+
--wrap=<format>, -w Wrap the compiled program in the specified format (default is none)
|
161
|
+
--no-aliases, -n Specifies whether to use the aliases configuration file (default is yes)
|
162
|
+
--aliases-file=<file>, -a Loads the provided aliases file instead of the usual one
|
105
163
|
|
106
164
|
Available wrapping formats:
|
107
165
|
none
|
108
166
|
elf.obj
|
109
167
|
elf.exec
|
110
168
|
mach-o.obj
|
111
|
-
mach-o.exec
|
112
|
-
|
169
|
+
mach-o.exec
|
170
|
+
|
113
171
|
Additional options for wrapping are:
|
114
|
-
--elf-machine=<type
|
115
|
-
--elf-class=<class
|
116
|
-
--mach-o-machine=<cputype.subtype
|
117
|
-
|
118
|
-
--mach-o-archtype=<type
|
172
|
+
--elf-machine=<type>, -m Specifies ELF header's e_machine to be the type provided (default is 0)
|
173
|
+
--elf-class=<class>, -c Specifies the ELF file's class to either 32 or 64 (default is 64)
|
174
|
+
--mach-o-machine=<cputype.subtype>, -m Specifies Mach-O header's cputype and subtype
|
175
|
+
to be the type provided
|
176
|
+
--mach-o-archtype=<type>, -t Specifies the file architecture type to either 32 or 64 (default is 64)
|
177
|
+
--exec-type=<type>, -et Used with --wrap=mach-o.exec. Specifies whether the executable is
|
178
|
+
statically (static) or dynamically (dylink) linked (default is dylink)
|
179
|
+
--mach-o-threadstate=<type>, -ts Used with --wrap=mach-o.exec and --exec-type=static. Specifies which
|
180
|
+
thread state type to use (arm64, arm32, x86-64 or x86-32)
|
181
|
+
--codesign=<yes|no>, -cs Used with --wrap=mach-o.*. Specifies whether to add a basic
|
182
|
+
code signature to the Mach-O file (default is no)
|
119
183
|
|
120
184
|
Available options:
|
121
|
-
--help, -h
|
122
|
-
--list-architectures Lists available architectures
|
123
|
-
--list-instructions [arch]
|
124
|
-
--list-registers [arch]
|
185
|
+
--help, -h Prints this information
|
186
|
+
--list-architectures,-lar Lists available architectures
|
187
|
+
--list-instructions [arch],-li Lists available instructions for the specified architecture
|
188
|
+
--list-registers [arch],-lr Lists available registers for the specified architecture
|
189
|
+
--list-aliases,-la Lists instruction aliases in the current configuration
|
190
|
+
--compact,-c Used with --list-instructions or --list-registers to print compact information
|
191
|
+
|
192
|
+
Available options for controlling aliases:
|
193
|
+
--add-alias[es] index keyword aliases Add the specified aliases to the configuration
|
194
|
+
--remove-alias[es] index keyword aliases Remove the specified aliases from the configuration
|
195
|
+
--reset-aliases Resets aliases to an empty configuration
|
196
|
+
--import-aliases filename Set the provided configuration as the default aliases
|
197
|
+
--export-aliases filename Export the default aliases into a file
|
125
198
|
"""
|
126
199
|
exit # Exit
|
127
200
|
end
|
128
201
|
|
202
|
+
no_aliases = arg_opts.include?("no-aliases") || arg_letters.include?("n")
|
203
|
+
|
204
|
+
arg_opts.delete "no-aliases"
|
205
|
+
arg_letters.delete "n"
|
206
|
+
|
207
|
+
use_aliases = !no_aliases
|
208
|
+
|
209
|
+
aliases_file = get_arg_key(arg_keys, ["aliases-file", "a"], nil)
|
210
|
+
|
211
|
+
if aliases_file
|
212
|
+
aliases_file = File.expand_path(aliases_file)
|
213
|
+
end
|
214
|
+
|
215
|
+
if use_aliases
|
216
|
+
if aliases_file
|
217
|
+
Kompiler::AliasManager.import_aliases_file aliases_file
|
218
|
+
else
|
219
|
+
Kompiler::AliasManager.load_aliases()
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
if arg_opts == ["add-aliases"] || arg_opts == ["add-alias"]
|
225
|
+
idx = arg_words[0]
|
226
|
+
keyword = arg_words[1]
|
227
|
+
aliases = arg_words[2..]
|
228
|
+
if idx[0] == "[" && idx[-1] == "]"
|
229
|
+
idx = idx[1...-1]
|
230
|
+
end
|
231
|
+
idx = idx.to_i
|
232
|
+
|
233
|
+
Kompiler::AliasManager.add_alias idx, keyword, *aliases
|
234
|
+
|
235
|
+
if aliases_file
|
236
|
+
Kompiler::AliasManager.export_aliases_file aliases_file
|
237
|
+
else
|
238
|
+
Kompiler::AliasManager.save_aliases()
|
239
|
+
end
|
240
|
+
|
241
|
+
exit
|
242
|
+
end
|
243
|
+
|
244
|
+
if arg_opts == ["remove-aliases"] || arg_opts == ["remove-alias"]
|
245
|
+
idx = arg_words[0]
|
246
|
+
keyword = arg_words[1]
|
247
|
+
aliases = arg_words[2..]
|
248
|
+
if idx[0] == "[" && idx[-1] == "]"
|
249
|
+
idx = idx[1...-1]
|
250
|
+
end
|
251
|
+
idx = idx.to_i
|
252
|
+
|
253
|
+
Kompiler::AliasManager.remove_alias idx, keyword, *aliases
|
254
|
+
|
255
|
+
if aliases_file
|
256
|
+
Kompiler::AliasManager.export_aliases_file aliases_file
|
257
|
+
else
|
258
|
+
Kompiler::AliasManager.save_aliases()
|
259
|
+
end
|
260
|
+
|
261
|
+
exit
|
262
|
+
end
|
263
|
+
|
264
|
+
|
265
|
+
if arg_opts == ["reset-aliases"]
|
266
|
+
Kompiler::AliasManager.reset_aliases()
|
267
|
+
|
268
|
+
if aliases_file
|
269
|
+
Kompiler::AliasManager.export_aliases_file aliases_file
|
270
|
+
else
|
271
|
+
Kompiler::AliasManager.save_aliases()
|
272
|
+
end
|
273
|
+
|
274
|
+
exit
|
275
|
+
end
|
276
|
+
|
277
|
+
|
278
|
+
if arg_opts == ["import-aliases"]
|
279
|
+
filename = arg_words[0]
|
280
|
+
if filename == nil
|
281
|
+
puts "kompile: A file path must be provided with --aliases-import."
|
282
|
+
puts "Type \"kompile --help\" for more information."
|
283
|
+
exit
|
284
|
+
end
|
285
|
+
filename = File.expand_path(filename)
|
286
|
+
if !File.exist?(filename)
|
287
|
+
puts "kompile: File \"#{filename}\" does not exist."
|
288
|
+
exit
|
289
|
+
end
|
290
|
+
Kompiler::AliasManager.import_aliases_file(filename)
|
291
|
+
Kompiler::AliasManager.save_aliases()
|
292
|
+
|
293
|
+
exit
|
294
|
+
end
|
295
|
+
|
296
|
+
if arg_opts == ["export-aliases"]
|
297
|
+
filename = arg_words[0]
|
298
|
+
if filename == nil
|
299
|
+
puts "kompile: A file path must be provided with --aliases-import."
|
300
|
+
puts "Type \"kompile --help\" for more information."
|
301
|
+
exit
|
302
|
+
end
|
303
|
+
filename = File.expand_path(filename)
|
304
|
+
|
305
|
+
Kompiler::AliasManager.export_aliases_file(filename)
|
306
|
+
|
307
|
+
exit
|
308
|
+
end
|
309
|
+
|
310
|
+
if arg_opts.include?("list-aliases") || arg_letters == ["l", "a"]
|
311
|
+
max_index = Kompiler::AliasManager.aliases.map{_1[:index]}.max
|
312
|
+
pad_width = max_index.to_s.size + 2
|
313
|
+
Kompiler::AliasManager.aliases.each do |alias_entry|
|
314
|
+
idx_string = alias_entry[:index].to_s
|
315
|
+
puts "[#{idx_string}]" + " " * (pad_width - idx_string.size) + "#{alias_entry[:keyword]}: " + alias_entry[:aliases].join(" ")
|
316
|
+
end
|
317
|
+
exit
|
318
|
+
end
|
319
|
+
|
129
320
|
|
130
321
|
# Print the available architectures if requested
|
131
|
-
if arg_opts == ["
|
322
|
+
if arg_opts.include?("list-architectures") || arg_letters == ["l", "a", "r"]
|
132
323
|
Kompiler::ArchManager.load_all_entries()
|
133
324
|
puts "Available architectures:"
|
134
325
|
|
@@ -138,31 +329,82 @@ if arg_opts == ["list-architectures"]
|
|
138
329
|
exit # Exit
|
139
330
|
end
|
140
331
|
|
141
|
-
if arg_opts == ["
|
332
|
+
if arg_opts.include?("list-instructions") || arg_letters[...2] == ["l", "i"]
|
142
333
|
arch_name = arg_words[0] || "armv8a"
|
143
334
|
Kompiler::ArchManager.load_all_entries()
|
144
|
-
|
335
|
+
Kompiler::ArchManager.load_arch arch_name
|
336
|
+
|
337
|
+
Kompiler::AliasManager.apply_aliases()
|
338
|
+
|
339
|
+
if !(arg_opts.include?("compact") || arg_letters.include?("c"))
|
340
|
+
|
341
|
+
# Calculate the size of the index column
|
342
|
+
idx_col_width = [7, (Kompiler::Architecture.instructions.length + 1).to_s.size + 3].max
|
343
|
+
|
344
|
+
console_width = IO.console.winsize[1] rescue 80
|
345
|
+
|
346
|
+
desc_col_width = console_width - idx_col_width
|
347
|
+
|
348
|
+
desc_col_padding = " " * idx_col_width
|
145
349
|
|
146
|
-
|
350
|
+
Kompiler::Architecture.instructions.each_with_index do |instruction, index|
|
351
|
+
|
352
|
+
display_index = (index + 1).to_s
|
353
|
+
|
354
|
+
print "[#{display_index}]"
|
355
|
+
|
356
|
+
print " " * (idx_col_width - 2 - display_index.bytesize)
|
357
|
+
|
358
|
+
print instruction[:keyword]
|
359
|
+
|
360
|
+
print " "
|
361
|
+
|
362
|
+
puts instruction[:operands].map{"<" + (_1[:name] || _1[:type] || "") + ">"}.join(" ")
|
363
|
+
|
364
|
+
desc = instruction[:description] || ""
|
365
|
+
|
366
|
+
puts desc_col_padding + desc
|
367
|
+
|
368
|
+
|
369
|
+
if instruction.keys.include?(:aliases) && instruction[:aliases].size > 0
|
370
|
+
aliases_str = "Aliases: " + instruction[:aliases].join(" ")
|
371
|
+
puts desc_col_padding + aliases_str
|
372
|
+
end
|
373
|
+
|
374
|
+
print "\n"
|
375
|
+
end
|
376
|
+
|
377
|
+
else
|
378
|
+
|
379
|
+
strings = []
|
380
|
+
|
381
|
+
Kompiler::Architecture.instructions.each_with_index do |instruction, index|
|
382
|
+
str = "#{index + 1} #{instruction[:keyword]}"
|
383
|
+
strings << str
|
384
|
+
end
|
385
|
+
|
386
|
+
puts strings.join(", ")
|
147
387
|
|
148
|
-
Kompiler::Architecture.instructions.each do |instr|
|
149
|
-
puts "#{instr[:keyword]} (#{instr[:operands].size} operands): #{instr[:name]}"
|
150
|
-
puts instr[:description]
|
151
|
-
puts
|
152
388
|
end
|
153
389
|
|
154
390
|
exit
|
155
391
|
end
|
156
392
|
|
157
|
-
|
393
|
+
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
if arg_opts.include?("list-registers") || arg_letters[...2] == ["l", "r"]
|
158
398
|
arch_name = arg_words[0] || "armv8a"
|
159
399
|
Kompiler::ArchManager.load_all_entries()
|
160
|
-
|
161
|
-
|
162
|
-
require arch[:include_path]
|
400
|
+
Kompiler::ArchManager.load_arch(arch_name)
|
163
401
|
|
164
|
-
|
165
|
-
|
402
|
+
if !(arg_opts.include?("compact") || arg_letters.include?("c"))
|
403
|
+
Kompiler::Architecture.registers.each do |reg|
|
404
|
+
puts "#{reg[:reg_name]}"
|
405
|
+
end
|
406
|
+
else
|
407
|
+
puts Kompiler::Architecture.registers.map{_1[:reg_name]}.join(", ")
|
166
408
|
end
|
167
409
|
|
168
410
|
exit
|
@@ -199,19 +441,7 @@ end
|
|
199
441
|
|
200
442
|
|
201
443
|
|
202
|
-
|
203
|
-
wrap_opt = arg_keys.select{_1[0] == "wrap"}
|
204
|
-
|
205
|
-
|
206
|
-
if wrap_opt.size > 1
|
207
|
-
puts "kompile: Only one wrapping option can be provided with \"--wrap\"."
|
208
|
-
puts "Type \"kompile --help\" for more information."
|
209
|
-
exit
|
210
|
-
elsif wrap_opt.size == 1
|
211
|
-
wrap_opt = wrap_opt[0][1]
|
212
|
-
else
|
213
|
-
wrap_opt = "none"
|
214
|
-
end
|
444
|
+
wrap_opt = get_arg_key(arg_keys, ["wrap", "w"], "none")
|
215
445
|
|
216
446
|
|
217
447
|
if !["elf.obj", "elf.exec", "mach-o.obj", "mach-o.exec", "none"].include?(wrap_opt)
|
@@ -222,18 +452,9 @@ end
|
|
222
452
|
|
223
453
|
|
224
454
|
|
455
|
+
arch_name = get_arg_key(arg_keys, ["arch", "ar"], "armv8a")
|
225
456
|
|
226
|
-
arch_opt = arg_keys.select{_1[0] == "arch"}
|
227
457
|
|
228
|
-
if arch_opt.size > 1
|
229
|
-
puts "kompile: Only one architecture can be provided with \"--arch\"."
|
230
|
-
puts "Type \"kompile --help\" for more information."
|
231
|
-
exit
|
232
|
-
elsif arch_opt.size == 1
|
233
|
-
arch_name = arch_opt[0][1]
|
234
|
-
else
|
235
|
-
arch_name = "armv8a"
|
236
|
-
end
|
237
458
|
|
238
459
|
# Load all the architecture entries
|
239
460
|
|
@@ -258,6 +479,10 @@ end
|
|
258
479
|
|
259
480
|
|
260
481
|
|
482
|
+
Kompiler::AliasManager.apply_aliases()
|
483
|
+
|
484
|
+
|
485
|
+
|
261
486
|
code = File.binread(in_filename)
|
262
487
|
|
263
488
|
detailed_out = Kompiler::CompilerFunctions.detailed_compile(code)
|
@@ -272,44 +497,119 @@ labels = detailed_out[:labels]
|
|
272
497
|
labels.delete "here"
|
273
498
|
|
274
499
|
|
500
|
+
|
501
|
+
add_exec_permission = false
|
502
|
+
|
503
|
+
|
275
504
|
case wrap_opt
|
276
505
|
when "none"
|
277
506
|
out = code
|
278
507
|
when "elf.obj"
|
279
|
-
elf_machine = arg_keys
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
508
|
+
elf_machine = get_arg_key(arg_keys, ["elf-machine", "m"], "0").to_num
|
509
|
+
elf_class = get_arg_key(arg_keys, ["elf-class", "c"], "64").to_num
|
510
|
+
|
511
|
+
if ![32, 64].include?(elf_class)
|
512
|
+
puts "kompile: Invalid ELF class specified."
|
513
|
+
puts "Type \"kompile --help\" for more information."
|
514
|
+
exit
|
515
|
+
end
|
285
516
|
|
286
517
|
symbols = Kompiler::Wrappers::ELF.labels_to_symbols(labels)
|
287
518
|
out = Kompiler::Wrappers::ELF.wrap_obj(code, symbols, machine: elf_machine, elf_class: elf_class)
|
288
519
|
when "elf.exec"
|
289
|
-
|
290
|
-
elf_machine = (elf_machine != nil) ? elf_machine[1].to_i : 0
|
520
|
+
vaddr = 0x80000
|
291
521
|
|
292
|
-
|
293
|
-
elf_class
|
294
|
-
elf_class = elf_class[1].to_i
|
522
|
+
elf_machine = get_arg_key(arg_keys, ["elf-machine", "m"], "0").to_num
|
523
|
+
elf_class = get_arg_key(arg_keys, ["elf-class", "c"], "64").to_num
|
295
524
|
|
296
|
-
|
297
|
-
|
525
|
+
if ![32, 64].include?(elf_class)
|
526
|
+
puts "kompile: Invalid ELF class specified."
|
527
|
+
puts "Type \"kompile --help\" for more information."
|
528
|
+
exit
|
529
|
+
end
|
530
|
+
|
531
|
+
|
532
|
+
symbols = Kompiler::Wrappers::ELF.labels_to_symbols(labels, vaddr: vaddr)
|
533
|
+
out = Kompiler::Wrappers::ELF.wrap_exec(code, symbols, machine: elf_machine, elf_class: elf_class, vaddr: vaddr)
|
534
|
+
|
535
|
+
add_exec_permission = true
|
536
|
+
|
298
537
|
when "mach-o.obj"
|
299
|
-
macho_cpu = arg_keys
|
300
|
-
|
301
|
-
|
538
|
+
macho_cpu = get_arg_key(arg_keys, ["mach-o-machine", "m"], "0.0")
|
539
|
+
cputype, cpusubtype = macho_cpu.split(".").map(&:to_num)
|
540
|
+
|
541
|
+
if [cputype, cpusubtype].include? nil
|
542
|
+
puts "kompile: Invalid Mach-O machine specified."
|
543
|
+
puts "Type \"kompile --help\" for more information."
|
544
|
+
exit
|
545
|
+
end
|
546
|
+
|
547
|
+
arch_type = get_arg_key(arg_keys, ["mach-o-archtype", "at"], "64").to_num
|
548
|
+
|
549
|
+
codesign = get_arg_key(arg_keys, ["codesign", "cs"], "false")
|
550
|
+
if !is_bool_opt(codesign)
|
551
|
+
puts "kompile: Invalid --codesign value."
|
552
|
+
puts "Type \"kompile --help\" for more information."
|
553
|
+
exit
|
554
|
+
end
|
302
555
|
|
303
|
-
|
304
|
-
arch_type = (arch_type != nil) ? arch_type[1].to_i : 64
|
556
|
+
codesign = is_pos_bool(codesign)
|
305
557
|
|
306
558
|
symbols = Kompiler::Wrappers::MachO.labels_to_symbols(labels)
|
307
559
|
out = Kompiler::Wrappers::MachO.wrap_obj(code, symbols, cputype: cputype, cpusubtype: cpusubtype, arch_type: arch_type)
|
308
560
|
when "mach-o.exec"
|
309
|
-
|
310
|
-
|
561
|
+
macho_cpu = get_arg_key(arg_keys, ["mach-o-machine", "m"], "0.0")
|
562
|
+
cputype, cpusubtype = macho_cpu.split(".").map(&:to_num)
|
563
|
+
|
564
|
+
if [cputype, cpusubtype].include? nil
|
565
|
+
puts "kompile: Invalid Mach-O machine specified."
|
566
|
+
puts "Type \"kompile --help\" for more information."
|
567
|
+
exit
|
568
|
+
end
|
569
|
+
|
570
|
+
arch_type = get_arg_key(arg_keys, ["mach-o-archtype", "t"], "64").to_num
|
571
|
+
|
572
|
+
codesign = get_arg_key(arg_keys, ["codesign", "cs"], "false")
|
573
|
+
if !is_bool_opt(codesign)
|
574
|
+
puts "kompile: Invalid --codesign value."
|
575
|
+
puts "Type \"kompile --help\" for more information."
|
576
|
+
exit
|
577
|
+
end
|
578
|
+
|
579
|
+
exec_type = get_arg_key(arg_keys, ["exec-type", "et"], "dylink")
|
580
|
+
|
581
|
+
|
582
|
+
codesign = is_pos_bool(codesign)
|
583
|
+
|
584
|
+
|
585
|
+
case exec_type
|
586
|
+
when "dylink"
|
587
|
+
symbols = Kompiler::Wrappers::MachO.labels_to_symbols(labels)
|
588
|
+
out = Kompiler::Wrappers::MachO.wrap_exec_dylink(code, symbols, cputype: cputype, cpusubtype: cpusubtype, arch_type: arch_type, codesign: codesign)
|
589
|
+
when "static"
|
590
|
+
symbols = Kompiler::Wrappers::MachO.labels_to_symbols(labels)
|
591
|
+
|
592
|
+
thread_state_arch = get_arg_key(arg_keys, ["mach-o-threadstate", "ts"], "arm64")
|
593
|
+
|
594
|
+
entry_address = 0x1000000
|
595
|
+
|
596
|
+
thread_state = Kompiler::Wrappers::MachO.build_thread_state arch: thread_state_arch, entry_address: 0x1000000, stack_pointer: 0
|
597
|
+
|
598
|
+
out = Kompiler::Wrappers::MachO.wrap_exec_static(code, symbols, cputype: cputype, cpusubtype: cpusubtype, arch_type: arch_type, thread_state: thread_state, codesign: codesign, virtual_entry_address: entry_address)
|
599
|
+
|
600
|
+
else
|
601
|
+
puts "kompile: Invalid Mach-O executable type specified."
|
602
|
+
puts "Type \"kompile --help\" for more information."
|
603
|
+
exit
|
604
|
+
end
|
605
|
+
|
606
|
+
add_exec_permission = true
|
311
607
|
end
|
312
608
|
|
313
609
|
|
314
610
|
File.binwrite out_filename, out
|
315
611
|
|
612
|
+
if add_exec_permission
|
613
|
+
FileUtils.chmod "+x", out_filename
|
614
|
+
end
|
615
|
+
|