Patch holes in big switches

This commit is contained in:
Théophile Bastian 2018-06-20 14:12:42 +02:00
parent 10ead4df37
commit da05f6b9f1
8 changed files with 86 additions and 4 deletions

View File

@ -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.
}
}

View File

@ -9,6 +9,8 @@ OBJS=\
SimpleDwarf.o \
CodeGenerator.o \
PcListReader.o \
SimpleDwarfFilter.o \
PcHoleFiller.o \
settings.o \
main.o

26
src/PcHoleFiller.cpp Normal file
View File

@ -0,0 +1,26 @@
#include "PcHoleFiller.hpp"
#include <algorithm>
#include <cstdio>
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;
}

15
src/PcHoleFiller.hpp Normal file
View File

@ -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;
};

View File

@ -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<DwRow> rows; ///< Dwarf rows for this FDE
friend std::ostream& operator<<(std::ostream &, const Fde&);

13
src/SimpleDwarfFilter.cpp Normal file
View File

@ -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);
}

22
src/SimpleDwarfFilter.hpp Normal file
View File

@ -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 <vector>
#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;
};

View File

@ -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;