/src/fluent-bit/lib/monkey/deps/flb_libco/amd64.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | libco.amd64 (2016-09-14) |
3 | | author: byuu |
4 | | license: public domain |
5 | | */ |
6 | | |
7 | | #define LIBCO_C |
8 | | #include "libco.h" |
9 | | #include "settings.h" |
10 | | |
11 | | #include <assert.h> |
12 | | #include <stdlib.h> |
13 | | |
14 | | #ifdef __cplusplus |
15 | | extern "C" { |
16 | | #endif |
17 | | |
18 | | static thread_local long long co_active_buffer[64]; |
19 | | static thread_local cothread_t co_active_handle = 0; |
20 | | static void (*co_swap)(cothread_t, cothread_t) = 0; |
21 | | |
22 | | #ifdef LIBCO_MPROTECT |
23 | | alignas(4096) |
24 | | #else |
25 | | text_section |
26 | | #endif |
27 | | #ifdef _WIN32 |
28 | | /* ABI: Win64 */ |
29 | | static const unsigned char co_swap_function[4096] = { |
30 | | 0x48, 0x89, 0x22, /* mov [rdx],rsp */ |
31 | | 0x48, 0x8b, 0x21, /* mov rsp,[rcx] */ |
32 | | 0x58, /* pop rax */ |
33 | | 0x48, 0x89, 0x6a, 0x08, /* mov [rdx+ 8],rbp */ |
34 | | 0x48, 0x89, 0x72, 0x10, /* mov [rdx+16],rsi */ |
35 | | 0x48, 0x89, 0x7a, 0x18, /* mov [rdx+24],rdi */ |
36 | | 0x48, 0x89, 0x5a, 0x20, /* mov [rdx+32],rbx */ |
37 | | 0x4c, 0x89, 0x62, 0x28, /* mov [rdx+40],r12 */ |
38 | | 0x4c, 0x89, 0x6a, 0x30, /* mov [rdx+48],r13 */ |
39 | | 0x4c, 0x89, 0x72, 0x38, /* mov [rdx+56],r14 */ |
40 | | 0x4c, 0x89, 0x7a, 0x40, /* mov [rdx+64],r15 */ |
41 | | #if !defined(LIBCO_NO_SSE) |
42 | | 0x0f, 0x29, 0x72, 0x50, /* movaps [rdx+ 80],xmm6 */ |
43 | | 0x0f, 0x29, 0x7a, 0x60, /* movaps [rdx+ 96],xmm7 */ |
44 | | 0x44, 0x0f, 0x29, 0x42, 0x70, /* movaps [rdx+112],xmm8 */ |
45 | | 0x48, 0x83, 0xc2, 0x70, /* add rdx,112 */ |
46 | | 0x44, 0x0f, 0x29, 0x4a, 0x10, /* movaps [rdx+ 16],xmm9 */ |
47 | | 0x44, 0x0f, 0x29, 0x52, 0x20, /* movaps [rdx+ 32],xmm10 */ |
48 | | 0x44, 0x0f, 0x29, 0x5a, 0x30, /* movaps [rdx+ 48],xmm11 */ |
49 | | 0x44, 0x0f, 0x29, 0x62, 0x40, /* movaps [rdx+ 64],xmm12 */ |
50 | | 0x44, 0x0f, 0x29, 0x6a, 0x50, /* movaps [rdx+ 80],xmm13 */ |
51 | | 0x44, 0x0f, 0x29, 0x72, 0x60, /* movaps [rdx+ 96],xmm14 */ |
52 | | 0x44, 0x0f, 0x29, 0x7a, 0x70, /* movaps [rdx+112],xmm15 */ |
53 | | #endif |
54 | | 0x48, 0x8b, 0x69, 0x08, /* mov rbp,[rcx+ 8] */ |
55 | | 0x48, 0x8b, 0x71, 0x10, /* mov rsi,[rcx+16] */ |
56 | | 0x48, 0x8b, 0x79, 0x18, /* mov rdi,[rcx+24] */ |
57 | | 0x48, 0x8b, 0x59, 0x20, /* mov rbx,[rcx+32] */ |
58 | | 0x4c, 0x8b, 0x61, 0x28, /* mov r12,[rcx+40] */ |
59 | | 0x4c, 0x8b, 0x69, 0x30, /* mov r13,[rcx+48] */ |
60 | | 0x4c, 0x8b, 0x71, 0x38, /* mov r14,[rcx+56] */ |
61 | | 0x4c, 0x8b, 0x79, 0x40, /* mov r15,[rcx+64] */ |
62 | | #if !defined(LIBCO_NO_SSE) |
63 | | 0x0f, 0x28, 0x71, 0x50, /* movaps xmm6, [rcx+ 80] */ |
64 | | 0x0f, 0x28, 0x79, 0x60, /* movaps xmm7, [rcx+ 96] */ |
65 | | 0x44, 0x0f, 0x28, 0x41, 0x70, /* movaps xmm8, [rcx+112] */ |
66 | | 0x48, 0x83, 0xc1, 0x70, /* add rcx,112 */ |
67 | | 0x44, 0x0f, 0x28, 0x49, 0x10, /* movaps xmm9, [rcx+ 16] */ |
68 | | 0x44, 0x0f, 0x28, 0x51, 0x20, /* movaps xmm10,[rcx+ 32] */ |
69 | | 0x44, 0x0f, 0x28, 0x59, 0x30, /* movaps xmm11,[rcx+ 48] */ |
70 | | 0x44, 0x0f, 0x28, 0x61, 0x40, /* movaps xmm12,[rcx+ 64] */ |
71 | | 0x44, 0x0f, 0x28, 0x69, 0x50, /* movaps xmm13,[rcx+ 80] */ |
72 | | 0x44, 0x0f, 0x28, 0x71, 0x60, /* movaps xmm14,[rcx+ 96] */ |
73 | | 0x44, 0x0f, 0x28, 0x79, 0x70, /* movaps xmm15,[rcx+112] */ |
74 | | #endif |
75 | | 0xff, 0xe0, /* jmp rax */ |
76 | | }; |
77 | | |
78 | | #include <windows.h> |
79 | | |
80 | | static void co_init() { |
81 | | #ifdef LIBCO_MPROTECT |
82 | | DWORD old_privileges; |
83 | | VirtualProtect((void*)co_swap_function, sizeof co_swap_function, PAGE_EXECUTE_READ, &old_privileges); |
84 | | #endif |
85 | | } |
86 | | #else |
87 | | /* ABI: SystemV */ |
88 | | static const unsigned char co_swap_function[4096] = { |
89 | | 0x48, 0x89, 0x26, /* mov [rsi],rsp */ |
90 | | 0x48, 0x8b, 0x27, /* mov rsp,[rdi] */ |
91 | | 0x58, /* pop rax */ |
92 | | 0x48, 0x89, 0x6e, 0x08, /* mov [rsi+ 8],rbp */ |
93 | | 0x48, 0x89, 0x5e, 0x10, /* mov [rsi+16],rbx */ |
94 | | 0x4c, 0x89, 0x66, 0x18, /* mov [rsi+24],r12 */ |
95 | | 0x4c, 0x89, 0x6e, 0x20, /* mov [rsi+32],r13 */ |
96 | | 0x4c, 0x89, 0x76, 0x28, /* mov [rsi+40],r14 */ |
97 | | 0x4c, 0x89, 0x7e, 0x30, /* mov [rsi+48],r15 */ |
98 | | 0x48, 0x8b, 0x6f, 0x08, /* mov rbp,[rdi+ 8] */ |
99 | | 0x48, 0x8b, 0x5f, 0x10, /* mov rbx,[rdi+16] */ |
100 | | 0x4c, 0x8b, 0x67, 0x18, /* mov r12,[rdi+24] */ |
101 | | 0x4c, 0x8b, 0x6f, 0x20, /* mov r13,[rdi+32] */ |
102 | | 0x4c, 0x8b, 0x77, 0x28, /* mov r14,[rdi+40] */ |
103 | | 0x4c, 0x8b, 0x7f, 0x30, /* mov r15,[rdi+48] */ |
104 | | 0xff, 0xe0, /* jmp rax */ |
105 | | }; |
106 | | |
107 | | #include <unistd.h> |
108 | | #include <sys/mman.h> |
109 | | |
110 | 1 | static void co_init() { |
111 | | #ifdef LIBCO_MPROTECT |
112 | | unsigned long long addr = (unsigned long long)co_swap_function; |
113 | | unsigned long long base = addr - (addr % sysconf(_SC_PAGESIZE)); |
114 | | unsigned long long size = (addr - base) + sizeof co_swap_function; |
115 | | mprotect((void*)base, size, PROT_READ | PROT_EXEC); |
116 | | #endif |
117 | 1 | } |
118 | | #endif |
119 | | |
120 | 0 | static void crash() { |
121 | 0 | assert(0); /* called only if cothread_t entrypoint returns */ |
122 | 0 | } |
123 | | |
124 | 2.57k | cothread_t co_active() { |
125 | 2.57k | if(!co_active_handle) co_active_handle = &co_active_buffer; |
126 | 2.57k | return co_active_handle; |
127 | 2.57k | } |
128 | | |
129 | | cothread_t co_create(unsigned int size, void (*entrypoint)(void), |
130 | 2.96k | size_t *out_size){ |
131 | 2.96k | cothread_t handle; |
132 | 2.96k | if(!co_swap) { |
133 | 1 | co_init(); |
134 | 1 | co_swap = (void (*)(cothread_t, cothread_t))co_swap_function; |
135 | 1 | } |
136 | | |
137 | 2.96k | if(!co_active_handle) co_active_handle = &co_active_buffer; |
138 | 2.96k | size += 512; /* allocate additional space for storage */ |
139 | 2.96k | size &= ~15; /* align stack to 16-byte boundary */ |
140 | 2.96k | *out_size = size; |
141 | | |
142 | 2.96k | if((handle = (cothread_t)malloc(size))) { |
143 | 2.96k | long long *p = (long long*)((char*)handle + size); /* seek to top of stack */ |
144 | 2.96k | *--p = (long long)crash; /* crash if entrypoint returns */ |
145 | 2.96k | *--p = (long long)entrypoint; /* start of function */ |
146 | 2.96k | *(long long*)handle = (long long)p; /* stack pointer */ |
147 | 2.96k | } |
148 | | |
149 | 2.96k | return handle; |
150 | 2.96k | } |
151 | | |
152 | 2.96k | void co_delete(cothread_t handle) { |
153 | 2.96k | free(handle); |
154 | 2.96k | } |
155 | | |
156 | 5.14k | void co_switch(cothread_t handle) { |
157 | 5.14k | register cothread_t co_previous_handle = co_active_handle; |
158 | 5.14k | co_swap(co_active_handle = handle, co_previous_handle); |
159 | 5.14k | } |
160 | | |
161 | | #ifdef __cplusplus |
162 | | } |
163 | | #endif |