int32_t find_hole(uint32_t size, uint8_t page_align, heap_t *heap) { uint32_t iterator = 0; while (iterator < heap->index.size) { header_t *header = (header_t*) lookup_list(iterator, &heap->index); if (page_align > 0) { uint32_t location = (uint32_t) header; int32_t offset = 0; if (((location + sizeof(header_t)) & 0xFFFFF000) != 0) { offset = 0x1000 - (location + sizeof(header_t) % 0x1000); } int32_t hole_size = (int32_t) header->size - offset; if (hole_size >= (int32_t) size) { break; } } else if (header->size >= size) { break; } iterator++; } if (iterator == heap->index.size) { return -1; } else { return iterator; } }
// non-deterministically finds an element in a list struct list_type* lookup_list(struct list_type* list) { if (!list) return NULL; return (__VERIFIER_nondet_int())?(list):(lookup_list(list->next)); }
int main(int argc, char* argv[]) { struct list_type* list = build_list(); struct list_type* el = lookup_list(list); free_list(list); ___cl_pt_build_fail(); return 0; }
static int prefetch_search_lists (void) { int i, j, cnt; hash_t h; int *L = 0; if (!cur_user) { for (i = 0; i < Qw; i++) { Qc[i] = 0; } return Qw; } for (i = 0; i < Qw; i++) { h = Q[i]; cnt = lookup_list (h, &L); j = i; while (j && Qc[j-1] > cnt) { Q[j] = Q[j-1]; Qc[j] = Qc[j-1]; Ql[j] = Ql[j-1]; j--; } Q[j] = h; Qc[j] = cnt; Ql[j] = L; } return Qw; }
/** * Compare a portion of the tokenized string, starting at word_stat with length * of numchar, to the dictionary or affix class word that is defined in the * capture group whose info is pointed to by cgnump. * * FIXME: Return int instead of bool, see the comment at E1 below. */ static bool is_word(const char *word_start, int numchar, cgnum_t *cgnump) { Dictionary const dict = cgnump->dict; const char * const afclass = cgnump->afclass; const int lookup_mark_len = (NULL != cgnump->lookup_mark) ? strlen(cgnump->lookup_mark) : 0; char * const word = alloca(numchar+lookup_mark_len+1); #ifdef AFFIX_DICTIONARY_TREE const Dict_node *dn; #endif const Afdict_class *ac; size_t i; /* Append/prepend stem/infix marks. */ if (NULL == cgnump->lookup_mark) { strncpy(word, word_start, numchar); word[numchar] = '\0'; } else { switch (cgnump->lookup_mark_pos) { case 'p': /* prepend a mark */ strcpy(word, cgnump->lookup_mark); strncat(word, word_start, numchar); word[numchar+lookup_mark_len] = '\0'; break; case 'a': /* append a mark */ strncpy(word, word_start, numchar); strcpy(word+numchar, cgnump->lookup_mark); break; default: printf("is_word:E3('%x' %s)", cgnump->lookup_mark_pos, cgnump->lookup_mark); strncpy(word, word_start, numchar); word[numchar] = '\0'; } } lgdebug(7, "LOOKUP '%s' in %s: ", word, dict->name); if (0 == afclass) return boolean_dictionary_lookup(dict, word); /* We don't have for now a tree representation of the affix file, only lists */ #ifdef AFFIX_DICTIONARY_TREE dn = lookup_list(dict, word); printf("WORD %s afclass %s dn %p\n", word, afclass, dn); if (NULL == dn) return false; for (; NULL != dn; dn = dn->left) { const char *con = word_only_connector(dn); if (NULL == con) { /* Internal error - nothing else to do for now unless we don't * rerun bool, but return an int so -1 signifies an error. */ printf("is_word(%s):E1 ", word); } printf("CON '%s'\n", con); if (0 == strcmp(afclass, con)) return true; } #else /* Make it the hard way. */ ac = afdict_find(dict, afclass, /*notify_err*/false); if (NULL == ac) { /* Internal error - nothing else to do for now unless we don't * rerun bool, but return an int so -1 signifies an error. */ printf("is_word(%s):E2 ", word); } for (i = 0; i < ac->length; i++) { if (0 == strcmp(ac->string[i], word)) return true; } #endif return false; }
void *alloc(uint32_t size, uint8_t page_align, heap_t *heap) { uint32_t new_size = size + sizeof(header_t) + sizeof(footer_t); int32_t iterator = find_hole(new_size, page_align, heap); if (iterator == (int32_t) -1) { uint32_t old_length = heap->end_address - heap->start_address; uint32_t old_end_address = heap->end_address; expand(old_length+new_size, heap); uint32_t new_length = heap->end_address-heap->start_address; iterator = 0; int32_t idx = -1; uint32_t value = 0x0; while (iterator < (int32_t) heap->index.size) { uint32_t tmp = (uint32_t)lookup_list(iterator, &heap->index); if (tmp > value) { value = tmp; idx = iterator; } iterator++; } if (idx == -1) { header_t *header = (header_t *)old_end_address; header->magic = HEAP_MAGIC; header->size = new_length - old_length; header->is_hole = 1; footer_t *footer = (footer_t *) (old_end_address + header->size - sizeof(footer_t)); footer->magic = HEAP_MAGIC; footer->header = header; insert_list((void*)header, &heap->index); } else { header_t *header = lookup_list(idx, &heap->index); header->size += new_length - old_length; footer_t *footer = (footer_t *) ( (uint32_t)header + header->size - sizeof(footer_t) ); footer->header = header; footer->magic = HEAP_MAGIC; } return alloc(size, page_align, heap); } header_t *orig_hole_header = (header_t *)lookup_list(iterator, &heap->index); uint32_t orig_hole_pos = (uint32_t) orig_hole_header; uint32_t orig_hole_size = orig_hole_header->size; if (orig_hole_size - new_size < sizeof(header_t) + sizeof(footer_t)) { size += orig_hole_size - new_size; new_size = orig_hole_size; } if (page_align && (orig_hole_pos & 0xFFFFF000)) { uint32_t new_location = orig_hole_pos + 0x1000 - (orig_hole_pos & 0xFFF) - sizeof(header_t); header_t *hole_header = (header_t*) orig_hole_pos; hole_header->size = 0x1000; hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; footer_t *hole_footer = (footer_t*) ((uint32_t) new_location - sizeof(footer_t)); hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; orig_hole_pos = new_location; orig_hole_size = orig_hole_size - hole_header->size; } else { remove_list(iterator, &heap->index); } header_t *block_header = (header_t*) orig_hole_pos; block_header->magic = HEAP_MAGIC; block_header->is_hole = 0; block_header->size = new_size; footer_t *block_footer = (footer_t*) (orig_hole_pos + sizeof(header_t) + size); block_footer->header = block_header; if (orig_hole_size - new_size > 0) { header_t *hole_header = (header_t*) (orig_hole_pos + sizeof(header_t) + size + sizeof(footer_t)); hole_header->magic = HEAP_MAGIC; hole_header->is_hole = 1; hole_header->size = orig_hole_size - new_size; footer_t *hole_footer = (footer_t*) ((uint32_t) hole_header + orig_hole_size - new_size - sizeof(footer_t)); if ((uint32_t) hole_footer < heap->end_address) { hole_footer->magic = HEAP_MAGIC; hole_footer->header = hole_header; } insert_list((void*)hole_header, &heap->index); } return (void*) ((uint32_t) block_header + sizeof(header_t)); }
void free(void *p, heap_t *heap) { // Exit gracefully for null pointers. if (p == 0) return; // Get the header and footer associated with this pointer. header_t *header = (header_t*) ( (uint32_t)p - sizeof(header_t) ); footer_t *footer = (footer_t*) ( (uint32_t)header + header->size - sizeof(footer_t) ); // Sanity checks. ASSERT(header->magic == HEAP_MAGIC); ASSERT(footer->magic == HEAP_MAGIC); // Make us a hole. header->is_hole = 1; // Do we want to add this header into the 'free holes' index? char do_add = 1; // Unify left // If the thing immediately to the left of us is a footer... footer_t *test_footer = (footer_t*) ( (uint32_t)header - sizeof(footer_t) ); if (test_footer->magic == HEAP_MAGIC && test_footer->header->is_hole == 1) { uint32_t cache_size = header->size; // Cache our current size. header = test_footer->header; // Rewrite our header with the new one. footer->header = header; // Rewrite our footer to point to the new header. header->size += cache_size; // Change the size. do_add = 0; // Since this header is already in the index, we don't want to add it again. } // Unify right // If the thing immediately to the right of us is a header... header_t *test_header = (header_t*) ( (uint32_t)footer + sizeof(footer_t) ); if (test_header->magic == HEAP_MAGIC && test_header->is_hole) { header->size += test_header->size; // Increase our size. test_footer = (footer_t*) ( (uint32_t)test_header + // Rewrite it's footer to point to our header. test_header->size - sizeof(footer_t) ); footer = test_footer; // Find and remove this header from the index. uint32_t iterator = 0; while ( (iterator < heap->index.size) && (lookup_list(iterator, &heap->index) != (void*)test_header) ) iterator++; // Make sure we actually found the item. ASSERT(iterator < heap->index.size); // Remove it. remove_list(iterator, &heap->index); } // If the footer location is the end address, we can contract. if ( (uint32_t)footer+sizeof(footer_t) == heap->end_address) { uint32_t old_length = heap->end_address-heap->start_address; uint32_t new_length = contract( (uint32_t)header - heap->start_address, heap); // Check how big we will be after resizing. if (header->size - (old_length-new_length) > 0) { // We will still exist, so resize us. header->size -= old_length-new_length; footer = (footer_t*) ( (uint32_t)header + header->size - sizeof(footer_t) ); footer->magic = HEAP_MAGIC; footer->header = header; } else { // We will no longer exist :(. Remove us from the index. uint32_t iterator = 0; while ( (iterator < heap->index.size) && (lookup_list(iterator, &heap->index) != (void*)test_header) ) iterator++; // If we didn't find ourselves, we have nothing to remove. if (iterator < heap->index.size) remove_list(iterator, &heap->index); } } // If required, add us to the index. if (do_add == 1) insert_list((void*)header, &heap->index); }