Skip to content
Snippets Groups Projects
Select Git revision
  • cf18a62bd1d0375b436a9f9075811789516011e6
  • main default protected
2 results

shamalloc.c

Blame
  • Christian Gram Kalhauge's avatar
    chrg authored
    cf18a62b
    History
    Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    shamalloc.c 1.64 KiB
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <dlfcn.h>
    
    #include "include/shamalloc.h"
    
    void
    break_alloc(int32_t until_broken) {
      shamalloc_time_until_broken = until_broken;
    }
    
    #define COUNTDOWN_OR_BREAK\
      if (shamalloc_time_until_broken == 0)\
        return NULL;\
      if (shamalloc_time_until_broken > 0)\
        shamalloc_time_until_broken -= 1;\
    
    // Might be to little on some systems.
    #define BUFFER_SIZE (1024)
    
    void *
    malloc(size_t size) {
      COUNTDOWN_OR_BREAK
    
      static void *(*fptr)(size_t) = NULL;
      if (fptr == NULL) {
        // To bootstrap malloc we need to allow dlsym to allocate
        // some memory. On my system only a single call is needed.
        static uint8_t is_recusive_call = 0;
        if (is_recusive_call++) {
          static uint8_t bootstrap_memory[BUFFER_SIZE];
          // Check that we don't bootstrap the same memory twice, or
          // that we try to allocate too much memory
          if (is_recusive_call > 1 || size > BUFFER_SIZE) abort();
          return bootstrap_memory;
        }
        fptr = (void *(*)(size_t)) dlsym(RTLD_NEXT, "malloc");
        is_recusive_call = 0;
      }
    
      if (fptr == NULL) abort();
      return (*fptr)(size);
    }
    
    void *
    calloc(size_t nmemb, size_t size) {
      COUNTDOWN_OR_BREAK
    
      static void *(*fptr)(size_t, size_t) = NULL;
      fptr = fptr ? fptr
             : ((void *(*)(size_t, size_t)) dlsym(RTLD_NEXT, "calloc"));
    
      if (fptr == NULL) abort();
      return (*fptr)(nmemb, size);
    }
    
    void *
    realloc(void * ptr, size_t size) {
      COUNTDOWN_OR_BREAK
    
      static void *(*fptr)(void*, size_t) = NULL;
      fptr = fptr ? fptr
             : ((void *(*)(void*, size_t)) dlsym(RTLD_NEXT, "realloc"));
    
      if (fptr == NULL) abort();
      return (*fptr)(ptr, size);
    }