Beispiel #1
0
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);
      }
    }
  }
}