selfpatch-slr/patchcompile/patchcompile.cpp

94 lines
2.4 KiB
C++

#include <iostream>
#include <string>
#include <vector>
#include <cstdint>
#include <getopt.h>
#include <filesystem>
#include "accumulation.h"
#include "emit.h"
/*
Notes:
Datapins for same var/symbol are randomized in order of their level, from bottom of nest to top
Between CUs, types with the same name HAVE TO HAVE the same layout -> randomized together
*/
int main(int argc, char** argv) {
static option long_options[] = {
{ "help", no_argument, 0, 0 },
{ "out", required_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
int option_index = 0;
int c;
std::vector<std::string> spslr_files;
std::string out_file;
while ((c = getopt_long(argc, argv, "h:o:", long_options, &option_index)) == 0) {
const option& opt = long_options[option_index];
std::string optname { opt.name };
if (optname == "help") {
std::cout << "To use spslr_patchcompile, supply these arguments:" << std::endl;
std::cout << " --out=<file> (the compiled asm file to be written)" << std::endl;
std::cout << " <file>... (one or more .spslr metadata files)" << std::endl;
return 0;
} else if (optname == "out") {
out_file = std::string{ optarg };
} else {
std::cerr << "Invalid option, try \"--help\"!" << std::endl;
return 1;
}
}
if (out_file.empty()) {
std::cerr << "Missing output file path, supply it via --out=<file>!" << std::endl;
return 1;
}
for (int i = optind; i < argc; ++i)
spslr_files.emplace_back(argv[i]);
if (spslr_files.empty()) {
std::cerr << "Missing spslr files! Pass one or more .spslr files as positional arguments." << std::endl;
return 1;
}
if (!accumulate(spslr_files)) {
std::cerr << "Failed to accumulate data from spslr directory!" << std::endl;
return 1;
}
std::cout << "Gathered a total of " << targets.size() << " distinct targets from "
<< units.size() << " compilation units!" << std::endl;
std::filesystem::path out_path { out_file };
if (out_path.has_parent_path()) {
std::error_code ec;
std::filesystem::create_directories(out_path.parent_path(), ec);
if (ec) {
std::cerr << "failed to create output directory '"
<< out_path.parent_path().string()
<< "': " << ec.message() << "\n";
return 1;
}
}
std::ofstream out(out_path);
if (!out) {
std::cerr << "Failed to open output file!" << std::endl;
return 1;
}
if (!emit_patcher_program_asm(out)) {
std::cerr << "Failed to write emit patcher program!" << std::endl;
return 1;
}
return 0;
}