Ejemplo n.º 1
0
bool test_poison(void) {
  size_t size;
  for (size = 1; size <= 16; size++) {
    {
      umm_init();
      corruption_cnt = 0;
      char *ptr = wrap_malloc(size);
      ptr[size]++;

      wrap_free(ptr);

      if (corruption_cnt == 0) {
        printf("corruption_cnt should not be 0, but it is\n");
        return false;
      }
    }

    {
      umm_init();
      corruption_cnt = 0;
      char *ptr = wrap_calloc(1, size);
      ptr[-1]++;

      wrap_free(ptr);

      if (corruption_cnt == 0) {
        printf("corruption_cnt should not be 0, but it is\n");
        return false;
      }
    }
  }

  return true;
}
Ejemplo n.º 2
0
bool test_oom_random(void) {
  umm_init();
  corruption_cnt = 0;
  void *ptrs[OOM_PTRS_CNT];

  size_t size = 100;

  while (1) {
    size_t i;
    for (i = 0; i < OOM_PTRS_CNT; i++) {
      size += rand() % 40 - 10;
      ptrs[i] = wrap_malloc(size);
      if (ptrs[i] == NULL) {
        goto out;
      }
    }

    /* free some of the blocks, so we have "holes" */
    for (i = 0; i < OOM_PTRS_CNT; i++) {
      if ((rand() % 10) <= 2) {
        wrap_free(ptrs[i]);
      }
    }
  }
out:

  if (corruption_cnt != 0) {
    printf("corruption_cnt should be 0, but it is %d\n", corruption_cnt);
    return false;
  }

  return true;
}
Ejemplo n.º 3
0
Archivo: main.c Proyecto: ESLab/rtdl
static void setup_heap()
{
	xMemoryInformationType	*mit	   = MIS_START_ADDRESS;
	void			*heap	   = mit[portCORE_ID()].phys_heap_begin;
	size_t			 heap_size = mit[portCORE_ID()].phys_heap_size - 0x10000;

	umm_init(heap, heap_size);
}
Ejemplo n.º 4
0
bool test_integrity_check(void) {
  size_t size;
  for (size = 1; size <= 16; size++) {
    {
      umm_init();
      corruption_cnt = 0;
      char *ptr = wrap_malloc(size);
      memset(ptr, 0xfe, size + 8 /* size of umm_block*/);

      /*
       * NOTE: we don't use wrap_free here, because we've just corrupted the
       * heap, and gathering of the umm info on corrupted heap can cause
       * segfault
       */
      umm_free(ptr);

      if (corruption_cnt == 0) {
        printf("corruption_cnt should not be 0, but it is\n");
        return false;
      }
    }

    {
      umm_init();
      corruption_cnt = 0;
      char *ptr = wrap_calloc(1, size);
      ptr[-1]++;

      /*
       * NOTE: we don't use wrap_free here, because we've just corrupted the
       * heap, and gathering of the umm info on corrupted heap can cause
       * segfault
       */
      umm_free(ptr);

      if (corruption_cnt == 0) {
        printf("corruption_cnt should not be 0, but it is\n");
        return false;
      }
    }
  }

  return true;
}
Ejemplo n.º 5
0
bool random_stress(void) {
  void *ptr_array[256];
  size_t i;
  int idx;

  corruption_cnt = 0;

  printf("Size of umm_heap is %u\n", (unsigned int) sizeof(test_umm_heap));

  umm_init();

  umm_info(NULL, 1);

  for (idx = 0; idx < 256; ++idx) ptr_array[idx] = (void *) NULL;

  for (idx = 0; idx < 100000; ++idx) {
    i = rand() % 256;

    /* try to realloc some pointer to deliberately too large value */
    {
      void *tmp = wrap_realloc(ptr_array[i], UMM_MALLOC_CFG__HEAP_SIZE);
      if (tmp != NULL) {
        printf("realloc to too large buffer should return NULL");
        return false;
      }
    }

    switch (rand() % 16) {
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6: {
        ptr_array[i] = wrap_realloc(ptr_array[i], 0);
        break;
      }
      case 7:
      case 8: {
        size_t size = rand() % 40;
        ptr_array[i] = wrap_realloc(ptr_array[i], size);
        memset(ptr_array[i], 0xfe, size);
        break;
      }

      case 9:
      case 10:
      case 11:
      case 12: {
        size_t size = rand() % 100;
        ptr_array[i] = wrap_realloc(ptr_array[i], size);
        memset(ptr_array[i], 0xfe, size);
        break;
      }

      case 13:
      case 14: {
        size_t size = rand() % 200;
        wrap_free(ptr_array[i]);
        ptr_array[i] = wrap_calloc(1, size);
        if (ptr_array[i] != NULL) {
          int a;
          for (a = 0; a < size; a++) {
            if (((char *) ptr_array[i])[a] != 0x00) {
              printf("calloc returned non-zeroed memory\n");
              return false;
            }
          }
        }
        memset(ptr_array[i], 0xfe, size);
        break;
      }

      default: {
        size_t size = rand() % 400;
        wrap_free(ptr_array[i]);
        ptr_array[i] = wrap_malloc(size);
        memset(ptr_array[i], 0xfe, size);
        break;
      }
    }
  }

  return (corruption_cnt == 0);
}
Ejemplo n.º 6
0
void *umm_realloc( void *ptr, size_t size ) {

  unsigned short int blocks;
  unsigned short int blockSize;
  unsigned short int prevBlockSize = 0;
  unsigned short int nextBlockSize = 0;

  unsigned short int c;

  size_t curSize;

  if (umm_heap == NULL) {
    umm_init();
  }

  /*
   * This code looks after the case of a NULL value for ptr. The ANSI C
   * standard says that if ptr is NULL and size is non-zero, then we've
   * got to work the same a malloc(). If size is also 0, then our version
   * of malloc() returns a NULL pointer, which is OK as far as the ANSI C
   * standard is concerned.
   */

  if( ((void *)NULL == ptr) ) {
    DBGLOG_DEBUG( "realloc the NULL pointer - call malloc()\n" );

    return( umm_malloc(size) );
  }

  /*
   * Now we're sure that we have a non_NULL ptr, but we're not sure what
   * we should do with it. If the size is 0, then the ANSI C standard says that
   * we should operate the same as free.
   */

  if( 0 == size ) {
    DBGLOG_DEBUG( "realloc to 0 size, just free the block\n" );

    umm_free( ptr );

    return( (void *)NULL );
  }

  /*
   * Otherwise we need to actually do a reallocation. A naiive approach
   * would be to malloc() a new block of the correct size, copy the old data
   * to the new block, and then free the old block.
   *
   * While this will work, we end up doing a lot of possibly unnecessary
   * copying. So first, let's figure out how many blocks we'll need.
   */

  blocks = umm_blocks( size );

  /* Figure out which block we're in. Note the use of truncated division... */

  c = (((char *)ptr)-(char *)(&(umm_heap[0])))/sizeof(umm_block);

  /* Figure out how big this block is ... the free bit is not set :-) */

  blockSize = (UMM_NBLOCK(c) - c);

  /* Figure out how many bytes are in this block */

  curSize   = (blockSize*sizeof(umm_block))-(sizeof(((umm_block *)0)->header));

  /* Protect the critical section... */
  UMM_CRITICAL_ENTRY();

  /* Now figure out if the previous and/or next blocks are free as well as
   * their sizes - this will help us to minimize special code later when we
   * decide if it's possible to use the adjacent blocks.
   *
   * We set prevBlockSize and nextBlockSize to non-zero values ONLY if they
   * are free!
   */

  if ((UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK)) {
      nextBlockSize = (UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) - UMM_NBLOCK(c);
  }

  if ((UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK)) {
      prevBlockSize = (c - UMM_PBLOCK(c));
  }

  DBGLOG_DEBUG( "realloc blocks %i blockSize %i nextBlockSize %i prevBlockSize %i\n", blocks, blockSize, nextBlockSize, prevBlockSize );

  /*
   * Ok, now that we're here we know how many blocks we want and the current
   * blockSize. The prevBlockSize and nextBlockSize are set and we can figure
   * out the best strategy for the new allocation as follows:
   *
   * 1. If the new block is the same size or smaller than the current block do
   *    nothing.
   * 2. If the next block is free and adding it to the current block gives us
   *    enough memory, assimilate the next block.
   * 3. If the prev block is free and adding it to the current block gives us
   *    enough memory, remove the previous block from the free list, assimilate
   *    it, copy to the new block.
   * 4. If the prev and next blocks are free and adding them to the current
   *    block gives us enough memory, assimilate the next block, remove the
   *    previous block from the free list, assimilate it, copy to the new block.
   * 5. Otherwise try to allocate an entirely new block of memory. If the
   *    allocation works free the old block and return the new pointer. If
   *    the allocation fails, return NULL and leave the old block intact.
   *
   * All that's left to do is decide if the fit was exact or not. If the fit
   * was not exact, then split the memory block so that we use only the requested
   * number of blocks and add what's left to the free list.
   */

    if (blockSize >= blocks) {
        DBGLOG_DEBUG( "realloc the same or smaller size block - %i, do nothing\n", blocks );
        /* This space intentionally left blank */
    } else if ((blockSize + nextBlockSize) >= blocks) {
        DBGLOG_DEBUG( "realloc using next block - %i\n", blocks );
        umm_assimilate_up( c );
        blockSize += nextBlockSize;
    } else if ((prevBlockSize + blockSize) >= blocks) {
        DBGLOG_DEBUG( "realloc using prev block - %i\n", blocks );
        umm_disconnect_from_free_list( UMM_PBLOCK(c) );
        c = umm_assimilate_down(c, 0);
        memmove( (void *)&UMM_DATA(c), ptr, curSize );
        ptr = (void *)&UMM_DATA(c);
        blockSize += prevBlockSize;
    } else if ((prevBlockSize + blockSize + nextBlockSize) >= blocks) {
        DBGLOG_DEBUG( "realloc using prev and next block - %i\n", blocks );
        umm_assimilate_up( c );
        umm_disconnect_from_free_list( UMM_PBLOCK(c) );
        c = umm_assimilate_down(c, 0);
        memmove( (void *)&UMM_DATA(c), ptr, curSize );
        ptr = (void *)&UMM_DATA(c);
        blockSize += (prevBlockSize + nextBlockSize);
    } else {
        DBGLOG_DEBUG( "realloc a completely new block %i\n", blocks );
        void *oldptr = ptr;
        if( (ptr = umm_malloc( size )) ) {
            DBGLOG_DEBUG( "realloc %i to a bigger block %i, copy, and free the old\n", blockSize, blocks );
            memcpy( ptr, oldptr, curSize );
            umm_free( oldptr );
        } else {
            DBGLOG_DEBUG( "realloc %i to a bigger block %i failed - return NULL and leave the old block!\n", blockSize, blocks );
            /* This space intentionally left blnk */
        }
        blockSize = blocks;
    }

    /* Now all we need to do is figure out if the block fit exactly or if we
     * need to split and free ...
     */

    if (blockSize > blocks ) {
        DBGLOG_DEBUG( "split and free %i blocks from %i\n", blocks, blockSize );
        umm_split_block( c, blocks, 0 );
        umm_free( (void *)&UMM_DATA(c+blocks) );
    }

    /* Release the critical section... */
    UMM_CRITICAL_EXIT();

    return( ptr );
}
Ejemplo n.º 7
0
void *umm_malloc( size_t size ) {
  unsigned short int blocks;
  unsigned short int blockSize = 0;

  unsigned short int bestSize;
  unsigned short int bestBlock;

  unsigned short int cf;

  if (umm_heap == NULL) {
    umm_init();
  }

  /*
   * the very first thing we do is figure out if we're being asked to allocate
   * a size of 0 - and if we are we'll simply return a null pointer. if not
   * then reduce the size by 1 byte so that the subsequent calculations on
   * the number of blocks to allocate are easier...
   */

  if( 0 == size ) {
    DBGLOG_DEBUG( "malloc a block of 0 bytes -> do nothing\n" );

    return( (void *)NULL );
  }

  /* Protect the critical section... */
  UMM_CRITICAL_ENTRY();

  blocks = umm_blocks( size );

  /*
   * Now we can scan through the free list until we find a space that's big
   * enough to hold the number of blocks we need.
   *
   * This part may be customized to be a best-fit, worst-fit, or first-fit
   * algorithm
   */

  cf = UMM_NFREE(0);

  bestBlock = UMM_NFREE(0);
  bestSize  = 0x7FFF;

  while( cf ) {
    blockSize = (UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK) - cf;

    DBGLOG_TRACE( "Looking at block %6i size %6i\n", cf, blockSize );

#if defined UMM_BEST_FIT
    if( (blockSize >= blocks) && (blockSize < bestSize) ) {
      bestBlock = cf;
      bestSize  = blockSize;
    }
#elif defined UMM_FIRST_FIT
    /* This is the first block that fits! */
    if( (blockSize >= blocks) )
      break;
#else
#  error "No UMM_*_FIT is defined - check umm_malloc_cfg.h"
#endif

    cf = UMM_NFREE(cf);
  }

  if( 0x7FFF != bestSize ) {
    cf        = bestBlock;
    blockSize = bestSize;
  }

  if( UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK && blockSize >= blocks ) {
    /*
     * This is an existing block in the memory heap, we just need to split off
     * what we need, unlink it from the free list and mark it as in use, and
     * link the rest of the block back into the freelist as if it was a new
     * block on the free list...
     */

    if( blockSize == blocks ) {
      /* It's an exact fit and we don't neet to split off a block. */
      DBGLOG_DEBUG( "Allocating %6i blocks starting at %6i - exact\n", blocks, cf );

      /* Disconnect this block from the FREE list */

      umm_disconnect_from_free_list( cf );

    } else {
      /* It's not an exact fit and we need to split off a block. */
      DBGLOG_DEBUG( "Allocating %6i blocks starting at %6i - existing\n", blocks, cf );

      /*
       * split current free block `cf` into two blocks. The first one will be
       * returned to user, so it's not free, and the second one will be free.
       */
      umm_split_block( cf, blocks, UMM_FREELIST_MASK /*new block is free*/ );

      /*
       * `umm_split_block()` does not update the free pointers (it affects
       * only free flags), but effectively we've just moved beginning of the
       * free block from `cf` to `cf + blocks`. So we have to adjust pointers
       * to and from adjacent free blocks.
       */

      /* previous free block */
      UMM_NFREE( UMM_PFREE(cf) ) = cf + blocks;
      UMM_PFREE( cf + blocks ) = UMM_PFREE(cf);

      /* next free block */
      UMM_PFREE( UMM_NFREE(cf) ) = cf + blocks;
      UMM_NFREE( cf + blocks ) = UMM_NFREE(cf);
    }
  } else {
    /* Out of memory */

    DBGLOG_DEBUG(  "Can't allocate %5i blocks\n", blocks );

    /* Release the critical section... */
    UMM_CRITICAL_EXIT();

    return( (void *)NULL );
  }

  /* Release the critical section... */
  UMM_CRITICAL_EXIT();

  return( (void *)&UMM_DATA(cf) );
}
Ejemplo n.º 8
0
void ICACHE_RAM_ATTR vPortInitialiseBlocks(void){
  return umm_init();
}