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; }
int _yr_ac_find_suitable_transition_table_slot( YR_AC_AUTOMATON* automaton, YR_AC_STATE* state, uint32_t* slot) { YR_AC_STATE* child_state; uint32_t i = automaton->t_table_unused_candidate; int first_unused = TRUE; int found = FALSE; while (!found) { // Check if there is enough room in the table to hold 257 items // (1 failure link + 256 transitions) starting at offset i. If there's // no room double the table size. if (automaton->tables_size - i < 257) { size_t t_bytes_size = automaton->tables_size * sizeof(YR_AC_TRANSITION); size_t m_bytes_size = automaton->tables_size * sizeof(YR_AC_MATCH_TABLE_ENTRY); automaton->t_table = (YR_AC_TRANSITION_TABLE) yr_realloc( automaton->t_table, t_bytes_size * 2); automaton->m_table = (YR_AC_MATCH_TABLE) yr_realloc( automaton->m_table, m_bytes_size * 2); if (automaton->t_table == NULL || automaton->m_table == NULL) return ERROR_INSUFFICIENT_MEMORY; memset((uint8_t*) automaton->t_table + t_bytes_size, 0, t_bytes_size); memset((uint8_t*) automaton->m_table + m_bytes_size, 0, m_bytes_size); automaton->tables_size *= 2; } if (YR_AC_UNUSED_TRANSITION_SLOT(automaton->t_table[i])) { // A unused slot in the table has been found and could be a potential // candidate. Let's check if table slots for the transitions are // unused too. found = TRUE; child_state = state->first_child; while (child_state != NULL) { if (YR_AC_USED_TRANSITION_SLOT( automaton->t_table[child_state->input + i + 1])) { found = FALSE; break; } child_state = child_state->siblings; } // If this is the first unused entry we found, use it as the first // candidate in the next call to this function. if (first_unused) { automaton->t_table_unused_candidate = found ? i + 1 : i; first_unused = FALSE; } if (found) *slot = i; } i++; } return ERROR_SUCCESS; }
static int _yr_ac_find_suitable_transition_table_slot( YR_AC_AUTOMATON* automaton, YR_AC_STATE* state, uint32_t* slot) { // The state's transition table has 257 entries, 1 for the failure link and // 256 for each possible input byte, so the state's bitmask has 257 bits. YR_BITMASK state_bitmask[YR_BITMASK_SIZE(257)]; YR_AC_STATE* child_state = state->first_child; // Start with all bits set to zero. yr_bitmask_clear_all(state_bitmask); // The first slot in the transition table is for the state's failure link, // so the first bit in the bitmask must be set to one. yr_bitmask_set(state_bitmask, 0); while (child_state != NULL) { yr_bitmask_set(state_bitmask, child_state->input + 1); child_state = child_state->siblings; } *slot = yr_bitmask_find_non_colliding_offset( automaton->bitmask, state_bitmask, automaton->tables_size, 257, &automaton->t_table_unused_candidate); // Make sure that we are not going beyond the maximum size of the transition // table, starting at the slot found there must be at least 257 other slots // for accommodating the state's transition table. assert(*slot + 257 < YR_AC_MAX_TRANSITION_TABLE_SIZE); if (*slot > automaton->tables_size - 257) { size_t t_bytes_size = automaton->tables_size * sizeof(YR_AC_TRANSITION); size_t m_bytes_size = automaton->tables_size * sizeof(YR_AC_MATCH_TABLE_ENTRY); size_t b_bytes_size = YR_BITMASK_SIZE(automaton->tables_size) * sizeof(YR_BITMASK); automaton->t_table = (YR_AC_TRANSITION_TABLE) yr_realloc( automaton->t_table, t_bytes_size * 2); automaton->m_table = (YR_AC_MATCH_TABLE) yr_realloc( automaton->m_table, m_bytes_size * 2); automaton->bitmask = (YR_BITMASK*) yr_realloc( automaton->bitmask, b_bytes_size * 2); if (automaton->t_table == NULL || automaton->m_table == NULL || automaton->bitmask == NULL) { return ERROR_INSUFFICIENT_MEMORY; } memset((uint8_t*) automaton->t_table + t_bytes_size, 0, t_bytes_size); memset((uint8_t*) automaton->m_table + m_bytes_size, 0, m_bytes_size); memset((uint8_t*) automaton->bitmask + b_bytes_size, 0, b_bytes_size); automaton->tables_size *= 2; } return ERROR_SUCCESS; }