コード例 #1
0
ファイル: arena.c プロジェクト: msuvajac/yara
int yr_arena_create(
    size_t initial_size,
    int flags,
    YR_ARENA** arena)
{
  YR_ARENA* new_arena;
  YR_ARENA_PAGE* new_page;

  *arena = NULL;
  new_arena = (YR_ARENA*) yr_malloc(sizeof(YR_ARENA));

  if (new_arena == NULL)
    return ERROR_INSUFFICIENT_MEMORY;

  new_page = _yr_arena_new_page(initial_size);

  if (new_page == NULL)
  {
    yr_free(new_arena);
    return ERROR_INSUFFICIENT_MEMORY;
  }

  new_arena->page_list_head = new_page;
  new_arena->current_page = new_page;
  new_arena->flags = flags | ARENA_FLAGS_COALESCED;

  *arena = new_arena;
  return ERROR_SUCCESS;
}
コード例 #2
0
ファイル: arena.c プロジェクト: chrisddom/yara
int yr_arena_allocate_memory(
    YR_ARENA* arena,
    size_t size,
    void** allocated_memory)
{
  size_t new_page_size;
  void* new_page_address;
  YR_ARENA_PAGE* new_page;

  if (size > free_space(arena->current_page))
  {
    // Requested space is bigger than current page's empty space,
    // lets calculate the size for a new page.

    new_page_size = arena->current_page->size * 2;

    while (new_page_size < size)
      new_page_size *= 2;

    if (arena->current_page->used == 0)
    {
      // Current page is not used at all, it can be reallocated.

      new_page_address = yr_realloc(
          arena->current_page->address,
          new_page_size);

      if (new_page_address == NULL)
        return ERROR_INSUFICIENT_MEMORY;

      arena->current_page->address = new_page_address;
      arena->current_page->size = new_page_size;
    }
    else
    {
      if (arena->flags & ARENA_FLAGS_FIXED_SIZE)
        return ERROR_INSUFICIENT_MEMORY;

      new_page = _yr_arena_new_page(new_page_size);

      if (new_page == NULL)
        return ERROR_INSUFICIENT_MEMORY;

      new_page->prev = arena->current_page;
      arena->current_page->next = new_page;
      arena->current_page = new_page;
      arena->flags &= ~ARENA_FLAGS_COALESCED;
    }
  }

  *allocated_memory = arena->current_page->address + \
                      arena->current_page->used;

  arena->current_page->used += size;

  return ERROR_SUCCESS;

}
コード例 #3
0
ファイル: arena.c プロジェクト: msuvajac/yara
int yr_arena_coalesce(
    YR_ARENA* arena)
{
  YR_ARENA_PAGE* page;
  YR_ARENA_PAGE* big_page;
  YR_ARENA_PAGE* next_page;
  YR_RELOC* reloc;

  uint8_t** reloc_address;
  uint8_t* reloc_target;
  size_t total_size = 0;

  page = arena->page_list_head;

  while(page != NULL)
  {
    total_size += page->used;
    page = page->next;
  }

  // Create a new page that will contain the entire arena.
  big_page = _yr_arena_new_page(total_size);

  if (big_page == NULL)
    return ERROR_INSUFFICIENT_MEMORY;

  // Copy data from current pages to the big page and adjust relocs.
  page = arena->page_list_head;

  while (page != NULL)
  {
    page->new_address = big_page->address + big_page->used;
    memcpy(page->new_address, page->address, page->used);

    reloc = page->reloc_list_head;

    while (reloc != NULL)
    {
      reloc->offset += (uint32_t) big_page->used;
      reloc = reloc->next;
    }

    if (big_page->reloc_list_head == NULL)
      big_page->reloc_list_head = page->reloc_list_head;

    if (big_page->reloc_list_tail != NULL)
      big_page->reloc_list_tail->next = page->reloc_list_head;

    if (page->reloc_list_tail != NULL)
      big_page->reloc_list_tail = page->reloc_list_tail;

    big_page->used += page->used;
    page = page->next;
  }

  // Relocate pointers.
  reloc = big_page->reloc_list_head;

  while (reloc != NULL)
  {
    reloc_address = (uint8_t**) (big_page->address + reloc->offset);
    reloc_target = *reloc_address;

    if (reloc_target != NULL)
    {
      page = _yr_arena_page_for_address(arena, reloc_target);
      assert(page != NULL);
      *reloc_address = page->new_address + (reloc_target - page->address);
    }

    reloc = reloc->next;
  }

  // Release current pages.
  page = arena->page_list_head;

  while(page != NULL)
  {
    next_page = page->next;
    yr_free(page->address);
    yr_free(page);
    page = next_page;
  }

  arena->page_list_head = big_page;
  arena->current_page = big_page;
  arena->flags |= ARENA_FLAGS_COALESCED;

  return ERROR_SUCCESS;
}
コード例 #4
0
ファイル: arena.c プロジェクト: hidd3ncod3s/hipara
int yr_arena_duplicate(
    YR_ARENA* arena,
    YR_ARENA** duplicated)
{
  YR_RELOC* reloc;
  YR_RELOC* new_reloc;
  YR_ARENA_PAGE* page;
  YR_ARENA_PAGE* new_page;
  YR_ARENA* new_arena;
  uint8_t** reloc_address;
  uint8_t* reloc_target;

  // Only coalesced arenas can be duplicated.
  assert(arena->flags & ARENA_FLAGS_COALESCED);

  new_arena = (YR_ARENA*) yr_malloc(sizeof(YR_ARENA));

  if (new_arena == NULL)
    return ERROR_INSUFICIENT_MEMORY;

  page = arena->page_list_head;
  new_page = _yr_arena_new_page(page->size);

  if (new_page == NULL)
  {
    yr_free(new_arena);
    return ERROR_INSUFICIENT_MEMORY;
  }

  memcpy(new_page->address, page->address, page->size);

  new_page->used = page->used;

  reloc = page->reloc_list_head;

  while (reloc != NULL)
  {
    new_reloc = yr_malloc(sizeof(YR_RELOC));

    if (new_reloc == NULL)
      return ERROR_INSUFICIENT_MEMORY;

    new_reloc->offset = reloc->offset;
    new_reloc->next = NULL;

    if (new_page->reloc_list_head == NULL)
      new_page->reloc_list_head = new_reloc;

    if (new_page->reloc_list_tail != NULL)
      new_page->reloc_list_tail->next = new_reloc;

    new_page->reloc_list_tail = new_reloc;

    reloc_address = (uint8_t**) (new_page->address + new_reloc->offset);
    reloc_target = *reloc_address;

    if (reloc_target != NULL)
    {
      assert(reloc_target >= page->address);
      assert(reloc_target < page->address + page->used);

      *reloc_address = reloc_target - \
                       page->address + \
                       new_page->address;
    }

    reloc = reloc->next;
  }

  new_arena->page_list_head = new_page;
  new_arena->current_page = new_page;
  new_arena->flags |= ARENA_FLAGS_COALESCED;

  *duplicated = new_arena;

  return ERROR_SUCCESS;
}