Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// for glibc < 2.37
#define _BSD_SOURCE
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif
#if defined(__APPLE__) && defined(__MACH__)
#define MAP_JIT_VALUE MAP_JIT
void sys_icache_invalidate(void *start, size_t len);
#else
#define MAP_JIT_VALUE 0
#endif
#include "arena.h"
#include "jit.h" // dasm_proto.h
#include "dasm_x86.h"
//|.arch x64
//|.actionlist my_dasm_actions
//|.section code
//|.globals DASM_LBL_
// Avoid IDE warnings about names that will defined after DynASM preprocessing
// step.
//|| #define PREPROCESSED_WITH_DASM
#ifndef PREPROCESSED_WITH_DASM
unsigned char my_dasm_actions[] = {};
#define DASM_SECTION_CODE 0
#define DASM_MAXSECTION 1
enum {
DASM_LBL__MAX,
};
#endif
static void *
dasm_link_and_encode(Dst_DECL)
{
size_t size;
void* code;
assert(dasm_checkstep(Dst, 0) == DASM_S_OK);
assert(dasm_link(Dst, &size) == DASM_S_OK);
#ifdef _WIN32
code = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
#else
code = mmap(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_JIT_VALUE, -1, 0);
#endif
assert(dasm_encode(Dst, code) == DASM_S_OK);
#ifdef _WIN32
DWORD original;
VirtualProtect(code, size, PAGE_EXECUTE_READ, &original);
#else
mprotect(code, size, PROT_READ | PROT_EXEC);
#endif
#if defined(__APPLE__) && defined(__MACH__)
sys_icache_invalidate(code, size);
#endif
return code;
}
void
jit_init(Dst_DECL, Arena *arena)
{
(void) arena;
dasm_init(Dst, DASM_MAXSECTION);
ms->global_labels = arena_alloc(arena, DASM_LBL__MAX * sizeof(ms->global_labels[0]));
dasm_setupglobal(Dst, ms->global_labels, DASM_LBL__MAX);
}
void
jit_free(Dst_DECL)
{
dasm_free(Dst);
}
int_plus_const_func *
jit_addition_with_constant(Dst_DECL, int constant)
{
(void) constant;
dasm_setup(Dst, my_dasm_actions);
//| lea eax, [rdi + constant]
//| ret
return (int_plus_const_func *) dasm_link_and_encode(Dst);
}