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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(UnsupportedRegister) {} // Just ignore it.
|
catch(const UnsupportedRegister&) {} // Just ignore it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,8 @@ OBJS=\
|
||||||
SimpleDwarf.o \
|
SimpleDwarf.o \
|
||||||
CodeGenerator.o \
|
CodeGenerator.o \
|
||||||
PcListReader.o \
|
PcListReader.o \
|
||||||
|
SimpleDwarfFilter.o \
|
||||||
|
PcHoleFiller.o \
|
||||||
settings.o \
|
settings.o \
|
||||||
main.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 {
|
struct Fde {
|
||||||
uintptr_t fde_offset; ///< This FDE's offset in the original DWARF
|
uintptr_t fde_offset; ///< This FDE's offset in the original DWARF
|
||||||
uintptr_t beg_ip, ///< This FDE's start instruction pointer
|
uintptr_t beg_ip, ///< This FDE's start instruction pointer incl.
|
||||||
end_ip; ///< This FDE's end instruction pointer
|
end_ip; ///< This FDE's end instruction pointer excl.
|
||||||
std::vector<DwRow> rows; ///< Dwarf rows for this FDE
|
std::vector<DwRow> rows; ///< Dwarf rows for this FDE
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream &, const 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 "SimpleDwarf.hpp"
|
||||||
#include "DwarfReader.hpp"
|
#include "DwarfReader.hpp"
|
||||||
#include "CodeGenerator.hpp"
|
#include "CodeGenerator.hpp"
|
||||||
|
#include "PcHoleFiller.hpp"
|
||||||
|
|
||||||
#include "settings.hpp"
|
#include "settings.hpp"
|
||||||
|
|
||||||
|
@ -92,8 +93,11 @@ int main(int argc, char** argv) {
|
||||||
MainOptions opts = options_parse(argc, argv);
|
MainOptions opts = options_parse(argc, argv);
|
||||||
SimpleDwarf parsed_dwarf = DwarfReader(opts.elf_path).read();
|
SimpleDwarf parsed_dwarf = DwarfReader(opts.elf_path).read();
|
||||||
|
|
||||||
|
SimpleDwarf filtered_dwarf =
|
||||||
|
PcHoleFiller()(parsed_dwarf);
|
||||||
|
|
||||||
CodeGenerator code_gen(
|
CodeGenerator code_gen(
|
||||||
parsed_dwarf,
|
filtered_dwarf,
|
||||||
cout,
|
cout,
|
||||||
[](const SimpleDwarf::Fde& fde) {
|
[](const SimpleDwarf::Fde& fde) {
|
||||||
std::ostringstream ss;
|
std::ostringstream ss;
|
||||||
|
|
Loading…
Reference in a new issue