Add generation of a lookup function
This commit is contained in:
parent
44543d85d3
commit
c07b0623e4
3 changed files with 58 additions and 6 deletions
|
@ -8,10 +8,16 @@ static const char* PRELUDE =
|
||||||
"\n"
|
"\n"
|
||||||
"typedef struct {\n"
|
"typedef struct {\n"
|
||||||
" uintptr_t rip, rsp, rbp;\n"
|
" uintptr_t rip, rsp, rbp;\n"
|
||||||
"} unwind_context_t;\n";
|
"} unwind_context_t;\n"
|
||||||
|
"\n"
|
||||||
|
"typedef unwind_context_t (*_fde_func_t)(unwind_context_t, uintptr_t);\n"
|
||||||
|
;
|
||||||
|
|
||||||
CodeGenerator::CodeGenerator(const SimpleDwarf& dwarf, std::ostream& os):
|
CodeGenerator::CodeGenerator(
|
||||||
dwarf(dwarf), os(os)
|
const SimpleDwarf& dwarf,
|
||||||
|
std::ostream& os,
|
||||||
|
NamingScheme naming_scheme):
|
||||||
|
dwarf(dwarf), os(os), naming_scheme(naming_scheme)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void CodeGenerator::generate() {
|
void CodeGenerator::generate() {
|
||||||
|
@ -21,15 +27,26 @@ void CodeGenerator::generate() {
|
||||||
void CodeGenerator::gen_of_dwarf() {
|
void CodeGenerator::gen_of_dwarf() {
|
||||||
os << PRELUDE << '\n' << endl;
|
os << PRELUDE << '\n' << endl;
|
||||||
|
|
||||||
|
vector<LookupEntry> lookup_entries;
|
||||||
|
|
||||||
// A function per FDE
|
// A function per FDE
|
||||||
for(const auto& fde: dwarf.fde_list) {
|
for(const auto& fde: dwarf.fde_list) {
|
||||||
|
LookupEntry cur_entry;
|
||||||
|
cur_entry.name = naming_scheme(fde);
|
||||||
|
cur_entry.beg = fde.beg_ip;
|
||||||
|
cur_entry.end = fde.end_ip;
|
||||||
|
lookup_entries.push_back(cur_entry);
|
||||||
|
|
||||||
gen_of_fde(fde);
|
gen_of_fde(fde);
|
||||||
os << endl;
|
os << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_lookup(lookup_entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeGenerator::gen_of_fde(const SimpleDwarf::Fde& fde) {
|
void CodeGenerator::gen_of_fde(const SimpleDwarf::Fde& fde) {
|
||||||
os << "unwind_context_t _fde_" << fde.beg_ip
|
os << "unwind_context_t "
|
||||||
|
<< naming_scheme(fde)
|
||||||
<< "(unwind_context_t ctx, uintptr_t pc) {\n"
|
<< "(unwind_context_t ctx, uintptr_t pc) {\n"
|
||||||
<< "\tunwind_context_t out_ctx;\n"
|
<< "\tunwind_context_t out_ctx;\n"
|
||||||
<< "\tswitch(pc) {" << endl;
|
<< "\tswitch(pc) {" << endl;
|
||||||
|
@ -104,3 +121,15 @@ void CodeGenerator::gen_of_reg(const SimpleDwarf::DwRegister& reg) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::gen_lookup(const std::vector<LookupEntry>& entries) {
|
||||||
|
os << "_fde_func_t _fde_lookup(uintptr_t pc) {\n"
|
||||||
|
<< "\tswitch(pc) {" << endl;
|
||||||
|
for(const auto& entry: entries) {
|
||||||
|
os << "\t\tcase " << entry.beg << " ... " << entry.end - 1 << ":\n"
|
||||||
|
<< "\t\t\treturn &" << entry.name << ";" << endl;
|
||||||
|
}
|
||||||
|
os << "\t\tdefault: assert(0);\n"
|
||||||
|
<< "\t}\n"
|
||||||
|
<< "}" << endl;
|
||||||
|
}
|
||||||
|
|
|
@ -3,22 +3,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "SimpleDwarf.hpp"
|
#include "SimpleDwarf.hpp"
|
||||||
|
|
||||||
class CodeGenerator {
|
class CodeGenerator {
|
||||||
public:
|
public:
|
||||||
|
/// A function deriving a generated function name from a FDE
|
||||||
|
typedef std::function<std::string(const SimpleDwarf::Fde&)>
|
||||||
|
NamingScheme;
|
||||||
|
|
||||||
/// Unimplemented case
|
/// Unimplemented case
|
||||||
class NotImplementedCase: public std::exception {};
|
class NotImplementedCase: public std::exception {};
|
||||||
|
|
||||||
/** Create a CodeGenerator to generate code for the given dwarf, on the
|
/** Create a CodeGenerator to generate code for the given dwarf, on the
|
||||||
* given std::ostream object (eg. cout). */
|
* given std::ostream object (eg. cout). */
|
||||||
CodeGenerator(const SimpleDwarf& dwarf, std::ostream& os);
|
CodeGenerator(const SimpleDwarf& dwarf, std::ostream& os,
|
||||||
|
NamingScheme naming_scheme);
|
||||||
|
|
||||||
/// Actually generate the code on the given stream
|
/// Actually generate the code on the given stream
|
||||||
void generate();
|
void generate();
|
||||||
|
|
||||||
private: //meth
|
private: //meth
|
||||||
|
struct LookupEntry {
|
||||||
|
std::string name;
|
||||||
|
uintptr_t beg, end;
|
||||||
|
};
|
||||||
|
|
||||||
void gen_of_dwarf();
|
void gen_of_dwarf();
|
||||||
void gen_of_fde(const SimpleDwarf::Fde& fde);
|
void gen_of_fde(const SimpleDwarf::Fde& fde);
|
||||||
void gen_of_row(
|
void gen_of_row(
|
||||||
|
@ -27,7 +38,11 @@ class CodeGenerator {
|
||||||
void gen_of_reg(
|
void gen_of_reg(
|
||||||
const SimpleDwarf::DwRegister& reg);
|
const SimpleDwarf::DwRegister& reg);
|
||||||
|
|
||||||
|
void gen_lookup(const std::vector<LookupEntry>& entries);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SimpleDwarf dwarf;
|
SimpleDwarf dwarf;
|
||||||
std::ostream& os;
|
std::ostream& os;
|
||||||
|
|
||||||
|
NamingScheme naming_scheme;
|
||||||
};
|
};
|
||||||
|
|
10
src/main.cpp
10
src/main.cpp
|
@ -1,6 +1,7 @@
|
||||||
/** Entry point */
|
/** Entry point */
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "SimpleDwarf.hpp"
|
#include "SimpleDwarf.hpp"
|
||||||
|
@ -23,7 +24,14 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
cerr << "=====================" << endl << endl;
|
cerr << "=====================" << endl << endl;
|
||||||
|
|
||||||
CodeGenerator code_gen(parsed_dwarf, cout);
|
CodeGenerator code_gen(
|
||||||
|
parsed_dwarf,
|
||||||
|
cout,
|
||||||
|
[](const SimpleDwarf::Fde& fde) {
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "_fde_" << fde.beg_ip;
|
||||||
|
return ss.str();
|
||||||
|
});
|
||||||
code_gen.generate();
|
code_gen.generate();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue