2018-04-23 16:20:31 +02:00
|
|
|
/** Entry point */
|
|
|
|
|
|
|
|
#include <iostream>
|
2018-04-24 17:44:09 +02:00
|
|
|
#include <sstream>
|
2018-04-23 16:20:31 +02:00
|
|
|
#include <cstdlib>
|
|
|
|
|
|
|
|
#include "SimpleDwarf.hpp"
|
|
|
|
#include "DwarfReader.hpp"
|
2018-04-23 18:58:05 +02:00
|
|
|
#include "CodeGenerator.hpp"
|
2018-06-25 11:33:36 +02:00
|
|
|
#include "SwitchStatement.hpp"
|
|
|
|
#include "NativeSwitchCompiler.hpp"
|
2018-06-25 16:32:52 +02:00
|
|
|
#include "FactoredSwitchCompiler.hpp"
|
2018-06-20 14:12:42 +02:00
|
|
|
#include "PcHoleFiller.hpp"
|
2018-07-04 18:14:30 +02:00
|
|
|
#include "EmptyFdeDeleter.hpp"
|
2018-06-22 08:57:36 +02:00
|
|
|
#include "ConseqEquivFilter.hpp"
|
2018-04-23 16:20:31 +02:00
|
|
|
|
2018-04-30 13:23:48 +02:00
|
|
|
#include "settings.hpp"
|
|
|
|
|
2018-04-23 16:20:31 +02:00
|
|
|
using namespace std;
|
|
|
|
|
2018-04-30 13:23:48 +02:00
|
|
|
struct MainOptions {
|
|
|
|
std::string elf_path;
|
|
|
|
};
|
2018-04-23 16:20:31 +02:00
|
|
|
|
2018-04-30 13:23:48 +02:00
|
|
|
MainOptions options_parse(int argc, char** argv) {
|
|
|
|
MainOptions out;
|
|
|
|
|
|
|
|
bool seen_switch_gen_policy = false;
|
|
|
|
bool print_helptext = false;
|
|
|
|
int exit_status = -1;
|
|
|
|
|
|
|
|
for(int option_pos = 1; option_pos < argc; ++option_pos) {
|
|
|
|
std::string option(argv[option_pos]);
|
|
|
|
|
|
|
|
if(option.find("-") != 0) { // This is not an option argument
|
|
|
|
out.elf_path = option;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(option == "--help") {
|
|
|
|
print_helptext = true;
|
|
|
|
exit_status = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if(option == "--switch-per-func") {
|
|
|
|
seen_switch_gen_policy = true;
|
|
|
|
settings::switch_generation_policy =
|
|
|
|
settings::SGP_SwitchPerFunc;
|
|
|
|
}
|
|
|
|
else if(option == "--global-switch") {
|
|
|
|
seen_switch_gen_policy = true;
|
|
|
|
settings::switch_generation_policy =
|
|
|
|
settings::SGP_GlobalSwitch;
|
|
|
|
}
|
2018-05-11 13:09:35 +02:00
|
|
|
|
|
|
|
else if(option == "--pc-list") {
|
|
|
|
if(option_pos + 1 == argc) { // missing parameter
|
|
|
|
exit_status = 1;
|
|
|
|
print_helptext = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
++option_pos;
|
|
|
|
settings::pc_list = argv[option_pos];
|
|
|
|
}
|
|
|
|
}
|
2018-06-01 19:46:43 +02:00
|
|
|
|
|
|
|
else if(option == "--enable-deref-arg") {
|
|
|
|
settings::enable_deref_arg = true;
|
|
|
|
}
|
2018-07-04 18:14:30 +02:00
|
|
|
|
|
|
|
else if(option == "--keep-holes") {
|
|
|
|
settings::keep_holes = true;
|
|
|
|
}
|
2018-04-23 16:20:31 +02:00
|
|
|
}
|
|
|
|
|
2018-04-30 13:23:48 +02:00
|
|
|
if(!seen_switch_gen_policy) {
|
|
|
|
cerr << "Error: please use either --switch-per-func or "
|
|
|
|
<< "--global-switch." << endl;
|
|
|
|
print_helptext = true;
|
|
|
|
exit_status = 1;
|
|
|
|
}
|
|
|
|
if(out.elf_path.empty()) {
|
|
|
|
cerr << "Error: missing input file." << endl;
|
|
|
|
print_helptext = true;
|
|
|
|
exit_status = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(print_helptext) {
|
|
|
|
cerr << "Usage: "
|
|
|
|
<< argv[0]
|
2018-06-05 18:25:34 +02:00
|
|
|
<< " [--switch-per-func | --global-switch]"
|
|
|
|
<< " [--enable-deref-arg]"
|
2018-07-04 18:14:30 +02:00
|
|
|
<< " [--keep-holes]"
|
2018-06-05 18:25:34 +02:00
|
|
|
<< " [--pc-list PC_LIST_FILE] elf_path"
|
2018-04-30 13:23:48 +02:00
|
|
|
<< endl;
|
|
|
|
}
|
|
|
|
if(exit_status >= 0)
|
|
|
|
exit(exit_status);
|
|
|
|
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
|
|
|
MainOptions opts = options_parse(argc, argv);
|
|
|
|
SimpleDwarf parsed_dwarf = DwarfReader(opts.elf_path).read();
|
2018-04-23 16:20:31 +02:00
|
|
|
|
2018-06-20 14:12:42 +02:00
|
|
|
SimpleDwarf filtered_dwarf =
|
2018-07-04 18:14:30 +02:00
|
|
|
PcHoleFiller(!settings::keep_holes)(
|
|
|
|
EmptyFdeDeleter()(
|
2018-06-22 08:57:36 +02:00
|
|
|
ConseqEquivFilter()(
|
2018-07-04 18:14:30 +02:00
|
|
|
parsed_dwarf)));
|
2018-06-20 14:12:42 +02:00
|
|
|
|
2018-06-25 16:32:52 +02:00
|
|
|
FactoredSwitchCompiler* sw_compiler = new FactoredSwitchCompiler(1);
|
2018-04-24 17:44:09 +02:00
|
|
|
CodeGenerator code_gen(
|
2018-06-20 14:12:42 +02:00
|
|
|
filtered_dwarf,
|
2018-04-24 17:44:09 +02:00
|
|
|
cout,
|
|
|
|
[](const SimpleDwarf::Fde& fde) {
|
|
|
|
std::ostringstream ss;
|
|
|
|
ss << "_fde_" << fde.beg_ip;
|
|
|
|
return ss.str();
|
2018-06-25 11:33:36 +02:00
|
|
|
},
|
2018-06-25 16:32:52 +02:00
|
|
|
//new NativeSwitchCompiler()
|
|
|
|
sw_compiler
|
|
|
|
);
|
|
|
|
|
2018-04-23 18:58:05 +02:00
|
|
|
code_gen.generate();
|
2018-04-23 16:20:31 +02:00
|
|
|
|
2018-06-25 16:32:52 +02:00
|
|
|
#ifdef STATS
|
|
|
|
cerr << "Factoring stats:\nRefers: "
|
|
|
|
<< sw_compiler->get_stats().refer_count
|
|
|
|
<< "\nGenerated: "
|
|
|
|
<< sw_compiler->get_stats().generated_count
|
|
|
|
<< "\nAvoided: "
|
|
|
|
<< sw_compiler->get_stats().refer_count
|
|
|
|
- sw_compiler->get_stats().generated_count
|
|
|
|
<< "\n";
|
|
|
|
#endif
|
|
|
|
|
2018-04-23 16:20:31 +02:00
|
|
|
return 0;
|
|
|
|
}
|