in Crashlytics/Crashlytics/Unwind/FIRCLSUnwind_arm.c [193:308]
bool FIRCLSDwarfUnwindSetRegisterValue(FIRCLSThreadContext* registers,
uint64_t num,
uintptr_t value) {
switch (num) {
case CLS_DWARF_ARM64_X0:
registers->__ss.__x[0] = value;
return true;
case CLS_DWARF_ARM64_X1:
registers->__ss.__x[1] = value;
return true;
case CLS_DWARF_ARM64_X2:
registers->__ss.__x[2] = value;
return true;
case CLS_DWARF_ARM64_X3:
registers->__ss.__x[3] = value;
return true;
case CLS_DWARF_ARM64_X4:
registers->__ss.__x[4] = value;
return true;
case CLS_DWARF_ARM64_X5:
registers->__ss.__x[5] = value;
return true;
case CLS_DWARF_ARM64_X6:
registers->__ss.__x[6] = value;
return true;
case CLS_DWARF_ARM64_X7:
registers->__ss.__x[7] = value;
return true;
case CLS_DWARF_ARM64_X8:
registers->__ss.__x[8] = value;
return true;
case CLS_DWARF_ARM64_X9:
registers->__ss.__x[9] = value;
return true;
case CLS_DWARF_ARM64_X10:
registers->__ss.__x[10] = value;
return true;
case CLS_DWARF_ARM64_X11:
registers->__ss.__x[11] = value;
return true;
case CLS_DWARF_ARM64_X12:
registers->__ss.__x[12] = value;
return true;
case CLS_DWARF_ARM64_X13:
registers->__ss.__x[13] = value;
return true;
case CLS_DWARF_ARM64_X14:
registers->__ss.__x[14] = value;
return true;
case CLS_DWARF_ARM64_X15:
registers->__ss.__x[15] = value;
return true;
case CLS_DWARF_ARM64_X16:
registers->__ss.__x[16] = value;
return true;
case CLS_DWARF_ARM64_X17:
registers->__ss.__x[17] = value;
return true;
case CLS_DWARF_ARM64_X18:
registers->__ss.__x[18] = value;
return true;
case CLS_DWARF_ARM64_X19:
registers->__ss.__x[19] = value;
return true;
case CLS_DWARF_ARM64_X20:
registers->__ss.__x[20] = value;
return true;
case CLS_DWARF_ARM64_X21:
registers->__ss.__x[21] = value;
return true;
case CLS_DWARF_ARM64_X22:
registers->__ss.__x[22] = value;
return true;
case CLS_DWARF_ARM64_X23:
registers->__ss.__x[23] = value;
return true;
case CLS_DWARF_ARM64_X24:
registers->__ss.__x[24] = value;
return true;
case CLS_DWARF_ARM64_X25:
registers->__ss.__x[25] = value;
return true;
case CLS_DWARF_ARM64_X26:
registers->__ss.__x[26] = value;
return true;
case CLS_DWARF_ARM64_X27:
registers->__ss.__x[27] = value;
return true;
case CLS_DWARF_ARM64_X28:
registers->__ss.__x[28] = value;
return true;
case CLS_DWARF_ARM64_FP:
FIRCLSThreadContextSetFramePointer(registers, value);
return true;
case CLS_DWARF_ARM64_SP:
FIRCLSThreadContextSetStackPointer(registers, value);
return true;
case CLS_DWARF_ARM64_LR:
// Here's what's going on. For x86, the "return register" is virtual. The architecture
// doesn't actually have one, but DWARF does have the concept. So, when the system
// tries to set the return register, we set the PC. You can see this behavior
// in the FIRCLSDwarfUnwindSetRegisterValue implemenation for that architecture. In the
// case of ARM64, the register is real. So, we have to be extra careful to make sure
// we update the PC here. Otherwise, when a DWARF unwind completes, it won't have
// changed the PC to the right value.
FIRCLSThreadContextSetLinkRegister(registers, value);
FIRCLSThreadContextSetPC(registers, value);
return true;
default:
break;
}
FIRCLSSDKLog("Unrecognized set register number %llu\n", num);
return false;
}