- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 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
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/mman.h>
typedef intptr_t binaryfunc(intptr_t, intptr_t);
typedef intptr_t unaryfunc(intptr_t);
#define evalsiz ((intptr_t)eval_end - (intptr_t)eval)
#define clossiz (evalsiz+sizeof(intptr_t)+sizeof(int))
void eval_end();
intptr_t eval(intptr_t rem) {
#define argsize ((intptr_t)&&argend - (intptr_t)eval)
#define leasize ((intptr_t)&&leaaft - (intptr_t)&&leabef)
#define eoffset (argsize+leasize)
argend:;
register void *ptr asm("r10");
leabef: asm("lea (%rip),%r10"); leaaft:;
void *off = (ptr - eoffset + evalsiz);
binaryfunc *bin = *(binaryfunc**)off;
return bin(*(intptr_t *)(off+sizeof(intptr_t)),rem);
}
void eval_end() { }
unaryfunc* apply(binaryfunc *bin, intptr_t arg) {
void *data = mmap(0, clossiz, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
memmove(data, &eval, evalsiz);
intptr_t ptr = (intptr_t)bin;
memmove(data+evalsiz, &ptr, sizeof(intptr_t));
memmove(data+evalsiz+sizeof(intptr_t), &arg, sizeof(intptr_t));
return data;
}
intptr_t add(intptr_t a, intptr_t b) {
return a+b;
}
int main() {
printf("%ld\n", apply(add, 1)(2));
return 0;
}
guest 03.01.2017 17:46 # 0
someone 04.01.2017 15:59 # 0
bormand 04.01.2017 16:01 # +1
bormand 04.01.2017 16:08 # +1
guestinho 04.01.2017 16:10 # 0