YR_API void yr_hash_table_destroy( YR_HASH_TABLE* table, YR_HASH_TABLE_FREE_VALUE_FUNC free_value) { yr_hash_table_clean(table, free_value); yr_free(table); }
YR_RULE* yr_parser_reduce_rule_declaration_phase_1( yyscan_t yyscanner, int32_t flags, const char* identifier) { YR_COMPILER* compiler = yyget_extra(yyscanner); YR_RULE* rule = NULL; if (yr_hash_table_lookup( compiler->rules_table, identifier, compiler->current_namespace->name) != NULL || yr_hash_table_lookup( compiler->objects_table, identifier, compiler->current_namespace->name) != NULL) { // A rule or variable with the same identifier already exists, return the // appropriate error. yr_compiler_set_error_extra_info(compiler, identifier); compiler->last_result = ERROR_DUPLICATED_IDENTIFIER; return NULL; } compiler->last_result = yr_arena_allocate_struct( compiler->rules_arena, sizeof(YR_RULE), (void**) &rule, offsetof(YR_RULE, identifier), offsetof(YR_RULE, tags), offsetof(YR_RULE, strings), offsetof(YR_RULE, metas), offsetof(YR_RULE, ns), EOL); if (compiler->last_result != ERROR_SUCCESS) return NULL; rule->g_flags = flags; rule->ns = compiler->current_namespace; #ifdef PROFILING_ENABLED rule->clock_ticks = 0; #endif compiler->last_result = yr_arena_write_string( compiler->sz_arena, identifier, (char**) &rule->identifier); if (compiler->last_result != ERROR_SUCCESS) return NULL; compiler->last_result = yr_parser_emit_with_arg_reloc( yyscanner, OP_INIT_RULE, PTR_TO_INT64(rule), NULL, NULL); if (compiler->last_result == ERROR_SUCCESS) compiler->last_result = yr_hash_table_add( compiler->rules_table, identifier, compiler->current_namespace->name, (void*) rule); // Clean strings_table as we are starting to parse a new rule. yr_hash_table_clean(compiler->strings_table, NULL); compiler->current_rule = rule; return rule; }
int yr_parser_reduce_rule_declaration_phase_1( yyscan_t yyscanner, int32_t flags, const char* identifier, YR_RULE** rule) { YR_FIXUP *fixup; YR_INIT_RULE_ARGS *init_rule_args; YR_COMPILER* compiler = yyget_extra(yyscanner); *rule = NULL; if (yr_hash_table_lookup( compiler->rules_table, identifier, compiler->current_namespace->name) != NULL || yr_hash_table_lookup( compiler->objects_table, identifier, NULL) != NULL) { // A rule or variable with the same identifier already exists, return the // appropriate error. yr_compiler_set_error_extra_info(compiler, identifier); return ERROR_DUPLICATED_IDENTIFIER; } FAIL_ON_ERROR(yr_arena_allocate_struct( compiler->rules_arena, sizeof(YR_RULE), (void**) rule, offsetof(YR_RULE, identifier), offsetof(YR_RULE, tags), offsetof(YR_RULE, strings), offsetof(YR_RULE, metas), offsetof(YR_RULE, ns), EOL)) (*rule)->g_flags = flags; (*rule)->ns = compiler->current_namespace; (*rule)->num_atoms = 0; #ifdef PROFILING_ENABLED (*rule)->time_cost = 0; memset( (*rule)->time_cost_per_thread, 0, sizeof((*rule)->time_cost_per_thread)); #endif FAIL_ON_ERROR(yr_arena_write_string( compiler->sz_arena, identifier, (char**) &(*rule)->identifier)); FAIL_ON_ERROR(yr_parser_emit( yyscanner, OP_INIT_RULE, NULL)); FAIL_ON_ERROR(yr_arena_allocate_struct( compiler->code_arena, sizeof(YR_INIT_RULE_ARGS), (void**) &init_rule_args, offsetof(YR_INIT_RULE_ARGS, rule), offsetof(YR_INIT_RULE_ARGS, jmp_addr), EOL)); init_rule_args->rule = *rule; // jmp_addr holds the address to jump to when we want to skip the code for // the rule. It is iniatialized as NULL at this point because we don't know // the address until emmiting the code for the rule's condition. The address // is set in yr_parser_reduce_rule_declaration_phase_2. init_rule_args->jmp_addr = NULL; // Create a fixup entry for the jump and push it in the stack fixup = (YR_FIXUP*) yr_malloc(sizeof(YR_FIXUP)); if (fixup == NULL) return ERROR_INSUFFICIENT_MEMORY; fixup->address = (void*) &(init_rule_args->jmp_addr); fixup->next = compiler->fixup_stack_head; compiler->fixup_stack_head = fixup; // Clean strings_table as we are starting to parse a new rule. yr_hash_table_clean(compiler->strings_table, NULL); FAIL_ON_ERROR(yr_hash_table_add( compiler->rules_table, identifier, compiler->current_namespace->name, (void*) *rule)); compiler->current_rule = *rule; return ERROR_SUCCESS; }