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,167 @@
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
+ #pragma once
19
+
20
+ #include "evoasm-pop-params.h"
21
+ #include "evoasm-x64.h"
22
+ #include "evoasm-program-io.h"
23
+
24
+ #define EVOASM_KERNEL_MAX_OUTPUT_REGS 254
25
+ #define EVOASM_KERNEL_MAX_INPUT_REGS 254
26
+
27
+ #define EVOASM_KERNEL_REG_INFO_N_TRANS_REGS 2
28
+
29
+ typedef struct {
30
+ bool input : 1;
31
+ bool written : 1;
32
+ bool output : 1;
33
+ /*registers in following kernels whose input is this register */
34
+ } evoasm_kernel_x64_reg_info_reg_t;
35
+
36
+ typedef struct {
37
+ evoasm_kernel_x64_reg_info_reg_t regs[EVOASM_X64_REG_NONE];
38
+
39
+ /* trans_regs[trans_idx][reg_id] stores the register in this kernel that is used
40
+ * to initialize reg_id in the trans_idx'th transition kernel.
41
+ * Right now, trans_idx=0 is the next kernel in line,
42
+ * while trans_idx=1 is the kernel jumped to using the programs jmp_offs table.
43
+ */
44
+ evoasm_x64_reg_id_t trans_regs[EVOASM_KERNEL_REG_INFO_N_TRANS_REGS][EVOASM_X64_REG_NONE];
45
+ unsigned written_flags : EVOASM_X64_RFLAGS_FLAGS_BITSIZE;
46
+ } evoasm_kernel_x64_reg_info_t;
47
+
48
+ typedef union {
49
+ evoasm_kernel_x64_reg_info_t x64;
50
+ } evoasm_kernel_reg_info_t;
51
+
52
+
53
+ typedef struct {
54
+ uint16_t size;
55
+ evoasm_inst_id_t *insts;
56
+ union {
57
+ evoasm_x64_basic_params_t *x64;
58
+ } params;
59
+ evoasm_kernel_reg_info_t reg_info;
60
+
61
+ union {
62
+ evoasm_x64_reg_id_t x64[EVOASM_KERNEL_MAX_OUTPUT_REGS];
63
+ } output_regs;
64
+
65
+ uint_fast8_t n_input_regs;
66
+ uint_fast8_t n_output_regs;
67
+ uint16_t idx;
68
+ uint16_t buf_start;
69
+ uint16_t buf_end;
70
+
71
+ #ifdef EVOASM_ENABLE_PARANOID_MODE
72
+ evoasm_program_io_val_t rand_vals[EVOASM_X64_REG_NONE];
73
+ #endif
74
+
75
+ } evoasm_kernel_t;
76
+
77
+
78
+ typedef enum {
79
+ EVOASM_PROGRAM_ERROR_CODE_NO_OUTPUT
80
+ } evoasm_program_error_code_t;
81
+
82
+ typedef enum {
83
+ EVOASM_PROGRAM_EMIT_FLAG_PREPARE = (1 << 0),
84
+ EVOASM_PROGRAM_EMIT_FLAG_EMIT_KERNELS = (1 << 1),
85
+ EVOASM_PROGRAM_EMIT_FLAG_EMIT_IO_LOAD_STORE = (1 << 2),
86
+ EVOASM_PROGRAM_EMIT_FLAG_SET_IO_MAPPING = (1 << 3)
87
+ } evoasm_program_emit_flags_t;
88
+
89
+ #define EVOASM_PROGRAM_MAX_SIZE 256
90
+ #define EVOASM_KERNEL_MAX_SIZE 2048
91
+
92
+ typedef struct {
93
+ evoasm_arch_info_t *arch_info;
94
+ evoasm_buf_t *buf;
95
+ evoasm_buf_t *body_buf;
96
+ bool reset_rflags : 1;
97
+ bool shallow : 1;
98
+ uint32_t recur_limit;
99
+ uint16_t size;
100
+ uint16_t max_tuples;
101
+ uint32_t exception_mask;
102
+ evoasm_program_io_val_type_t types[EVOASM_PROGRAM_OUTPUT_MAX_ARITY];
103
+ evoasm_program_io_val_t *output_vals;
104
+ evoasm_kernel_t *kernels;
105
+ int16_t *jmp_offs;
106
+ uint8_t *jmp_conds;
107
+ uint32_t *recur_counters;
108
+
109
+ /* these two are incomplete (values missig)
110
+ * We only need arity and types */
111
+ evoasm_program_input_t _input;
112
+ evoasm_program_output_t _output;
113
+
114
+ evoasm_reg_id_t output_regs[EVOASM_PROGRAM_IO_MAX_ARITY];
115
+ evoasm_buf_t _buf;
116
+ evoasm_buf_t _body_buf;
117
+
118
+ union {
119
+ /* register at index i has _input i % input_arity */
120
+ uint8_t x64[EVOASM_X64_REG_NONE];
121
+ } reg_inputs;
122
+
123
+ } evoasm_program_t;
124
+
125
+ evoasm_success_t
126
+ evoasm_program_clone(evoasm_program_t *program, evoasm_program_t *cloned_program);
127
+
128
+ evoasm_success_t
129
+ evoasm_program_init(evoasm_program_t *program,
130
+ evoasm_arch_info_t *arch_info,
131
+ size_t program_size,
132
+ size_t kernel_size,
133
+ size_t max_tuples,
134
+ size_t recur_limit,
135
+ bool shallow);
136
+
137
+
138
+ evoasm_program_output_t *
139
+ evoasm_program_run(evoasm_program_t *program,
140
+ evoasm_program_input_t *input);
141
+
142
+
143
+ evoasm_success_t
144
+ evoasm_program_destroy(evoasm_program_t *program);
145
+
146
+ evoasm_success_t
147
+ evoasm_program_eliminate_introns(evoasm_program_t *program, evoasm_program_t *dest_program);
148
+
149
+ evoasm_success_t
150
+ evoasm_program_emit(evoasm_program_t *program,
151
+ evoasm_program_input_t *input,
152
+ evoasm_program_emit_flags_t emit_flags);
153
+
154
+ evoasm_loss_t
155
+ evoasm_program_eval(evoasm_program_t *program,
156
+ evoasm_program_output_t *output);
157
+
158
+ evoasm_success_t
159
+ evoasm_program_detach(evoasm_program_t *program,
160
+ evoasm_program_io_t *input,
161
+ evoasm_program_io_t *output);
162
+
163
+
164
+ void
165
+ evoasm_program_log(evoasm_program_t *program, evoasm_log_level_t log_level);
166
+
167
+ EVOASM_DECL_ALLOC_FREE_FUNCS(program)
@@ -0,0 +1,65 @@
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.h"
19
+ #include "evoasm-util.h"
20
+ #include "evoasm-rand.h"
21
+
22
+ EVOASM_DEF_LOG_TAG("rand")
23
+
24
+ EVOASM_DEF_ALLOC_FREE_FUNCS(prng)
25
+
26
+ void
27
+ evoasm_prng_init(evoasm_prng_t *prng, evoasm_prng_state_t *seed) {
28
+ prng->state = *seed;
29
+ prng->p = 0;
30
+ }
31
+
32
+ void
33
+ evoasm_prng_destroy(evoasm_prng_t *prng) {
34
+ }
35
+
36
+ uint64_t
37
+ evoasm_prng_rand64(evoasm_prng_t *prng) {
38
+ return evoasm_prng_rand64_(prng);
39
+ }
40
+
41
+ uint32_t
42
+ evoasm_prng_rand32(evoasm_prng_t *prng) {
43
+ return evoasm_prng_rand32_(prng);
44
+ }
45
+
46
+ uint16_t
47
+ evoasm_prng_rand16(evoasm_prng_t *prng) {
48
+ return evoasm_prng_rand16_(prng);
49
+ }
50
+
51
+ uint8_t
52
+ evoasm_prng_rand8(evoasm_prng_t *prng) {
53
+ return evoasm_prng_rand8_(prng);
54
+ }
55
+
56
+ float
57
+ evoasm_prng_randf(evoasm_prng_t *prng) {
58
+ return evoasm_prng_randf_(prng);
59
+ }
60
+
61
+ int64_t
62
+ evoasm_prng_rand_between(evoasm_prng_t *prng, int64_t min, int64_t max) {
63
+ return evoasm_prng_rand_between_(prng, min, max);
64
+ }
65
+
@@ -0,0 +1,76 @@
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
+ #pragma once
19
+
20
+ #include "evoasm-error.h"
21
+ #include "evoasm-log.h"
22
+
23
+ #define EVOASM_PRNG_SEED_LEN 16
24
+
25
+ typedef struct {
26
+ uint64_t data[EVOASM_PRNG_SEED_LEN];
27
+ } evoasm_prng_state_t;
28
+
29
+ typedef struct evoasm_prng64 {
30
+ /* xorshift1024star */
31
+ evoasm_prng_state_t state;
32
+ int p;
33
+ } evoasm_prng_t;
34
+
35
+ void
36
+ evoasm_prng_init(evoasm_prng_t *prng, evoasm_prng_state_t *seed);
37
+
38
+ void
39
+ evoasm_prng_destroy(evoasm_prng_t *prng);
40
+
41
+
42
+ /* From: https://en.wikipedia.org/wiki/Xorshift */
43
+ static inline uint64_t
44
+ evoasm_prng_rand64_(evoasm_prng_t *prng) {
45
+ uint64_t *s = prng->state.data;
46
+ const uint64_t s0 = s[prng->p];
47
+ uint64_t s1 = s[prng->p = (prng->p + 1) & 15];
48
+ s1 ^= s1 << 31; // a
49
+ s[prng->p] = s1 ^ s0 ^ (s1 >> 11) ^ (s0 >> 30); // b,c
50
+ return (s[prng->p] * UINT64_C(1181783497276652981)) - 1;
51
+ }
52
+
53
+ static inline uint32_t
54
+ evoasm_prng_rand32_(evoasm_prng_t *prng) {
55
+ return (uint32_t) (evoasm_prng_rand64_(prng) & UINT32_MAX);
56
+ }
57
+
58
+ static inline uint16_t
59
+ evoasm_prng_rand16_(evoasm_prng_t *prng) {
60
+ return (uint16_t) (evoasm_prng_rand64_(prng) & UINT16_MAX);
61
+ }
62
+
63
+ static inline uint8_t
64
+ evoasm_prng_rand8_(evoasm_prng_t *prng) {
65
+ return (uint8_t) (evoasm_prng_rand64_(prng) & UINT8_MAX);
66
+ }
67
+
68
+ static inline float
69
+ evoasm_prng_randf_(evoasm_prng_t *prng) {
70
+ return (float) evoasm_prng_rand32_(prng) / (float) UINT32_MAX;
71
+ }
72
+
73
+ static inline int64_t
74
+ evoasm_prng_rand_between_(evoasm_prng_t *prng, int64_t min, int64_t max) {
75
+ return min + (int64_t)(evoasm_prng_rand64_(prng) % (uint64_t)(max - min + 1ll));
76
+ }
@@ -0,0 +1,106 @@
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-signal.h"
19
+
20
+ #ifdef EVOASM_UNIX
21
+
22
+ #define EVOASM_SIGNAL_EXCEPTION_MASK_GET(exc) (_evoasm_signal_ctx.exception_mask & (1u << exc))
23
+
24
+ _Thread_local evoasm_signal_ctx_t _evoasm_signal_ctx;
25
+
26
+ static void
27
+ evoasm_signal_handler(int sig, siginfo_t *siginfo, void *ctx) {
28
+ bool handle = false;
29
+
30
+ switch(_evoasm_signal_ctx.arch_id) {
31
+ case EVOASM_ARCH_X64: {
32
+ switch(sig) {
33
+ case SIGFPE: {
34
+ int exception = EVOASM_X64_EXCEPTION_DE;
35
+ bool catch_div_by_zero = siginfo->si_code == FPE_INTDIV &&
36
+ EVOASM_SIGNAL_EXCEPTION_MASK_GET(exception);
37
+ _evoasm_signal_ctx.last_exception = exception;
38
+ handle = catch_div_by_zero;
39
+ break;
40
+ }
41
+ default:
42
+ break;
43
+ }
44
+ break;
45
+ }
46
+ default:
47
+ evoasm_assert_not_reached();
48
+ }
49
+
50
+ if(handle) {
51
+ siglongjmp(_evoasm_signal_ctx.env, 1);
52
+ } else {
53
+ evoasm_signal_uninstall();
54
+ raise(sig);
55
+ }
56
+ }
57
+
58
+ static struct sigaction prev_action;
59
+
60
+ void
61
+ evoasm_signal_install() {
62
+ struct sigaction action = {0};
63
+
64
+ evoasm_arch_id_t arch_id = evoasm_get_current_arch();
65
+ assert(arch_id != EVOASM_ARCH_NONE);
66
+
67
+ _evoasm_signal_ctx.arch_id = (volatile evoasm_arch_id_t) arch_id;
68
+ _evoasm_signal_ctx.exception_mask = 0;
69
+ _evoasm_signal_ctx.last_exception = 0;
70
+
71
+ action.sa_sigaction = evoasm_signal_handler;
72
+ sigemptyset(&action.sa_mask);
73
+ action.sa_flags = SA_SIGINFO;
74
+
75
+ if(sigaction(SIGFPE, &action, &prev_action) < 0) {
76
+ perror("sigaction");
77
+ exit(1);
78
+ }
79
+ }
80
+
81
+ void
82
+ evoasm_signal_set_exception_mask(uint64_t exception_mask) {
83
+ _evoasm_signal_ctx.exception_mask = exception_mask;
84
+ }
85
+
86
+ void
87
+ evoasm_signal_clear_exception_mask() {
88
+ _evoasm_signal_ctx.exception_mask = 0;
89
+ }
90
+
91
+ int
92
+ evoasm_signal_get_last_exception() {
93
+ return _evoasm_signal_ctx.last_exception;
94
+ }
95
+
96
+ void
97
+ evoasm_signal_uninstall() {
98
+ if(sigaction(SIGFPE, &prev_action, NULL) < 0) {
99
+ perror("sigaction");
100
+ exit(1);
101
+ }
102
+ }
103
+
104
+ #else
105
+ #error
106
+ #endif
@@ -0,0 +1,58 @@
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
+ #pragma once
19
+
20
+ #include "evoasm-util.h"
21
+ #include "evoasm-arch.h"
22
+ #include <stdint.h>
23
+
24
+ #ifdef EVOASM_UNIX
25
+
26
+ #include <setjmp.h>
27
+ #include <signal.h>
28
+
29
+ typedef struct {
30
+ volatile uint64_t exception_mask;
31
+ volatile evoasm_arch_id_t arch_id;
32
+ sigjmp_buf env;
33
+ int last_exception;
34
+ } evoasm_signal_ctx_t;
35
+
36
+ extern _Thread_local evoasm_signal_ctx_t _evoasm_signal_ctx;
37
+
38
+ #define EVOASM_SIGNAL_TRY() (sigsetjmp(_evoasm_signal_ctx.env, 1) == 0)
39
+ #else
40
+ #error
41
+ #endif
42
+
43
+ #include "evoasm-arch.h"
44
+
45
+ int
46
+ evoasm_signal_get_last_exception();
47
+
48
+ void
49
+ evoasm_signal_uninstall();
50
+
51
+ void
52
+ evoasm_signal_install();
53
+
54
+ void
55
+ evoasm_signal_set_exception_mask(uint64_t exception_mask);
56
+
57
+ void
58
+ evoasm_signal_clear_exception_mask();