diff --git a/src/CodeGenerator.cpp b/src/CodeGenerator.cpp index 1e7e600..f5b165c 100644 --- a/src/CodeGenerator.cpp +++ b/src/CodeGenerator.cpp @@ -4,9 +4,13 @@ #include #include +#include +#include using namespace std; +class UnhandledRegister: public std::exception {}; + static const char* PRELUDE = "#include \n" "\n" @@ -24,6 +28,16 @@ CodeGenerator::CodeGenerator( } } +static std::string undefined_register() { + static std::string val = ""; + if(val.empty()) { + std::ostringstream oss; + oss << std::numeric_limits::max() << "ull"; + val = oss.str(); + } + return val; +} + void CodeGenerator::generate() { gen_of_dwarf(); } @@ -77,7 +91,11 @@ void CodeGenerator::gen_unwind_func_header(const std::string& name) { } void CodeGenerator::gen_unwind_func_footer() { - os << "\t\tdefault: assert(0);\n" + os << "\t\tdefault:\n" + << "\t\t\tout_ctx.rsp = " << undefined_register() << ";\n" + << "\t\t\tout_ctx.rbp = " << undefined_register() << ";\n" + << "\t\t\tout_ctx.rip = " << undefined_register() << ";\n" + << "\t\t\treturn out_ctx;" << "\t}\n" << "}" << endl; } @@ -109,17 +127,24 @@ void CodeGenerator::gen_of_row( { gen_case(row.ip, row_end); - os << "\t\t\t" << "out_ctx.rsp = "; - gen_of_reg(row.cfa); - os << ';' << endl; + try { + os << "\t\t\t" << "out_ctx.rsp = "; + gen_of_reg(row.cfa); + os << ';' << endl; - os << "\t\t\t" << "out_ctx.rbp = "; - gen_of_reg(row.rbp); - os << ';' << endl; + os << "\t\t\t" << "out_ctx.rbp = "; + gen_of_reg(row.rbp); + os << ';' << endl; - os << "\t\t\t" << "out_ctx.rip = "; - gen_of_reg(row.ra); - os << ';' << endl; + os << "\t\t\t" << "out_ctx.rip = "; + gen_of_reg(row.ra); + os << ';' << endl; + } catch(const UnhandledRegister& exn) { + os << ";\n" + << "\t\t\tout_ctx.rip = " << undefined_register() << ";\n" + << "\t\t\tout_ctx.rsp = " << undefined_register() << ";\n" + << "\t\t\tout_ctx.rbp = " << undefined_register() << ";\n"; + } os << "\t\t\treturn " << "out_ctx" << ";" << endl; } @@ -166,7 +191,7 @@ static const char* ctx_of_dw_name(SimpleDwarf::MachineRegister reg) { void CodeGenerator::gen_of_reg(const SimpleDwarf::DwRegister& reg) { switch(reg.type) { case SimpleDwarf::DwRegister::REG_UNDEFINED: - os << std::numeric_limits::max() << "ull"; + os << undefined_register(); break; case SimpleDwarf::DwRegister::REG_REGISTER: os << ctx_of_dw_name(reg.reg) @@ -186,7 +211,8 @@ void CodeGenerator::gen_of_reg(const SimpleDwarf::DwRegister& reg) { break; } case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED: - os << "0; assert(0)"; + os << "0"; + throw UnhandledRegister(); break; } } diff --git a/stack_walker/stack_walker.cpp b/stack_walker/stack_walker.cpp index 43b3d9a..c5e34ce 100644 --- a/stack_walker/stack_walker.cpp +++ b/stack_walker/stack_walker.cpp @@ -228,6 +228,9 @@ bool unwind_context(unwind_context_t& ctx) { uintptr_t tr_pc = ctx.rip - mmap_entry->beg; ctx = fde_func(ctx, tr_pc); + if(ctx.rip + 1 == 0 && ctx.rsp + 1 == 0 && ctx.rbp + 1 == 0) // no entry + return false; + return true; }