Patch holes in big switches
This commit is contained in:
parent
10ead4df37
commit
da05f6b9f1
8 changed files with 86 additions and 4 deletions
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
26
src/PcHoleFiller.cpp
Normal 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
15
src/PcHoleFiller.hpp
Normal 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;
|
||||
};
|
|
@ -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
13
src/SimpleDwarfFilter.cpp
Normal 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
22
src/SimpleDwarfFilter.hpp
Normal 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;
|
||||
};
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue