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: