diff --git a/libunwind/src/DwarfInstructions.hpp b/libunwind/src/DwarfInstructions.hpp
--- a/libunwind/src/DwarfInstructions.hpp
+++ b/libunwind/src/DwarfInstructions.hpp
@@ -46,20 +46,25 @@
DW_X86_RET_ADDR = 8
};
- typedef typename CFI_Parser::RegisterLocation RegisterLocation;
- typedef typename CFI_Parser::PrologInfo PrologInfo;
- typedef typename CFI_Parser::FDE_Info FDE_Info;
- typedef typename CFI_Parser::CIE_Info CIE_Info;
+ typedef typename CFI_Parser::RegisterSavedWhere RegisterSavedWhere;
+ typedef typename CFI_Parser::PrologInfo PrologInfo;
+ typedef typename CFI_Parser::FDE_Info FDE_Info;
+ typedef typename CFI_Parser::CIE_Info CIE_Info;
static pint_t evaluateExpression(pint_t expression, A &addressSpace,
const R ®isters,
pint_t initialStackValue);
static pint_t getSavedRegister(A &addressSpace, const R ®isters,
- pint_t cfa, const RegisterLocation &savedReg);
+ pint_t cfa, const RegisterSavedWhere location,
+ const int64_t value);
static double getSavedFloatRegister(A &addressSpace, const R ®isters,
- pint_t cfa, const RegisterLocation &savedReg);
+ pint_t cfa,
+ const RegisterSavedWhere location,
+ const int64_t value);
static v128 getSavedVectorRegister(A &addressSpace, const R ®isters,
- pint_t cfa, const RegisterLocation &savedReg);
+ pint_t cfa,
+ const RegisterSavedWhere location,
+ const int64_t value);
static pint_t getCFA(A &addressSpace, const PrologInfo &prolog,
const R ®isters) {
@@ -67,7 +72,7 @@
return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
prolog.cfaRegisterOffset);
if (prolog.cfaExpression != 0)
- return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
+ return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
registers, 0);
assert(0 && "getCFA(): unknown location");
__builtin_unreachable();
@@ -78,21 +83,20 @@
template
typename A::pint_t DwarfInstructions::getSavedRegister(
A &addressSpace, const R ®isters, pint_t cfa,
- const RegisterLocation &savedReg) {
- switch (savedReg.location) {
+ const RegisterSavedWhere location, const int64_t value) {
+ switch (location) {
case CFI_Parser::kRegisterInCFA:
- return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value);
+ return (pint_t)addressSpace.getRegister(cfa + (pint_t)value);
case CFI_Parser::kRegisterAtExpression:
- return (pint_t)addressSpace.getRegister(evaluateExpression(
- (pint_t)savedReg.value, addressSpace, registers, cfa));
+ return (pint_t)addressSpace.getRegister(
+ evaluateExpression((pint_t)value, addressSpace, registers, cfa));
case CFI_Parser::kRegisterIsExpression:
- return evaluateExpression((pint_t)savedReg.value, addressSpace,
- registers, cfa);
+ return evaluateExpression((pint_t)value, addressSpace, registers, cfa);
case CFI_Parser::kRegisterInRegister:
- return registers.getRegister((int)savedReg.value);
+ return registers.getRegister((int)value);
case CFI_Parser::kRegisterUnused:
case CFI_Parser::kRegisterOffsetFromCFA:
@@ -105,15 +109,14 @@
template
double DwarfInstructions::getSavedFloatRegister(
A &addressSpace, const R ®isters, pint_t cfa,
- const RegisterLocation &savedReg) {
- switch (savedReg.location) {
+ const RegisterSavedWhere location, const int64_t value) {
+ switch (location) {
case CFI_Parser::kRegisterInCFA:
- return addressSpace.getDouble(cfa + (pint_t)savedReg.value);
+ return addressSpace.getDouble(cfa + (pint_t)value);
case CFI_Parser::kRegisterAtExpression:
return addressSpace.getDouble(
- evaluateExpression((pint_t)savedReg.value, addressSpace,
- registers, cfa));
+ evaluateExpression((pint_t)value, addressSpace, registers, cfa));
case CFI_Parser::kRegisterIsExpression:
case CFI_Parser::kRegisterUnused:
@@ -128,15 +131,14 @@
template
v128 DwarfInstructions::getSavedVectorRegister(
A &addressSpace, const R ®isters, pint_t cfa,
- const RegisterLocation &savedReg) {
- switch (savedReg.location) {
+ const RegisterSavedWhere location, const int64_t value) {
+ switch (location) {
case CFI_Parser::kRegisterInCFA:
- return addressSpace.getVector(cfa + (pint_t)savedReg.value);
+ return addressSpace.getVector(cfa + (pint_t)value);
case CFI_Parser::kRegisterAtExpression:
return addressSpace.getVector(
- evaluateExpression((pint_t)savedReg.value, addressSpace,
- registers, cfa));
+ evaluateExpression((pint_t)value, addressSpace, registers, cfa));
case CFI_Parser::kRegisterIsExpression:
case CFI_Parser::kRegisterUnused:
@@ -171,23 +173,27 @@
assert(lastReg >= (int)cieInfo.returnAddressRegister &&
"register range does not contain return address register");
for (int i = 0; i <= lastReg; ++i) {
- if (prolog.savedRegisters[i].location !=
+ if (prolog.savedRegisterLocations[i] !=
CFI_Parser::kRegisterUnused) {
if (registers.validFloatRegister(i))
newRegisters.setFloatRegister(
i, getSavedFloatRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]));
+ prolog.savedRegisterLocations[i],
+ prolog.savedRegisterValues[i]));
else if (registers.validVectorRegister(i))
newRegisters.setVectorRegister(
i, getSavedVectorRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]));
+ prolog.savedRegisterLocations[i],
+ prolog.savedRegisterValues[i]));
else if (i == (int)cieInfo.returnAddressRegister)
returnAddress = getSavedRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]);
+ prolog.savedRegisterLocations[i],
+ prolog.savedRegisterValues[i]);
else if (registers.validRegister(i))
newRegisters.setRegister(
i, getSavedRegister(addressSpace, registers, cfa,
- prolog.savedRegisters[i]));
+ prolog.savedRegisterLocations[i],
+ prolog.savedRegisterValues[i]));
else
return UNW_EBADREG;
}
@@ -206,7 +212,7 @@
// restored. autia1716 is used instead of autia as autia1716 assembles
// to a NOP on pre-v8.3a architectures.
if ((R::getArch() == REGISTERS_ARM64) &&
- prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value) {
+ prolog.savedRegisterValues[UNW_ARM64_RA_SIGN_STATE]) {
#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
return UNW_ECROSSRASIGNING;
#else
diff --git a/libunwind/src/DwarfParser.hpp b/libunwind/src/DwarfParser.hpp
--- a/libunwind/src/DwarfParser.hpp
+++ b/libunwind/src/DwarfParser.hpp
@@ -67,7 +67,7 @@
enum {
kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER
};
- enum RegisterSavedWhere {
+ enum RegisterSavedWhere : uint8_t {
kRegisterUnused,
kRegisterInCFA,
kRegisterOffsetFromCFA,
@@ -75,21 +75,18 @@
kRegisterAtExpression,
kRegisterIsExpression
};
- struct RegisterLocation {
- RegisterSavedWhere location;
- int64_t value;
- };
/// Information about a frame layout and registers saved determined
/// by "running" the DWARF FDE "instructions"
struct PrologInfo {
- uint32_t cfaRegister;
- int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
- int64_t cfaExpression; // CFA = expression
- uint32_t spExtraArgSize;
- uint32_t codeOffsetAtStackDecrement;
- bool registersInOtherRegisters;
- bool sameValueUsed;
- RegisterLocation savedRegisters[kMaxRegisterNumber + 1];
+ uint32_t cfaRegister;
+ int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
+ int64_t cfaExpression; // CFA = expression
+ uint32_t spExtraArgSize;
+ uint32_t codeOffsetAtStackDecrement;
+ bool registersInOtherRegisters;
+ bool sameValueUsed;
+ RegisterSavedWhere savedRegisterLocations[kMaxRegisterNumber + 1];
+ int64_t savedRegisterValues[kMaxRegisterNumber + 1];
};
struct PrologInfoStackEntry {
@@ -443,8 +440,8 @@
"malformed DW_CFA_offset_extended DWARF unwind, reg too big");
return false;
}
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
+ results->savedRegisterLocations[reg] = kRegisterInCFA;
+ results->savedRegisterValues[reg] = offset;
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
"offset=%" PRId64 ")\n",
reg, offset);
@@ -456,7 +453,9 @@
"malformed DW_CFA_restore_extended DWARF unwind, reg too big");
return false;
}
- results->savedRegisters[reg] = initialState.savedRegisters[reg];
+ results->savedRegisterLocations[reg] =
+ initialState.savedRegisterLocations[reg];
+ results->savedRegisterValues[reg] = initialState.savedRegisterValues[reg];
_LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n", reg);
break;
case DW_CFA_undefined:
@@ -466,7 +465,7 @@
"malformed DW_CFA_undefined DWARF unwind, reg too big");
return false;
}
- results->savedRegisters[reg].location = kRegisterUnused;
+ results->savedRegisterLocations[reg] = kRegisterUnused;
_LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
break;
case DW_CFA_same_value:
@@ -480,7 +479,7 @@
// "same value" means register was stored in frame, but its current
// value has not changed, so no need to restore from frame.
// We model this as if the register was never saved.
- results->savedRegisters[reg].location = kRegisterUnused;
+ results->savedRegisterLocations[reg] = kRegisterUnused;
// set flag to disable conversion to compact unwind
results->sameValueUsed = true;
_LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
@@ -498,8 +497,8 @@
"malformed DW_CFA_register DWARF unwind, reg2 too big");
return false;
}
- results->savedRegisters[reg].location = kRegisterInRegister;
- results->savedRegisters[reg].value = (int64_t)reg2;
+ results->savedRegisterLocations[reg] = kRegisterInRegister;
+ results->savedRegisterValues[reg] = (int64_t)reg2;
// set flag to disable conversion to compact unwind
results->registersInOtherRegisters = true;
_LIBUNWIND_TRACE_DWARF(
@@ -576,15 +575,15 @@
"malformed DW_CFA_expression DWARF unwind, reg too big");
return false;
}
- results->savedRegisters[reg].location = kRegisterAtExpression;
- results->savedRegisters[reg].value = (int64_t)p;
+ results->savedRegisterLocations[reg] = kRegisterAtExpression;
+ results->savedRegisterValues[reg] = (int64_t)p;
length = addressSpace.getULEB128(p, instructionsEnd);
assert(length < static_cast(~0) && "pointer overflow");
p += static_cast(length);
_LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
"expression=0x%" PRIx64 ", "
"length=%" PRIu64 ")\n",
- reg, results->savedRegisters[reg].value, length);
+ reg, results->savedRegisterValues[reg], length);
break;
case DW_CFA_offset_extended_sf:
reg = addressSpace.getULEB128(p, instructionsEnd);
@@ -595,8 +594,8 @@
}
offset =
addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
+ results->savedRegisterLocations[reg] = kRegisterInCFA;
+ results->savedRegisterValues[reg] = offset;
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
"offset=%" PRId64 ")\n",
reg, offset);
@@ -634,8 +633,8 @@
}
offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
* cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
- results->savedRegisters[reg].value = offset;
+ results->savedRegisterLocations[reg] = kRegisterOffsetFromCFA;
+ results->savedRegisterValues[reg] = offset;
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
"offset=%" PRId64 "\n",
reg, offset);
@@ -649,8 +648,8 @@
}
offset =
addressSpace.getSLEB128(p, instructionsEnd) * cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterOffsetFromCFA;
- results->savedRegisters[reg].value = offset;
+ results->savedRegisterLocations[reg] = kRegisterOffsetFromCFA;
+ results->savedRegisterValues[reg] = offset;
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
"offset=%" PRId64 "\n",
reg, offset);
@@ -662,14 +661,14 @@
"malformed DW_CFA_val_expression DWARF unwind, reg too big");
return false;
}
- results->savedRegisters[reg].location = kRegisterIsExpression;
- results->savedRegisters[reg].value = (int64_t)p;
+ results->savedRegisterLocations[reg] = kRegisterIsExpression;
+ results->savedRegisterValues[reg] = (int64_t)p;
length = addressSpace.getULEB128(p, instructionsEnd);
assert(length < static_cast(~0) && "pointer overflow");
p += static_cast(length);
_LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
"expression=0x%" PRIx64 ", length=%" PRIu64 ")\n",
- reg, results->savedRegisters[reg].value, length);
+ reg, results->savedRegisterValues[reg], length);
break;
case DW_CFA_GNU_args_size:
length = addressSpace.getULEB128(p, instructionsEnd);
@@ -685,8 +684,8 @@
}
offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
* cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = -offset;
+ results->savedRegisterLocations[reg] = kRegisterInCFA;
+ results->savedRegisterValues[reg] = -offset;
_LIBUNWIND_TRACE_DWARF(
"DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
break;
@@ -700,7 +699,7 @@
switch (arch) {
#if defined(_LIBUNWIND_TARGET_AARCH64)
case REGISTERS_ARM64:
- results->savedRegisters[UNW_ARM64_RA_SIGN_STATE].value ^= 0x1;
+ results->savedRegisterValues[UNW_ARM64_RA_SIGN_STATE] ^= 0x1;
_LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
break;
#endif
@@ -709,15 +708,14 @@
case REGISTERS_SPARC:
_LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
- results->savedRegisters[reg].location = kRegisterInRegister;
- results->savedRegisters[reg].value =
+ results->savedRegisterLocations[reg] = kRegisterInRegister;
+ results->savedRegisterValues[reg] =
((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0;
}
for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value =
- ((int64_t)reg - UNW_SPARC_L0) * 4;
+ results->savedRegisterLocations[reg] = kRegisterInCFA;
+ results->savedRegisterValues[reg] = ((int64_t)reg - UNW_SPARC_L0) * 4;
}
break;
#endif
@@ -740,8 +738,8 @@
}
offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd)
* cieInfo.dataAlignFactor;
- results->savedRegisters[reg].location = kRegisterInCFA;
- results->savedRegisters[reg].value = offset;
+ results->savedRegisterLocations[reg] = kRegisterInCFA;
+ results->savedRegisterValues[reg] = offset;
_LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
operand, offset);
break;
@@ -758,7 +756,10 @@
reg);
return false;
}
- results->savedRegisters[reg] = initialState.savedRegisters[reg];
+ results->savedRegisterLocations[reg] =
+ initialState.savedRegisterLocations[reg];
+ results->savedRegisterValues[reg] =
+ initialState.savedRegisterValues[reg];
_LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
static_cast(operand));
break;