evoasm 0.0.2.pre7

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 (75) hide show
  1. checksums.yaml +7 -0
  2. data/.gemrelease +2 -0
  3. data/.gitignore +16 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.rake +8 -0
  6. data/Gemfile.rake.lock +51 -0
  7. data/LICENSE.txt +373 -0
  8. data/Makefile +6 -0
  9. data/README.md +43 -0
  10. data/Rakefile +128 -0
  11. data/bin/gdb +2 -0
  12. data/data/tables/README.md +19 -0
  13. data/data/tables/x64.csv +1684 -0
  14. data/data/templates/evoasm-x64.c.erb +319 -0
  15. data/data/templates/evoasm-x64.h.erb +126 -0
  16. data/evoasm.gemspec +30 -0
  17. data/examples/abs.yml +20 -0
  18. data/examples/popcnt.yml +17 -0
  19. data/examples/sym_reg.yml +26 -0
  20. data/exe/evoasm-search +13 -0
  21. data/ext/evoasm_ext/evoasm-alloc.c +145 -0
  22. data/ext/evoasm_ext/evoasm-alloc.h +59 -0
  23. data/ext/evoasm_ext/evoasm-arch.c +44 -0
  24. data/ext/evoasm_ext/evoasm-arch.h +161 -0
  25. data/ext/evoasm_ext/evoasm-bitmap.h +114 -0
  26. data/ext/evoasm_ext/evoasm-buf.c +130 -0
  27. data/ext/evoasm_ext/evoasm-buf.h +47 -0
  28. data/ext/evoasm_ext/evoasm-error.c +31 -0
  29. data/ext/evoasm_ext/evoasm-error.h +75 -0
  30. data/ext/evoasm_ext/evoasm-free-list.c.tmpl +121 -0
  31. data/ext/evoasm_ext/evoasm-free-list.h.tmpl +86 -0
  32. data/ext/evoasm_ext/evoasm-log.c +108 -0
  33. data/ext/evoasm_ext/evoasm-log.h +69 -0
  34. data/ext/evoasm_ext/evoasm-misc.c +23 -0
  35. data/ext/evoasm_ext/evoasm-misc.h +282 -0
  36. data/ext/evoasm_ext/evoasm-param.h +37 -0
  37. data/ext/evoasm_ext/evoasm-search.c +2145 -0
  38. data/ext/evoasm_ext/evoasm-search.h +214 -0
  39. data/ext/evoasm_ext/evoasm-util.h +40 -0
  40. data/ext/evoasm_ext/evoasm-x64.c +275624 -0
  41. data/ext/evoasm_ext/evoasm-x64.h +5436 -0
  42. data/ext/evoasm_ext/evoasm.c +7 -0
  43. data/ext/evoasm_ext/evoasm.h +23 -0
  44. data/ext/evoasm_ext/evoasm_ext.c +1757 -0
  45. data/ext/evoasm_ext/extconf.rb +31 -0
  46. data/lib/evoasm/cli/search.rb +127 -0
  47. data/lib/evoasm/cli.rb +6 -0
  48. data/lib/evoasm/core_ext/array.rb +9 -0
  49. data/lib/evoasm/core_ext/integer.rb +10 -0
  50. data/lib/evoasm/core_ext/kwstruct.rb +13 -0
  51. data/lib/evoasm/core_ext/range.rb +5 -0
  52. data/lib/evoasm/core_ext.rb +1 -0
  53. data/lib/evoasm/error.rb +20 -0
  54. data/lib/evoasm/examples.rb +27 -0
  55. data/lib/evoasm/gen/enum.rb +169 -0
  56. data/lib/evoasm/gen/name_util.rb +80 -0
  57. data/lib/evoasm/gen/state.rb +176 -0
  58. data/lib/evoasm/gen/state_dsl.rb +152 -0
  59. data/lib/evoasm/gen/strio.rb +27 -0
  60. data/lib/evoasm/gen/translator.rb +1102 -0
  61. data/lib/evoasm/gen/version.rb +5 -0
  62. data/lib/evoasm/gen/x64/funcs.rb +495 -0
  63. data/lib/evoasm/gen/x64/inst.rb +781 -0
  64. data/lib/evoasm/gen/x64.rb +237 -0
  65. data/lib/evoasm/gen.rb +8 -0
  66. data/lib/evoasm/program.rb +23 -0
  67. data/lib/evoasm/search.rb +40 -0
  68. data/lib/evoasm/tasks/gen_task.rb +86 -0
  69. data/lib/evoasm/tasks/template_task.rb +52 -0
  70. data/lib/evoasm/version.rb +3 -0
  71. data/lib/evoasm.rb +22 -0
  72. data/test/test_helper.rb +1 -0
  73. data/test/x64/test_helper.rb +19 -0
  74. data/test/x64/x64_test.rb +87 -0
  75. metadata +221 -0
