9 #include "bitmapped_patricia_tree.h"
13 /* This code is only for x86_64 gcc linux. It is NOT threadsafe. */
15 void* slice_alloc (size_t length) {
16 static intptr_t *nextslice = NULL + 1;
17 static intptr_t *lastslice = NULL;
19 int num = length / sizeof(intptr_t) + 1;
21 if (lastslice < nextslice + num) {
22 nextslice = (intptr_t *)malloc(1024*sizeof(intptr_t));
23 lastslice = nextslice + 1023;
26 void* ret = (void*) nextslice;
31 /* w00t, I am a three-star-programmer! */
32 void ***dereferencedPointer;
33 void ***lastDereferencedPointer;
35 void **lastLockedPointer;
38 void* (*function) (void*);
40 void*** dereferencedPointer;
45 bpt_t bpt_assoc_and_release(bpt_t bpt, bpt_key_t key, void *value) {
46 bpt_t new_bpt = bpt_assoc(bpt, key, value);
51 void maybeAllocateMorePointers () {
52 if (lastDereferencedPointer > dereferencedPointer) {
53 lockedPointer = (void**) mmap(NULL,
54 sysconf(_SC_PAGE_SIZE)*sizeof(void*),
55 PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE,
57 dereferencedPointer = (void***) mmap(NULL,
58 sysconf(_SC_PAGE_SIZE)*sizeof(void**),
59 PROT_READ | PROT_WRITE,
60 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
62 if ((dereferencedPointer == MAP_FAILED)) {
63 printf("Mmap failed 2!\n");
64 if ((lockedPointer == MAP_FAILED)) {
65 printf("Mmap failed 1!\n");
71 lastLockedPointer = lockedPointer + sysconf(_SC_PAGE_SIZE);
72 lastDereferencedPointer = dereferencedPointer + sysconf(_SC_PAGE_SIZE);
74 void** lp = lockedPointer;
75 void*** dp = dereferencedPointer;
76 while (lp < lastLockedPointer) {
83 inline void initializePointerTree () {
85 dereferencedPointer = NULL + 2;
86 lastDereferencedPointer = 1 + dereferencedPointer;
87 maybeAllocateMorePointers ();
90 void*** lazy_alloc (void* (*calculate) (void*), void* opt) {
91 maybeAllocateMorePointers ();
92 void*** ret = dereferencedPointer;
95 dereferencedPointer++;
97 tree_entry *en = (tree_entry*) slice_alloc (sizeof(tree_entry));
98 en->function = calculate;
100 en->dereferencedPointer = ret;
103 pointer_tree = bpt_assoc_and_release(pointer_tree, (intptr_t) *ret,
108 void handle_segv(int segv, siginfo_t* siginfo, void* ucontext) {
109 ucontext_t* uc = (ucontext_t*) ucontext;
111 /* do disassembly at from IP */
114 ud_set_mode(&ud_obj, 64);
115 ud_set_syntax(&ud_obj, UD_SYN_ATT);
116 ud_set_input_buffer(&ud_obj, (unsigned char*) uc->uc_mcontext.gregs[REG_RIP],
119 /* was disassembly successful? */
120 if (!ud_disassemble(&ud_obj)) {
121 printf("Disassembly fail!\n");
125 /* is disassembly a memory-operation? */
126 struct ud_operand op0 = ud_obj.operand[0];
127 struct ud_operand op1 = ud_obj.operand[1];
128 struct ud_operand op;
130 if (op0.type == UD_OP_MEM) {
132 } else if (op1.type == UD_OP_MEM) {
135 printf("Instruction unknown\n");
139 /* find out the register - this part is clumsy as we have two sets
209 printf("Register not supported!\n");
213 intptr_t address = uc->uc_mcontext.gregs[setreg];
215 if (!bpt_has_key(pointer_tree, address)) {
216 printf("Address not found in Patricia tree.\n");
220 tree_entry *te = (tree_entry*) bpt_get(pointer_tree, address);
221 void* newAddress = (te->function)(te->argument);
222 *(te->dereferencedPointer) = newAddress;
224 /* set the register - as before */
225 uc->uc_mcontext.gregs[setreg] = (greg_t) newAddress;
228 inline void initializeSignalHandler () {
230 bzero(&q, sizeof(q));
231 q.sa_sigaction = handle_segv;
232 q.sa_flags = SA_SIGINFO;
233 sigaction(11, &q, NULL);
236 void *calculateLazy24 (void* bla) {
237 int* ret = (int*) slice_alloc (sizeof(int));
243 initializePointerTree ();
244 initializeSignalHandler ();
245 void *** lazy42 = lazy_alloc(calculateLazy24, NULL);
246 printf("%d\n", **((int**)lazy42));