PassManager::PassManager( const std::vector<Pass*>& passes, std::unique_ptr<redex::ProguardConfiguration> pg_config, const Json::Value& config, const RedexOptions& options) : m_apk_mgr(get_apk_dir(config)), m_registered_passes(passes), m_current_pass_info(nullptr), m_pg_config(std::move(pg_config)), m_redex_options(options), m_testing_mode(false) { init(config); if (getenv("PROFILE_COMMAND") && getenv("PROFILE_PASS")) { // Resolve the pass in the constructor so that any typos / references to // nonexistent passes are caught as early as possible auto pass = find_pass(getenv("PROFILE_PASS")); always_assert(pass != nullptr); m_profiler_info = ProfilerInfo(getenv("PROFILE_COMMAND"), pass); fprintf(stderr, "Will run profiler for %s\n", pass->name().c_str()); } if (getenv("MALLOC_PROFILE_PASS")) { m_malloc_profile_pass = find_pass(getenv("MALLOC_PROFILE_PASS")); always_assert(m_malloc_profile_pass != nullptr); fprintf(stderr, "Will run jemalloc profiler for %s\n", m_malloc_profile_pass->name().c_str()); } }
struct opt_pass *find_pass(char *pass_name, struct opt_pass **pass_list) { struct opt_pass *pass = *pass_list, *pass_tmp=NULL; for( ; pass; pass = pass->next) { if(strcmp(pass->name, pass_name) == 0) return pass; else if(pass->sub) { pass_tmp = find_pass(pass_name, &pass->sub); if(pass_tmp != NULL) return pass_tmp; } } return NULL; }
void substitute_passes(void *gcc_data, void *user_data) { const char *dname; int number_of_passes; struct opt_pass *pass_tmp; if (save_all_passes==NULL) save_all_passes=all_passes; /* For now we deal only with ALL PASSES per function */ if(current_function_decl != NULL) { dname = lang_hooks.decl_printable_name(current_function_decl, 2); if (dname!=NULL) { /* Function */ j_tmp1=openme_get_obj(j_in, dname); if (j_tmp1!=NULL) { /* Passes */ j_tmp2=openme_get_obj(j_tmp1, "all_passes"); if (j_tmp2==NULL) { printf("Alchemist error: can't find all_passes for function '%s' in input file ...\n", dname); exit(1); } printf("\nSubstituting passes for function %s ...\n\n", dname); number_of_passes = cJSON_GetArraySize(j_tmp2); j_tmp3 = j_tmp2->child; while(number_of_passes > 0) { j_tmp4 = cJSON_GetObjectItem(j_tmp3, "pass"); if (j_tmp4==NULL) { printf("Alchemist error: pass structure is broken in input file for function %s...\n", dname); exit(1); } strcpy(buf, j_tmp4->valuestring); if (strcmp(buf, "*clean_state")!=0) { pass_tmp = find_pass(buf, &all_passes); if(pass_tmp) { printf("Executing pass %s, %s\n", buf, pass_tmp->name); fflush(stdout); execute_one_pass(pass_tmp); } else { printf("Alchemist error: pass %s was not found in GCC...\n", pass_tmp->name); exit(1); } } j_tmp3 = j_tmp3->next; number_of_passes--; } printf("\nFinishing substitution ...\n"); /* Pointing real pass list to the final pass */ all_passes = find_pass("*clean_state", &all_passes); } } } }