@@ -0,0 +1,59 @@
1
+ #pragma once
2
+
3
+ #if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
4
+ # if !defined(_DEFAULT_SOURCE)
5
+ # define _DEFAULT_SOURCE
6
+ # endif
7
+ # include <unistd.h>
8
+ # include <sys/mman.h>
9
+ # if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
10
+ # define MAP_ANONYMOUS MAP_ANON
11
+ # endif
12
+ #endif
13
+
14
+ #include <string.h>
15
+ #include <alloca.h>
16
+
17
+ #if defined(_WIN32)
18
+ # include <malloc.h>
19
+ #endif
20
+
21
+ #include "evoasm-error.h"
22
+
23
+ #ifdef __GNUC__
24
+ # define EVOASM_MALLOC_ATTRS __attribute__((malloc))
25
+ # define EVOASM_CALLOC_ATTRS __attribute__((malloc))
26
+ # define EVOASM_REALLOC_ATTRS __attribute__((malloc))
27
+ #else
28
+ # define EVOASM_MALLOC_ATTRS
29
+ # define EVOASM_CALLOC_ATTRS
30
+ # define EVOASM_REALLOC_ATTRS
31
+ #endif
32
+
33
+ #if defined(_WIN32)
34
+ #define EVOASM_MPROT_RW PAGE_READWRITE
35
+ #define EVOASM_MPROT_RX PAGE_EXECUTE_READ
36
+ #define EVOASM_MPROT_RWX PAGE_EXECUTE_READWRITE
37
+ #elif defined(_POSIX_VERSION)
38
+ #define EVOASM_MPROT_RW (PROT_READ|PROT_WRITE)
39
+ #define EVOASM_MPROT_RX (PROT_READ|PROT_EXEC)
40
+ #define EVOASM_MPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC)
41
+ #else
42
+ #error
43
+ #endif
44
+
45
+ void *evoasm_malloc(size_t) EVOASM_MALLOC_ATTRS;
46
+ void *evoasm_calloc(size_t, size_t) EVOASM_CALLOC_ATTRS;
47
+ void *evoasm_realloc(void *, size_t) EVOASM_REALLOC_ATTRS;
48
+ void evoasm_free(void *);
49
+
50
+ void *evoasm_mmap(size_t size, void *p);
51
+ evoasm_success evoasm_munmap(void *p, size_t size);
52
+ evoasm_success evoasm_mprot(void *p, size_t size, int mode);
53
+ long evoasm_page_size();
54
+
55
+ #if defined(_WIN32)
56
+ #define evoasm_alloca(s) _malloca(s);
57
+ #else
58
+ #define evoasm_alloca(s) alloca(s);
59
+ #endif
@@ -0,0 +1,44 @@
1
+ #include "evoasm-arch.h"
2
+ #include "evoasm-util.h"
3
+ #include <string.h>
4
+ #include <inttypes.h>
5
+
6
+ EVOASM_DECL_LOG_TAG("arch")
7
+
8
+ evoasm_success
9
+ evoasm_inst_encode(evoasm_inst *inst, evoasm_arch *arch, evoasm_arch_param_val *param_vals, evoasm_bitmap *set_params) {
10
+ return inst->encode_func(arch, param_vals, set_params);
11
+ }
12
+
13
+ uint16_t
14
+ evoasm_arch_insts(evoasm_arch *arch, const evoasm_inst **insts) {
15
+ return arch->cls->insts_func(arch, insts);
16
+ }
17
+
18
+ void
19
+ evoasm_arch_reset(evoasm_arch *arch) {
20
+ arch->buf_start = EVOASM_ARCH_BUF_CAPA / 2;
21
+ arch->buf_end = EVOASM_ARCH_BUF_CAPA / 2;
22
+ }
23
+
24
+ void
25
+ evoasm_arch_init(evoasm_arch *arch, evoasm_arch_cls *cls) {
26
+ static evoasm_arch zero_arch = {0};
27
+ *arch = zero_arch;
28
+ evoasm_arch_reset(arch);
29
+ arch->cls = cls;
30
+ }
31
+
32
+ void
33
+ evoasm_arch_destroy(evoasm_arch *arch) {
34
+ }
35
+
36
+ void
37
+ evoasm_arch_save(evoasm_arch *arch, evoasm_buf *buf) {
38
+ uint8_t len = (uint8_t)(arch->buf_end - arch->buf_start);
39
+
40
+ memcpy(buf->data + buf->pos, arch->buf + arch->buf_start, len);
41
+ buf->pos += len;
42
+
43
+ evoasm_arch_reset(arch);
44
+ }
@@ -0,0 +1,161 @@
1
+ #pragma once
2
+
3
+ #include <stdint.h>
4
+ #include "evoasm-error.h"
5
+ #include "evoasm-param.h"
6
+ #include "evoasm-buf.h"
7
+ #include "evoasm-log.h"
8
+
9
+ #define EVOASM_ARCH_BUF_CAPA 32
10
+ #define EVOASM_ARCH_MAX_PARAMS 64
11
+
12
+ typedef uint8_t evoasm_reg_id;
13
+ #define EVOASM_REG_ID_MAX UINT8_MAX
14
+ typedef uint16_t evoasm_inst_id;
15
+
16
+ typedef enum {
17
+ EVOASM_OPERAND_SIZE_1,
18
+ EVOASM_OPERAND_SIZE_8,
19
+ EVOASM_OPERAND_SIZE_16,
20
+ EVOASM_OPERAND_SIZE_32,
21
+ EVOASM_OPERAND_SIZE_64,
22
+ EVOASM_OPERAND_SIZE_128,
23
+ EVOASM_OPERAND_SIZE_256,
24
+ EVOASM_OPERAND_SIZE_512,
25
+ EVOASM_N_OPERAND_SIZES,
26
+ } evoasm_operand_size;
27
+
28
+ #define EVOASM_OPERAND_SIZE_BITSIZE 3
29
+ #define EVOASM_OPERAND_SIZE_BITSIZE_WITH_N 4
30
+
31
+ struct evoasm_arch;
32
+ struct evoasm_inst;
33
+
34
+ typedef uint16_t (*evoasm_arch_insts_func)(struct evoasm_arch *arch, const struct evoasm_inst **insts);
35
+
36
+ typedef enum {
37
+ EVOASM_ARCH_X64
38
+ } evoasm_arch_id;
39
+
40
+ typedef struct {
41
+ evoasm_arch_id id : 8;
42
+ uint16_t n_insts;
43
+ uint8_t n_params;
44
+ uint8_t max_inst_len;
45
+ evoasm_arch_insts_func insts_func;
46
+ } evoasm_arch_cls;
47
+
48
+ typedef enum {
49
+ EVOASM_ARCH_ERROR_CODE_NOT_ENCODABLE = EVOASM_N_ERROR_CODES,
50
+ EVOASM_ARCH_ERROR_CODE_MISSING_PARAM,
51
+ EVOASM_ARCH_ERROR_CODE_INVALID_ACCESS,
52
+ EVOASM_ARCH_ERROR_CODE_MISSING_FEATURE,
53
+ } evoasm_arch_error_code;
54
+
55
+ struct evoasm_arch;
56
+
57
+ typedef struct {
58
+ struct evoasm_arch *arch;
59
+ uint8_t reg;
60
+ uint8_t param;
61
+ uint16_t inst;
62
+ } evoasm_arch_error_data;
63
+
64
+ _Static_assert(sizeof(evoasm_error_data) >= sizeof(evoasm_arch_error_data), "evoasm_arch_error_data exceeds evoasm_error_data size limit");
65
+
66
+ typedef struct {
67
+ EVOASM_ERROR_HEADER
68
+ evoasm_arch_error_data data;
69
+ } evoasm_arch_error;
70
+
71
+ typedef struct evoasm_arch {
72
+ evoasm_arch_cls *cls;
73
+ uint8_t buf_end;
74
+ uint8_t buf_start;
75
+ uint8_t buf[EVOASM_ARCH_BUF_CAPA];
76
+ void *user_data;
77
+ /* must have a bit for every
78
+ * writable register */
79
+ evoasm_bitmap128 acc;
80
+ } evoasm_arch;
81
+
82
+ typedef bool (*evoasm_inst_encode_func)(evoasm_arch *arch, evoasm_arch_param_val *param_vals, evoasm_bitmap *set_params);
83
+
84
+ typedef struct evoasm_inst {
85
+ evoasm_inst_id id;
86
+ uint16_t params_len;
87
+ evoasm_arch_param *params;
88
+ evoasm_inst_encode_func encode_func;
89
+ } evoasm_inst;
90
+
91
+ uint16_t
92
+ evoasm_arch_insts(evoasm_arch *arch, const evoasm_inst **insts);
93
+
94
+ evoasm_success
95
+ evoasm_inst_encode(evoasm_inst *inst, evoasm_arch *arch, evoasm_arch_param_val *param_vals, evoasm_bitmap *set_params);
96
+
97
+ void
98
+ evoasm_arch_reset(evoasm_arch *arch);
99
+
100
+ void
101
+ evoasm_arch_init(evoasm_arch *arch, evoasm_arch_cls *cls);
102
+
103
+ void
104
+ evoasm_arch_destroy(evoasm_arch *arch);
105
+
106
+ void
107
+ evoasm_arch_save(evoasm_arch *arch, evoasm_buf *buf);
108
+
109
+ static inline void
110
+ evoasm_arch_write8(evoasm_arch *arch, int64_t datum) {
111
+ uint8_t new_end = (uint8_t)(arch->buf_end + 1);
112
+ *((uint8_t *)(arch->buf + arch->buf_end)) = (uint8_t) datum;
113
+ arch->buf_end = new_end;
114
+ }
115
+
116
+ static inline void
117
+ evoasm_arch_write16(evoasm_arch *arch, int64_t datum) {
118
+ uint8_t new_end = (uint8_t)(arch->buf_end + 2);
119
+ *((int16_t *)(arch->buf + arch->buf_end)) = (int16_t) datum;
120
+ arch->buf_end = new_end;
121
+ }
122
+
123
+ static inline void
124
+ evoasm_arch_write32(evoasm_arch *arch, int64_t datum) {
125
+ uint8_t new_end = (uint8_t)(arch->buf_end + 4);
126
+ *((int32_t *)(arch->buf + arch->buf_end)) = (int32_t) datum;
127
+ arch->buf_end = new_end;
128
+ }
129
+
130
+ static inline void
131
+ evoasm_arch_write64(evoasm_arch *arch, int64_t datum) {
132
+ uint8_t new_end = (uint8_t)(arch->buf_end + 8);
133
+ *((int64_t *)(arch->buf + arch->buf_end)) = (int64_t) datum;
134
+ arch->buf_end = new_end;
135
+ }
136
+
137
+ static inline void
138
+ evoasm_arch_write_access(evoasm_arch *arch, evoasm_bitmap *acc, evoasm_reg_id reg) {
139
+ evoasm_bitmap_set(acc, (unsigned) reg);
140
+ }
141
+
142
+ static inline void
143
+ evoasm_arch_undefined_access(evoasm_arch *arch, evoasm_bitmap *acc, evoasm_reg_id reg) {
144
+ evoasm_bitmap_unset(acc, (unsigned) reg);
145
+ }
146
+
147
+ static inline evoasm_success
148
+ _evoasm_arch_read_access(evoasm_arch *arch, evoasm_bitmap *acc, evoasm_reg_id reg, evoasm_inst_id inst, const char *file, unsigned line) {
149
+ if(!evoasm_bitmap_get(acc, (unsigned) reg)) {
150
+ evoasm_arch_error_data error_data = {
151
+ .reg = (uint8_t) reg,
152
+ .inst = (uint16_t) inst,
153
+ .arch = arch
154
+ };
155
+ evoasm_set_error(EVOASM_ERROR_TYPE_ARCH, EVOASM_ARCH_ERROR_CODE_INVALID_ACCESS, &error_data, file, line, "read access violation");
156
+ return false;
157
+ }
158
+ return true;
159
+ }
160
+
161
+ #define evoasm_arch_read_access(arch, acc, reg, inst) _evoasm_arch_read_access(arch, acc, reg, inst, __FILE__, __LINE__)
@@ -0,0 +1,114 @@
1
+ #pragma once
2
+
3
+ #include <stdint.h>
4
+ #include <stdbool.h>
5
+
6
+ #define _EVOASM_BITMAP_INDEX_DECLS(key) \
7
+ unsigned size = sizeof(uint64_t) * 8;\
8
+ unsigned ary_idx = ((unsigned) key) / size;\
9
+ unsigned bit_idx = ((unsigned) key) % size;
10
+
11
+ typedef struct {
12
+ uint64_t data[1];
13
+ } evoasm_bitmap64;
14
+
15
+ typedef struct {
16
+ uint64_t data[2];
17
+ } evoasm_bitmap128;
18
+
19
+ typedef struct {
20
+ uint64_t data[4];
21
+ } evoasm_bitmap256;
22
+
23
+ typedef struct {
24
+ uint64_t data[8];
25
+ } evoasm_bitmap512;
26
+
27
+ typedef struct {
28
+ uint64_t data[16];
29
+ } evoasm_bitmap1024;
30
+
31
+ typedef uint64_t evoasm_bitmap;
32
+
33
+ static inline void
34
+ evoasm_bitmap_set(evoasm_bitmap *bitmap, unsigned idx) {
35
+ _EVOASM_BITMAP_INDEX_DECLS(idx);
36
+ bitmap[ary_idx] |= (1ull << bit_idx);
37
+ }
38
+
39
+ static inline void
40
+ evoasm_bitmap_unset(evoasm_bitmap *bitmap, unsigned idx) {
41
+ _EVOASM_BITMAP_INDEX_DECLS(idx);
42
+ /* unset values must be 0*/
43
+ bitmap[ary_idx] &= ~(1ull << bit_idx);
44
+ }
45
+
46
+ static inline bool
47
+ evoasm_bitmap_get(evoasm_bitmap *bitmap, unsigned idx) {
48
+ _EVOASM_BITMAP_INDEX_DECLS(idx);
49
+ return !!(bitmap[ary_idx] & (1ull << bit_idx));
50
+ }
51
+
52
+
53
+ #define _EVOASM_BITMAP_DECL_UNOP(name, width, op) \
54
+ static inline void evoasm_bitmap ## width ## _ ## name (evoasm_bitmap##width *bitmap, evoasm_bitmap##width *result) { \
55
+ unsigned i;\
56
+ for(i = 0; i < width / 64; i++) {\
57
+ result->data[i] = op bitmap->data[i];\
58
+ }\
59
+ }
60
+
61
+ #define _EVOASM_BITMAP_DECL_BINOP(name, width, op) \
62
+ static inline void evoasm_bitmap ## width ## _ ## name (evoasm_bitmap##width *bitmap1, evoasm_bitmap##width *bitmap2, evoasm_bitmap##width *result) { \
63
+ unsigned i;\
64
+ for(i = 0; i < width / 64; i++) {\
65
+ result->data[i] = bitmap1->data[i] op bitmap2->data[i];\
66
+ }\
67
+ }
68
+
69
+ #define _EVOASM_BITMAP_DECL_EQL(width) \
70
+ static inline bool evoasm_bitmap ## width ## _ ## eql (evoasm_bitmap##width *bitmap1, evoasm_bitmap##width *bitmap2) { \
71
+ unsigned i;\
72
+ for(i = 0; i < width / 64; i++) {\
73
+ if(bitmap1->data[i] != bitmap2->data[i]) return false;\
74
+ } \
75
+ return true;\
76
+ }
77
+
78
+
79
+ #ifdef __GNUC__
80
+ # define _EVOASM_BITMAP_DECL_POPCOUNT(width) \
81
+ static inline unsigned evoasm_bitmap ## width ## _ ## popcount (evoasm_bitmap##width *bitmap) { \
82
+ unsigned c = 0, i;\
83
+ for(i = 0; i < width / 64; i++) {\
84
+ c += (unsigned) __builtin_popcountll(bitmap->data[i]);\
85
+ } \
86
+ return c;\
87
+ }
88
+ #else
89
+ # define _EVOASM_BITMAP_DECL_POPCOUNT(width) \
90
+ static inline unsigned evoasm_bitmap ## width ## _ ## popcount (evoasm_bitmap##width *bitmap) { \
91
+ unsigned c = 0, i;\
92
+ for(i = 0; i < width / 64; i++) {\
93
+ uint64_t x = bitmap->data[i]; \
94
+ for(; x > 0; x &= x - 1) c++;\
95
+ } \
96
+ return c;\
97
+ }
98
+ #endif
99
+
100
+ _EVOASM_BITMAP_DECL_UNOP(not, 128, ~)
101
+ _EVOASM_BITMAP_DECL_BINOP(and, 128, &)
102
+ _EVOASM_BITMAP_DECL_BINOP(or, 128, |)
103
+ _EVOASM_BITMAP_DECL_BINOP(andn, 128, &~)
104
+ _EVOASM_BITMAP_DECL_POPCOUNT(128)
105
+ _EVOASM_BITMAP_DECL_EQL(128)
106
+
107
+ _EVOASM_BITMAP_DECL_UNOP(not, 64, ~)
108
+ _EVOASM_BITMAP_DECL_BINOP(and, 64, &)
109
+ _EVOASM_BITMAP_DECL_BINOP(or, 64, |)
110
+ _EVOASM_BITMAP_DECL_POPCOUNT(64)
111
+ _EVOASM_BITMAP_DECL_EQL(64)
112
+
113
+
114
+ _EVOASM_BITMAP_DECL_EQL(1024)
@@ -0,0 +1,130 @@
1
+ #include <string.h>
2
+
3
+ #include "evoasm-buf.h"
4
+ #include "evoasm-util.h"
5
+ #include "evoasm-error.h"
6
+ #include "evoasm-alloc.h"
7
+ #include "evoasm-log.h"
8
+
9
+ EVOASM_DECL_LOG_TAG("buf")
10
+
11
+ static evoasm_success
12
+ evoasm_buf_init_mmap(evoasm_buf *buf, size_t size) {
13
+ uint8_t *mem;
14
+
15
+ //size = EVOASM_ALIGN_UP(size, evoasm_page_size());
16
+ mem = evoasm_mmap(size, NULL);
17
+
18
+ if(mem) {
19
+ buf->capa = size;
20
+ buf->data = mem;
21
+ buf->pos = 0;
22
+ return true;
23
+ }
24
+ else {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ static evoasm_success
30
+ evoasm_buf_init_malloc(evoasm_buf *buf, size_t size) {
31
+ uint8_t *mem;
32
+
33
+ mem = malloc(size);
34
+
35
+ if(mem) {
36
+ buf->capa = size;
37
+ buf->data = mem;
38
+ buf->pos = 0;
39
+ return true;
40
+ }
41
+ else {
42
+ return false;
43
+ }
44
+ }
45
+
46
+ evoasm_success
47
+ evoasm_buf_init(evoasm_buf *buf, evoasm_buf_type buf_type, size_t size)
48
+ {
49
+ buf->type = buf_type;
50
+ switch(buf_type) {
51
+ case EVOASM_BUF_TYPE_MMAP: return evoasm_buf_init_mmap(buf, size);
52
+ case EVOASM_BUF_TYPE_MALLOC: return evoasm_buf_init_malloc(buf, size);
53
+ default: evoasm_assert_not_reached();
54
+ }
55
+ }
56
+
57
+ static evoasm_success
58
+ evoasm_buf_destroy_mmap(evoasm_buf *buf) {
59
+ return evoasm_munmap(buf->data, buf->capa);
60
+ }
61
+
62
+ static evoasm_success
63
+ evoasm_buf_destroy_malloc(evoasm_buf *buf) {
64
+ evoasm_free(buf->data);
65
+ return true;
66
+ }
67
+
68
+ evoasm_success
69
+ evoasm_buf_destroy(evoasm_buf *buf)
70
+ {
71
+ switch(buf->type) {
72
+ case EVOASM_BUF_TYPE_MMAP: return evoasm_buf_destroy_mmap(buf);
73
+ case EVOASM_BUF_TYPE_MALLOC: return evoasm_buf_destroy_malloc(buf);
74
+ default: evoasm_assert_not_reached();
75
+ }
76
+ }
77
+
78
+ void
79
+ evoasm_buf_reset(evoasm_buf *buf) {
80
+ memset(buf->data, 0, buf->pos);
81
+ buf->pos = 0;
82
+ }
83
+
84
+ evoasm_success
85
+ evoasm_buf_protect(evoasm_buf *buf, int mode) {
86
+ return evoasm_mprot(buf->data, buf->capa, mode);
87
+ }
88
+
89
+ intptr_t
90
+ evoasm_buf_exec(evoasm_buf *buf) {
91
+ intptr_t (*func)(void);
92
+ intptr_t result = 0;
93
+ *(void **) (&func) = buf->data;
94
+ result = func();
95
+ return result;
96
+ }
97
+
98
+ void
99
+ evoasm_buf_log(evoasm_buf *buf, evoasm_log_level log_level) {
100
+ unsigned i;
101
+
102
+ evoasm_log(log_level, EVOASM_LOG_TAG, "Evoasm::Buffer: capa: %zu, pos: %zu, addr: %p\n", buf->capa, buf->pos, (void *) buf->data);
103
+ for(i = 0; i < buf->pos; i++)
104
+ {
105
+ if (i > 0) evoasm_log(log_level, EVOASM_LOG_TAG, " ");
106
+ evoasm_log(log_level, EVOASM_LOG_TAG, " %02X ", buf->data[i]);
107
+ }
108
+ evoasm_log(log_level, EVOASM_LOG_TAG, " \n ");
109
+ }
110
+
111
+ size_t
112
+ evoasm_buf_append(evoasm_buf * restrict dst, evoasm_buf * restrict src) {
113
+ size_t free = dst->capa - dst->pos;
114
+ if(src->pos > free) {
115
+ evoasm_set_error(EVOASM_ERROR_TYPE_ARGUMENT, EVOASM_ERROR_CODE_NONE,
116
+ NULL, "buffer does not fit (need %zu bytes but only %zu free)", src->pos, free);
117
+ return src->pos - (dst->capa - dst->pos);
118
+ }
119
+ memcpy(dst->data + dst->pos, src->data, src->pos);
120
+ dst->pos += src->pos;
121
+ return 0;
122
+ }
123
+
124
+ evoasm_success
125
+ evoasm_buf_clone(evoasm_buf * restrict buf, evoasm_buf * restrict cloned_buf) {
126
+ if(!evoasm_buf_init(cloned_buf, buf->type, buf->capa)) {
127
+ return false;
128
+ }
129
+ return evoasm_buf_append(cloned_buf, buf) == 0;
130
+ }
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ #include <stdbool.h>
4
+ #include <stdint.h>
5
+ #include <stdlib.h>
6
+ #include <stdio.h>
7
+
8
+ #include "evoasm-error.h"
9
+ #include "evoasm-log.h"
10
+
11
+ typedef enum {
12
+ EVOASM_BUF_TYPE_MMAP,
13
+ EVOASM_BUF_TYPE_MALLOC,
14
+ EVOASM_N_BUF_TYPES
15
+ } evoasm_buf_type;
16
+
17
+ typedef struct {
18
+ size_t capa;
19
+ size_t pos;
20
+ evoasm_buf_type type : 2;
21
+ uint8_t *data;
22
+ } evoasm_buf;
23
+
24
+ evoasm_success
25
+ evoasm_buf_init(evoasm_buf *buf, evoasm_buf_type buf_type, size_t size);
26
+
27
+ evoasm_success
28
+ evoasm_buf_destroy(evoasm_buf *buf);
29
+
30
+ void
31
+ evoasm_buf_reset(evoasm_buf *buf);
32
+
33
+ size_t
34
+ evoasm_buf_append(evoasm_buf * restrict dst, evoasm_buf * restrict src);
35
+
36
+ evoasm_success
37
+ evoasm_buf_protect(evoasm_buf *buf, int mode);
38
+
39
+ intptr_t
40
+ evoasm_buf_exec(evoasm_buf *buf);
41
+
42
+ void
43
+ evoasm_buf_log(evoasm_buf *buf, evoasm_log_level log_level);
44
+
45
+ evoasm_success
46
+ evoasm_buf_clone(evoasm_buf * restrict buf, evoasm_buf * restrict cloned_buf);
47
+
@@ -0,0 +1,31 @@
1
+ #include "evoasm-error.h"
2
+
3
+ _Thread_local evoasm_error evoasm_last_error;
4
+
5
+ void
6
+ evoasm_error_setv(evoasm_error *error, unsigned error_type, unsigned error_code,
7
+ void *error_data, const char *file,
8
+ unsigned line, const char *format, va_list args) {
9
+
10
+ error->type = (uint16_t) error_type;
11
+ error->code = (uint16_t) error_code;
12
+ error->line = line;
13
+ strncpy(error->filename, file, EVOASM_ERROR_MAX_FILENAME_LEN);
14
+ vsnprintf(error->msg, EVOASM_ERROR_MAX_MSG_LEN, format, args);
15
+
16
+ if(error_data != NULL) {
17
+ memcpy(&error->data, error_data, sizeof(evoasm_error_data));
18
+ }
19
+ }
20
+
21
+ void
22
+ evoasm_error_set(evoasm_error *error, unsigned error_type, unsigned error_code,
23
+ void *error_data, const char *file,
24
+ unsigned line, const char *format, ...) {
25
+ va_list args;
26
+ va_start(args, format);
27
+ evoasm_error_setv(error, error_type, error_code,
28
+ error_data, file, line,
29
+ format, args);
30
+ va_end(args);
31
+ }
@@ -0,0 +1,75 @@
1
+ #pragma once
2
+
3
+ #include <assert.h>
4
+ #include <stdio.h>
5
+ #include <stdlib.h>
6
+ #include <stdint.h>
7
+ #include <stdbool.h>
8
+ #include <string.h>
9
+ #include <stdarg.h>
10
+ #include <setjmp.h>
11
+
12
+ #include "evoasm-util.h"
13
+
14
+ #define EVOASM_ERROR_MAX_FILENAME_LEN 128
15
+ #define EVOASM_ERROR_MAX_MSG_LEN 128
16
+
17
+ #define EVOASM_ERROR_HEADER \
18
+ uint16_t type; \
19
+ uint16_t code; \
20
+ uint32_t line; \
21
+ char filename[EVOASM_ERROR_MAX_FILENAME_LEN]; \
22
+ char msg[EVOASM_ERROR_MAX_MSG_LEN];
23
+
24
+ typedef enum {
25
+ EVOASM_ERROR_CODE_NONE,
26
+ EVOASM_N_ERROR_CODES
27
+ } evoasm_error_code;
28
+
29
+ typedef enum {
30
+ EVOASM_ERROR_TYPE_INVALID,
31
+ EVOASM_ERROR_TYPE_ARGUMENT,
32
+ EVOASM_ERROR_TYPE_MEMORY,
33
+ EVOASM_ERROR_TYPE_ARCH,
34
+ EVOASM_ERROR_TYPE_GRAPH,
35
+ } evoasm_error_type;
36
+
37
+ typedef struct {
38
+ uint8_t data[64];
39
+ } evoasm_error_data;
40
+
41
+ typedef struct {
42
+ EVOASM_ERROR_HEADER
43
+ evoasm_error_data data;
44
+ } evoasm_error;
45
+
46
+
47
+ void
48
+ evoasm_error_setv(evoasm_error *error, unsigned error_type, unsigned error_code,
49
+ void *error_data, const char *file,
50
+ unsigned line, const char *format, va_list args);
51
+
52
+ void
53
+ evoasm_error_set(evoasm_error *error, unsigned error_type, unsigned error_code,
54
+ void *error_data, const char *file,
55
+ unsigned line, const char *format, ...);
56
+
57
+
58
+ extern _Thread_local evoasm_error evoasm_last_error;
59
+
60
+ #define EVOASM_TRY(label, func, ...) \
61
+ do { if(!func(__VA_ARGS__)) {goto label;} } while(0)
62
+
63
+ #define evoasm_success evoasm_check_return bool
64
+
65
+ #define evoasm_set_error(type, code, data, ...) \
66
+ evoasm_error_set(&evoasm_last_error, (type), (code), (data),\
67
+ __FILE__, __LINE__, __VA_ARGS__)
68
+
69
+ #define evoasm_assert_not_reached() \
70
+ evoasm_assert_not_reached_full(__FILE__, __LINE__)
71
+
72
+ static inline _Noreturn void evoasm_assert_not_reached_full(const char *file, unsigned line) {
73
+ fprintf(stderr, "FATAL: %s:%d should not be reached\n", file, line);
74
+ abort();
75
+ }