Index: libunwind/src/DwarfInstructions.hpp =================================================================== --- libunwind/src/DwarfInstructions.hpp +++ libunwind/src/DwarfInstructions.hpp @@ -93,7 +93,8 @@ case CFI_Parser::kRegisterInRegister: return registers.getRegister((int)savedReg.value); - + case CFI_Parser::kRegisterUndefined: + return 0; case CFI_Parser::kRegisterUnused: case CFI_Parser::kRegisterOffsetFromCFA: // FIX ME @@ -117,6 +118,7 @@ case CFI_Parser::kRegisterIsExpression: case CFI_Parser::kRegisterUnused: + case CFI_Parser::kRegisterUndefined: case CFI_Parser::kRegisterOffsetFromCFA: case CFI_Parser::kRegisterInRegister: // FIX ME @@ -140,6 +142,7 @@ case CFI_Parser::kRegisterIsExpression: case CFI_Parser::kRegisterUnused: + case CFI_Parser::kRegisterUndefined: case CFI_Parser::kRegisterOffsetFromCFA: case CFI_Parser::kRegisterInRegister: // FIX ME @@ -190,6 +193,10 @@ prolog.savedRegisters[i])); else return UNW_EBADREG; + } else if (i == (int)cieInfo.returnAddressRegister) { + // Leaf function keeps the return address in register and there is no + // explicit intructions how to restore it. + returnAddress = registers.getRegister(cieInfo.returnAddressRegister); } } Index: libunwind/src/DwarfParser.hpp =================================================================== --- libunwind/src/DwarfParser.hpp +++ libunwind/src/DwarfParser.hpp @@ -69,6 +69,7 @@ }; enum RegisterSavedWhere { kRegisterUnused, + kRegisterUndefined, kRegisterInCFA, kRegisterOffsetFromCFA, kRegisterInRegister, @@ -502,7 +503,7 @@ "malformed DW_CFA_undefined DWARF unwind, reg too big"); return false; } - results->setRegisterLocation(reg, kRegisterUnused, initialState); + results->setRegisterLocation(reg, kRegisterUndefined, initialState); _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg); break; case DW_CFA_same_value: