9 #include "bitmapped_patricia_tree.h"
13 /* This code is only for x86_64 gcc linux. It is NOT threadsafe. */
15 /* w00t, I am a three-star-programmer! */
16 void ***dereferencedPointer;
17 void ***lastDereferencedPointer;
19 void **lastLockedPointer;
22 void* (*function) (void*);
24 void*** dereferencedPointer;
29 bpt_t bpt_assoc_and_release(bpt_t bpt, bpt_key_t key, void *value) {
30 bpt_t new_bpt = bpt_assoc(bpt, key, value);
35 void maybeAllocateMorePointers () {
36 if (lastDereferencedPointer > dereferencedPointer) {
37 lockedPointer = (void**) mmap(NULL,
38 sysconf(_SC_PAGE_SIZE)*sizeof(void*),
39 PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE,
41 dereferencedPointer = (void***) mmap(NULL,
42 sysconf(_SC_PAGE_SIZE)*sizeof(void**),
43 PROT_READ | PROT_WRITE,
44 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
46 if ((dereferencedPointer == MAP_FAILED)) {
47 printf("Mmap failed 2!\n");
48 if ((lockedPointer == MAP_FAILED)) {
49 printf("Mmap failed 1!\n");
55 lastLockedPointer = lockedPointer + sysconf(_SC_PAGE_SIZE);
56 lastDereferencedPointer = dereferencedPointer + sysconf(_SC_PAGE_SIZE);
58 void** lp = lockedPointer;
59 void*** dp = dereferencedPointer;
60 while (lp < lastLockedPointer) {
67 inline void initializePointerTree () {
69 dereferencedPointer = NULL + 2;
70 lastDereferencedPointer = 1 + dereferencedPointer;
71 maybeAllocateMorePointers ();
74 void*** lazy_alloc (void* (*calculate) (void*), void* opt) {
75 maybeAllocateMorePointers ();
76 void*** ret = dereferencedPointer;
79 dereferencedPointer++;
81 /* we should use a slice allocator here */
82 tree_entry *en = (tree_entry*) malloc (sizeof(tree_entry));
83 en->function = calculate;
85 en->dereferencedPointer = ret;
88 pointer_tree = bpt_assoc_and_release(pointer_tree, (intptr_t) *ret,
93 void handle_segv(int segv, siginfo_t* siginfo, void* ucontext) {
94 ucontext_t* uc = (ucontext_t*) ucontext;
96 /* do disassembly at from IP */
99 ud_set_mode(&ud_obj, 64);
100 ud_set_syntax(&ud_obj, UD_SYN_ATT);
101 ud_set_input_buffer(&ud_obj, (unsigned char*) uc->uc_mcontext.gregs[REG_RIP],
104 /* was disassembly successful? */
105 if (!ud_disassemble(&ud_obj)) {
106 printf("Disassembly fail!\n");
110 /* is disassembly a memory-operation? */
111 struct ud_operand op0 = ud_obj.operand[0];
112 struct ud_operand op1 = ud_obj.operand[1];
113 struct ud_operand op;
115 if (op0.type == UD_OP_MEM) {
117 } else if (op1.type == UD_OP_MEM) {
120 printf("Instruction unknown\n");
124 /* find out the register - this part is clumsy as we have two sets
194 printf("Register not supported!\n");
198 intptr_t address = uc->uc_mcontext.gregs[setreg];
200 if (!bpt_has_key(pointer_tree, address)) {
201 printf("Address not found in Patricia tree.\n");
205 tree_entry *te = (tree_entry*) bpt_get(pointer_tree, address);
206 void* newAddress = (te->function)(te->argument);
207 *(te->dereferencedPointer) = newAddress;
209 /* set the register - as before */
210 uc->uc_mcontext.gregs[setreg] = (greg_t) newAddress;
213 inline void initializeSignalHandler () {
215 bzero(&q, sizeof(q));
216 q.sa_sigaction = handle_segv;
217 q.sa_flags = SA_SIGINFO;
218 sigaction(11, &q, NULL);
221 void *calculateLazy24 (void* bla) {
222 int* ret = (int*) malloc(sizeof(int));
228 initializePointerTree ();
229 initializeSignalHandler ();
230 void *** lazy42 = lazy_alloc(calculateLazy24, NULL);
231 printf("%d\n", **((int**)lazy42));