示例#1
0
文件: main.cpp 项目: monitai/redex
int main(int argc, char* argv[]) {
  signal(SIGSEGV, crash_backtrace);
  signal(SIGABRT, crash_backtrace);
  signal(SIGBUS, crash_backtrace);

  g_redex = new RedexContext();

  auto passes = create_passes();

  Arguments args;
  std::vector<KeepRule> rules;
  // Currently there are two sources that specify the library jars:
  // 1. The jar_path argument, which may specify one library jar.
  // 2. The library_jars vector, which lists the library jars specified in
  //    the ProGuard configuration.
  // If -jarpath specified a library jar it is appended to the
  // library_jars vector so this vector can be used to iterate over
  // all the library jars regardless of whether they were specified
  // on the command line or ProGuard file.
  // TODO: Make the command line -jarpath option like a colon separated
  //       list of library JARS.
  std::set<std::string> library_jars;
  auto start = parse_args(argc, argv, args);
  if (!dir_is_writable(args.out_dir)) {
    fprintf(stderr,
            "outdir %s is not a writable directory\n",
            args.out_dir.c_str());
    exit(1);
  }

  if (!args.proguard_config.empty()) {
    if (!load_proguard_config_file(
            args.proguard_config.c_str(), &rules, &library_jars)) {
      fprintf(stderr,
              "ERROR: Unable to open proguard config %s\n",
              args.proguard_config.c_str());
      // For now tolerate missing or unparseable ProGuard configuration files.
      // start = 0;
    }
  } else {
    TRACE(MAIN,
          1,
          "Skipping parsing the proguard config file "
          "because no file was specified\n");
  }

  for (const auto jar_path : args.jar_paths) {
    std::stringstream jar_stream(jar_path);
    std::string dependent_jar_path;
    while (std::getline(jar_stream, dependent_jar_path, ':')) {
      TRACE(MAIN,
            2,
            "Dependent JAR specified on command-line: %s\n",
            dependent_jar_path.c_str());
      library_jars.emplace(dependent_jar_path);
    }
  }

  if (start == 0 || start == argc) {
    usage();
    exit(1);
  }

  DexClassesVector dexen;
  for (int i = start; i < argc; i++) {
    dexen.emplace_back(load_classes_from_dex(argv[i]));
  }

  for (const auto& library_jar : library_jars) {
    TRACE(MAIN, 1, "LIBRARY JAR: %s\n", library_jar.c_str());
    if (!load_jar_file(library_jar.c_str())) {
      fprintf(
          stderr,
          "WARNING: Error in jar %s - continue. This may lead to unexpected "
          "behavior, please check your jars\n",
          library_jar.c_str());
    }
  }

  ConfigFiles cfg(args.config);
  cfg.using_seeds = false;
  if (!args.seeds_filename.empty()) {
    cfg.using_seeds = init_seed_classes(args.seeds_filename) > 0;
  }

  PassManager manager(passes, rules, args.config);
  manager.run_passes(dexen, cfg);

  TRACE(MAIN, 1, "Writing out new DexClasses...\n");

  LocatorIndex* locator_index = nullptr;
  if (args.config.get("emit_locator_strings", false).asBool()) {
    TRACE(LOC,
          1,
          "Will emit class-locator strings for classloader optimization\n");
    locator_index = new LocatorIndex(make_locator_index(dexen));
  }

  dex_output_stats_t totals;
  std::vector<dex_output_stats_t> dexes_stats;

  auto pos_output = args.config.get("line_number_map", "").asString();
  std::unique_ptr<PositionMapper> pos_mapper(PositionMapper::make(pos_output));

  for (size_t i = 0; i < dexen.size(); i++) {
    std::stringstream ss;
    ss << args.out_dir + "/classes";
    if (i > 0) {
      ss << (i + 1);
    }
    ss << ".dex";
    auto stats = write_classes_to_dex(
      ss.str(),
      &dexen[i],
      locator_index,
      i,
      cfg,
      args.config,
      pos_mapper.get());
    totals += stats;
    dexes_stats.push_back(stats);
  }

  auto stats_output = args.config.get("stats_output", "").asString();
  auto method_move_map = args.config.get("method_move_map", "").asString();

  pos_mapper->write_map();
  output_stats(stats_output.c_str(), totals, dexes_stats, manager);
  output_moved_methods_map(method_move_map.c_str(), dexen, cfg);
  print_warning_summary();
  delete g_redex;
  TRACE(MAIN, 1, "Done.\n");

  return 0;
}
示例#2
0
void load_and_shift_map(int dist) {
	char fname[256], line[1024];
	FILE *index, *wld;
	int block, vnum, island, type, junk;
	
	// nowork
	if (dist == 0) {
		printf("Shift by distance 0: no work to do.\n");
		return;
	}
	
	init_grid();
	printf("Loaded existing map...\n");
	
	// load in existing map
	if (!(index = fopen("index", "r"))) {
		printf("ERROR: Unable to load index file.\n");
		exit(1);
	}
	
	while (fscanf(index, "%d.wld\n", &block) == 1) {
		sprintf(fname, "%d.wld", block);
		printf("Loading file %s ...\n", fname);
		if (!(wld = fopen(fname, "r"))) {
			printf("ERROR: Unable to open world file %s.\n", fname);
			exit(1);
		}
		
		while (get_line(wld, line)) {
			if (*line == '$') {
				break;
			}
			else if (*line == '#') {
				// found entry
				vnum = atoi(line + 1);
				
				if (!get_line(wld, line) || sscanf(line, "%d %d %d", &island, &type, &junk) != 3) {
					printf("Error reading room #%d\n", vnum);
					exit(1);
				}
				
				change_grid(vnum, sect_to_terrain(type));
				grid[vnum].island_id = island;
				
				// trailing 'S' line
				get_line(wld, line);
			}
			else {
				printf("Unknown line in %s: %s\n", fname, line);
				exit(1);
			}
		}
	}
	
	shift_map_x(dist);
	
	print_map_graphic();
	print_map_to_files();

	printf("Map shifted %d on X-axis.\n", dist);
	output_stats();	
}
int main (int argc, char *argv[]) {
  int i;
  progname = argv[0];
  while ((i = getopt (argc, argv, "hfvu:m:s:t:z:")) != -1) {
    switch (i) {
    case 'v':
      verbosity = 1;
      break;
    case 'f':
      skip_rotate = 1;
      break;
    case 'h':
      usage();
      return 2;
    case 'u':
      username = optarg;
      break;
    case 'm':
      if (sscanf (optarg, "%d,%d", &copy_rem, &copy_mod) != 2 || copy_rem < 0 || copy_rem >= copy_mod) {
	usage();
	return 2;
      }
      break;
    case 's':
      jump_log_pos = atoll (optarg);
      break;
    case 't':
      log_limit_pos = atoll (optarg);
      break;
    case 'z':
      split_mode = get_split_mode(optarg);
      switch (split_mode) {
      case SM_NONE:  
        fprintf (stderr, "fatal: unsupported split mode: %s\n", optarg);
        return 2;
      case SM_HASH:
        fits = &hash_key_fits;
        break;
      case SM_FIRSTINT:
        fits = &firstint_fits;        
        break;
      case SM_DOT:
        fits = &dot_fits;
        break;
      }
      break;
    }
  }
  
  if (copy_mod < 0) {
    usage ();
    return 2;
  }


  if (optind >= argc || optind + 2 < argc) {
    usage();
    return 2;
  }

  if (log_limit_pos >= 0) {
    if (jump_log_pos > log_limit_pos) {
      fprintf (stderr, "fatal: log start position %lld after stop position %lld\n", jump_log_pos, log_limit_pos);
      return 2;
    }
  }

  if (username && change_user (username) < 0) {
    fprintf (stderr, "fatal: cannot change user to %s\n", username ? username : "******");
    return 1;
  }

  if (engine_preload_filelist (argv[optind], binlogname) < 0) {
    fprintf (stderr, "cannot open binlog files for %s\n", binlogname ? binlogname : argv[optind]);
    exit (1);
  }

  Binlog = open_binlog (engine_replica, jump_log_pos);
  if (!Binlog) {
    fprintf (stderr, "fatal: cannot find binlog for %s, log position %lld\n", engine_replica->replica_prefix, 0LL);
    exit (1);
  }

  binlogname = Binlog->info->filename;

  if (verbosity) {
    fprintf (stderr, "replaying binlog file %s (size %lld)\n", binlogname, Binlog->info->file_size);
  }

  clear_log();

  init_log_data (jump_log_pos, 0, 0);

  if (jump_log_pos > 0) {
    init_pmemcached_data (0);
  }

  if (optind + 1 < argc) {
    targ_fname = argv[optind+1];
    targ_fd = open (targ_fname, O_WRONLY | O_APPEND | O_CREAT, 0644);
    if (targ_fd < 0) {
      fprintf (stderr, "cannot create %s: %m\n", targ_fname);
      return 1;
    }
    targ_orig_size = lseek (targ_fd, 0, SEEK_END);
    targ_existed = (targ_orig_size > 0);
  } else {
    targ_fname = "stdout";
    targ_fd = 1;
  }

  i = replay_log (0, 1);

  if (i < 0) {
    fprintf (stderr, "fatal: error reading binlog\n");
    exit (1);
  }

  if (log_limit_pos >= 0 && log_readto_pos != log_limit_pos) {
    fprintf (stderr, "fatal: binlog read up to position %lld instead of %lld\n", log_readto_pos, log_limit_pos);
    exit (1);
  }

  flush_out ();

  if (targ_fd != 1) {
    if (fdatasync (targ_fd) < 0) {
      fprintf (stderr, "error syncing %s: %m", targ_fname);
      exit (1);
    }
    close (targ_fd);
  }

  if (verbosity > 0) {
    output_stats ();
  }

  return 0;
}
示例#4
0
void outputStats(uint8_t argc, char * argv[]) {
	output_stats();
}