diff --git a/src/DwarfReader.cpp b/src/DwarfReader.cpp index c8a13f0..ec25ac8 100644 --- a/src/DwarfReader.cpp +++ b/src/DwarfReader.cpp @@ -62,7 +62,7 @@ SimpleDwarf::Fde DwarfReader::read_fde(const core::Fde& fde) const { break; } } - catch(UnsupportedRegister) {} // Just ignore it. + catch(const UnsupportedRegister&) {} // Just ignore it. } } diff --git a/src/Makefile b/src/Makefile index 430c010..b9cfe69 100644 --- a/src/Makefile +++ b/src/Makefile @@ -9,6 +9,8 @@ OBJS=\ SimpleDwarf.o \ CodeGenerator.o \ PcListReader.o \ + SimpleDwarfFilter.o \ + PcHoleFiller.o \ settings.o \ main.o diff --git a/src/PcHoleFiller.cpp b/src/PcHoleFiller.cpp new file mode 100644 index 0000000..763c8c3 --- /dev/null +++ b/src/PcHoleFiller.cpp @@ -0,0 +1,26 @@ +#include "PcHoleFiller.hpp" + +#include +#include + +using namespace std; + +PcHoleFiller::PcHoleFiller() {} + +SimpleDwarf PcHoleFiller::do_apply(const SimpleDwarf& dw) const { + SimpleDwarf out(dw); + sort(out.fde_list.begin(), out.fde_list.end(), + [](const SimpleDwarf::Fde& a, const SimpleDwarf::Fde& b) { + return a.beg_ip < b.beg_ip; + }); + + for(size_t pos=0; pos < out.fde_list.size() - 1; ++pos) { + if(out.fde_list[pos].end_ip > out.fde_list[pos + 1].beg_ip) { + fprintf(stderr, "WARNING: FDE %016lx-%016lx and %016lx-%016lx\n", + out.fde_list[pos].beg_ip, out.fde_list[pos].end_ip, + out.fde_list[pos + 1].beg_ip, out.fde_list[pos + 1].end_ip); + } + out.fde_list[pos].end_ip = out.fde_list[pos + 1].beg_ip; + } + return out; +} diff --git a/src/PcHoleFiller.hpp b/src/PcHoleFiller.hpp new file mode 100644 index 0000000..ccfad6d --- /dev/null +++ b/src/PcHoleFiller.hpp @@ -0,0 +1,15 @@ +/** Ensures there is no "hole" between two consecutive PC ranges, to optimize + * generated code size. */ + +#pragma once + +#include "SimpleDwarf.hpp" +#include "SimpleDwarfFilter.hpp" + +class PcHoleFiller: public SimpleDwarfFilter { + public: + PcHoleFiller(); + + private: + SimpleDwarf do_apply(const SimpleDwarf& dw) const; +}; diff --git a/src/SimpleDwarf.hpp b/src/SimpleDwarf.hpp index 80602bc..d5dbfc3 100644 --- a/src/SimpleDwarf.hpp +++ b/src/SimpleDwarf.hpp @@ -51,8 +51,8 @@ struct SimpleDwarf { struct Fde { uintptr_t fde_offset; ///< This FDE's offset in the original DWARF - uintptr_t beg_ip, ///< This FDE's start instruction pointer - end_ip; ///< This FDE's end instruction pointer + uintptr_t beg_ip, ///< This FDE's start instruction pointer incl. + end_ip; ///< This FDE's end instruction pointer excl. std::vector rows; ///< Dwarf rows for this FDE friend std::ostream& operator<<(std::ostream &, const Fde&); diff --git a/src/SimpleDwarfFilter.cpp b/src/SimpleDwarfFilter.cpp new file mode 100644 index 0000000..5466b24 --- /dev/null +++ b/src/SimpleDwarfFilter.cpp @@ -0,0 +1,13 @@ +#include "SimpleDwarfFilter.hpp" + +SimpleDwarfFilter::SimpleDwarfFilter() +{} + +SimpleDwarf SimpleDwarfFilter::apply(const SimpleDwarf& dw) const { + // For convenience of future enhancements + return do_apply(dw); +} + +SimpleDwarf SimpleDwarfFilter::operator()(const SimpleDwarf& dw) { + return apply(dw); +} diff --git a/src/SimpleDwarfFilter.hpp b/src/SimpleDwarfFilter.hpp new file mode 100644 index 0000000..278f1f9 --- /dev/null +++ b/src/SimpleDwarfFilter.hpp @@ -0,0 +1,22 @@ +/** An abstract parent class for any SimpleDwarf filter, that is. a class that + * transforms some SimpleDwarf into some other SimpleDwarf. */ + +#pragma once + +#include + +#include "SimpleDwarf.hpp" + +class SimpleDwarfFilter { + public: + SimpleDwarfFilter(); + + /// Applies the filter + SimpleDwarf apply(const SimpleDwarf& dw) const; + + /// Same as apply() + SimpleDwarf operator()(const SimpleDwarf& dw); + + private: + virtual SimpleDwarf do_apply(const SimpleDwarf& dw) const = 0; +}; diff --git a/src/main.cpp b/src/main.cpp index 9185921..915405e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -7,6 +7,7 @@ #include "SimpleDwarf.hpp" #include "DwarfReader.hpp" #include "CodeGenerator.hpp" +#include "PcHoleFiller.hpp" #include "settings.hpp" @@ -92,8 +93,11 @@ int main(int argc, char** argv) { MainOptions opts = options_parse(argc, argv); SimpleDwarf parsed_dwarf = DwarfReader(opts.elf_path).read(); + SimpleDwarf filtered_dwarf = + PcHoleFiller()(parsed_dwarf); + CodeGenerator code_gen( - parsed_dwarf, + filtered_dwarf, cout, [](const SimpleDwarf::Fde& fde) { std::ostringstream ss;