evoasm 0.0.2.pre7 → 0.1.0.pre2
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/.gdbinit +41 -0
- data/.gitignore +1 -2
- data/.gitmodules +3 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +4 -0
- data/LICENSE.md +660 -0
- data/Makefile +1 -1
- data/README.md +17 -9
- data/Rakefile +39 -107
- data/bin/gdb +1 -1
- data/bin/gdb_loop +4 -0
- data/docs/FindingInstructions.md +17 -0
- data/docs/JIT.md +14 -0
- data/docs/SymbolicRegression.md +102 -0
- data/docs/Visualization.md +29 -0
- data/docs/examples/bit_insts.rb +44 -0
- data/docs/examples/jit.rb +26 -0
- data/docs/examples/loss.gif +0 -0
- data/docs/examples/program.png +0 -0
- data/docs/examples/sym_reg.rb +64 -0
- data/docs/examples/vis.rb +38 -0
- data/evoasm.gemspec +21 -15
- data/ext/evoasm_ext/Rakefile +3 -0
- data/ext/evoasm_ext/compile.rake +35 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
- data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
- data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
- data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
- data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
- data/lib/evoasm.rb +28 -11
- data/lib/evoasm/buffer.rb +105 -0
- data/lib/evoasm/capstone.rb +100 -0
- data/lib/evoasm/domain.rb +116 -0
- data/lib/evoasm/error.rb +37 -16
- data/lib/evoasm/exception_error.rb +19 -0
- data/lib/evoasm/ffi_ext.rb +53 -0
- data/lib/evoasm/libevoasm.rb +286 -0
- data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
- data/lib/evoasm/parameter.rb +20 -0
- data/lib/evoasm/population.rb +145 -0
- data/lib/evoasm/population/parameters.rb +227 -0
- data/lib/evoasm/population/plotter.rb +89 -0
- data/lib/evoasm/prng.rb +64 -0
- data/lib/evoasm/program.rb +195 -12
- data/lib/evoasm/program/io.rb +144 -0
- data/lib/evoasm/test.rb +8 -0
- data/lib/evoasm/version.rb +1 -1
- data/lib/evoasm/x64.rb +115 -0
- data/lib/evoasm/x64/cpu_state.rb +95 -0
- data/lib/evoasm/x64/instruction.rb +109 -0
- data/lib/evoasm/x64/operand.rb +156 -0
- data/lib/evoasm/x64/parameters.rb +211 -0
- data/test/helpers/population_helper.rb +128 -0
- data/test/helpers/test_helper.rb +1 -0
- data/test/helpers/x64_helper.rb +24 -0
- data/test/integration/bitwise_reverse_test.rb +41 -0
- data/test/integration/gcd_test.rb +52 -0
- data/test/integration/popcnt_test.rb +46 -0
- data/test/integration/sym_reg_test.rb +68 -0
- data/test/unit/evoasm/buffer_test.rb +48 -0
- data/test/unit/evoasm/capstone_test.rb +18 -0
- data/test/unit/evoasm/domain_test.rb +55 -0
- data/test/unit/evoasm/population/parameters_test.rb +106 -0
- data/test/unit/evoasm/population_test.rb +96 -0
- data/test/unit/evoasm/prng_test.rb +47 -0
- data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
- data/test/unit/evoasm/x64/encoding_test.rb +320 -0
- data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
- data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
- data/test/unit/evoasm/x64/instruction_test.rb +62 -0
- data/test/unit/evoasm/x64/parameters_test.rb +65 -0
- data/test/unit/evoasm/x64_test.rb +52 -0
- metadata +195 -89
- data/Gemfile.rake +0 -8
- data/Gemfile.rake.lock +0 -51
- data/LICENSE.txt +0 -373
- data/data/tables/README.md +0 -19
- data/data/tables/x64.csv +0 -1684
- data/data/templates/evoasm-x64.c.erb +0 -319
- data/data/templates/evoasm-x64.h.erb +0 -126
- data/examples/abs.yml +0 -20
- data/examples/popcnt.yml +0 -17
- data/examples/sym_reg.yml +0 -26
- data/exe/evoasm-search +0 -13
- data/ext/evoasm_ext/evoasm-alloc.c +0 -145
- data/ext/evoasm_ext/evoasm-alloc.h +0 -59
- data/ext/evoasm_ext/evoasm-arch.c +0 -44
- data/ext/evoasm_ext/evoasm-arch.h +0 -161
- data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
- data/ext/evoasm_ext/evoasm-buf.c +0 -130
- data/ext/evoasm_ext/evoasm-buf.h +0 -47
- data/ext/evoasm_ext/evoasm-error.c +0 -31
- data/ext/evoasm_ext/evoasm-error.h +0 -75
- data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
- data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
- data/ext/evoasm_ext/evoasm-log.h +0 -69
- data/ext/evoasm_ext/evoasm-misc.c +0 -23
- data/ext/evoasm_ext/evoasm-misc.h +0 -282
- data/ext/evoasm_ext/evoasm-param.h +0 -37
- data/ext/evoasm_ext/evoasm-search.c +0 -2145
- data/ext/evoasm_ext/evoasm-search.h +0 -214
- data/ext/evoasm_ext/evoasm-util.h +0 -40
- data/ext/evoasm_ext/evoasm-x64.c +0 -275624
- data/ext/evoasm_ext/evoasm-x64.h +0 -5436
- data/ext/evoasm_ext/evoasm.c +0 -7
- data/ext/evoasm_ext/evoasm.h +0 -23
- data/ext/evoasm_ext/evoasm_ext.c +0 -1757
- data/ext/evoasm_ext/extconf.rb +0 -31
- data/lib/evoasm/cli.rb +0 -6
- data/lib/evoasm/cli/search.rb +0 -127
- data/lib/evoasm/core_ext.rb +0 -1
- data/lib/evoasm/core_ext/array.rb +0 -9
- data/lib/evoasm/core_ext/integer.rb +0 -10
- data/lib/evoasm/core_ext/kwstruct.rb +0 -13
- data/lib/evoasm/core_ext/range.rb +0 -5
- data/lib/evoasm/examples.rb +0 -27
- data/lib/evoasm/gen.rb +0 -8
- data/lib/evoasm/gen/enum.rb +0 -169
- data/lib/evoasm/gen/name_util.rb +0 -80
- data/lib/evoasm/gen/state.rb +0 -176
- data/lib/evoasm/gen/state_dsl.rb +0 -152
- data/lib/evoasm/gen/strio.rb +0 -27
- data/lib/evoasm/gen/translator.rb +0 -1102
- data/lib/evoasm/gen/version.rb +0 -5
- data/lib/evoasm/gen/x64.rb +0 -237
- data/lib/evoasm/gen/x64/funcs.rb +0 -495
- data/lib/evoasm/gen/x64/inst.rb +0 -781
- data/lib/evoasm/search.rb +0 -40
- data/lib/evoasm/tasks/gen_task.rb +0 -86
- data/lib/evoasm/tasks/template_task.rb +0 -52
- data/test/test_helper.rb +0 -1
- data/test/x64/test_helper.rb +0 -19
- data/test/x64/x64_test.rb +0 -87
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'evoasm'
|
|
2
|
+
require 'evoasm/x64'
|
|
3
|
+
|
|
4
|
+
buffer = Evoasm::Buffer.new 1024
|
|
5
|
+
Evoasm::X64.emit_stack_frame buffer do
|
|
6
|
+
Evoasm::X64.encode(:mov_rm32_imm32, {reg0: :a, imm0: 1}, buffer)
|
|
7
|
+
Evoasm::X64.encode(:mov_rm32_imm32, {reg0: :b, imm0: 2}, buffer)
|
|
8
|
+
Evoasm::X64.encode(:add_r32_rm32, {reg0: :a, reg1: :b}, buffer)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
puts "Result: #{buffer.execute!}"
|
|
12
|
+
|
|
13
|
+
buffer.reset
|
|
14
|
+
|
|
15
|
+
Evoasm::X64.emit_stack_frame buffer do
|
|
16
|
+
Evoasm::X64.encode(:mov_rm32_imm32, {reg0: :b, imm0: 0}, buffer)
|
|
17
|
+
Evoasm::X64.encode(:mov_rm32_imm32, {reg0: :a, imm0: 100}, buffer)
|
|
18
|
+
Evoasm::X64.encode(:div_rm64, {reg0: :b}, buffer)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
begin
|
|
22
|
+
buffer.execute!
|
|
23
|
+
rescue Evoasm::ExceptionError => e
|
|
24
|
+
puts "Execution failed with exception `#{e.exception_name}'"
|
|
25
|
+
end
|
|
26
|
+
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
require 'evoasm'
|
|
2
|
+
require 'evoasm/x64'
|
|
3
|
+
|
|
4
|
+
Evoasm.log_level = :warn
|
|
5
|
+
|
|
6
|
+
examples = {
|
|
7
|
+
0.0 => 0.0,
|
|
8
|
+
0.5 => 1.0606601717798212,
|
|
9
|
+
1.0 => 1.7320508075688772,
|
|
10
|
+
1.5 => 2.5248762345905194,
|
|
11
|
+
2.0 => 3.4641016151377544,
|
|
12
|
+
2.5 => 4.541475531146237,
|
|
13
|
+
3.0 => 5.744562646538029,
|
|
14
|
+
3.5 => 7.0622234459127675,
|
|
15
|
+
4.0 => 8.48528137423857,
|
|
16
|
+
4.5 => 10.00624804809475,
|
|
17
|
+
5.0 => 11.61895003862225
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
parameters = Evoasm::Population::Parameters.new do |p|
|
|
21
|
+
p.instructions = Evoasm::X64.instruction_names(:xmm).grep /(add|mul|sqrt).*?sd/
|
|
22
|
+
p.examples = examples
|
|
23
|
+
p.deme_size = 1024
|
|
24
|
+
p.deme_count = 1
|
|
25
|
+
p.kernel_size = 10
|
|
26
|
+
p.program_size = 1
|
|
27
|
+
p.parameters = %i(reg0 reg1 reg2 reg3)
|
|
28
|
+
|
|
29
|
+
regs = %i(xmm0 xmm1 xmm2 xmm3)
|
|
30
|
+
|
|
31
|
+
p.domains = {
|
|
32
|
+
reg0: regs,
|
|
33
|
+
reg1: regs,
|
|
34
|
+
reg2: regs,
|
|
35
|
+
reg3: regs
|
|
36
|
+
}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
puts "Supported features:"
|
|
40
|
+
Evoasm::X64.features.each do |feature, supported|
|
|
41
|
+
puts "\t#{feature.to_s.upcase}: #{supported ? 'YES' : 'NO'}"
|
|
42
|
+
end
|
|
43
|
+
puts
|
|
44
|
+
|
|
45
|
+
population = Evoasm::Population.new parameters
|
|
46
|
+
program, loss = population.run
|
|
47
|
+
|
|
48
|
+
puts program.disassemble format: true
|
|
49
|
+
|
|
50
|
+
puts
|
|
51
|
+
|
|
52
|
+
puts program.run 6.0
|
|
53
|
+
puts program.run 7.0
|
|
54
|
+
|
|
55
|
+
puts
|
|
56
|
+
|
|
57
|
+
program = program.eliminate_introns
|
|
58
|
+
puts program.disassemble format: true
|
|
59
|
+
|
|
60
|
+
puts
|
|
61
|
+
|
|
62
|
+
puts program.run 6.0
|
|
63
|
+
puts program.run 7.0
|
|
64
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'evoasm'
|
|
2
|
+
require 'evoasm/x64'
|
|
3
|
+
|
|
4
|
+
Evoasm.log_level = :warn
|
|
5
|
+
|
|
6
|
+
examples = {
|
|
7
|
+
[5, 1] => 1,
|
|
8
|
+
[15, 5] => 5,
|
|
9
|
+
[8, 2] => 2,
|
|
10
|
+
[8, 4] => 4,
|
|
11
|
+
[8, 6] => 2,
|
|
12
|
+
[16, 8] => 8,
|
|
13
|
+
[16, 2] => 2,
|
|
14
|
+
[100, 10] => 10,
|
|
15
|
+
[60, 10] => 10
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
parameters = Evoasm::Population::Parameters.new do |p|
|
|
19
|
+
p.instructions = Evoasm::X64.instruction_names(:gp, :rflags)
|
|
20
|
+
p.examples = examples
|
|
21
|
+
p.deme_size = 2048
|
|
22
|
+
p.parameters = %i(reg0 reg1 reg2 reg3)
|
|
23
|
+
p.kernel_size = 20
|
|
24
|
+
p.program_size = 3
|
|
25
|
+
p.mutation_rate = 0.03
|
|
26
|
+
p.deme_count = 2
|
|
27
|
+
p.recur_limit = 100
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
population = Evoasm::Population.new parameters
|
|
31
|
+
program, loss = population.run do
|
|
32
|
+
p "gen"
|
|
33
|
+
population.plot File.join(__dir__, 'loss.gif')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
p loss
|
|
37
|
+
|
|
38
|
+
program.to_gv.save File.join(__dir__, 'program.png')
|
data/evoasm.gemspec
CHANGED
|
@@ -4,27 +4,33 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
4
4
|
require 'evoasm/version'
|
|
5
5
|
|
|
6
6
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name =
|
|
7
|
+
spec.name = 'evoasm'
|
|
8
8
|
spec.version = Evoasm::VERSION
|
|
9
|
-
spec.authors = [
|
|
10
|
-
spec.email = [
|
|
11
|
-
spec.summary = %q{An AIMGP
|
|
12
|
-
spec.
|
|
13
|
-
spec.
|
|
9
|
+
spec.authors = ['Julian Aron Prenner (furunkel)']
|
|
10
|
+
spec.email = ['furunkel@polyadic.com']
|
|
11
|
+
spec.summary = %q{An AIMGP engine}
|
|
12
|
+
spec.description = %q{An AIMGP (Automatic Induction of Machine code by Genetic Programming) engine}
|
|
13
|
+
spec.homepage = 'https://github.com/evoasm/evoasm/'
|
|
14
|
+
spec.license = 'AGPL-3.0'
|
|
14
15
|
|
|
15
16
|
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.files += Dir['ext/evoasm_ext/**/*.[ch]']
|
|
16
18
|
spec.bindir = 'exe'
|
|
17
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
18
20
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
-
spec.require_paths = [
|
|
20
|
-
spec.extensions =
|
|
21
|
+
spec.require_paths = ['lib']
|
|
22
|
+
spec.extensions = %w(ext/evoasm_ext/Rakefile)
|
|
21
23
|
|
|
22
|
-
spec.add_dependency
|
|
23
|
-
spec.add_dependency
|
|
24
|
+
spec.add_dependency 'pastel', '~> 0.6'
|
|
25
|
+
spec.add_dependency 'ffi', '~> 1.9'
|
|
26
|
+
spec.add_dependency 'gv', '~> 0.1'
|
|
27
|
+
spec.add_dependency 'haml', '~> 4.0'
|
|
24
28
|
|
|
25
|
-
spec.add_development_dependency
|
|
26
|
-
spec.add_development_dependency
|
|
27
|
-
spec.add_development_dependency
|
|
28
|
-
spec.add_development_dependency '
|
|
29
|
-
spec.add_development_dependency
|
|
29
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
|
30
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
31
|
+
spec.add_development_dependency 'rubocop', '~> 0.41'
|
|
32
|
+
spec.add_development_dependency 'minitest', '~> 5.8'
|
|
33
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
|
34
|
+
spec.add_development_dependency 'redcarpet', '~> 3.3'
|
|
35
|
+
spec.add_development_dependency 'yard', '~> 0.9'
|
|
30
36
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'rake/clean'
|
|
2
|
+
require 'ffi'
|
|
3
|
+
|
|
4
|
+
SHARED_LIB = File.join(__dir__, FFI.map_library_name('evoasm'))
|
|
5
|
+
SRC_FILES = FileList[File.join __dir__, 'libevoasm/src/**/*.[ch]']
|
|
6
|
+
C_FILES = SRC_FILES.clone.exclude(/\.h$/).join(' ')
|
|
7
|
+
CC = ENV['cc'] || 'cc'
|
|
8
|
+
INC_FLAGS = %w(libevoasm/src).map { |dir| "-I#{File.join __dir__, dir}"}.join ' '
|
|
9
|
+
|
|
10
|
+
DEFS = ''
|
|
11
|
+
CFLAGS = ''
|
|
12
|
+
|
|
13
|
+
if ARGV.include?('--debug')
|
|
14
|
+
DEFS << ' -DEVOASM_LOG_LEVEL=EVOASM_LOG_LEVEL_DEBUG'
|
|
15
|
+
CFLAGS << ' -ggdb3 -O0'
|
|
16
|
+
else
|
|
17
|
+
DEFS << ' -DNDEBUG'
|
|
18
|
+
CFLAGS << ' -O3 -march=native'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
if ARGV.include?('--paranoid')
|
|
22
|
+
DEFS << ' -DEVOASM_ENABLE_PARANOID_MODE'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
unless ARGV.include?('--no-omp')
|
|
26
|
+
CFLAGS << ' -fopenmp'
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
CLEAN.include(SHARED_LIB)
|
|
30
|
+
|
|
31
|
+
desc "Compile shared library"
|
|
32
|
+
task :compile => [SHARED_LIB]
|
|
33
|
+
file SHARED_LIB => SRC_FILES do |t|
|
|
34
|
+
sh "#{CC} -shared -fPIC #{CFLAGS} #{DEFS} #{C_FILES} #{INC_FLAGS} -o #{SHARED_LIB}"
|
|
35
|
+
end
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2016 Julian Aron Prenner <jap@polyadic.com>
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
6
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "evoasm-alloc.h"
|
|
19
|
+
#include "evoasm.h"
|
|
20
|
+
|
|
21
|
+
#include <stdlib.h>
|
|
22
|
+
#include <errno.h>
|
|
23
|
+
|
|
24
|
+
EVOASM_DEF_LOG_TAG("alloc")
|
|
25
|
+
|
|
26
|
+
void *
|
|
27
|
+
evoasm_malloc(size_t size) {
|
|
28
|
+
void *ptr = malloc(size);
|
|
29
|
+
if(evoasm_unlikely(!ptr)) {
|
|
30
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
31
|
+
"Allocating %zu bytes via malloc failed: %s", size, strerror(errno));
|
|
32
|
+
return NULL;
|
|
33
|
+
}
|
|
34
|
+
return ptr;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
void *
|
|
38
|
+
evoasm_aligned_alloc(size_t align, size_t size) {
|
|
39
|
+
void *ptr = aligned_alloc(align, size);
|
|
40
|
+
if(evoasm_unlikely(!ptr)) {
|
|
41
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
42
|
+
"Allocating %zu bytes via aligned_alloc failed: %s", size, strerror(errno));
|
|
43
|
+
return NULL;
|
|
44
|
+
}
|
|
45
|
+
return ptr;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
void *
|
|
49
|
+
evoasm_calloc(size_t n, size_t size) {
|
|
50
|
+
void *ptr = calloc(n, size);
|
|
51
|
+
|
|
52
|
+
if(evoasm_unlikely(!ptr)) {
|
|
53
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
54
|
+
"Allocating %zux%zu (%zu) bytes via calloc failed: %s", n, size, n * size, strerror(errno));
|
|
55
|
+
return NULL;
|
|
56
|
+
}
|
|
57
|
+
return ptr;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
void *
|
|
61
|
+
evoasm_aligned_calloc(size_t align, size_t n, size_t size) {
|
|
62
|
+
if(evoasm_unlikely(size == 0 || n >= SIZE_MAX / size)) {
|
|
63
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
64
|
+
"Allocating %zux%zu bytes via aligned_calloc failed: integer overflow", n, size);
|
|
65
|
+
return NULL;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
size_t len = n * size;
|
|
69
|
+
void *ptr = evoasm_aligned_alloc(align, len);
|
|
70
|
+
|
|
71
|
+
if(evoasm_likely(ptr != NULL)) {
|
|
72
|
+
memset(ptr, 0, len);
|
|
73
|
+
}
|
|
74
|
+
return ptr;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
void *
|
|
78
|
+
evoasm_realloc(void *ptr, size_t size) {
|
|
79
|
+
void *new_ptr = realloc(ptr, size);
|
|
80
|
+
|
|
81
|
+
if(evoasm_unlikely(!ptr)) {
|
|
82
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
83
|
+
"Allocating %zu bytes via realloc failed: %s", size, strerror(errno));
|
|
84
|
+
return NULL;
|
|
85
|
+
}
|
|
86
|
+
return new_ptr;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
void
|
|
90
|
+
evoasm_free(void *ptr) {
|
|
91
|
+
free(ptr);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
void *
|
|
95
|
+
evoasm_mmap(size_t size, void *p) {
|
|
96
|
+
/* Note that mmap considers the pointer passed soley as a hint address
|
|
97
|
+
* and returns a valid address (possibly at a different address) in any case.
|
|
98
|
+
* VirtualAlloc, on the other hand, will return NULL if the address is
|
|
99
|
+
* not available
|
|
100
|
+
*/
|
|
101
|
+
void *mem;
|
|
102
|
+
|
|
103
|
+
#if defined(_WIN32)
|
|
104
|
+
retry:
|
|
105
|
+
mem = VirtualAlloc(p, size, MEM_COMMIT, PAGE_READWRITE);
|
|
106
|
+
if(mem == NULL) {
|
|
107
|
+
if(p != NULL) {
|
|
108
|
+
goto retry;
|
|
109
|
+
} else {
|
|
110
|
+
goto error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return mem;
|
|
114
|
+
#elif defined(_POSIX_VERSION)
|
|
115
|
+
mem = mmap(p, size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
|
116
|
+
if(mem == MAP_FAILED) {
|
|
117
|
+
goto error;
|
|
118
|
+
}
|
|
119
|
+
#else
|
|
120
|
+
#error
|
|
121
|
+
#endif
|
|
122
|
+
return mem;
|
|
123
|
+
|
|
124
|
+
error:
|
|
125
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
126
|
+
"Allocating %zu bytes via mmap failed: %s", size, strerror(errno));
|
|
127
|
+
return NULL;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
evoasm_success_t
|
|
131
|
+
evoasm_munmap(void *p, size_t size) {
|
|
132
|
+
bool ret;
|
|
133
|
+
#if defined(_WIN32)
|
|
134
|
+
ret = VirtualFree(p, size, MEM_DECOMMIT);
|
|
135
|
+
#elif defined(_POSIX_VERSION)
|
|
136
|
+
ret = (munmap(p, size) == 0);
|
|
137
|
+
#else
|
|
138
|
+
# error
|
|
139
|
+
#endif
|
|
140
|
+
|
|
141
|
+
if(!ret) {
|
|
142
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
143
|
+
"Unmapping %zu bytes via munmap failed: %s", size, strerror(errno));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return ret;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
#if defined(_WIN32)
|
|
151
|
+
#define EVOASM_MPROT_RW PAGE_READWRITE
|
|
152
|
+
#define EVOASM_MPROT_RX PAGE_EXECUTE_READ
|
|
153
|
+
#define EVOASM_MPROT_RWX PAGE_EXECUTE_READWRITE
|
|
154
|
+
#elif defined(_POSIX_VERSION)
|
|
155
|
+
#define EVOASM_MPROT_RW (PROT_READ|PROT_WRITE)
|
|
156
|
+
#define EVOASM_MPROT_RX (PROT_READ|PROT_EXEC)
|
|
157
|
+
#define EVOASM_MPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
|
|
158
|
+
#else
|
|
159
|
+
#error
|
|
160
|
+
#endif
|
|
161
|
+
|
|
162
|
+
evoasm_success_t
|
|
163
|
+
evoasm_mprot(void *p, size_t size, evoasm_mprot_mode_t mode) {
|
|
164
|
+
int mode_;
|
|
165
|
+
|
|
166
|
+
switch(mode) {
|
|
167
|
+
case EVOASM_MPROT_MODE_RW:
|
|
168
|
+
mode_ = EVOASM_MPROT_RW;
|
|
169
|
+
break;
|
|
170
|
+
case EVOASM_MPROT_MODE_RWX:
|
|
171
|
+
mode_ = EVOASM_MPROT_RWX;
|
|
172
|
+
break;
|
|
173
|
+
case EVOASM_MPROT_MODE_RX:
|
|
174
|
+
mode_ = EVOASM_MPROT_RX;
|
|
175
|
+
break;
|
|
176
|
+
default:
|
|
177
|
+
evoasm_assert_not_reached();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
#if defined(_WIN32)
|
|
182
|
+
if(VirtualProtect(p, size, mode_, NULL) != 0) {
|
|
183
|
+
goto error;
|
|
184
|
+
}
|
|
185
|
+
#elif defined(_POSIX_VERSION)
|
|
186
|
+
if(mprotect(p, size, mode_) != 0) {
|
|
187
|
+
goto error;
|
|
188
|
+
}
|
|
189
|
+
#else
|
|
190
|
+
#error
|
|
191
|
+
#endif
|
|
192
|
+
return true;
|
|
193
|
+
|
|
194
|
+
error:
|
|
195
|
+
evoasm_error(EVOASM_ERROR_TYPE_ALLOC, EVOASM_ERROR_CODE_NONE,
|
|
196
|
+
"Changing memory protection failed: %s", strerror(errno));
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
static size_t _evoasm_page_size = 0;
|
|
201
|
+
|
|
202
|
+
static long
|
|
203
|
+
evoasm_query_page_size() {
|
|
204
|
+
#if defined(_WIN32)
|
|
205
|
+
SYSTEM_INFO si;
|
|
206
|
+
GetSystemInfo(&si);
|
|
207
|
+
return si.dwPageSize;
|
|
208
|
+
#elif defined(_POSIX_VERSION)
|
|
209
|
+
return sysconf(_SC_PAGESIZE);
|
|
210
|
+
#else
|
|
211
|
+
#error
|
|
212
|
+
#endif
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
size_t
|
|
216
|
+
evoasm_get_page_size() {
|
|
217
|
+
if(_evoasm_page_size == 0) {
|
|
218
|
+
long page_size = evoasm_query_page_size();
|
|
219
|
+
if(page_size == -1) {
|
|
220
|
+
page_size = 4096;
|
|
221
|
+
evoasm_log_warn("requesting page size failed. This might cause problems.");
|
|
222
|
+
}
|
|
223
|
+
_evoasm_page_size = (size_t) page_size;
|
|
224
|
+
}
|
|
225
|
+
return (size_t) _evoasm_page_size;
|
|
226
|
+
}
|