diff --git a/src/ConseqEquivFilter.cpp b/src/ConseqEquivFilter.cpp new file mode 100644 index 0000000..6724298 --- /dev/null +++ b/src/ConseqEquivFilter.cpp @@ -0,0 +1,49 @@ +#include "ConseqEquivFilter.hpp" + +using namespace std; + +ConseqEquivFilter::ConseqEquivFilter() {} + +static bool equiv_reg( + const SimpleDwarf::DwRegister& r1, + const SimpleDwarf::DwRegister& r2) +{ + return r1.type == r2.type + && r1.offset == r2.offset + && r1.reg == r2.reg; +} + +static bool equiv_row( + const SimpleDwarf::DwRow& r1, + const SimpleDwarf::DwRow& r2) +{ + return r1.ip == r2.ip + && equiv_reg(r1.cfa, r2.cfa) + && equiv_reg(r1.rbp, r2.rbp) + && equiv_reg(r1.ra, r2.ra); +} + +SimpleDwarf ConseqEquivFilter::do_apply(const SimpleDwarf& dw) const { + SimpleDwarf out; + + for(const auto& fde: dw.fde_list) { + out.fde_list.push_back(SimpleDwarf::Fde()); + SimpleDwarf::Fde& cur_fde = out.fde_list.back(); + cur_fde.fde_offset = fde.fde_offset; + cur_fde.beg_ip = fde.beg_ip; + cur_fde.end_ip = fde.end_ip; + + if(fde.rows.empty()) + continue; + + cur_fde.rows.push_back(fde.rows.front()); + for(size_t pos=1; pos < fde.rows.size(); ++pos) { + const auto& row = fde.rows[pos]; + if(!equiv_row(row, cur_fde.rows.back())) { + cur_fde.rows.push_back(row); + } + } + } + + return out; +} diff --git a/src/ConseqEquivFilter.hpp b/src/ConseqEquivFilter.hpp new file mode 100644 index 0000000..fdc7af4 --- /dev/null +++ b/src/ConseqEquivFilter.hpp @@ -0,0 +1,16 @@ +/** SimpleDwarfFilter to keep a unique Dwarf row for each group of consecutive + * lines that are equivalent, that is, that share the same considered + * registers' values. */ + +#pragma once + +#include "SimpleDwarf.hpp" +#include "SimpleDwarfFilter.hpp" + +class ConseqEquivFilter: public SimpleDwarfFilter { + public: + ConseqEquivFilter(); + + private: + SimpleDwarf do_apply(const SimpleDwarf& dw) const; +}; diff --git a/src/Makefile b/src/Makefile index b9cfe69..4e52eb8 100644 --- a/src/Makefile +++ b/src/Makefile @@ -11,6 +11,7 @@ OBJS=\ PcListReader.o \ SimpleDwarfFilter.o \ PcHoleFiller.o \ + ConseqEquivFilter.o \ settings.o \ main.o diff --git a/src/main.cpp b/src/main.cpp index 915405e..4fa824f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,6 +8,7 @@ #include "DwarfReader.hpp" #include "CodeGenerator.hpp" #include "PcHoleFiller.hpp" +#include "ConseqEquivFilter.hpp" #include "settings.hpp" @@ -94,7 +95,9 @@ int main(int argc, char** argv) { SimpleDwarf parsed_dwarf = DwarfReader(opts.elf_path).read(); SimpleDwarf filtered_dwarf = - PcHoleFiller()(parsed_dwarf); + PcHoleFiller()( + ConseqEquivFilter()( + parsed_dwarf)); CodeGenerator code_gen( filtered_dwarf,