Use max(uintptr_t) as error, not assert(0)

This commit is contained in:
Théophile Bastian 2018-06-13 19:13:33 +02:00
parent d53fcd22c6
commit 81b3419690
2 changed files with 41 additions and 12 deletions

View file

@ -4,9 +4,13 @@
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
#include <exception>
#include <sstream>
using namespace std; using namespace std;
class UnhandledRegister: public std::exception {};
static const char* PRELUDE = static const char* PRELUDE =
"#include <assert.h>\n" "#include <assert.h>\n"
"\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<uintptr_t>::max() << "ull";
val = oss.str();
}
return val;
}
void CodeGenerator::generate() { void CodeGenerator::generate() {
gen_of_dwarf(); gen_of_dwarf();
} }
@ -77,7 +91,11 @@ void CodeGenerator::gen_unwind_func_header(const std::string& name) {
} }
void CodeGenerator::gen_unwind_func_footer() { 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" << "\t}\n"
<< "}" << endl; << "}" << endl;
} }
@ -109,6 +127,7 @@ void CodeGenerator::gen_of_row(
{ {
gen_case(row.ip, row_end); gen_case(row.ip, row_end);
try {
os << "\t\t\t" << "out_ctx.rsp = "; os << "\t\t\t" << "out_ctx.rsp = ";
gen_of_reg(row.cfa); gen_of_reg(row.cfa);
os << ';' << endl; os << ';' << endl;
@ -120,6 +139,12 @@ void CodeGenerator::gen_of_row(
os << "\t\t\t" << "out_ctx.rip = "; os << "\t\t\t" << "out_ctx.rip = ";
gen_of_reg(row.ra); gen_of_reg(row.ra);
os << ';' << endl; 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; 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) { void CodeGenerator::gen_of_reg(const SimpleDwarf::DwRegister& reg) {
switch(reg.type) { switch(reg.type) {
case SimpleDwarf::DwRegister::REG_UNDEFINED: case SimpleDwarf::DwRegister::REG_UNDEFINED:
os << std::numeric_limits<uintptr_t>::max() << "ull"; os << undefined_register();
break; break;
case SimpleDwarf::DwRegister::REG_REGISTER: case SimpleDwarf::DwRegister::REG_REGISTER:
os << ctx_of_dw_name(reg.reg) os << ctx_of_dw_name(reg.reg)
@ -186,7 +211,8 @@ void CodeGenerator::gen_of_reg(const SimpleDwarf::DwRegister& reg) {
break; break;
} }
case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED: case SimpleDwarf::DwRegister::REG_NOT_IMPLEMENTED:
os << "0; assert(0)"; os << "0";
throw UnhandledRegister();
break; break;
} }
} }

View file

@ -228,6 +228,9 @@ bool unwind_context(unwind_context_t& ctx) {
uintptr_t tr_pc = ctx.rip - mmap_entry->beg; uintptr_t tr_pc = ctx.rip - mmap_entry->beg;
ctx = fde_func(ctx, tr_pc); 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; return true;
} }