void *apmalloc(size_t size) { if (size == 0) return NULL; size_t request_size = ALIGN(size + sizeof(header_t)); // if it's more than our last bin's capacity, just mmap it if (request_size >= (1 << MAX_BINS)) { request_size = round_to_next_page(request_size); void *ptr = MMAP(request_size); if (ptr == MAP_FAILED) return NULL; header_t *header = (header_t*)ptr; header->size = request_size; return (void*)(header + 1); } // look for free blocks in our lists for (unsigned int request_bin = bin_index(request_size); request_bin < MAX_BINS; request_bin++) { header_t *candidate = free_list[request_bin]; while (candidate != NULL) { // we found a suitable block if (candidate->size >= request_size) { // take this block out of the free list if (candidate->prev) candidate->prev->next = candidate->next; if (candidate->next) candidate->next->prev = candidate->prev; if (!(candidate->prev || candidate->next)) free_list[request_bin] = NULL; // if there's a remainder, add it back to the appropriate list if (candidate->size > request_size) { header_t *remainder = (header_t*)((char*)candidate + request_size); remainder->size = candidate->size - request_size; apfree(remainder + 1); candidate->size = request_size; } return (void*)(candidate + 1); } candidate = candidate->next; } } // no block big enough found, request and split a big chunk void *ptr = MMAP(PAGE_SIZE); if (ptr == MAP_FAILED) return NULL; header_t *remainder = (header_t*)((char*)ptr + request_size); remainder->size = PAGE_SIZE - request_size; apfree(remainder + 1); header_t *header = (header_t*)ptr; header->size = request_size; return (void*)(header + 1); }
void *allocate_executable_buffer(uint64_t *length) { uint64_t sys_pagesize=sysconf(_SC_PAGESIZE); uint64_t real_length=round_to_next_page(*length);//round size to nearest page size uint8_t *buf=mmap(NULL,real_length,PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_SHARED,-1,0); if(buf == MAP_FAILED) { perror("Error allocating memory\n"); return (void*)-1;//a function shouldn't exit the main program by itself } *length=real_length; return buf; }