myasan.c 2.18 KB
#define _GNU_SOURCE 1

#include <inttypes.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>

#include "util.h"

static const size_t PAGE_SIZE = 4096;
typedef uint8_t page_t[PAGE_SIZE];

static void *const START_PAGE = (void *) ((size_t) 1 << 32);
static const size_t MAX_HEAP_SIZE = (size_t) 1 << 30;
static const int HEAP_MMAP_FLAGS = MAP_ANONYMOUS | MAP_PRIVATE;
static const size_t HEADER_MAGIC = 0x0123456789ABCDEF;

typedef struct {
    size_t magic;
    size_t size;
    bool is_allocated;
} header_t;

static bool is_initialized = false;
static page_t *current_page;

static size_t pages_round_up(size_t size) {
    return (size + PAGE_SIZE - 1) / PAGE_SIZE;
}

static void set_header(page_t *header_page, size_t size, bool is_allocated) {
    // TODO: Edit this in stage 1
    (void) header_page;
    (void) size;
    (void) is_allocated;
    (void) HEADER_MAGIC;
}

static void *get_payload(page_t *header_page, size_t size) {
    // TODO: Edit this in stage 1
    (void) header_page;
    (void) size;
    return NULL;
}

static void check_for_leaks(void) {
    // Prevent memory leaks from stdout
    fclose(stdout);

    // TODO: Edit this in stage 4
}

static void asan_init(void) {
    if (is_initialized) {
        return;
    }

    // Avoid buffering on stdout
    setbuf(stdout, NULL);

    current_page = mmap(START_PAGE, MAX_HEAP_SIZE,
                        PROT_READ | PROT_WRITE, // TODO: Edit this in stage 5
                        HEAP_MMAP_FLAGS, -1, 0);
    assert(current_page == START_PAGE);

    atexit(check_for_leaks);

    is_initialized = true;
}

void *malloc(size_t size) {
    asan_init();

    size_t pages_necessary = pages_round_up(size);

    // Store the size of the allocation at the beginning of the page before the payload
    page_t *header_page = current_page;
    set_header(header_page, size, true);
    current_page += 1 + pages_necessary;

    // Provide the user with the END of the first page
    return get_payload(header_page, size);
}

void free(void *ptr) {
    asan_init();

    if (ptr == NULL) {
        return;
    }

    // TODO: Edit this in stages 2 & 3
    (void) ptr;
}