]> git.lizzy.rs Git - cclosure.git/blob - closure.c
Fix obi-wan problem
[cclosure.git] / closure.c
1 #include <stdlib.h>
2 #include <stdint.h>
3 #include <string.h>
4 #include <unistd.h>
5 #include <sys/mman.h>
6 #include "closure.h"
7
8 typedef struct __attribute__((packed)) {
9         uint16_t opcode_0;
10         void *operand_0;
11
12         uint16_t opcode_1;
13         void *operand_1;
14
15         uint16_t opcode_2;
16 } Closure;
17
18 // rdi, rsi, rdx, rcx, r8, r9
19 static const uint16_t mov[6] = {0xbf48, 0xbe48, 0xba48, 0xb948, 0xb849, 0xb949};
20 static size_t size;
21
22 __attribute__((constructor)) static void init()
23 {
24         size = sysconf(_SC_PAGESIZE);
25 }
26
27 void *closure_create(void *self, ClosureParam *param, size_t num)
28 {
29         Closure *block = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
30
31         for (size_t i = 0; i < num; i++) {
32                 if (param[i].arg >= 6)
33                         abort(); // TODO
34
35                 block[i].opcode_0 = 0xb848;
36                 block[i].operand_0 = param[i].fun;
37
38                 block[i].opcode_1 = mov[param[i].arg];
39                 block[i].operand_1 = self;
40
41                 block[i].opcode_2 = 0xe0ff;
42
43                 *((void **) param[i].ptr) = &block[i];
44         }
45
46         mprotect(block, size, PROT_READ | PROT_EXEC);
47         return block;   
48 }
49
50 void closure_destroy(void *closure)
51 {
52         munmap(closure, size);  
53 }