Advertisement
Guest User

Untitled

a guest
Aug 19th, 2017
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.21 KB | None | 0 0
  1. /* File released under CC0 (public domain), read more
  2.    https://creativecommons.org/publicdomain/zero/1.0/deed.en
  3.    */
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <stdint.h>
  8.  
  9. #define HEAP_MAGIC 0x1DEFEC8D
  10. #define HEAP_SIZE 0x100000
  11. #define HEAP_FLAG_FREE (1 << 0)
  12.  
  13. typedef struct heap_header{
  14.     uint32_t magic;
  15.     uint32_t flags;
  16.     uint64_t size;
  17.     struct heap_header* prev;
  18.     struct heap_header* next;
  19. } heap_header_t;
  20.  
  21. static char heap[HEAP_SIZE] ;
  22. static heap_header_t* heap_start;
  23.  
  24. static inline char is_block_free(heap_header_t* block)
  25. {
  26.     if(block == NULL) return 0;
  27.     return (block->flags & HEAP_FLAG_FREE);
  28. }
  29.  
  30. static void dump_header(heap_header_t* header);
  31. static void* initialize_heap(uint64_t size);
  32.  
  33. static inline heap_header_t* find_free_block(uint64_t size);
  34. static inline void split_block(heap_header_t* block, uint64_t size);
  35. static inline void* allocate_block(uint64_t size);
  36.  
  37. static inline void deallocate_block(heap_header_t* address);
  38.  
  39. void* malloc(size_t size);
  40. void free(void* ptr);
  41.  
  42. int main(void)
  43. {
  44.     heap_start = initialize_heap(HEAP_SIZE);
  45.  
  46.     dump_header(allocate_block(0x40));
  47.     dump_header(allocate_block(0x40));
  48.     dump_header(allocate_block(0x40));
  49.  
  50.     printf("%p, %p, %p\n", malloc(0x20), malloc(0x500), malloc(0x800));
  51.     void* ptr1 = malloc(0x100);
  52.     void* ptr2 = malloc(0x100);
  53.     void* ptr3 = malloc(0x100);
  54.     printf("%p, %p, %p\n", malloc(0x20), malloc(0x500), malloc(0x800));
  55.  
  56.     free(ptr2);
  57.     dump_header((heap_header_t*)((uint64_t)ptr1 - sizeof(heap_header_t)));
  58.     dump_header((heap_header_t*)((uint64_t)ptr2 - sizeof(heap_header_t)));
  59.     dump_header((heap_header_t*)((uint64_t)ptr3 - sizeof(heap_header_t)));
  60.     free(ptr1);
  61.     dump_header((heap_header_t*)((uint64_t)ptr1 - sizeof(heap_header_t)));
  62.     dump_header((heap_header_t*)((uint64_t)ptr2 - sizeof(heap_header_t)));
  63.     dump_header((heap_header_t*)((uint64_t)ptr3 - sizeof(heap_header_t)));
  64.  
  65.     return 0;
  66. }
  67.  
  68. void dump_header(heap_header_t* header)
  69. {
  70.     if(header != NULL)
  71.         printf("%p, 0x%X, 0x%lX, %p, %p\n",
  72.                 header,
  73.                 header->flags,
  74.                 header->size,
  75.                 header->prev,
  76.                 header->next
  77.               );
  78.     else
  79.         printf("(nil)\n");
  80. }
  81.  
  82. void* initialize_heap(uint64_t size)
  83. {
  84.     heap_header_t* header = (heap_header_t*)&heap[0];
  85.  
  86.     header->magic = HEAP_MAGIC;
  87.     header->flags = HEAP_FLAG_FREE;
  88.     header->size = size - sizeof(*header);
  89.     header->prev = NULL;
  90.     header->next = NULL;
  91.  
  92.     return (void*)header;
  93. }
  94.  
  95. heap_header_t* find_free_block(uint64_t size)
  96. {
  97.     heap_header_t* current = (heap_header_t*)&heap[0];
  98.  
  99.     while(current != NULL)
  100.     {
  101.         if(current->size >= size && is_block_free(current))
  102.             return current;
  103.  
  104.         current = current->next;
  105.     }
  106.  
  107.     return current;
  108. }
  109.  
  110. void split_block(heap_header_t* block, uint64_t size)
  111. {
  112.     heap_header_t* new_block =
  113.         (heap_header_t*)((uint64_t)block + sizeof(*block) + size);
  114.  
  115.     new_block->magic = HEAP_MAGIC;
  116.     new_block->flags = HEAP_FLAG_FREE;
  117.     new_block->size = block->size - size - sizeof(*new_block);
  118.     new_block->prev = block;
  119.     new_block->next = block->next;
  120.  
  121.     block->size = size;
  122.     block->next = new_block;
  123. }
  124.  
  125. void* allocate_block(uint64_t size)
  126. {
  127.     heap_header_t* block = find_free_block(size);
  128.  
  129.     if(block == NULL) return NULL;
  130.  
  131.     if(block->size - size > sizeof(*block))
  132.         split_block(block, size);
  133.  
  134.     block->flags &= (uint32_t)~HEAP_FLAG_FREE;
  135.  
  136.     return block;
  137. }
  138.  
  139. void deallocate_block(heap_header_t* block)
  140. {
  141.     block->flags |= (uint32_t)HEAP_FLAG_FREE;
  142.     while(is_block_free(block->next))
  143.         block->next = block->next->next;
  144.     while(is_block_free(block->prev))
  145.         block->prev = block->prev->prev;
  146.  
  147.     block->next->prev = block->prev;
  148. }
  149.  
  150. void* malloc(size_t size)
  151. {
  152.     heap_header_t* block = allocate_block((uint64_t)size);
  153.  
  154.     if(block == NULL) return NULL;
  155.  
  156.     return (void*)((uint64_t)block + sizeof(*block));
  157. }
  158.  
  159. void free(void* ptr)
  160. {
  161.     if(ptr == NULL) return;
  162.  
  163.     heap_header_t* block = (heap_header_t*)((uint64_t)ptr - sizeof(*block));
  164.     deallocate_block(block);
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement