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.
Files changed (168) hide show
  1. checksums.yaml +4 -4
  2. data/.gdbinit +41 -0
  3. data/.gitignore +1 -2
  4. data/.gitmodules +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.md +660 -0
  8. data/Makefile +1 -1
  9. data/README.md +17 -9
  10. data/Rakefile +39 -107
  11. data/bin/gdb +1 -1
  12. data/bin/gdb_loop +4 -0
  13. data/docs/FindingInstructions.md +17 -0
  14. data/docs/JIT.md +14 -0
  15. data/docs/SymbolicRegression.md +102 -0
  16. data/docs/Visualization.md +29 -0
  17. data/docs/examples/bit_insts.rb +44 -0
  18. data/docs/examples/jit.rb +26 -0
  19. data/docs/examples/loss.gif +0 -0
  20. data/docs/examples/program.png +0 -0
  21. data/docs/examples/sym_reg.rb +64 -0
  22. data/docs/examples/vis.rb +38 -0
  23. data/evoasm.gemspec +21 -15
  24. data/ext/evoasm_ext/Rakefile +3 -0
  25. data/ext/evoasm_ext/compile.rake +35 -0
  26. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.c +226 -0
  27. data/ext/evoasm_ext/libevoasm/src/evoasm-alloc.h +84 -0
  28. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.c +52 -0
  29. data/ext/evoasm_ext/libevoasm/src/evoasm-arch.h +101 -0
  30. data/ext/evoasm_ext/libevoasm/src/evoasm-bitmap.h +158 -0
  31. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.c +204 -0
  32. data/ext/evoasm_ext/libevoasm/src/evoasm-buf.h +109 -0
  33. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.c +124 -0
  34. data/ext/evoasm_ext/libevoasm/src/evoasm-domain.h +279 -0
  35. data/ext/evoasm_ext/libevoasm/src/evoasm-error.c +65 -0
  36. data/ext/evoasm_ext/libevoasm/src/evoasm-error.h +108 -0
  37. data/ext/evoasm_ext/{evoasm-log.c → libevoasm/src/evoasm-log.c} +36 -18
  38. data/ext/evoasm_ext/libevoasm/src/evoasm-log.h +93 -0
  39. data/ext/evoasm_ext/libevoasm/src/evoasm-param.c +22 -0
  40. data/ext/evoasm_ext/libevoasm/src/evoasm-param.h +33 -0
  41. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.c +192 -0
  42. data/ext/evoasm_ext/libevoasm/src/evoasm-pop-params.h +60 -0
  43. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.c +1323 -0
  44. data/ext/evoasm_ext/libevoasm/src/evoasm-pop.h +107 -0
  45. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.c +116 -0
  46. data/ext/evoasm_ext/libevoasm/src/evoasm-program-io.h +60 -0
  47. data/ext/evoasm_ext/libevoasm/src/evoasm-program.c +1827 -0
  48. data/ext/evoasm_ext/libevoasm/src/evoasm-program.h +167 -0
  49. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.c +65 -0
  50. data/ext/evoasm_ext/libevoasm/src/evoasm-rand.h +76 -0
  51. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.c +106 -0
  52. data/ext/evoasm_ext/libevoasm/src/evoasm-signal.h +58 -0
  53. data/ext/evoasm_ext/libevoasm/src/evoasm-util.h +112 -0
  54. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.c +925 -0
  55. data/ext/evoasm_ext/libevoasm/src/evoasm-x64.h +277 -0
  56. data/ext/evoasm_ext/libevoasm/src/evoasm.c +28 -0
  57. data/ext/evoasm_ext/libevoasm/src/evoasm.h +35 -0
  58. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-enums.h +2077 -0
  59. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.c +191203 -0
  60. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-insts.h +1713 -0
  61. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.c +348 -0
  62. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-misc.h +93 -0
  63. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.c +51 -0
  64. data/ext/evoasm_ext/libevoasm/src/gen/evoasm-x64-params.h +509 -0
  65. data/lib/evoasm.rb +28 -11
  66. data/lib/evoasm/buffer.rb +105 -0
  67. data/lib/evoasm/capstone.rb +100 -0
  68. data/lib/evoasm/domain.rb +116 -0
  69. data/lib/evoasm/error.rb +37 -16
  70. data/lib/evoasm/exception_error.rb +19 -0
  71. data/lib/evoasm/ffi_ext.rb +53 -0
  72. data/lib/evoasm/libevoasm.rb +286 -0
  73. data/lib/evoasm/libevoasm/x64_enums.rb +1967 -0
  74. data/lib/evoasm/parameter.rb +20 -0
  75. data/lib/evoasm/population.rb +145 -0
  76. data/lib/evoasm/population/parameters.rb +227 -0
  77. data/lib/evoasm/population/plotter.rb +89 -0
  78. data/lib/evoasm/prng.rb +64 -0
  79. data/lib/evoasm/program.rb +195 -12
  80. data/lib/evoasm/program/io.rb +144 -0
  81. data/lib/evoasm/test.rb +8 -0
  82. data/lib/evoasm/version.rb +1 -1
  83. data/lib/evoasm/x64.rb +115 -0
  84. data/lib/evoasm/x64/cpu_state.rb +95 -0
  85. data/lib/evoasm/x64/instruction.rb +109 -0
  86. data/lib/evoasm/x64/operand.rb +156 -0
  87. data/lib/evoasm/x64/parameters.rb +211 -0
  88. data/test/helpers/population_helper.rb +128 -0
  89. data/test/helpers/test_helper.rb +1 -0
  90. data/test/helpers/x64_helper.rb +24 -0
  91. data/test/integration/bitwise_reverse_test.rb +41 -0
  92. data/test/integration/gcd_test.rb +52 -0
  93. data/test/integration/popcnt_test.rb +46 -0
  94. data/test/integration/sym_reg_test.rb +68 -0
  95. data/test/unit/evoasm/buffer_test.rb +48 -0
  96. data/test/unit/evoasm/capstone_test.rb +18 -0
  97. data/test/unit/evoasm/domain_test.rb +55 -0
  98. data/test/unit/evoasm/population/parameters_test.rb +106 -0
  99. data/test/unit/evoasm/population_test.rb +96 -0
  100. data/test/unit/evoasm/prng_test.rb +47 -0
  101. data/test/unit/evoasm/x64/cpu_state_test.rb +73 -0
  102. data/test/unit/evoasm/x64/encoding_test.rb +320 -0
  103. data/test/unit/evoasm/x64/instruction_access_test.rb +177 -0
  104. data/test/unit/evoasm/x64/instruction_encoding_test.rb +780 -0
  105. data/test/unit/evoasm/x64/instruction_test.rb +62 -0
  106. data/test/unit/evoasm/x64/parameters_test.rb +65 -0
  107. data/test/unit/evoasm/x64_test.rb +52 -0
  108. metadata +195 -89
  109. data/Gemfile.rake +0 -8
  110. data/Gemfile.rake.lock +0 -51
  111. data/LICENSE.txt +0 -373
  112. data/data/tables/README.md +0 -19
  113. data/data/tables/x64.csv +0 -1684
  114. data/data/templates/evoasm-x64.c.erb +0 -319
  115. data/data/templates/evoasm-x64.h.erb +0 -126
  116. data/examples/abs.yml +0 -20
  117. data/examples/popcnt.yml +0 -17
  118. data/examples/sym_reg.yml +0 -26
  119. data/exe/evoasm-search +0 -13
  120. data/ext/evoasm_ext/evoasm-alloc.c +0 -145
  121. data/ext/evoasm_ext/evoasm-alloc.h +0 -59
  122. data/ext/evoasm_ext/evoasm-arch.c +0 -44
  123. data/ext/evoasm_ext/evoasm-arch.h +0 -161
  124. data/ext/evoasm_ext/evoasm-bitmap.h +0 -114
  125. data/ext/evoasm_ext/evoasm-buf.c +0 -130
  126. data/ext/evoasm_ext/evoasm-buf.h +0 -47
  127. data/ext/evoasm_ext/evoasm-error.c +0 -31
  128. data/ext/evoasm_ext/evoasm-error.h +0 -75
  129. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +0 -121
  130. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +0 -86
  131. data/ext/evoasm_ext/evoasm-log.h +0 -69
  132. data/ext/evoasm_ext/evoasm-misc.c +0 -23
  133. data/ext/evoasm_ext/evoasm-misc.h +0 -282
  134. data/ext/evoasm_ext/evoasm-param.h +0 -37
  135. data/ext/evoasm_ext/evoasm-search.c +0 -2145
  136. data/ext/evoasm_ext/evoasm-search.h +0 -214
  137. data/ext/evoasm_ext/evoasm-util.h +0 -40
  138. data/ext/evoasm_ext/evoasm-x64.c +0 -275624
  139. data/ext/evoasm_ext/evoasm-x64.h +0 -5436
  140. data/ext/evoasm_ext/evoasm.c +0 -7
  141. data/ext/evoasm_ext/evoasm.h +0 -23
  142. data/ext/evoasm_ext/evoasm_ext.c +0 -1757
  143. data/ext/evoasm_ext/extconf.rb +0 -31
  144. data/lib/evoasm/cli.rb +0 -6
  145. data/lib/evoasm/cli/search.rb +0 -127
  146. data/lib/evoasm/core_ext.rb +0 -1
  147. data/lib/evoasm/core_ext/array.rb +0 -9
  148. data/lib/evoasm/core_ext/integer.rb +0 -10
  149. data/lib/evoasm/core_ext/kwstruct.rb +0 -13
  150. data/lib/evoasm/core_ext/range.rb +0 -5
  151. data/lib/evoasm/examples.rb +0 -27
  152. data/lib/evoasm/gen.rb +0 -8
  153. data/lib/evoasm/gen/enum.rb +0 -169
  154. data/lib/evoasm/gen/name_util.rb +0 -80
  155. data/lib/evoasm/gen/state.rb +0 -176
  156. data/lib/evoasm/gen/state_dsl.rb +0 -152
  157. data/lib/evoasm/gen/strio.rb +0 -27
  158. data/lib/evoasm/gen/translator.rb +0 -1102
  159. data/lib/evoasm/gen/version.rb +0 -5
  160. data/lib/evoasm/gen/x64.rb +0 -237
  161. data/lib/evoasm/gen/x64/funcs.rb +0 -495
  162. data/lib/evoasm/gen/x64/inst.rb +0 -781
  163. data/lib/evoasm/search.rb +0 -40
  164. data/lib/evoasm/tasks/gen_task.rb +0 -86
  165. data/lib/evoasm/tasks/template_task.rb +0 -52
  166. data/test/test_helper.rb +0 -1
  167. data/test/x64/test_helper.rb +0 -19
  168. 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 = "evoasm"
7
+ spec.name = 'evoasm'
8
8
  spec.version = Evoasm::VERSION
9
- spec.authors = ["Julian Aron Prenner (furunkel)"]
10
- spec.email = ["furunkel@polyadic.com"]
11
- spec.summary = %q{An AIMGP (Automatic Induction of Machine code by Genetic Programming) engine}
12
- spec.homepage = "https://github.com/furunkel/evoasm/"
13
- spec.license = "MPL-2.0"
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 = ["lib"]
20
- spec.extensions = spec.files.grep(%r{extconf.rb})
21
+ spec.require_paths = ['lib']
22
+ spec.extensions = %w(ext/evoasm_ext/Rakefile)
21
23
 
22
- spec.add_dependency "pry", "~> 0.10"
23
- spec.add_dependency "pastel", "~> 0.6"
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 "bundler", "~> 1.7"
26
- spec.add_development_dependency "rake", "~> 10.0"
27
- spec.add_development_dependency "rake-compiler", "~> 0.9"
28
- spec.add_development_dependency 'erubis', '~> 2.6'
29
- spec.add_development_dependency "minitest", "~> 5.8"
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,3 @@
1
+ import 'compile.rake'
2
+
3
+ task :default => :compile
@@ -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
+ }